Some refactoring, and permissions checks

Former-commit-id: 65ef6af336
pull/10/head
Jens Pelzetter 2021-02-03 20:26:22 +01:00
parent af0b0c12a0
commit 8aa371571d
10 changed files with 612 additions and 302 deletions

View File

@ -34,38 +34,6 @@ public final class ItemPrivileges {
*/
public static final String ADMINISTER = "administer_items";
/**
* Allows the user to approve {@link ContentItem}s.
*/
public static final String APPROVE = "approve_items";
/**
* Allows the user to publish, republish and unpublish {@link ContentItem}.
*/
public static final String PUBLISH = "publish_items";
/**
* Allows the user to categorise {@link ContentItem}s.
*/
public static final String CATEGORIZE = "categorize_items";
/**
* Allows the user to create new {@link ContentItem}s.
*/
public static final String CREATE_NEW = "create_new_items";
/**
* Allows the user to delete {@link ContentItem}s.
*/
public static final String DELETE = "delete_items";
/**
* Allows the user to edit existing {@link ContentItem}s.
*/
public static final String EDIT = "edit_items";
/**
* Allows to user to view the draft version of {@link ContentItem}.
*/
public static final String PREVIEW = "preview_items";
/**
* Allows the user to view the live version of {@link ContentItems}.
*/
public static final String VIEW_PUBLISHED = "view_published_items";
/**
* Allows the user to apply another {@link Workflow} than the default one to
* an {@link ContentItem}.
@ -73,6 +41,46 @@ public final class ItemPrivileges {
public static final String APPLY_ALTERNATE_WORKFLOW
= "apply_alternate_workflow";
/**
* Allows the user to approve {@link ContentItem}s.
*/
public static final String APPROVE = "approve_items";
/**
* Allows the user to categorise {@link ContentItem}s.
*/
public static final String CATEGORIZE = "categorize_items";
/**
* Allows the user to create new {@link ContentItem}s.
*/
public static final String CREATE_NEW = "create_new_items";
/**
* Allows the user to delete {@link ContentItem}s.
*/
public static final String DELETE = "delete_items";
/**
* Allows the user to edit existing {@link ContentItem}s.
*/
public static final String EDIT = "edit_items";
/**
* Allows to user to view the draft version of {@link ContentItem}.
*/
public static final String PREVIEW = "preview_items";
/**
* Allows the user to publish, republish and unpublish {@link ContentItem}.
*/
public static final String PUBLISH = "publish_items";
/**
* Allows the user to view the live version of {@link ContentItems}.
*/
public static final String VIEW_PUBLISHED = "view_published_items";
private ItemPrivileges() {
//Nothing
}

View File

@ -5,7 +5,6 @@
*/
package org.librecms.ui.contentsections;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.api.Identifier;
@ -145,81 +144,41 @@ public class DocumentFolderController {
@QueryParam("maxResults") @DefaultValue("20") final int maxResults
) {
final long start = System.currentTimeMillis();
final Identifier identifier = identifierParser.parseIdentifier(
final Optional<ContentSection> sectionResult = retrieveContentSection(
sectionIdentifier
);
final Optional<ContentSection> sectionResult;
switch (identifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(identifier.getIdentifier())
LOGGER.info("Retrieved content section in {} ms",
System.currentTimeMillis() - start
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(identifier
.getIdentifier());
break;
default:
sectionResult = sectionRepo.findByLabel(identifier
.getIdentifier());
break;
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
LOGGER.info("Retrieved content section in {} ms", System
.currentTimeMillis() - start);
if (sectionResult.isPresent()) {
final ContentSection section = sectionResult.get();
final long permissionCheckStart = System.currentTimeMillis();
if (permissionChecker.isPermitted(
if (!permissionChecker.isPermitted(
ItemPrivileges.EDIT, section.getRootDocumentsFolder()
)) {
contentSectionModel.setSection(section);
LOGGER.info(
"Checked in permisisons in {} ms.",
System.currentTimeMillis() - permissionCheckStart
);
models.put("sectionidentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Folder folder;
if (folderPath.isBlank()) {
if (folderPath.isEmpty()) {
folder = section.getRootDocumentsFolder();
documentFolderModel.setBreadcrumbs(Collections.emptyList());
} else {
final Optional<Folder> folderResult = folderRepo
.findByPath(section,
.findByPath(
section,
folderPath,
FolderType.DOCUMENTS_FOLDER
);
if (folderResult.isPresent()) {
folder = folderResult.get();
if (!permissionChecker.isPermitted(
ItemPrivileges.EDIT, folder
)) {
models.put("sectionidentifier", sectionIdentifier);
models.put("folderPath", folderPath);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final List<DocumentFolderBreadcrumbModel> breadcrumbs
= new ArrayList<>();
final List<String> tokens = Arrays
.stream(folderPath.split("/"))
.filter(token -> !token.isEmpty())
.collect(Collectors.toList());
for (final String token : tokens) {
final String path = breadcrumbs
.stream()
.map(DocumentFolderBreadcrumbModel::getPathToken)
.collect(Collectors.joining("/"));
final DocumentFolderBreadcrumbModel breadcrumb
= new DocumentFolderBreadcrumbModel();
breadcrumb.setPath(path);
breadcrumb.setPathToken(token);
breadcrumbs.add(breadcrumb);
}
breadcrumbs
.get(breadcrumbs.size() - 1)
.setCurrentFolder(true);
documentFolderModel.setBreadcrumbs(breadcrumbs);
documentFolderModel.setBreadcrumbs(buildBreadcrumbs(folderPath));
} else {
models.put("contentSection", section.getLabel());
models.put("folderPath", folderPath);
@ -227,7 +186,12 @@ public class DocumentFolderController {
}
}
final long objectsStart = System.currentTimeMillis();
if (!permissionChecker.isPermitted(ItemPrivileges.EDIT, folder)) {
models.put("sectionidentifier", sectionIdentifier);
models.put("folderPath", folderPath);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final List<DocumentFolderEntry> folderEntries = folderRepo
.getDocumentFolderEntries(
folder,
@ -235,36 +199,23 @@ public class DocumentFolderController {
maxResults,
filterTerm
);
LOGGER.info(
"Retrieved objects in {} ms",
System.currentTimeMillis() - objectsStart
);
documentFolderModel.setCount(
folderRepo.countDocumentFolderEntries(folder, filterTerm)
);
documentFolderModel.setFirstResult(firstResult);
documentFolderModel.setMaxResults(maxResults);
LOGGER.info(
"Retrieved and counted objects in {} ms",
System.currentTimeMillis() - objectsStart
);
final List<FolderTreeNode> folderTree = buildFolderTree(
section, folder
);
contentSectionModel.setFolders(folderTree);
final long rowsStart = System.currentTimeMillis();
documentFolderModel.setRows(
folderEntries
.stream()
.map(entry -> buildRowModel(section, entry))
.collect(Collectors.toList())
);
LOGGER.info(
"Build rows in {} ms.",
System.currentTimeMillis() - rowsStart
);
documentFolderModel.setPath(folderPath);
documentFolderModel.setCanCreateSubFolders(
@ -272,17 +223,13 @@ public class DocumentFolderController {
ItemPrivileges.CREATE_NEW, folder
)
);
documentFolderModel.setCanCreateItems(
permissionChecker.isPermitted(
ItemPrivileges.CREATE_NEW, folder
)
);
return "org/librecms/ui/contentsection/documentfolder/documentfolder.xhtml";
} else {
models.put("sectionidentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
} else {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
}
@GET
@ -400,34 +347,20 @@ public class DocumentFolderController {
@PathParam("parentFolderPath") final String parentFolderPath,
@FormParam("folderName") final String folderName
) {
final Identifier identifier = identifierParser.parseIdentifier(
final Optional<ContentSection> sectionResult = retrieveContentSection(
sectionIdentifier
);
final Optional<ContentSection> sectionResult;
switch (identifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(identifier.getIdentifier())
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(identifier
.getIdentifier());
break;
default:
sectionResult = sectionRepo.findByLabel(identifier
.getIdentifier());
break;
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
if (sectionResult.isPresent()) {
final ContentSection section = sectionResult.get();
if (!permissionChecker.isPermitted(
ItemPrivileges.EDIT, section.getRootDocumentsFolder()
)) {
models.put("sectionidentifier", sectionIdentifier);
models.put("folderPath", parentFolderPath);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
@ -447,9 +380,14 @@ public class DocumentFolderController {
}
}
if (permissionChecker.isPermitted(
if (!permissionChecker.isPermitted(
ItemPrivileges.CREATE_NEW, parentFolder
)) {
models.put("sectionidentifier", sectionIdentifier);
models.put("folderPath", parentFolderPath);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
folderManager.createFolder(folderName, parentFolder);
return String.format(
@ -457,19 +395,33 @@ public class DocumentFolderController {
sectionIdentifier,
parentFolderPath
);
} else {
models.put("sectionidentifier", sectionIdentifier);
models.put("folderPath", parentFolderPath);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
} else {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
}
private Optional<ContentSection> retrieveContentSection(
final String sectionIdentifier
) {
final Identifier identifier = identifierParser.parseIdentifier(
sectionIdentifier
);
final Optional<ContentSection> sectionResult;
switch (identifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(identifier.getIdentifier())
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(identifier
.getIdentifier());
break;
default:
sectionResult = sectionRepo.findByLabel(identifier
.getIdentifier());
break;
}
return sectionResult;
}
private List<FolderTreeNode> buildFolderTree(
final ContentSection section, final Folder currentFolder
@ -515,6 +467,7 @@ public class DocumentFolderController {
node.setPath(folderPath);
node.setOpen(currentFolderPath.startsWith(folderPath));
node.setSelected(currentFolderPath.equals(folderPath));
node.setPermissions(buildItemPermissionsModel(folder));
node.setSubFolders(
folder
.getSubFolders()
@ -534,6 +487,32 @@ public class DocumentFolderController {
return node;
}
private List<DocumentFolderBreadcrumbModel> buildBreadcrumbs(
final String folderPath
) {
final List<DocumentFolderBreadcrumbModel> breadcrumbs
= new ArrayList<>();
final List<String> tokens = Arrays
.stream(folderPath.split("/"))
.filter(token -> !token.isEmpty())
.collect(Collectors.toList());
for (final String token : tokens) {
final String path = breadcrumbs
.stream()
.map(DocumentFolderBreadcrumbModel::getPathToken)
.collect(Collectors.joining("/"));
final DocumentFolderBreadcrumbModel breadcrumb
= new DocumentFolderBreadcrumbModel();
breadcrumb.setPath(path);
breadcrumb.setPathToken(token);
breadcrumbs.add(breadcrumb);
}
breadcrumbs
.get(breadcrumbs.size() - 1)
.setCurrentFolder(true);
return breadcrumbs;
}
private DocumentFolderRowModel buildRowModel(
final ContentSection section, final DocumentFolderEntry entry
) {
@ -575,6 +554,7 @@ public class DocumentFolderController {
"org.librecms.CmsAdminMessages"
).getText("contentsection.documentfolder.types.folder")
);
row.setPermissions(buildItemPermissionsModel(folder));
} else {
final ContentItem contentItem = itemRepo
.findById(entry.getEntryId())
@ -635,8 +615,9 @@ public class DocumentFolderController {
);
row.setType(
contentTypeRepo
.findByContentSectionAndClass(section, contentItem
.getClass())
.findByContentSectionAndClass(
section, contentItem.getClass()
)
.map(ContentType::getLabel)
.map(
label -> globalizationHelper
@ -645,10 +626,125 @@ public class DocumentFolderController {
)
).orElse("?")
);
row.setPermissions(buildItemPermissionsModel(contentItem));
}
return row;
}
private ItemPermissionsModel buildItemPermissionsModel(
final Folder folder
) {
final ItemPermissionsModel model = new ItemPermissionsModel();
model.setGrantedAdminister(
permissionChecker.isPermitted(
ItemPrivileges.ADMINISTER, folder
)
);
model.setGrantedApplyAlternateWorkflow(
permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, folder
)
);
model.setGrantedApprove(
permissionChecker.isPermitted(
ItemPrivileges.APPROVE, folder
)
);
model.setGrantedCategorize(
permissionChecker.isPermitted(
ItemPrivileges.CATEGORIZE, folder
)
);
model.setGrantedCreateNew(
permissionChecker.isPermitted(
ItemPrivileges.CREATE_NEW, folder
)
);
model.setGrantedDelete(
permissionChecker.isPermitted(
ItemPrivileges.DELETE, folder
)
);
model.setGrantedEdit(
permissionChecker.isPermitted(
ItemPrivileges.EDIT, folder
)
);
model.setGrantedPreview(
permissionChecker.isPermitted(
ItemPrivileges.PREVIEW, folder
)
);
model.setGrantedPublish(
permissionChecker.isPermitted(
ItemPrivileges.PUBLISH, folder
)
);
model.setGrantedViewPublished(
permissionChecker.isPermitted(
ItemPrivileges.VIEW_PUBLISHED, folder
)
);
return model;
}
private ItemPermissionsModel buildItemPermissionsModel(
final ContentItem item
) {
final ItemPermissionsModel model = new ItemPermissionsModel();
model.setGrantedAdminister(
permissionChecker.isPermitted(
ItemPrivileges.ADMINISTER, item
)
);
model.setGrantedApplyAlternateWorkflow(
permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, item
)
);
model.setGrantedApprove(
permissionChecker.isPermitted(
ItemPrivileges.APPROVE, item
)
);
model.setGrantedCategorize(
permissionChecker.isPermitted(
ItemPrivileges.CATEGORIZE, item
)
);
model.setGrantedCreateNew(
permissionChecker.isPermitted(
ItemPrivileges.CREATE_NEW, item
)
);
model.setGrantedDelete(
permissionChecker.isPermitted(
ItemPrivileges.DELETE, item
)
);
model.setGrantedEdit(
permissionChecker.isPermitted(
ItemPrivileges.EDIT, item
)
);
model.setGrantedPreview(
permissionChecker.isPermitted(
ItemPrivileges.PREVIEW, item
)
);
model.setGrantedPublish(
permissionChecker.isPermitted(
ItemPrivileges.PUBLISH, item
)
);
model.setGrantedViewPublished(
permissionChecker.isPermitted(
ItemPrivileges.VIEW_PUBLISHED, item
)
);
return model;
}
}

View File

@ -35,6 +35,7 @@ public class DocumentFolderModel {
private boolean canCreateSubFolders;
private boolean canCreateItems;
public long getCount() {
return count;
@ -102,4 +103,12 @@ public class DocumentFolderModel {
this.canCreateSubFolders = canCreateSubFolders;
}
public boolean isCanCreateItems() {
return canCreateItems;
}
protected void setCanCreateItems(final boolean canCreateItems) {
this.canCreateItems = canCreateItems;
}
}

View File

@ -36,6 +36,8 @@ public class DocumentFolderRowModel {
private String type;
private ItemPermissionsModel permissions;
public String getCreated() {
return created;
}
@ -128,4 +130,14 @@ public class DocumentFolderRowModel {
this.type = type;
}
public ItemPermissionsModel getPermissions() {
return permissions;
}
protected void setPermissions(
final ItemPermissionsModel permissions
) {
this.permissions = permissions;
}
}

View File

@ -5,6 +5,7 @@
*/
package org.librecms.ui.contentsections;
import java.util.Collections;
import java.util.List;
/**
@ -27,6 +28,8 @@ public class FolderTreeNode {
private boolean selected;
private ItemPermissionsModel permissions;
public long getFolderId() {
return folderId;
}
@ -60,7 +63,7 @@ public class FolderTreeNode {
}
public List<FolderTreeNode> getSubFolders() {
return subFolders;
return Collections.unmodifiableList(subFolders);
}
public void setSubFolders(final List<FolderTreeNode> subFolders) {
@ -83,6 +86,14 @@ public class FolderTreeNode {
this.selected = selected;
}
public ItemPermissionsModel getPermissions() {
return permissions;
}
public void setPermissions(
final ItemPermissionsModel permissions
) {
this.permissions = permissions;
}
}

View File

@ -0,0 +1,115 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ItemPermissionsModel {
private boolean grantedAdminister;
private boolean grantedApplyAlternateWorkflow;
private boolean grantedApprove;
private boolean grantedCategorize;
private boolean grantedCreateNew;
private boolean grantedDelete;
private boolean grantedEdit;
private boolean grantedPreview;
private boolean grantedPublish;
private boolean grantedViewPublished;
public boolean isGrantedAdminister() {
return grantedAdminister;
}
public void setGrantedAdminister(final boolean grantedAdminister) {
this.grantedAdminister = grantedAdminister;
}
public boolean isGrantedApplyAlternateWorkflow() {
return grantedApplyAlternateWorkflow;
}
public void setGrantedApplyAlternateWorkflow(
boolean grantedApplyAlternateWorkflow) {
this.grantedApplyAlternateWorkflow = grantedApplyAlternateWorkflow;
}
public boolean isGrantedApprove() {
return grantedApprove;
}
public void setGrantedApprove(final boolean grantedApprove) {
this.grantedApprove = grantedApprove;
}
public boolean isGrantedCategorize() {
return grantedCategorize;
}
public void setGrantedCategorize(final boolean grantedCategorize) {
this.grantedCategorize = grantedCategorize;
}
public boolean isGrantedCreateNew() {
return grantedCreateNew;
}
public void setGrantedCreateNew(final boolean grantedCreateNew) {
this.grantedCreateNew = grantedCreateNew;
}
public boolean isGrantedDelete() {
return grantedDelete;
}
public void setGrantedDelete(final boolean grantedDelete) {
this.grantedDelete = grantedDelete;
}
public boolean isGrantedEdit() {
return grantedEdit;
}
public void setGrantedEdit(final boolean grantedEdit) {
this.grantedEdit = grantedEdit;
}
public boolean isGrantedPreview() {
return grantedPreview;
}
public void setGrantedPreview(final boolean grantedPreview) {
this.grantedPreview = grantedPreview;
}
public boolean isGrantedPublish() {
return grantedPublish;
}
public void setGrantedPublish(final boolean grantedPublish) {
this.grantedPublish = grantedPublish;
}
public boolean isGrantedViewPublished() {
return grantedViewPublished;
}
public void setGrantedViewPublished(final boolean grantedViewPublished) {
this.grantedViewPublished = grantedViewPublished;
}
}

View File

@ -19,8 +19,16 @@
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.foldersnav.subfolders.expand']}
</span>
</button>
<c:choose>
<c:when test="#{folder.permissions.grantedEdit}">
<a class="pl-0"
href="#{basePath}#{folder.path}">#{folder.name}</a>
</c:when>
<c:otherwise>
<span>#{folder.name}</span>
</c:otherwise>
</c:choose>
</div>
<ul class="border-0 #{!folder.open ? 'collapse' : 'collapse.show'} list-group"
id="#{folder.name}-subfolders">

View File

@ -114,6 +114,8 @@
${CmsAdminMessages.getMessage("contentsection.documentfolder.pageof", [DocumentFolderModel.currentPage, DocumentFolderModel.numberOfPages])}
</p>
<div>
<c:choose>
<c:when test="#{DocumentFolderModel.canCreateSubFolders}">
<button class="btn btn-primary"
data-toggle="modal"
data-target="#new-subfolder-dialog"
@ -174,10 +176,32 @@
</form>
</div>
</div>
</c:when>
<c:otherwise>
<button class="btn btn-primary"
disabled="disabled"
title="#{CmsAdminMessages['contentsection.documentfolder.add_subfolder']}">
<bootstrap:svgIcon icon="folder-plus" />
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.add_subfolder']}</span>
</button>
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="#{DocumentFolderModel.canCreateItems}">
<button class="btn btn-primary" title="#{CmsAdminMessages['contentsection.documentfolder.add_document']}">
<bootstrap:svgIcon icon="file-earmark-plus" />
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.add_document']}</span>
</button>
</c:when>
<c:otherwise>
<button class="btn btn-primary"
disabled="disabled"
title="#{CmsAdminMessages['contentsection.documentfolder.add_document']}">
<bootstrap:svgIcon icon="file-earmark-plus" />
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.add_document']}</span>
</button>
</c:otherwise>
</c:choose>
</div>
</div>
<table class="table table-hover documentfolder">
@ -201,7 +225,7 @@
<th>
#{CmsAdminMessages['contentsection.documentfolder.headers.lastedit.label']}
</th>
<th>
<th class="text-center" colspan="3">
#{CmsAdminMessages['contentsection.documentfolder.headers.actions.label']}
</th>
</tr>
@ -212,11 +236,14 @@
<tr>
<td>
<c:choose>
<c:when test="#{row.folder}">
<c:when test="#{row.folder and (row.permissions.grantedEdit or row.permissions.grantedPreview)}">
<a href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documentfolders/#{row.folderPath}">#{row.name}</a>
</c:when>
<c:otherwise>
<c:when test="#{row.permissions.grantedApprove or row.permissions.grantedCategorize or row.permissions.grantedEdit or row.permissions.grantedPreview or row.permissions.grantedPublish}">
<a href="#">#{row.name}</a>
</c:when>
<c:otherwise>
<span>#{row.name}</span>
</c:otherwise>
</c:choose>
</td>
@ -247,11 +274,31 @@
</c:if>
</c:if>
</td>
<td>
<c:if test="#{row.folder and row.permissions.grantedEdit}">
<button class="btn btn-info"
title="#{CmsAdminMessages['contentsection.documentfolder.actions.rename_folder.button.label']}">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.actions.rename_folder.button.label']}</span>
</button>
</c:if>
</td>
<td>
<c:if test="#{row.permissions.grantedAdminister}">
<button class="btn btn-info"
title="#{CmsAdminMessages['contentsection.documentfolder.actions.edit_permissions.button.label']}">
<bootstrap:svgIcon icon="shield" />
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.actions.edit_permissions.button.label']}</span>
</button>
</c:if>
</td>
<td>
<c:if test="#{row.deletable}">
<button class="btn btn-danger">
<button class="btn btn-danger"
title="#{CmsAdminMessages['contentsection.documentfolder.actions.delete.button.label']}">
<bootstrap:svgIcon icon="x-circle" />
<span>${CmsAdminMessages['contentsection.documentfolder.actions.delete.button.label']}</span>
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.actions.delete.button.label']}</span>
</button>
</c:if>
</td>

View File

@ -62,3 +62,5 @@ contentsection.documentfolder.new_subfolder.name.help=The new name of the subfol
contentsection.documentfolder.new_subfolder_dialog.submit=Create new subfolder
contentsection.documentfolder.new_subfolder_dialog.close=Cancel
contentsection.documentfolders.root.title=Documents
contentsection.documentfolder.actions.rename_folder.button.label=Rename folder
contentsection.documentfolder.actions.edit_permissions.button.label=Edit permissions

View File

@ -62,3 +62,5 @@ contentsection.documentfolder.new_subfolder.name.help=Der Name des neuen Ordners
contentsection.documentfolder.new_subfolder_dialog.submit=Neuen Ordner anlegen
contentsection.documentfolder.new_subfolder_dialog.close=Abbrechen
contentsection.documentfolders.root.title=Dokumente
contentsection.documentfolder.actions.rename_folder.button.label=Ordner umbebennen
contentsection.documentfolder.actions.edit_permissions.button.label=Berechtigungen bearbeiten