Some typos fixed, base classes for asset edit steps
parent
cf79f39a7a
commit
bf62007391
|
|
@ -34,6 +34,7 @@ import org.librecms.contentsection.FolderManager;
|
|||
import org.librecms.contentsection.FolderRepository;
|
||||
import org.librecms.contentsection.FolderType;
|
||||
import org.librecms.contentsection.privileges.AssetPrivileges;
|
||||
import org.librecms.ui.contentsections.assets.MvcAssetCreateStep;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -44,6 +45,8 @@ import java.util.Optional;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.enterprise.inject.Any;
|
||||
import javax.enterprise.inject.Instance;
|
||||
import javax.inject.Inject;
|
||||
import javax.mvc.Controller;
|
||||
import javax.mvc.Models;
|
||||
|
|
@ -154,6 +157,10 @@ public class AssetFolderController {
|
|||
@Inject
|
||||
private Models models;
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
private Instance<MvcAssetCreateStep<?>> assetCreateSteps;
|
||||
|
||||
/**
|
||||
* Performs operations on permissions.
|
||||
*/
|
||||
|
|
@ -267,6 +274,17 @@ public class AssetFolderController {
|
|||
assetFolderTree.buildFolderTree(section, folder)
|
||||
);
|
||||
|
||||
contentSectionModel.setAvailableAssetTypes(
|
||||
assetCreateSteps
|
||||
.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
step -> step.getAssetType(),
|
||||
step -> step.getLabel()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
assetFolderModel.setRows(
|
||||
folderEntries
|
||||
.stream()
|
||||
|
|
|
|||
|
|
@ -145,6 +145,14 @@ public class AssetFolderModel {
|
|||
this.path = path;
|
||||
}
|
||||
|
||||
public String getPathWithTrailingSlash() {
|
||||
if (path.isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
return String.format("%s/", path);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCanCreateSubFolders() {
|
||||
return canCreateSubFolders;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public class AssetPermissionsChecker {
|
|||
* {@link AssetPrivileges#EDIT} privilege for the provided
|
||||
* {@link Asset} to the current user, {@code false} otherwise.
|
||||
*/
|
||||
public boolean canEditAssets(final Asset asset) {
|
||||
public boolean canEditAsset(final Asset asset) {
|
||||
return permissionChecker.isPermitted(
|
||||
AssetPrivileges.EDIT, asset
|
||||
);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public class AssetPermissionsModelProvider {
|
|||
permissionChecker.canDeleteAssets(asset)
|
||||
);
|
||||
model.setGrantedEdit(
|
||||
permissionChecker.canEditAssets(asset)
|
||||
permissionChecker.canEditAsset(asset)
|
||||
);
|
||||
model.setGrantedUse(
|
||||
permissionChecker.canUseAssets(asset)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ public class ContentSectionModel {
|
|||
|
||||
private Map<String, String> availableDocumentTypes;
|
||||
|
||||
private Map<String, String> availableAssetTypes;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
|
@ -129,6 +131,16 @@ public class ContentSectionModel {
|
|||
= new LinkedHashMap<>(availableDocumentTypes);
|
||||
}
|
||||
|
||||
public Map<String, String> getAvailableAssetTypes() {
|
||||
return Collections.unmodifiableMap(availableAssetTypes);
|
||||
}
|
||||
|
||||
protected void setAvailableAssetTypes(
|
||||
final Map<String, String> availableAssetTypes
|
||||
) {
|
||||
this.availableAssetTypes = new LinkedHashMap<>(availableAssetTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the current user administer the categories of the domains/category
|
||||
* sytems assigned to the section?
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
/**
|
||||
* Used by the {@link MvcAuthoringStepService} to indicate that the requested
|
||||
|
|
@ -39,7 +39,7 @@ public class ContentSectionNotFoundException extends Exception {
|
|||
*
|
||||
* @param errorMessageTemplate Template for the error message.
|
||||
*/
|
||||
ContentSectionNotFoundException(final String errorMessageTemplate) {
|
||||
public ContentSectionNotFoundException(final String errorMessageTemplate) {
|
||||
super();
|
||||
this.errorMessageTemplate = errorMessageTemplate;
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ public class ContentSectionNotFoundException extends Exception {
|
|||
* @param msg The detail message.
|
||||
* @param errorMessageTemplate Template for the error message.
|
||||
*/
|
||||
ContentSectionNotFoundException(
|
||||
public ContentSectionNotFoundException(
|
||||
final String errorMessageTemplate, final String msg
|
||||
) {
|
||||
super(msg);
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.assets;
|
||||
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetManager;
|
||||
import org.librecms.contentsection.AssetRepository;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.ui.contentsections.AssetPermissionsChecker;
|
||||
import org.librecms.ui.contentsections.ContentSectionModel;
|
||||
import org.librecms.ui.contentsections.ContentSectionsUi;
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.mvc.Models;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public abstract class AbstractMvcAssetEditStep implements MvcAssetEditStep {
|
||||
|
||||
@Inject
|
||||
private AssetUi assetUi;
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private AssetPermissionsChecker assetPermissionsChecker;
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepo;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private ContentSectionModel sectionModel;
|
||||
|
||||
@Inject
|
||||
private ContentSectionsUi sectionsUi;
|
||||
|
||||
@Inject
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Inject
|
||||
private Models models;
|
||||
|
||||
@Inject
|
||||
private SelectedAssetModel assetModel;
|
||||
|
||||
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||
private String sectionIdentifier;
|
||||
|
||||
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||
private String assetPathParam;
|
||||
|
||||
private ContentSection contentSection;
|
||||
|
||||
private Asset asset;
|
||||
|
||||
private String assetPath;
|
||||
|
||||
private String stepPath;
|
||||
|
||||
protected void init() throws ContentSectionNotFoundException,
|
||||
AssetNotFoundException {
|
||||
contentSection = sectionsUi
|
||||
.findContentSection(sectionIdentifier)
|
||||
.orElseThrow(
|
||||
() -> new ContentSectionNotFoundException(
|
||||
sectionsUi.showContentSectionNotFound(sectionIdentifier),
|
||||
String.format(
|
||||
"ContentSection %s not found.",
|
||||
sectionIdentifier
|
||||
)
|
||||
)
|
||||
);
|
||||
sectionModel.setSection(contentSection);
|
||||
|
||||
asset = assetRepo
|
||||
.findByPath(contentSection, assetPathParam)
|
||||
.orElseThrow(
|
||||
() -> new AssetNotFoundException(
|
||||
assetUi.showAssetNotFound(
|
||||
contentSection, assetPathParam
|
||||
),
|
||||
String.format(
|
||||
"No asset for path %s found in section %s.",
|
||||
assetPathParam,
|
||||
contentSection.getLabel()
|
||||
)
|
||||
)
|
||||
);
|
||||
assetModel.setAsset(asset);
|
||||
|
||||
assetPath = assetManager.getAssetPath(asset);
|
||||
final Map<String, String> values = new HashMap<>();
|
||||
values.put(
|
||||
MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM,
|
||||
contentSection.getLabel()
|
||||
);
|
||||
values.put(
|
||||
MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME,
|
||||
assetPath
|
||||
);
|
||||
|
||||
stepPath = Optional
|
||||
.ofNullable(getStepClass().getAnnotation(Path.class))
|
||||
.map(Path::value)
|
||||
.map(
|
||||
path -> UriBuilder
|
||||
.fromPath(path)
|
||||
.buildFromMap(values)
|
||||
.toString()
|
||||
)
|
||||
.orElse("");
|
||||
|
||||
models.put("activeAssetTab", "editTab");
|
||||
models.put("stepPath", stepPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentSection getContentSection() {
|
||||
return Optional
|
||||
.ofNullable(contentSection)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit step %s was not initialized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Asset getAsset() {
|
||||
return Optional
|
||||
.ofNullable(asset)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit step %s was not initialized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetPath() {
|
||||
return Optional
|
||||
.ofNullable(assetPath)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit step %s was not initialized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanEdit() {
|
||||
return assetPermissionsChecker.canEditAsset(asset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAssetPath() {
|
||||
assetPath = assetManager.getAssetPath(asset).substring(1); // Without leading slash
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStepPath() {
|
||||
return stepPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildRedirectPathForStep() {
|
||||
final ContentSection section = Optional
|
||||
.ofNullable(contentSection)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit Step %s was not initalized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
final String assetPathNonNull = Optional
|
||||
.ofNullable(assetPath)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit step %s was not initialized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
final Map<String, String> values = new HashMap<>();
|
||||
values.put(
|
||||
MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM,
|
||||
section.getLabel()
|
||||
);
|
||||
values.put(
|
||||
MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME,
|
||||
assetPathNonNull
|
||||
);
|
||||
|
||||
return Optional
|
||||
.ofNullable(getStepClass().getAnnotation(Path.class))
|
||||
.map(Path::value)
|
||||
.map(
|
||||
path -> UriBuilder
|
||||
.fromPath(path)
|
||||
.buildFromMap(values)
|
||||
.toString()
|
||||
)
|
||||
.map(path -> String.format("redirect:%s", path))
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildRedirectPathForStep(final String subPath) {
|
||||
final ContentSection section = Optional
|
||||
.ofNullable(contentSection)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit Step %s was not initalized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
final String assetPathNonNull = Optional
|
||||
.ofNullable(assetPath)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"Edit step %s was not initialized properly. "
|
||||
+ "Did you forget to call %s#init()?",
|
||||
getStepClass().getName(),
|
||||
AbstractMvcAssetEditStep.class.getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
final Map<String, String> values = new HashMap<>();
|
||||
values.put(
|
||||
MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM,
|
||||
section.getLabel()
|
||||
);
|
||||
values.put(
|
||||
MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME,
|
||||
assetPathNonNull
|
||||
);
|
||||
|
||||
return Optional
|
||||
.ofNullable(getStepClass().getAnnotation(Path.class))
|
||||
.map(Path::value)
|
||||
.map(
|
||||
path -> UriBuilder
|
||||
.fromPath(path)
|
||||
.path(subPath)
|
||||
.buildFromMap(values)
|
||||
.toString()
|
||||
)
|
||||
.map(path -> String.format("redirect:%s", path))
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -75,12 +75,12 @@ public class AssetEditStepsValidator {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (stepClass.getAnnotation(MvcAssetEditStep.class) == null) {
|
||||
if (stepClass.getAnnotation(MvcAssetEditStepDef.class) == null) {
|
||||
LOGGER.warn(
|
||||
"Class {} is part of a set of asset edit steps, but is not "
|
||||
+ "annotated with {}. The class will be ignored.",
|
||||
stepClass.getName(),
|
||||
MvcAssetEditStep.class
|
||||
MvcAssetEditStepDef.class
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ public class AssetEditStepsValidator {
|
|||
|
||||
public boolean supportsAsset(final Class<?> stepClass, final Asset asset) {
|
||||
return Optional
|
||||
.ofNullable(stepClass.getAnnotation(MvcAssetEditStep.class))
|
||||
.ofNullable(stepClass.getAnnotation(MvcAssetEditStepDef.class))
|
||||
.map(
|
||||
stepAnnotation -> asset.getClass().isAssignableFrom(
|
||||
stepAnnotation.supportedAssetType()
|
||||
|
|
@ -97,8 +97,8 @@ public class AssetEditStepsValidator {
|
|||
)
|
||||
.orElse(false);
|
||||
|
||||
// final MvcAssetEditStep stepAnnotation = stepClass.getAnnotation(
|
||||
// MvcAssetEditStep.class
|
||||
// final MvcAssetEditStepDef stepAnnotation = stepClass.getAnnotation(
|
||||
// MvcAssetEditStepDef.class
|
||||
// );
|
||||
//
|
||||
// if (stepAnnotation == null) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package org.librecms.ui.contentsections.assets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class AssetNotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String errorMessageTemplate;
|
||||
|
||||
public AssetNotFoundException(final String errorMessageTemplate) {
|
||||
super();
|
||||
this.errorMessageTemplate = errorMessageTemplate;
|
||||
}
|
||||
|
||||
public AssetNotFoundException(
|
||||
final String errorMessageTemplate, final String msg
|
||||
) {
|
||||
super(msg);
|
||||
this.errorMessageTemplate = errorMessageTemplate;
|
||||
}
|
||||
|
||||
public String showErrorMessage() {
|
||||
return errorMessageTemplate;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -67,6 +67,15 @@ public interface MvcAssetCreateStep<T extends Asset> {
|
|||
*/
|
||||
String getAssetType();
|
||||
|
||||
/**
|
||||
* Localized label of the asset type. The current locale as returned by
|
||||
* {@link GlobalizationHelper#getNegotiatedLocale()} should be used to
|
||||
* select the language variant to return.
|
||||
*
|
||||
* @return The localized label of the asset type.
|
||||
*/
|
||||
String getLabel();
|
||||
|
||||
/**
|
||||
* Localized description of the create step. The current locale as returned
|
||||
* by {@link GlobalizationHelper#getNegotiatedLocale()} should be used to
|
||||
|
|
|
|||
|
|
@ -19,50 +19,51 @@
|
|||
package org.librecms.ui.contentsections.assets;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
|
||||
/**
|
||||
* Metadata of an edit step for assets.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MvcAssetEditStep {
|
||||
public interface MvcAssetEditStep {
|
||||
|
||||
Class<? extends MvcAssetEditStep> getStepClass();
|
||||
|
||||
ContentSection getContentSection() throws ContentSectionNotFoundException;
|
||||
|
||||
Asset getAsset() throws ContentSectionNotFoundException,
|
||||
AssetNotFoundException;
|
||||
|
||||
String getAssetPath() throws ContentSectionNotFoundException,
|
||||
AssetNotFoundException;
|
||||
|
||||
/**
|
||||
* The name of the resource bundle providing the localized values for
|
||||
* {@link #labelKey} and {@link descriptionKey}.
|
||||
* Can the current user edit the asset. This method MUST only return
|
||||
*
|
||||
* @return The resource bundle providing the localized labelKey and
|
||||
* descriptionKey.
|
||||
* @return {@code true} if the current user can edit the asset, {
|
||||
*
|
||||
* @false} otherwise.
|
||||
*/
|
||||
String bundle();
|
||||
boolean getCanEdit();
|
||||
|
||||
/**
|
||||
* The key for the localized description of the step.
|
||||
* If an edit step alters the name of the asset and therefore the path of
|
||||
* the asset, the step MUST call this method to update the asset path used
|
||||
* by the step.
|
||||
*
|
||||
* @return The key for the localized description of the step.
|
||||
* @throws ContentSectionNotFoundException
|
||||
* @throws AssetNotFoundException
|
||||
*/
|
||||
String descriptionKey();
|
||||
void updateAssetPath() throws ContentSectionNotFoundException,
|
||||
AssetNotFoundException;
|
||||
|
||||
/**
|
||||
* The key for the localized label of the authoring step..
|
||||
*
|
||||
* @return The key for the localized label of the authoring step...
|
||||
*/
|
||||
String labelKey();
|
||||
String getStepPath();
|
||||
|
||||
/**
|
||||
* Edit steps only support a specific type, and all subtypes.
|
||||
*
|
||||
* @return The asset type supported by the edit step.
|
||||
*/
|
||||
String buildRedirectPathForStep() throws ContentSectionNotFoundException,
|
||||
AssetNotFoundException;
|
||||
|
||||
Class<? extends Asset> supportedAssetType();
|
||||
String buildRedirectPathForStep(final String subPath)
|
||||
throws ContentSectionNotFoundException, AssetNotFoundException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.assets;
|
||||
|
||||
import org.librecms.contentsection.Asset;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Metadata of an edit step for assets.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MvcAssetEditStepDef {
|
||||
|
||||
/**
|
||||
* The name of the resource bundle providing the localized values for
|
||||
* {@link #labelKey} and {@link descriptionKey}.
|
||||
*
|
||||
* @return The resource bundle providing the localized labelKey and
|
||||
* descriptionKey.
|
||||
*/
|
||||
String bundle();
|
||||
|
||||
/**
|
||||
* The key for the localized description of the step.
|
||||
*
|
||||
* @return The key for the localized description of the step.
|
||||
*/
|
||||
String descriptionKey();
|
||||
|
||||
/**
|
||||
* The key for the localized label of the authoring step..
|
||||
*
|
||||
* @return The key for the localized label of the authoring step...
|
||||
*/
|
||||
String labelKey();
|
||||
|
||||
/**
|
||||
* Edit steps only support a specific type, and all subtypes.
|
||||
*
|
||||
* @return The asset type supported by the edit step.
|
||||
*/
|
||||
|
||||
Class<? extends Asset> supportedAssetType();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
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 java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Named("CmsPostalAddressCreateStep")
|
||||
public class PostalAddressCreateStep
|
||||
extends AbstractMvcAssetCreateStep<PostalAddress> {
|
||||
|
||||
private static final String FORM_PARAMS_NAME = "name";
|
||||
|
||||
private static final String FORM_PARAMS_TITLE = "title";
|
||||
|
||||
private static final String FORM_PARAM_INITIAL_LOCALE = "locale";
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private AssetRepository assetRepo;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Override
|
||||
public String showCreateStep() {
|
||||
return "/org/librecms/ui/assets/postaladdress/create-postaladdress.xhtml";
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public String createAsset(final Map<String, String[]> formParams) {
|
||||
if (!formParams.containsKey(FORM_PARAMS_NAME)
|
||||
|| formParams.get(FORM_PARAMS_NAME) == null
|
||||
|| formParams.get(FORM_PARAMS_NAME).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("postaladdress.createstep.name.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
||||
final String name = formParams.get(FORM_PARAMS_NAME)[0];
|
||||
if (!name.matches("^([a-zA-Z0-9_-]*)$")) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("postaladdress.createstep.name.error.invalid")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
||||
if (!formParams.containsKey(FORM_PARAMS_TITLE)
|
||||
|| formParams.get(FORM_PARAMS_TITLE) == null
|
||||
|| formParams.get(FORM_PARAMS_TITLE).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("postaladdress.createstep.title.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
final String title = formParams.get(FORM_PARAMS_TITLE)[0];
|
||||
|
||||
if (!formParams.containsKey(FORM_PARAM_INITIAL_LOCALE)
|
||||
|| formParams.get(FORM_PARAM_INITIAL_LOCALE) == null
|
||||
|| formParams.get(FORM_PARAM_INITIAL_LOCALE).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper.getLocalizedTextsUtil(
|
||||
getBundle()
|
||||
).getText("createstep.initial_locale.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
final Locale locale = new Locale(
|
||||
formParams.get(FORM_PARAM_INITIAL_LOCALE)[0]
|
||||
);
|
||||
|
||||
final String address = formParams.get("address")[0];
|
||||
final String postalCode = formParams.get("postalCode")[0];
|
||||
final String city = formParams.get("city")[0];
|
||||
final String state = formParams.get("state")[0];
|
||||
final String isoCountryCode = formParams.get("isoCountryCode")[0];
|
||||
|
||||
final PostalAddress postalAddress = assetManager.createAsset(
|
||||
name,
|
||||
title,
|
||||
locale,
|
||||
getFolder(),
|
||||
PostalAddress.class
|
||||
);
|
||||
|
||||
postalAddress.setAddress(address);
|
||||
postalAddress.setPostalCode(postalCode);
|
||||
postalAddress.setCity(city);
|
||||
postalAddress.setState(state);
|
||||
postalAddress.setIsoCountryCode(isoCountryCode);
|
||||
|
||||
assetRepo.save(postalAddress);
|
||||
|
||||
return String.format(
|
||||
"redirect:/%s/assets/%s/%s/@postaladdress-edit",
|
||||
getContentSectionLabel(),
|
||||
getFolderPath(),
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAssetType() {
|
||||
return PostalAddress.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("postal_address.label");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("postal_address.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBundle() {
|
||||
return MvcAssetStepsConstants.BUNDLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.assets;
|
||||
|
||||
import org.librecms.assets.PostalAddress;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Named;
|
||||
import javax.mvc.Controller;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Path(MvcAssetEditSteps.PATH_PREFIX + "postaladdress-edit")
|
||||
@Controller
|
||||
@Named("CmsPostalAddressEditStep")
|
||||
@MvcAssetEditStepDef(
|
||||
bundle = MvcAssetStepsConstants.BUNDLE,
|
||||
descriptionKey = "postaladdress.editstep.description",
|
||||
labelKey = "postaladdress.editstep.label",
|
||||
supportedAssetType = PostalAddress.class
|
||||
)
|
||||
public class PostalAddressEditStep {
|
||||
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
|
|
@ -109,7 +110,8 @@ public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
|
|||
sectionsUi.showContentSectionNotFound(sectionIdentifier),
|
||||
String.format(
|
||||
"ContentSection %s not found.",
|
||||
sectionIdentifier)
|
||||
sectionIdentifier
|
||||
)
|
||||
)
|
||||
);
|
||||
sectionModel.setSection(contentSection);
|
||||
|
|
@ -119,9 +121,10 @@ public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
|
|||
.orElseThrow(
|
||||
() -> new DocumentNotFoundException(
|
||||
documentUi.showDocumentNotFound(
|
||||
contentSection, documentPathParam),
|
||||
contentSection, documentPathParam
|
||||
),
|
||||
String.format(
|
||||
"Not document for path %s in section %s.",
|
||||
"No document for path %s in section %s.",
|
||||
documentPathParam,
|
||||
contentSection.getLabel()
|
||||
)
|
||||
|
|
@ -129,7 +132,7 @@ public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
|
|||
);
|
||||
documentModel.setContentItem(document);
|
||||
|
||||
this.documentPath = itemManager.getItemPath(document);
|
||||
documentPath = itemManager.getItemPath(document);
|
||||
final Map<String, String> values = new HashMap<>();
|
||||
values.put(
|
||||
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM,
|
||||
|
|
@ -356,11 +359,4 @@ public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
|
|||
.orElse("");
|
||||
}
|
||||
|
||||
private String withoutLeadingSlash(final String path) {
|
||||
if (path.startsWith("/")) {
|
||||
return path.substring(1);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.libreccm.api.Identifier;
|
||||
import org.libreccm.api.IdentifierParser;
|
||||
import org.libreccm.categorization.Category;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentItemManager;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.libreccm.api.Identifier;
|
||||
import org.libreccm.api.IdentifierParser;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
|
|
|
|||
|
|
@ -179,9 +179,9 @@ public class MvcArticleCreateStep
|
|||
|| formParams.get(FORM_PARAM_NAME).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper.getLocalizedTextsUtil(
|
||||
getBundle()
|
||||
).getText("createstep.name.error.missing")
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("createstep.name.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
|
@ -190,9 +190,9 @@ public class MvcArticleCreateStep
|
|||
if (!name.matches("^([a-zA-Z0-9_-]*)$")) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper.getLocalizedTextsUtil(
|
||||
getBundle()
|
||||
).getText("createstep.name.error.invalid")
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("createstep.name.error.invalid")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
|
@ -202,9 +202,9 @@ public class MvcArticleCreateStep
|
|||
|| formParams.get(FORM_PARAM_TITLE).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper.getLocalizedTextsUtil(
|
||||
getBundle()
|
||||
).getText("createstep.title.error.missing")
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("createstep.title.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
|
@ -215,9 +215,9 @@ public class MvcArticleCreateStep
|
|||
|| formParams.get(FORM_PARAM_SUMMARY).length == 0) {
|
||||
addMessage(
|
||||
"danger",
|
||||
globalizationHelper.getLocalizedTextsUtil(
|
||||
getBundle()
|
||||
).getText("createstep.summary.error.missing")
|
||||
globalizationHelper
|
||||
.getLocalizedTextsUtil(getBundle())
|
||||
.getText("createstep.summary.error.missing")
|
||||
);
|
||||
return showCreateStep();
|
||||
}
|
||||
|
|
@ -292,6 +292,4 @@ public class MvcArticleCreateStep
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import org.librecms.contentsection.FolderManager;
|
|||
import org.librecms.contenttypes.Article;
|
||||
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
||||
import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
|
||||
import org.librecms.ui.contentsections.documents.ContentSectionNotFoundException;
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
|
||||
import org.librecms.ui.contentsections.documents.DocumentUi;
|
||||
import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import org.librecms.contenttypes.Article;
|
|||
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
||||
import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
|
||||
import org.librecms.ui.contentsections.documents.CmsEditorLocaleVariantRow;
|
||||
import org.librecms.ui.contentsections.documents.ContentSectionNotFoundException;
|
||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||
import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
|
||||
import org.librecms.ui.contentsections.documents.DocumentUi;
|
||||
|
||||
|
|
|
|||
|
|
@ -188,10 +188,55 @@
|
|||
</c:choose>
|
||||
<c:choose>
|
||||
<c:when test="#{AssetFolderModel.canCreateAssets}">
|
||||
<button class="btn btn-primary" title="#{CmsAdminMessages['contentsection.assetfolder.add_asset']}">
|
||||
<button class="btn btn-primary"
|
||||
data-toggle="modal"
|
||||
data-target="#new-asset-dialog"
|
||||
title="#{CmsAdminMessages['contentsection.assetfolder.add_asset']}">
|
||||
<bootstrap:svgIcon icon="file-earmark-plus" />
|
||||
<span class="sr-only">#{CmsAdminMessages['contentsection.assetfolder.add_asset']}</span>
|
||||
</button>
|
||||
<div aria-hidden="true"
|
||||
aria-labelledby="new-asset-dialog-title"
|
||||
class="modal fade"
|
||||
id="new-asset-dialog">
|
||||
<div class="modal-dialog">
|
||||
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{AssetFolderModel.pathWithTrailingSlash}@create"
|
||||
class="modal-content"
|
||||
method="post">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title"
|
||||
id="new-asset-dialog-title">
|
||||
#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.title']}
|
||||
</h2>
|
||||
<button aria-label="#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.close']}"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
type="button">
|
||||
<bootstrap:svgIcon icon="x" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<bootstrap:formGroupSelect
|
||||
help="#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.assettype.help']}"
|
||||
inputId="assetType"
|
||||
label="#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.assettype.label']}"
|
||||
name="assetType"
|
||||
options="#{ContentSectionModel.availableAssetTypes}" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-warning"
|
||||
data-dismiss="modal"
|
||||
type="button">
|
||||
#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.close']}
|
||||
</button>
|
||||
<button class="btn btn-success"
|
||||
type="submit">
|
||||
#{CmsAdminMessages['contentsection.assetfolder.new_asset_dialog.submit']}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<button class="btn btn-primary"
|
||||
|
|
@ -263,7 +308,7 @@
|
|||
id="rename-folder-#{row.name}-dialog-title">
|
||||
#{CmsAdminMessages.getMessage('contentsection.assetfolder.rename_folder_dialog.title', [row.folderPath])}
|
||||
</h2>
|
||||
<button aria-label="#{CmsMessages['contentsection.assetfolder.rename_folder_dialog.close']}"
|
||||
<button aria-label="#{CmsAdminMessages['contentsection.assetfolder.rename_folder_dialog.close']}"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
type="button" >
|
||||
|
|
|
|||
|
|
@ -777,3 +777,9 @@ edit_button.label=Edit
|
|||
save_button.label=Save
|
||||
text.edit.dialog.title=Edit localized variant
|
||||
text.editor.no_localized_values=No localized variants available yet.
|
||||
contentsection.assetfolder.types.folder=Folder
|
||||
contentsection.assetfolder.new_asset_dialog.close=Cancel
|
||||
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
|
||||
|
|
|
|||
|
|
@ -778,3 +778,9 @@ edit_button.label=Bearbeiten
|
|||
save_button.label=Speichern
|
||||
text.edit.dialog.title=Lokalisierte Variante bearbeiten
|
||||
text.editor.no_localized_values=Es wurden noch keine lokalisierten Varianten angelegt
|
||||
contentsection.assetfolder.types.folder=Ordner
|
||||
contentsection.assetfolder.new_asset_dialog.close=Abbrechen
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
create_step=Access denied
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
create_step=Zugriff verweigert
|
||||
Loading…
Reference in New Issue