Faster (native SQL) queries for folder browsing
parent
80b568cc28
commit
40efbfdc6e
|
|
@ -107,5 +107,7 @@
|
||||||
<Logger name="org.libreccm.ui.admin.applications.ApplicationsPage"
|
<Logger name="org.libreccm.ui.admin.applications.ApplicationsPage"
|
||||||
level="debug">
|
level="debug">
|
||||||
</Logger>
|
</Logger>
|
||||||
|
<Logger name="org.librecms.ui.ContentSectionController" level="debug">
|
||||||
|
</Logger>
|
||||||
</Loggers>
|
</Loggers>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<property name="wildfly.jpa.hibernate.search.module"
|
<property name="wildfly.jpa.hibernate.search.module"
|
||||||
value="org.hibernate.search.orm:main" />
|
value="org.hibernate.search.orm:main" />
|
||||||
|
|
||||||
<!--<property name="hibernate.show_sql" value="true" />
|
<!-- <property name="hibernate.show_sql" value="true" />
|
||||||
<property name="format_sql" value="true" />
|
<property name="format_sql" value="true" />
|
||||||
<property name="use_sql_comments" value="true" />-->
|
<property name="use_sql_comments" value="true" />-->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* 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.contentsection;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class DocumentFolderEntry {
|
||||||
|
|
||||||
|
private long entryId;
|
||||||
|
|
||||||
|
private String entryUuid;
|
||||||
|
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
|
private String itemClass;
|
||||||
|
|
||||||
|
private Date creationDate;
|
||||||
|
|
||||||
|
private Date lastModified;
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
private boolean folder;
|
||||||
|
|
||||||
|
public DocumentFolderEntry() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentFolderEntry(
|
||||||
|
final long entryId,
|
||||||
|
final String entryUuid,
|
||||||
|
final String displayName,
|
||||||
|
final String itemClass,
|
||||||
|
final Date creationDate,
|
||||||
|
final Date lastModified,
|
||||||
|
final String version,
|
||||||
|
final boolean folder
|
||||||
|
) {
|
||||||
|
this.entryId = entryId;
|
||||||
|
this.entryUuid = entryUuid;;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.itemClass = itemClass;
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
this.lastModified = lastModified;
|
||||||
|
this.version = version;
|
||||||
|
this.folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEntryId() {
|
||||||
|
return entryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntryId(final long entryId) {
|
||||||
|
this.entryId = entryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntryUuid() {
|
||||||
|
return entryUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntryUuid(final String entryUuid) {
|
||||||
|
this.entryUuid = entryUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(final String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemClass() {
|
||||||
|
return itemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemClass(final String itemClass) {
|
||||||
|
this.itemClass = itemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(final Date creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastModified() {
|
||||||
|
return lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastModified(final Date lastModified) {
|
||||||
|
this.lastModified = lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(final String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFolder() {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFolder(final boolean folder) {
|
||||||
|
this.folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
hash = 29 * hash + (int) (entryId ^ (entryId >>> 32));
|
||||||
|
hash = 29 * hash + Objects.hashCode(entryUuid);
|
||||||
|
hash = 29 * hash + Objects.hashCode(displayName);
|
||||||
|
hash = 29 * hash + Objects.hashCode(itemClass);
|
||||||
|
hash = 29 * hash + Objects.hashCode(creationDate);
|
||||||
|
hash = 29 * hash + Objects.hashCode(lastModified);
|
||||||
|
hash = 29 * hash + Objects.hashCode(version);
|
||||||
|
hash = 29 * hash + (folder ? 1 : 0);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof DocumentFolderEntry)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final DocumentFolderEntry other = (DocumentFolderEntry) obj;
|
||||||
|
if (!other.canEqual(this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entryId != other.getEntryId()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (folder != other.isFolder()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(entryUuid, other.getEntryUuid())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(displayName, other.getDisplayName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (version != other.getVersion()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canEqual(final Object obj) {
|
||||||
|
return obj instanceof DocumentFolderEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -26,18 +26,25 @@ import javax.persistence.Table;
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.ColumnResult;
|
||||||
|
import javax.persistence.ConstructorResult;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.NamedNativeQueries;
|
||||||
|
import javax.persistence.NamedNativeQuery;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
|
import javax.persistence.SqlResultSetMapping;
|
||||||
|
import javax.persistence.SqlResultSetMappings;
|
||||||
|
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
|
||||||
|
|
@ -52,27 +59,23 @@ import static org.librecms.CmsConstants.*;
|
||||||
name = "Folder.rootFolders",
|
name = "Folder.rootFolders",
|
||||||
query = "SELECT f FROM Folder f "
|
query = "SELECT f FROM Folder f "
|
||||||
+ "WHERE f.parentCategory IS NULL "
|
+ "WHERE f.parentCategory IS NULL "
|
||||||
+ " AND f.type = :type")
|
+ " AND f.type = :type"),
|
||||||
,
|
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Folder.findByName",
|
name = "Folder.findByName",
|
||||||
query = "SELECT f FROM Folder f WHERE f.name = :name")
|
query = "SELECT f FROM Folder f WHERE f.name = :name"),
|
||||||
,
|
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Folder.findSubFolders",
|
name = "Folder.findSubFolders",
|
||||||
query = "SELECT f "
|
query = "SELECT f "
|
||||||
+ "FROM Folder f"
|
+ "FROM Folder f"
|
||||||
+ " WHERE f.parentCategory = :parent "
|
+ " WHERE f.parentCategory = :parent "
|
||||||
+ "ORDER BY f.name"
|
+ "ORDER BY f.name"
|
||||||
)
|
),
|
||||||
,
|
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Folder.countSubFolders",
|
name = "Folder.countSubFolders",
|
||||||
query = "SELECT COUNT(f) "
|
query = "SELECT COUNT(f) "
|
||||||
+ "FROM Folder f "
|
+ "FROM Folder f "
|
||||||
+ "WHERE f.parentCategory = :parent"
|
+ "WHERE f.parentCategory = :parent"
|
||||||
)
|
),
|
||||||
,
|
|
||||||
// @NamedQuery(
|
// @NamedQuery(
|
||||||
// name = "Folder.findItems",
|
// name = "Folder.findItems",
|
||||||
// query = "SELECT c.categorizedObject "
|
// query = "SELECT c.categorizedObject "
|
||||||
|
|
@ -104,66 +107,136 @@ import static org.librecms.CmsConstants.*;
|
||||||
+ "FROM ContentItem i JOIN i.categories c "
|
+ "FROM ContentItem i JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE"
|
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE"
|
||||||
)
|
),
|
||||||
,
|
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Folder.findObjects",
|
name = "Folder.findObjects",
|
||||||
query = "SELECT o FROM CcmObject o "
|
query
|
||||||
+ "WHERE o IN (SELECT f FROM Folder f "
|
= "SELECT o FROM CcmObject o WHERE TYPE(O) IN (ContentItem, Folder) AND o IN (SELECT f FROM Category f WHERE TYPE(f) IN (Folder) AND f.parentCategory = :folder AND LOWER(f.name) LIKE LOWER(CONCAT('%', :term))) OR o IN (SELECT i FROM ContentItem i JOIN i.categories c WHERE TYPE(i) IN (ContentItem) AND c.category = :folder AND c.type = '"
|
||||||
+ "WHERE f.parentCategory = :folder "
|
+ CATEGORIZATION_TYPE_FOLDER
|
||||||
+ "AND LOWER(f.name) LIKE :term) "
|
+ "' AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)))) ORDER BY o.displayName"
|
||||||
+ "OR o IN (SELECT i FROM ContentItem i JOIN i.categories c "
|
),
|
||||||
+ "WHERE c.category = :folder "
|
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
|
||||||
+ "AND i.version = "
|
|
||||||
+ "org.librecms.contentsection.ContentItemVersion.DRAFT "
|
|
||||||
+ "AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)) "
|
|
||||||
// + "OR LOWER(i.name.values) LIKE LOWER(:term)"
|
|
||||||
+ ")) "
|
|
||||||
+ "ORDER BY o.displayName"
|
|
||||||
// query = "SELECT o FROM CcmObject o "
|
|
||||||
// + "WHERE o IN (SELECT f FROM Folder f "
|
|
||||||
// + "WHERE f.parentCategory = :parent "
|
|
||||||
// + "AND lower(f.name) LIKE :term) "
|
|
||||||
// + "OR o IN (SELECT c.categorizedObject "
|
|
||||||
// + "FROM Categorization c "
|
|
||||||
// + "WHERE c.category = :folder "
|
|
||||||
// + "AND TYPE(c.categorizedObject) IN ContentItem "
|
|
||||||
// + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
|
||||||
// + "AND c.version = "
|
|
||||||
// + "org.librecms.contentsection.ContentItemVersion.DRAFT"
|
|
||||||
// + "AND (LOWER(c.categorizedObject.displayName) LIKE :term "
|
|
||||||
// + "OR LOWER(c.categorizedObject.name.value) LIKE :term)) "
|
|
||||||
// + "ORDER BY o.displayName"
|
|
||||||
)
|
|
||||||
,
|
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Folder.countObjects",
|
name = "Folder.countObjects",
|
||||||
query = "SELECT COUNT(o) FROM CcmObject o "
|
query
|
||||||
+ "WHERE o IN (SELECT f FROM Folder f "
|
= "SELECT COUNT(o) FROM CcmObject o WHERE TYPE(O) IN (ContentItem, Folder) AND o IN (SELECT f FROM Category f WHERE TYPE(f) IN (Folder) AND f.parentCategory = :folder AND LOWER(f.name) LIKE LOWER(CONCAT('%', :term))) OR o IN (SELECT i FROM ContentItem i JOIN i.categories c WHERE TYPE(i) IN (ContentItem) AND c.category = :folder AND c.type = '"
|
||||||
+ "WHERE f.parentCategory = :folder "
|
+ CATEGORIZATION_TYPE_FOLDER
|
||||||
+ "AND LOWER(f.name) LIKE :term) "
|
+ "' AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term))))"
|
||||||
+ "OR o IN (SELECT i FROM ContentItem i JOIN i.categories c "
|
)
|
||||||
+ "WHERE c.category = :folder "
|
})
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
@NamedNativeQueries({
|
||||||
+ "AND i.version = "
|
@NamedNativeQuery(
|
||||||
+ "org.librecms.contentsection.ContentItemVersion.DRAFT "
|
name = "Folder.countDocumentFolderEntries",
|
||||||
+ "AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)) "
|
query = "SELECT ("
|
||||||
// + "OR LOWER(i.name.values) LIKE LOWER(:term)"
|
+ "("
|
||||||
+ "))"
|
+ "SELECT COUNT(*) "
|
||||||
// query = "SELECT COUNT(o) FROM CcmObject o "
|
+ "FROM ccm_core.ccm_objects "
|
||||||
// + "WHERE o IN (SELECT f FROM Folder f "
|
+ "JOIN ccm_cms.content_items "
|
||||||
// + "WHERE f.parentCategory = :parent "
|
+ "ON ccm_objects.object_id = content_items.object_id "
|
||||||
// + "AND lower(f.name) LIKE :term) "
|
+ "JOIN ccm_core.categorizations "
|
||||||
// + "OR o IN (SELECT c.categorizedObject AS co "
|
+ " ON ccm_objects.object_id "
|
||||||
// + "FROM Categorization c "
|
+ " = categorizations.object_id "
|
||||||
// + "WHERE c.category = :folder "
|
+ "WHERE categorizations.category_id = :folderId "
|
||||||
// // + "AND TYPE(co) IN ContentItem "
|
+ "AND content_items.version = 'DRAFT'"
|
||||||
// + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
+ ") "
|
||||||
// + "AND co.version = "
|
+ "+ "
|
||||||
// + "org.librecms.contentsection.ContentItemVersion.DRAFT "
|
+ "("
|
||||||
// + "AND ((LOWER(co.displayName) LIKE :term "
|
+ "SELECT COUNT(*) "
|
||||||
// + "OR LOWER(co.name.value) LIKE :term)))"
|
+ "FROM ccm_core.categories "
|
||||||
|
+ "JOIN ccm_core.ccm_objects "
|
||||||
|
+ " ON categories.object_id = ccm_objects.object_id "
|
||||||
|
+ "JOIN ccm_cms.folders "
|
||||||
|
+ " ON categories.object_id = folders.object_id "
|
||||||
|
+ "WHERE categories.parent_category_id = :folderId "
|
||||||
|
+ "AND folders.type = 'DOCUMENTS_FOLDER'"
|
||||||
|
+ ") AS entries_count",
|
||||||
|
resultSetMapping = "Folder.countDocumentFolderEntries"
|
||||||
|
),
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "Folder.getDocumentFolderEntries",
|
||||||
|
query
|
||||||
|
= "SELECT ccm_objects.object_id AS entry_id, "
|
||||||
|
+ " ccm_objects.uuid AS entry_uuid, "
|
||||||
|
+ " ccm_objects.display_name AS display_name, "
|
||||||
|
+ " content_types.content_item_class AS item_class, "
|
||||||
|
+ " content_items.creation_date AS creation_date, "
|
||||||
|
+ " content_items.last_modified AS last_modified, "
|
||||||
|
+ " content_items.\"version\" AS version, "
|
||||||
|
+ " false AS is_folder "
|
||||||
|
+ "FROM ccm_cms.content_items "
|
||||||
|
+ "JOIN ccm_core.ccm_objects "
|
||||||
|
+ " ON ccm_cms.content_items.object_id "
|
||||||
|
+ " = ccm_core.ccm_objects.object_id "
|
||||||
|
+ "JOIN ccm_core.categorizations "
|
||||||
|
+ " ON ccm_objects.object_id "
|
||||||
|
+ " = ccm_core.categorizations.object_id "
|
||||||
|
+ "JOIN ccm_cms.content_types "
|
||||||
|
+ " ON content_items.content_type_id "
|
||||||
|
+ " = content_types.object_id "
|
||||||
|
+ "WHERE categorizations.category_id = :folderId "
|
||||||
|
+ "AND content_items.\"version\" ='DRAFT' "
|
||||||
|
+ "UNION "
|
||||||
|
+ "SELECT categories.object_id AS entry_id, "
|
||||||
|
+ " ccm_objects.uuid AS entry_uuid, "
|
||||||
|
+ " categories.\"name\" AS display_name, "
|
||||||
|
+ " null AS item_class, "
|
||||||
|
+ " null AS creation_date, "
|
||||||
|
+ " null AS last_modified, "
|
||||||
|
+ " null AS version, "
|
||||||
|
+ " true as is_folder "
|
||||||
|
+ "FROM ccm_core.categories "
|
||||||
|
+ "JOIN ccm_core.ccm_objects "
|
||||||
|
+ " ON categories.object_id = ccm_objects.object_id "
|
||||||
|
+ "JOIN ccm_cms.folders "
|
||||||
|
+ " ON categories.object_id = folders.object_id "
|
||||||
|
+ "WHERE categories.parent_category_id = :folderId "
|
||||||
|
+ "AND folders.\"type\" = 'DOCUMENTS_FOLDER'",
|
||||||
|
resultSetMapping = "Folder.DocumentFolderEntry"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
@SqlResultSetMappings({
|
||||||
|
@SqlResultSetMapping(
|
||||||
|
name = "Folder.countDocumentFolderEntries",
|
||||||
|
columns = {
|
||||||
|
@ColumnResult(name = "entries_count", type = long.class)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
@SqlResultSetMapping(
|
||||||
|
name = "Folder.DocumentFolderEntry",
|
||||||
|
classes = {
|
||||||
|
@ConstructorResult(
|
||||||
|
columns = {
|
||||||
|
@ColumnResult(name = "entry_id", type = long.class),
|
||||||
|
@ColumnResult(name = "entry_uuid"),
|
||||||
|
@ColumnResult(name = "display_name"),
|
||||||
|
@ColumnResult(name = "item_class"),
|
||||||
|
@ColumnResult(name = "creation_date"),
|
||||||
|
@ColumnResult(name = "last_modified"),
|
||||||
|
@ColumnResult(name = "version"),
|
||||||
|
@ColumnResult(name = "is_folder", type = boolean.class)
|
||||||
|
},
|
||||||
|
targetClass = DocumentFolderEntry.class
|
||||||
|
),}
|
||||||
|
// entities = {
|
||||||
|
// @EntityResult(
|
||||||
|
// entityClass = DocumentFolderEntry.class,
|
||||||
|
// fields = {
|
||||||
|
// @FieldResult(column = "entry_id", name = "entryId"),
|
||||||
|
// @FieldResult(column = "entry_uuid", name = "entryUuid"),
|
||||||
|
// @FieldResult(column = "display_name", name = "displayName"),
|
||||||
|
// @FieldResult(column = "item_class", name = "itemClass"),
|
||||||
|
// @FieldResult(
|
||||||
|
// column = "creation_date",
|
||||||
|
// name = "creation_date"
|
||||||
|
// ),
|
||||||
|
// @FieldResult(
|
||||||
|
// column = "last_modified",
|
||||||
|
// name = "lastModified"
|
||||||
|
// ),
|
||||||
|
// @FieldResult(column = "version", name = "version"),
|
||||||
|
// @FieldResult(column = "is_folder", name = "folder")
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
public class Folder extends Category implements Serializable {
|
public class Folder extends Category implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,35 @@ public class FolderRepository extends AbstractEntityRepository<Long, Folder> {
|
||||||
.getResultList();
|
.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<DocumentFolderEntry> getDocumentFolderEntries(
|
||||||
|
final Folder folder,
|
||||||
|
final int firstResult,
|
||||||
|
final int maxResults,
|
||||||
|
final String term
|
||||||
|
) {
|
||||||
|
return getEntityManager()
|
||||||
|
.createNamedQuery(
|
||||||
|
"Folder.getDocumentFolderEntries", DocumentFolderEntry.class
|
||||||
|
)
|
||||||
|
.setParameter(
|
||||||
|
"folderId", Objects.requireNonNull(folder).getObjectId()
|
||||||
|
)
|
||||||
|
.setFirstResult(firstResult)
|
||||||
|
.setMaxResults(maxResults)
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long countDocumentFolderEntries(
|
||||||
|
final Folder folder,
|
||||||
|
final String term
|
||||||
|
) {
|
||||||
|
return getEntityManager()
|
||||||
|
.createNamedQuery("Folder.countDocumentFolderEntries", Long.class)
|
||||||
|
.setParameter(
|
||||||
|
"folderId", Objects.requireNonNull(folder).getObjectId()
|
||||||
|
).getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
public long countObjectsInFolder(final Folder folder) {
|
public long countObjectsInFolder(final Folder folder) {
|
||||||
return countObjectsInFolder(folder, "");
|
return countObjectsInFolder(folder, "");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,29 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui;
|
package org.librecms.ui;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.libreccm.api.Identifier;
|
import org.libreccm.api.Identifier;
|
||||||
import org.libreccm.api.IdentifierParser;
|
import org.libreccm.api.IdentifierParser;
|
||||||
import org.libreccm.core.CcmObject;
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
|
import org.libreccm.security.PermissionChecker;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contentsection.ContentItemL10NManager;
|
import org.librecms.contentsection.ContentItemL10NManager;
|
||||||
import org.librecms.contentsection.ContentItemManager;
|
import org.librecms.contentsection.ContentItemManager;
|
||||||
|
import org.librecms.contentsection.ContentItemRepository;
|
||||||
import org.librecms.contentsection.ContentSection;
|
import org.librecms.contentsection.ContentSection;
|
||||||
import org.librecms.contentsection.ContentSectionRepository;
|
import org.librecms.contentsection.ContentSectionRepository;
|
||||||
import org.librecms.contentsection.ContentType;
|
import org.librecms.contentsection.ContentType;
|
||||||
import org.librecms.contentsection.ContentTypeManager;
|
import org.librecms.contentsection.ContentTypeManager;
|
||||||
import org.librecms.contentsection.ContentTypeRepository;
|
import org.librecms.contentsection.ContentTypeRepository;
|
||||||
|
import org.librecms.contentsection.DocumentFolderEntry;
|
||||||
import org.librecms.contentsection.Folder;
|
import org.librecms.contentsection.Folder;
|
||||||
import org.librecms.contentsection.FolderManager;
|
import org.librecms.contentsection.FolderManager;
|
||||||
import org.librecms.contentsection.FolderRepository;
|
import org.librecms.contentsection.FolderRepository;
|
||||||
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
|
import org.librecms.contenttypes.Article;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
|
@ -30,6 +37,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
@ -43,7 +51,6 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -54,12 +61,19 @@ import javax.ws.rs.WebApplicationException;
|
||||||
@Path("/{sectionIdentifier}")
|
@Path("/{sectionIdentifier}")
|
||||||
public class ContentSectionController {
|
public class ContentSectionController {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
ContentSectionController.class
|
||||||
|
);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CmsAdminMessages cmsAdminMessages;
|
private CmsAdminMessages cmsAdminMessages;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemManager itemManager;
|
private ContentItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemRepository itemRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemL10NManager itemL10NManager;
|
private ContentItemL10NManager itemL10NManager;
|
||||||
|
|
||||||
|
|
@ -73,7 +87,7 @@ public class ContentSectionController {
|
||||||
private ContentTypeRepository contentTypeRepo;
|
private ContentTypeRepository contentTypeRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private FolderBrowserModel folderBrowserModel;
|
private DocumentFolderModel documentFolderModel;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private FolderManager folderManager;
|
private FolderManager folderManager;
|
||||||
|
|
@ -93,8 +107,11 @@ public class ContentSectionController {
|
||||||
@Inject
|
@Inject
|
||||||
private IdentifierParser identifierParser;
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PermissionChecker permissionChecker;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/folderbrowser")
|
@Path("/document-folders")
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String listItems(
|
public String listItems(
|
||||||
|
|
@ -102,105 +119,226 @@ public class ContentSectionController {
|
||||||
@QueryParam("firstResult") @DefaultValue("0") final int firstResult,
|
@QueryParam("firstResult") @DefaultValue("0") final int firstResult,
|
||||||
@QueryParam("maxResults") @DefaultValue("20") final int maxResults
|
@QueryParam("maxResults") @DefaultValue("20") final int maxResults
|
||||||
) {
|
) {
|
||||||
|
final long start = System.currentTimeMillis();
|
||||||
final Identifier identifier = identifierParser.parseIdentifier(
|
final Identifier identifier = identifierParser.parseIdentifier(
|
||||||
sectionIdentifier
|
sectionIdentifier
|
||||||
);
|
);
|
||||||
final ContentSection section;
|
final Optional<ContentSection> sectionResult;
|
||||||
switch (identifier.getType()) {
|
switch (identifier.getType()) {
|
||||||
case ID:
|
case ID:
|
||||||
section = sectionRepo
|
sectionResult = sectionRepo.findById(
|
||||||
.findById(Long.parseLong(identifier.getIdentifier()))
|
Long.parseLong(identifier.getIdentifier())
|
||||||
.orElseThrow(
|
|
||||||
() -> new WebApplicationException(
|
|
||||||
String.format(
|
|
||||||
"No ContentSection with ID %s found.",
|
|
||||||
identifier.getIdentifier()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case UUID:
|
case UUID:
|
||||||
section = sectionRepo
|
sectionResult = sectionRepo.findByUuid(identifier
|
||||||
.findByUuid(identifier.getIdentifier())
|
.getIdentifier());
|
||||||
.orElseThrow(
|
|
||||||
() -> new WebApplicationException(
|
|
||||||
String.format(
|
|
||||||
"No ContentSection with UUID %s found.",
|
|
||||||
identifier.getIdentifier()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
section = sectionRepo
|
sectionResult = sectionRepo.findByLabel(identifier
|
||||||
.findByLabel(identifier.getIdentifier())
|
.getIdentifier());
|
||||||
.orElseThrow(
|
break;
|
||||||
() -> new WebApplicationException(
|
}
|
||||||
String.format(
|
LOGGER.info("Retrieved content section in {} ms", System
|
||||||
"No ContentSection named %s found.",
|
.currentTimeMillis() - start);
|
||||||
identifier.getIdentifier()
|
|
||||||
)
|
if (sectionResult.isPresent()) {
|
||||||
|
final ContentSection section = sectionResult.get();
|
||||||
|
|
||||||
|
final long permissionCheckStart = System.currentTimeMillis();
|
||||||
|
if (permissionChecker.isPermitted(
|
||||||
|
ItemPrivileges.EDIT, section.getRootDocumentsFolder()
|
||||||
|
)) {
|
||||||
|
contentSectionModel.setSection(section);
|
||||||
|
LOGGER.info("Checked in permisisons in {} ms.", System
|
||||||
|
.currentTimeMillis() - permissionCheckStart);
|
||||||
|
|
||||||
|
final long objectsStart = System.currentTimeMillis();
|
||||||
|
// final List<CcmObject> objects = folderRepo
|
||||||
|
// .findObjectsInFolder(
|
||||||
|
// section.getRootDocumentsFolder(), firstResult,
|
||||||
|
// maxResults
|
||||||
|
// );
|
||||||
|
final List<DocumentFolderEntry> folderEntries = folderRepo
|
||||||
|
.getDocumentFolderEntries(
|
||||||
|
section.getRootDocumentsFolder(),
|
||||||
|
firstResult,
|
||||||
|
maxResults,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
LOGGER.info("Retrieved objects in {} ms", System
|
||||||
|
.currentTimeMillis() - objectsStart);
|
||||||
|
documentFolderModel.setCount(
|
||||||
|
// folderRepo
|
||||||
|
// .countObjectsInFolder(section.getRootDocumentsFolder())
|
||||||
|
folderRepo.countDocumentFolderEntries(
|
||||||
|
section.getRootDocumentsFolder(), ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
documentFolderModel.setFirstResult(firstResult);
|
||||||
|
documentFolderModel.setMaxResults(maxResults);
|
||||||
|
LOGGER.info(
|
||||||
|
"Retrieved and counted objects in {} ms",
|
||||||
|
System.currentTimeMillis() - objectsStart
|
||||||
|
);
|
||||||
|
|
||||||
|
final long rowsStart = System.currentTimeMillis();
|
||||||
|
// documentFolderModel.setRows(
|
||||||
|
// objects
|
||||||
|
// .stream()
|
||||||
|
// .map(object -> buildRowModel(section, object))
|
||||||
|
// .collect(Collectors.toList())
|
||||||
|
// );
|
||||||
|
documentFolderModel.setRows(
|
||||||
|
folderEntries
|
||||||
|
.stream()
|
||||||
|
.map(entry -> buildRowModel(section, entry))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
LOGGER.info("Build rows in {} ms.", System.currentTimeMillis()
|
||||||
|
- rowsStart);
|
||||||
|
|
||||||
|
return "org/librecms/ui/content-section/document-folder.xhtml";
|
||||||
|
} else {
|
||||||
|
models.put("sectionidentifier", sectionIdentifier);
|
||||||
|
return "org/librecms/ui/content-section/access-denied.xhtml";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
models.put("sectionIdentifier", sectionIdentifier);
|
||||||
|
return "org/librecms/ui/content-section/contentsection-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/create-testdata")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String createTestData(
|
||||||
|
@PathParam("sectionIdentifier") 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentSectionModel.setSection(section);
|
if (sectionResult.isPresent()) {
|
||||||
|
final ContentSection section = sectionResult.get();
|
||||||
|
|
||||||
final List<CcmObject> objects = folderRepo
|
if (permissionChecker.isPermitted(
|
||||||
.findObjectsInFolder(
|
ItemPrivileges.EDIT, section.getRootDocumentsFolder()
|
||||||
section.getRootDocumentsFolder(), firstResult, maxResults
|
)) {
|
||||||
|
if (section.getRootDocumentsFolder().getObjects().isEmpty()) {
|
||||||
|
folderManager.createFolder(
|
||||||
|
"folder-1", section.getRootDocumentsFolder()
|
||||||
);
|
);
|
||||||
folderBrowserModel.setCount(
|
final Folder folder2 = folderManager.createFolder(
|
||||||
folderRepo.countObjectsInFolder(section.getRootDocumentsFolder())
|
"folder-2", section.getRootDocumentsFolder()
|
||||||
);
|
);
|
||||||
folderBrowserModel.setFirstResult(firstResult);
|
folderManager.createFolder(
|
||||||
folderBrowserModel.setMaxResults(maxResults);
|
"folder-3", section.getRootDocumentsFolder()
|
||||||
|
|
||||||
folderBrowserModel.setRows(
|
|
||||||
objects
|
|
||||||
.stream()
|
|
||||||
.map(object -> buildRowModel(section, object))
|
|
||||||
.collect(Collectors.toList())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return "org/librecms/ui/content-section/folderbrowser.xhtml";
|
final Article article = itemManager.createContentItem(
|
||||||
|
"test-article",
|
||||||
|
section,
|
||||||
|
section.getRootDocumentsFolder(),
|
||||||
|
Article.class,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
|
article.getTitle().addValue(Locale.ENGLISH, "Article 1");
|
||||||
|
article.getTitle().addValue(Locale.GERMAN, "Artikel 1");
|
||||||
|
itemRepo.save(article);
|
||||||
|
|
||||||
|
final Folder folder2a = folderManager.createFolder(
|
||||||
|
"folder-2a", folder2
|
||||||
|
);
|
||||||
|
|
||||||
|
final Article article2 = itemManager.createContentItem(
|
||||||
|
"test-article-in-folder-2",
|
||||||
|
section,
|
||||||
|
folder2,
|
||||||
|
Article.class,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
|
article2.getTitle().addValue(
|
||||||
|
Locale.ENGLISH, "Article in Folder 2"
|
||||||
|
);
|
||||||
|
article2.getTitle().addValue(
|
||||||
|
Locale.GERMAN, "Artikel in Ordner 2"
|
||||||
|
);
|
||||||
|
|
||||||
|
models.put(
|
||||||
|
"testdataMessage", "Test data created successfully."
|
||||||
|
);
|
||||||
|
return "org/librecms/ui/content-section/testdata.xhtml";
|
||||||
|
} else {
|
||||||
|
models.put(
|
||||||
|
"testdataMessage", "Test data was already created..."
|
||||||
|
);
|
||||||
|
return "org/librecms/ui/content-section/testdata.xhtml";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
models.put("sectionidentifier", sectionIdentifier);
|
||||||
|
return "org/librecms/ui/content-section/access-denied.xhtml";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
models.put("sectionIdentifier", sectionIdentifier);
|
||||||
|
return "org/librecms/ui/content-section/contentsection-not-found.xhtml";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FolderBrowserRowModel buildRowModel(
|
private DocumentFolderRowModel buildRowModel(
|
||||||
final ContentSection section, final CcmObject object
|
final ContentSection section, final DocumentFolderEntry entry
|
||||||
) {
|
) {
|
||||||
Objects.requireNonNull(section);
|
Objects.requireNonNull(section);
|
||||||
Objects.requireNonNull(object);
|
Objects.requireNonNull(entry);
|
||||||
if (object instanceof ContentItem) {
|
|
||||||
return buildRowModel(section, (ContentItem) object);
|
|
||||||
} else if (object instanceof Folder) {
|
|
||||||
return buildRowModel(section, (Folder) object);
|
|
||||||
} else {
|
|
||||||
final FolderBrowserRowModel row = new FolderBrowserRowModel();
|
|
||||||
|
|
||||||
|
final DocumentFolderRowModel row = new DocumentFolderRowModel();
|
||||||
|
if (entry.isFolder()) {
|
||||||
|
final Folder folder = folderRepo
|
||||||
|
.findById(entry.getEntryId())
|
||||||
|
.get();
|
||||||
row.setCreated("");
|
row.setCreated("");
|
||||||
row.setDeletable(false);
|
row.setDeletable(
|
||||||
row.setIsFolder(false);
|
folderManager
|
||||||
|
.folderIsDeletable(folder)
|
||||||
|
== FolderManager.FolderIsDeletable.YES
|
||||||
|
);
|
||||||
|
row.setIsFolder(true);
|
||||||
row.setLanguages(Collections.emptySortedSet());
|
row.setLanguages(Collections.emptySortedSet());
|
||||||
row.setLastEditPublished(false);
|
row.setLastEditPublished(false);
|
||||||
row.setLastEdited("");
|
row.setLastEdited("");
|
||||||
row.setName(object.getDisplayName());
|
row.setName(entry.getDisplayName());
|
||||||
row.setTitle("");
|
row.setTitle(
|
||||||
row.setType(object.getClass().getSimpleName());
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
folder.getTitle()
|
||||||
return row;
|
)
|
||||||
}
|
);
|
||||||
}
|
row.setType(
|
||||||
|
globalizationHelper.getLocalizedTextsUtil(
|
||||||
private FolderBrowserRowModel buildRowModel(
|
"org.librecms.CmsAdminMessages"
|
||||||
final ContentSection section, final ContentItem contentItem
|
).getText("contentsection.documentfolder.types.folder")
|
||||||
) {
|
);
|
||||||
Objects.requireNonNull(section);
|
} else {
|
||||||
Objects.requireNonNull(contentItem);
|
final ContentItem contentItem = itemRepo
|
||||||
|
.findById(entry.getEntryId())
|
||||||
final FolderBrowserRowModel row = new FolderBrowserRowModel();
|
.get();
|
||||||
row.setCreated(
|
row.setCreated(
|
||||||
DateTimeFormatter.ISO_DATE.format(
|
DateTimeFormatter.ISO_DATE.format(
|
||||||
LocalDate.ofInstant(
|
LocalDate.ofInstant(
|
||||||
|
|
@ -236,7 +374,6 @@ public class ContentSectionController {
|
||||||
row.setLastEditPublished(
|
row.setLastEditPublished(
|
||||||
liveLastModified.isBefore(draftLastModified)
|
liveLastModified.isBefore(draftLastModified)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
row.setLastEditPublished(false);
|
row.setLastEditPublished(false);
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +386,7 @@ public class ContentSectionController {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
row.setName(contentItem.getDisplayName());
|
row.setName(entry.getDisplayName());
|
||||||
row.setNoneCmsObject(false);
|
row.setNoneCmsObject(false);
|
||||||
row.setTitle(
|
row.setTitle(
|
||||||
globalizationHelper.getValueFromLocalizedString(
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
|
@ -258,46 +395,151 @@ public class ContentSectionController {
|
||||||
);
|
);
|
||||||
row.setType(
|
row.setType(
|
||||||
contentTypeRepo
|
contentTypeRepo
|
||||||
.findByContentSectionAndClass(section, contentItem.getClass())
|
.findByContentSectionAndClass(section, contentItem
|
||||||
|
.getClass())
|
||||||
.map(ContentType::getLabel)
|
.map(ContentType::getLabel)
|
||||||
.map(
|
.map(
|
||||||
label -> globalizationHelper.getValueFromLocalizedString(
|
label -> globalizationHelper
|
||||||
|
.getValueFromLocalizedString(
|
||||||
label
|
label
|
||||||
)
|
)
|
||||||
).orElse("?")
|
).orElse("?")
|
||||||
);
|
);
|
||||||
|
|
||||||
return row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private FolderBrowserRowModel buildRowModel(
|
|
||||||
final ContentSection section, final Folder folder
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(section);
|
|
||||||
Objects.requireNonNull(folder);
|
|
||||||
|
|
||||||
final FolderBrowserRowModel row = new FolderBrowserRowModel();
|
|
||||||
row.setCreated("");
|
|
||||||
row.setDeletable(
|
|
||||||
folderManager.folderIsDeletable(folder)
|
|
||||||
== FolderManager.FolderIsDeletable.YES
|
|
||||||
);
|
|
||||||
row.setIsFolder(true);
|
|
||||||
row.setLanguages(Collections.emptySortedSet());
|
|
||||||
row.setLastEditPublished(false);
|
|
||||||
row.setLastEdited("");
|
|
||||||
row.setName(folder.getDisplayName());
|
|
||||||
row.setNoneCmsObject(false);
|
|
||||||
row.setTitle(
|
|
||||||
globalizationHelper.getValueFromLocalizedString(folder.getTitle())
|
|
||||||
);
|
|
||||||
row.setType(
|
|
||||||
globalizationHelper.getLocalizedTextsUtil(
|
|
||||||
"org.libreccms.CmsAdminMessages"
|
|
||||||
).getText("contentsection.folderbrowser.types.folder")
|
|
||||||
);
|
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private DocumentFolderRowModel buildRowModel(
|
||||||
|
// final ContentSection section, final CcmObject object
|
||||||
|
// ) {
|
||||||
|
// Objects.requireNonNull(section);
|
||||||
|
// Objects.requireNonNull(object);
|
||||||
|
// if (object instanceof ContentItem) {
|
||||||
|
// return buildRowModel(section, (ContentItem) object);
|
||||||
|
// } else if (object instanceof Folder) {
|
||||||
|
// return buildRowModel(section, (Folder) object);
|
||||||
|
// } else {
|
||||||
|
// final DocumentFolderRowModel row = new DocumentFolderRowModel();
|
||||||
|
//
|
||||||
|
// row.setCreated("");
|
||||||
|
// row.setDeletable(false);
|
||||||
|
// row.setIsFolder(false);
|
||||||
|
// row.setLanguages(Collections.emptySortedSet());
|
||||||
|
// row.setLastEditPublished(false);
|
||||||
|
// row.setLastEdited("");
|
||||||
|
// row.setName(object.getDisplayName());
|
||||||
|
// row.setTitle("");
|
||||||
|
// row.setType(object.getClass().getSimpleName());
|
||||||
|
//
|
||||||
|
// return row;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private DocumentFolderRowModel buildRowModel(
|
||||||
|
// final ContentSection section, final ContentItem contentItem
|
||||||
|
// ) {
|
||||||
|
// Objects.requireNonNull(section);
|
||||||
|
// Objects.requireNonNull(contentItem);
|
||||||
|
//
|
||||||
|
// final DocumentFolderRowModel row = new DocumentFolderRowModel();
|
||||||
|
// row.setCreated(
|
||||||
|
// DateTimeFormatter.ISO_DATE.format(
|
||||||
|
// LocalDate.ofInstant(
|
||||||
|
// contentItem.getCreationDate().toInstant(),
|
||||||
|
// ZoneId.systemDefault()
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// row.setDeletable(!itemManager.isLive(contentItem));
|
||||||
|
// row.setIsFolder(false);
|
||||||
|
// row.setLanguages(
|
||||||
|
// new TreeSet<>(
|
||||||
|
// itemL10NManager
|
||||||
|
// .availableLanguages(contentItem)
|
||||||
|
// .stream()
|
||||||
|
// .map(Locale::toString)
|
||||||
|
// .collect(Collectors.toSet())
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// if (itemManager.isLive(contentItem)) {
|
||||||
|
// final LocalDate draftLastModified = LocalDate.ofInstant(
|
||||||
|
// contentItem.getLastModified().toInstant(),
|
||||||
|
// ZoneId.systemDefault()
|
||||||
|
// );
|
||||||
|
// final LocalDate liveLastModified = LocalDate.ofInstant(
|
||||||
|
// itemManager
|
||||||
|
// .getLiveVersion(contentItem, contentItem.getClass())
|
||||||
|
// .map(ContentItem::getLastModified)
|
||||||
|
// .map(Date::toInstant)
|
||||||
|
// .get(),
|
||||||
|
// ZoneId.systemDefault()
|
||||||
|
// );
|
||||||
|
// row.setLastEditPublished(
|
||||||
|
// liveLastModified.isBefore(draftLastModified)
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
// row.setLastEditPublished(false);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// row.setLastEdited(
|
||||||
|
// DateTimeFormatter.ISO_DATE.format(
|
||||||
|
// LocalDate.ofInstant(
|
||||||
|
// contentItem.getLastModified().toInstant(),
|
||||||
|
// ZoneId.systemDefault()
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// row.setName(contentItem.getDisplayName());
|
||||||
|
// row.setNoneCmsObject(false);
|
||||||
|
// row.setTitle(
|
||||||
|
// globalizationHelper.getValueFromLocalizedString(
|
||||||
|
// contentItem.getTitle()
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// row.setType(
|
||||||
|
// contentTypeRepo
|
||||||
|
// .findByContentSectionAndClass(section, contentItem.getClass())
|
||||||
|
// .map(ContentType::getLabel)
|
||||||
|
// .map(
|
||||||
|
// label -> globalizationHelper.getValueFromLocalizedString(
|
||||||
|
// label
|
||||||
|
// )
|
||||||
|
// ).orElse("?")
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// return row;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private DocumentFolderRowModel buildRowModel(
|
||||||
|
// final ContentSection section, final Folder folder
|
||||||
|
// ) {
|
||||||
|
// Objects.requireNonNull(section);
|
||||||
|
// Objects.requireNonNull(folder);
|
||||||
|
//
|
||||||
|
// final DocumentFolderRowModel row = new DocumentFolderRowModel();
|
||||||
|
// row.setCreated("");
|
||||||
|
// row.setDeletable(
|
||||||
|
// folderManager.folderIsDeletable(folder)
|
||||||
|
// == FolderManager.FolderIsDeletable.YES
|
||||||
|
// );
|
||||||
|
// row.setIsFolder(true);
|
||||||
|
// row.setLanguages(Collections.emptySortedSet());
|
||||||
|
// row.setLastEditPublished(false);
|
||||||
|
// row.setLastEdited("");
|
||||||
|
// row.setName(folder.getDisplayName());
|
||||||
|
// row.setNoneCmsObject(false);
|
||||||
|
// row.setTitle(
|
||||||
|
// globalizationHelper.getValueFromLocalizedString(folder.getTitle())
|
||||||
|
// );
|
||||||
|
// row.setType(
|
||||||
|
// globalizationHelper.getLocalizedTextsUtil(
|
||||||
|
// "org.librecms.CmsAdminMessages"
|
||||||
|
// ).getText("contentsection.documentfolder.types.folder")
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// return row;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ package org.librecms.ui;
|
||||||
import org.librecms.contentsection.ContentSection;
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
@ -29,7 +30,10 @@ public class ContentSectionModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSectionName() {
|
public String getSectionName() {
|
||||||
return section.getLabel();
|
return Optional
|
||||||
|
.ofNullable(section)
|
||||||
|
.map(ContentSection::getLabel)
|
||||||
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,15 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class FolderBrowserModel {
|
@Named("DocumentFolderModel")
|
||||||
|
public class DocumentFolderModel {
|
||||||
|
|
||||||
private long count;
|
private long count;
|
||||||
|
|
||||||
|
|
@ -25,7 +27,7 @@ public class FolderBrowserModel {
|
||||||
|
|
||||||
private int maxResults;
|
private int maxResults;
|
||||||
|
|
||||||
private List<FolderBrowserRowModel> rows;
|
private List<DocumentFolderRowModel> rows;
|
||||||
|
|
||||||
public long getCount() {
|
public long getCount() {
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -51,11 +53,11 @@ public class FolderBrowserModel {
|
||||||
this.maxResults = maxResults;
|
this.maxResults = maxResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FolderBrowserRowModel> getRows() {
|
public List<DocumentFolderRowModel> getRows() {
|
||||||
return Collections.unmodifiableList(rows);
|
return Collections.unmodifiableList(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setRows(final List<FolderBrowserRowModel> rows) {
|
protected void setRows(final List<DocumentFolderRowModel> rows) {
|
||||||
this.rows = new ArrayList<>(rows);
|
this.rows = new ArrayList<>(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.SortedSet;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public class FolderBrowserRowModel {
|
public class DocumentFolderRowModel {
|
||||||
|
|
||||||
private String created;
|
private String created;
|
||||||
|
|
||||||
|
|
@ -62,6 +62,10 @@ public class FolderBrowserRowModel {
|
||||||
return Collections.unmodifiableSortedSet(languages);
|
return Collections.unmodifiableSortedSet(languages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLanguagesAsString() {
|
||||||
|
return String.join(", ", languages);
|
||||||
|
}
|
||||||
|
|
||||||
protected void setLanguages(final SortedSet<String> languages) {
|
protected void setLanguages(final SortedSet<String> languages) {
|
||||||
this.languages = languages;
|
this.languages = languages;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<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:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||||
|
>
|
||||||
|
<head>
|
||||||
|
<title>Content Section #{ContentSectionModel.sectionName} #{title} - LibreCMS</title>
|
||||||
|
<link href="#{request.contextPath}/assets/@content-sections/cms-admin.css"
|
||||||
|
rel="stylesheet"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
#{CmsAdminMessages.getMessage("contentsection.accessdenied", [sectionidentifier])}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<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/content-section/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:param name="activePage" value="folderBrowser" />
|
||||||
|
<ui:param name="title" value="#{CmsAdminMessages['folderbrowser.title']}" />
|
||||||
|
<ui:define name="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
#{CmsAdminMessages['contentsections.list.label']}
|
||||||
|
</li>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
#{CmsAdminMessages.getMessage('contentsection.not_found', [sectionIdentifier])}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<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/content-section/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:param name="activePage" value="folderBrowser" />
|
||||||
|
<ui:param name="title" value="#{CmsAdminMessages['contentsection.documentfolder.title']}" />
|
||||||
|
<ui:define name="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
#{CmsAdminMessages['contentsections.list.label']}
|
||||||
|
</li>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<h1>#{CmsAdminMessages.getMessage("contentsection.documentfolder.heading", [ContentSectionModel.sectionName])}</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<nav class="col-sm-3 documentfolder">
|
||||||
|
<!-- <ul class="nav flex-column border">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 1</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<div class="d-flex">
|
||||||
|
<button class="btn btn-light pr-0 subfolders-toggler"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#folder-2-subfolders"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="folder-2-subfolders"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="caret-right-fill" />
|
||||||
|
<span class="sr-only">
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.foldersnav.subfolders.expand']}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<a class="nav-link pl-0" href="#">Folder 2</a>
|
||||||
|
</div>
|
||||||
|
<ul class="nav flex-column collapse"
|
||||||
|
id="folder-2-subfolders">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 2-1</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 2-2</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 2-3</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 3</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 4</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Folder 5</a>
|
||||||
|
</li>
|
||||||
|
</ul>-->
|
||||||
|
<ul class="list-group">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<a class="" href="#">Folder 1</a>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<div class="d-flex">
|
||||||
|
<button class="btn btn-light p-0 subfolders-toggler"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#folder-2-subfolders"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="folder-2-subfolders"
|
||||||
|
type="button">
|
||||||
|
<!--<bootstrap:svgIcon icon="caret-right-fill" />-->
|
||||||
|
<span class="sr-only">
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.foldersnav.subfolders.expand']}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<a class="pl-0" href="#">Folder 2</a>
|
||||||
|
</div>
|
||||||
|
<ul class="border-0 collapse list-group "
|
||||||
|
id="folder-2-subfolders">
|
||||||
|
<li class="border-0 list-group-item">
|
||||||
|
<a class="" href="#">Folder 2-1</a>
|
||||||
|
</li>
|
||||||
|
<li class="border-0 list-group-item">
|
||||||
|
<a class="" href="#">Folder 2-2</a>
|
||||||
|
</li>
|
||||||
|
<li class="border-0 list-group-item">
|
||||||
|
<a class="" href="#">Folder 2-3</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<a class="" href="#">Folder 3</a>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<a class="" href="#">Folder 4</a>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<a class="" href="#">Folder 5</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<table class="table table-hover documentfolder">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.name.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.languages.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.title.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.type.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.creationdate.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.lastedit.label']}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
#{CmsAdminMessages['contentsection.documentfolder.headers.actions.label']}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<c:forEach items="#{DocumentFolderModel.rows}"
|
||||||
|
var="row">
|
||||||
|
<tr>
|
||||||
|
<td><a href="#">#{row.name}</a></td>
|
||||||
|
<td>
|
||||||
|
#{row.languagesAsString}
|
||||||
|
</td>
|
||||||
|
<td>#{row.title}</td>
|
||||||
|
<td>#{row.type}</td>
|
||||||
|
<td>#{row.created}</td>
|
||||||
|
<td>
|
||||||
|
<span>#{row.lastEdited}</span>
|
||||||
|
<c:if test="#{row.lastEdited != null}">
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="#{row.lastEditPublished}">
|
||||||
|
<span aria-describedby="#{row.name}-publication-state-desc">
|
||||||
|
<bootstrap:svgIcon icon="eye" />
|
||||||
|
</span>
|
||||||
|
<span class="sr-only" id="#{row.name}-publication-state-desc">#{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.published']}</span>
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
<span aria-describedby="#{row.name}-publication-state-desc">
|
||||||
|
<bootstrap:svgIcon icon="eye-slash" />
|
||||||
|
</span>
|
||||||
|
<span class="sr-only" id="#{row.name}-publication-state-desc">#{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.unpublished']}</span>
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<c:if test="#{row.deletable}">
|
||||||
|
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</c:forEach>
|
||||||
|
<!-- <tr>
|
||||||
|
<td><a href="#">folder-1</a></td>
|
||||||
|
<td></td>
|
||||||
|
<td>Folder 1</td>
|
||||||
|
<td>Ordner</td>
|
||||||
|
<td>2021-01-20 08:59</td>
|
||||||
|
<td>2021-01-20 08:59</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#">an-item</a></td>
|
||||||
|
<td>de, en</td>
|
||||||
|
<td>An item</td>
|
||||||
|
<td>Article</td>
|
||||||
|
<td>2021-01-20 09:03</td>
|
||||||
|
<td>
|
||||||
|
<span>2021-01-20 10:11</span>
|
||||||
|
<span aria-describedby="an-item-publication-state-desc">
|
||||||
|
<bootstrap:svgIcon icon="eye" />
|
||||||
|
</span>
|
||||||
|
<span class="sr-only" id="an-item-publication-state-desc">#{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.published']}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x-circle" />
|
||||||
|
<span>#{CmsAdminMessages['contentsection.documentfolder.actions.delete.button.label']}</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#">unpublished-item</a></td>
|
||||||
|
<td>de, en</td>
|
||||||
|
<td>Unppublished item item</td>
|
||||||
|
<td>Article</td>
|
||||||
|
<td>2021-01-20 10:31</td>
|
||||||
|
<td>
|
||||||
|
<span>2021-01-20 10:34</span>
|
||||||
|
<span aria-describedby="unpublished-item-publication-state-desc">
|
||||||
|
<bootstrap:svgIcon icon="eye-slash" />
|
||||||
|
</span>
|
||||||
|
<span class="sr-only" id="unpublished-item-publication-state-desc">#{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.unpublished']}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x-circle" />
|
||||||
|
<span>#{CmsAdminMessages['contentsection.documentfolder.actions.delete.button.label']}</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>-->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<nav aria-label="#{CmsAdminMessages['contentsection.documentfolder.pagination.label']}">
|
||||||
|
<ul class="justify-content-center pagination">
|
||||||
|
<li class="page-item disabled" tabindex="-1" aria-disabled="true">
|
||||||
|
<a class="page-link" href="#">
|
||||||
|
<bootstrap:svgIcon icon="caret-left" />
|
||||||
|
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.pagination.previous_page']}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="page-link" href="#">1</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="page-link" href="#">2</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="page-link" href="#">3</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="page-link" href="#">
|
||||||
|
<bootstrap:svgIcon icon="caret-right" />
|
||||||
|
<span class="sr-only">#{CmsAdminMessages['contentsection.documentfolder.pagination.next_page']}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
<!DOCTYPE html [<!ENTITY times '×'>]>
|
|
||||||
<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/content-section/contentsection.xhtml">
|
|
||||||
|
|
||||||
<ui:param name="activePage" value="folderBrowser" />
|
|
||||||
<ui:param name="title" value="#{CmsAdminMessages['folderbrowser.title']}" />
|
|
||||||
<ui:define name="breadcrumb">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
#{CmsAdminMessages['contentsections.list.label']}
|
|
||||||
</li>
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
<ui:define name="main">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<h1>#{CmsAdminMessages.getMessage("folderbrowser.heading", [ContentSectionModel.sectionName])}</h1>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<nav class="col-sm-3 folderbrowser">
|
|
||||||
<!-- <ul class="nav flex-column border">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 1</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<div class="d-flex">
|
|
||||||
<button class="btn btn-light pr-0 subfolders-toggler"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#folder-2-subfolders"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-controls="folder-2-subfolders"
|
|
||||||
type="button">
|
|
||||||
<bootstrap:svgIcon icon="caret-right-fill" />
|
|
||||||
<span class="sr-only">
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.foldersnav.subfolders.expand']}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<a class="nav-link pl-0" href="#">Folder 2</a>
|
|
||||||
</div>
|
|
||||||
<ul class="nav flex-column collapse"
|
|
||||||
id="folder-2-subfolders">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 2-1</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 2-2</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 2-3</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 3</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 4</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">Folder 5</a>
|
|
||||||
</li>
|
|
||||||
</ul>-->
|
|
||||||
<ul class="list-group">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<a class="" href="#">Folder 1</a>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<div class="d-flex">
|
|
||||||
<button class="btn btn-light p-0 subfolders-toggler"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#folder-2-subfolders"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-controls="folder-2-subfolders"
|
|
||||||
type="button">
|
|
||||||
<!--<bootstrap:svgIcon icon="caret-right-fill" />-->
|
|
||||||
<span class="sr-only">
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.foldersnav.subfolders.expand']}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<a class="pl-0" href="#">Folder 2</a>
|
|
||||||
</div>
|
|
||||||
<ul class="border-0 collapse list-group "
|
|
||||||
id="folder-2-subfolders">
|
|
||||||
<li class="border-0 list-group-item">
|
|
||||||
<a class="" href="#">Folder 2-1</a>
|
|
||||||
</li>
|
|
||||||
<li class="border-0 list-group-item">
|
|
||||||
<a class="" href="#">Folder 2-2</a>
|
|
||||||
</li>
|
|
||||||
<li class="border-0 list-group-item">
|
|
||||||
<a class="" href="#">Folder 2-3</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<a class="" href="#">Folder 3</a>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<a class="" href="#">Folder 4</a>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<a class="" href="#">Folder 5</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<table class="col-sm-9 table table-hover folderbrowser">
|
|
||||||
<thead class="thead-light">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.name.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.languages.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.title.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.type.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.creationdate.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.lastedit.label']}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
#{CmsAdminMessages['contentsection.folderbrowser.headers.actions.label']}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#">folder-1</a></td>
|
|
||||||
<td></td>
|
|
||||||
<td>Folder 1</td>
|
|
||||||
<td>Ordner</td>
|
|
||||||
<td>2021-01-20 08:59</td>
|
|
||||||
<td>2021-01-20 08:59</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#">an-item</a></td>
|
|
||||||
<td>de, en</td>
|
|
||||||
<td>An item</td>
|
|
||||||
<td>Article</td>
|
|
||||||
<td>2021-01-20 09:03</td>
|
|
||||||
<td>
|
|
||||||
<span>2021-01-20 10:11</span>
|
|
||||||
<span aria-describedby="an-item-publication-state-desc">
|
|
||||||
<bootstrap:svgIcon icon="eye" />
|
|
||||||
</span>
|
|
||||||
<span class="sr-only" id="an-item-publication-state-desc">#{CmsAdminMessages['contentsection.folderbrowser.cols.lastedit.published']}</span>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#">unpublished-item</a></td>
|
|
||||||
<td>de, en</td>
|
|
||||||
<td>Unppublished item item</td>
|
|
||||||
<td>Article</td>
|
|
||||||
<td>2021-01-20 10:31</td>
|
|
||||||
<td>
|
|
||||||
<span>2021-01-20 10:34</span>
|
|
||||||
<span aria-describedby="unpublished-item-publication-state-desc">
|
|
||||||
<bootstrap:svgIcon icon="eye-slash" />
|
|
||||||
</span>
|
|
||||||
<span class="sr-only" id="unpublished-item-publication-state-desc">#{CmsAdminMessages['contentsection.folderbrowser.cols.lastedit.unpublished']}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger"
|
|
||||||
type="button">
|
|
||||||
<bootstrap:svgIcon icon="x-circle" />
|
|
||||||
<span>#{CmsAdminMessages['contentsection.folderbrowser.actions.delete.button.label']}</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
</ui:composition>
|
|
||||||
</html>
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<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/content-section/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:param name="activePage" value="folderBrowser" />
|
||||||
|
<ui:param name="title" value="#{CmsAdminMessages['folderbrowser.title']}" />
|
||||||
|
<ui:define name="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
#{CmsAdminMessages['contentsections.list.label']}
|
||||||
|
</li>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
#{testdataMessage}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -24,17 +24,23 @@ contentsections.edit_dialog.close=Cancel
|
||||||
contentsections.edit_dialog.name.label=Name
|
contentsections.edit_dialog.name.label=Name
|
||||||
contentsections.edit_dialog.save=Rename content section
|
contentsections.edit_dialog.save=Rename content section
|
||||||
contentsections.edit_dialog.name.help=The name of the content section. Can only contain the letters a to z, the numbers 0-9, the hyphen and the underscore.
|
contentsections.edit_dialog.name.help=The name of the content section. Can only contain the letters a to z, the numbers 0-9, the hyphen and the underscore.
|
||||||
folderbrowser.title=Folder Browser
|
contentsection.documentfolder.title=Document Folders
|
||||||
folderbrowser.heading=Content Section {0} Folderbrowser
|
contentsection.documentfolder.heading=Content Section {0} Documents Folder
|
||||||
contentsection.folderbrowser.headers.name.label=Name
|
contentsection.documentfolder.headers.name.label=Name
|
||||||
contentsection.folderbrowser.headers.languages.label=Languages
|
contentsection.documentfolder.headers.languages.label=Languages
|
||||||
contentsection.folderbrowser.headers.title.label=Title
|
contentsection.documentfolder.headers.title.label=Title
|
||||||
contentsection.folderbrowser.headers.type.label=Type
|
contentsection.documentfolder.headers.type.label=Type
|
||||||
contentsection.folderbrowser.headers.creationdate.label=Created
|
contentsection.documentfolder.headers.creationdate.label=Created
|
||||||
contentsection.folderbrowser.headers.lastedit.label=Last edit
|
contentsection.documentfolder.headers.lastedit.label=Last edit
|
||||||
contentsection.folderbrowser.headers.actions.label=Aktionen
|
contentsection.documentfolder.headers.actions.label=Aktionen
|
||||||
contentsection.folderbrowser.cols.lastedit.published=Published
|
contentsection.documentfolder.cols.lastedit.published=Published
|
||||||
contentsection.folderbrowser.cols.lastedit.unpublished=Not published yet
|
contentsection.documentfolder.cols.lastedit.unpublished=Not published yet
|
||||||
contentsection.folderbrowser.actions.delete.button.label=Delete
|
contentsection.documentfolder.actions.delete.button.label=Delete
|
||||||
contentsection.folderbrowser.foldersnav.subfolders.expand=Show subfolders of
|
contentsection.documentfolder.foldersnav.subfolders.expand=Show subfolders of
|
||||||
org.libreccms.CmsAdminMessages=Folder
|
org.libreccms.CmsAdminMessages=Folder
|
||||||
|
contentsection.documentfolder.pagination.label=Pages
|
||||||
|
contentsection.documentfolder.pagination.previous_page=Previous page
|
||||||
|
contentsection.documentfolder.pagination.next_page=Next page
|
||||||
|
contentsection.not_found=No content section identifed by {0} available.
|
||||||
|
contentsection.accessdenied=Your are not permitted to access content section {0}.
|
||||||
|
contentsection.documentfolder.types.folder=Folder
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,23 @@ contentsections.edit_dialog.close=Abbrechen
|
||||||
contentsections.edit_dialog.name.label=Name
|
contentsections.edit_dialog.name.label=Name
|
||||||
contentsections.edit_dialog.save=Content Section umbenennen
|
contentsections.edit_dialog.save=Content Section umbenennen
|
||||||
contentsections.edit_dialog.name.help=Der Name der Content Section. Darf nur die Zeichen a bis z, 0-9, the Bindestrich und den Unterstrich enthalten.
|
contentsections.edit_dialog.name.help=Der Name der Content Section. Darf nur die Zeichen a bis z, 0-9, the Bindestrich und den Unterstrich enthalten.
|
||||||
folderbrowser.title=Ordner
|
contentsection.documentfolder.title=Dokumenten-Ordner
|
||||||
folderbrowser.heading=Content Section {0} Ordner
|
contentsection.documentfolder.heading=Content Section {0} Dokumenten-Ordner
|
||||||
contentsection.folderbrowser.headers.name.label=Name
|
contentsection.documentfolder.headers.name.label=Name
|
||||||
contentsection.folderbrowser.headers.languages.label=Sprachen
|
contentsection.documentfolder.headers.languages.label=Sprachen
|
||||||
contentsection.folderbrowser.headers.title.label=Titel
|
contentsection.documentfolder.headers.title.label=Titel
|
||||||
contentsection.folderbrowser.headers.type.label=Typ
|
contentsection.documentfolder.headers.type.label=Typ
|
||||||
contentsection.folderbrowser.headers.creationdate.label=Erstellt
|
contentsection.documentfolder.headers.creationdate.label=Erstellt
|
||||||
contentsection.folderbrowser.headers.lastedit.label=Letzte \u00c4nderung
|
contentsection.documentfolder.headers.lastedit.label=Letzte \u00c4nderung
|
||||||
contentsection.folderbrowser.headers.actions.label=Aktionen
|
contentsection.documentfolder.headers.actions.label=Aktionen
|
||||||
contentsection.folderbrowser.cols.lastedit.published=Publiziert
|
contentsection.documentfolder.cols.lastedit.published=Publiziert
|
||||||
contentsection.folderbrowser.cols.lastedit.unpublished=Nicht nicht publiziert
|
contentsection.documentfolder.cols.lastedit.unpublished=Nicht nicht publiziert
|
||||||
contentsection.folderbrowser.actions.delete.button.label=L\u00f6schen
|
contentsection.documentfolder.actions.delete.button.label=L\u00f6schen
|
||||||
contentsection.folderbrowser.foldersnav.subfolders.expand=Unterordner anzeigen
|
contentsection.documentfolder.foldersnav.subfolders.expand=Unterordner anzeigen
|
||||||
org.libreccms.CmsAdminMessages=Ordner
|
org.libreccms.CmsAdminMessages=Ordner
|
||||||
|
contentsection.documentfolder.pagination.label=Seiten
|
||||||
|
contentsection.documentfolder.pagination.previous_page=Eine Seite zur\u00fcck
|
||||||
|
contentsection.documentfolder.pagination.next_page=Eine Seite weiter
|
||||||
|
contentsection.not_found=Keine Content Section mit dem Identifier {0} gefunden.
|
||||||
|
contentsection.accessdenied=Sind sind nicht berechtigt auf die Content Section {0} zuzugreifen.
|
||||||
|
contentsection.documentfolder.types.folder=Ordner
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<groupId>org.libreccm</groupId>
|
<groupId>org.libreccm</groupId>
|
||||||
<artifactId>ccm-wildfly</artifactId>
|
<artifactId>ccm-wildfly</artifactId>
|
||||||
<version>7.0.0-SNAPSHOT</version>
|
<version>7.0.0-SNAPSHOT</version>
|
||||||
<name>CCM Wildfly Integration</name>
|
<name>LibreCCM Wildfly Integration</name>
|
||||||
<description>
|
<description>
|
||||||
Wildfly specific stuff for CCM.
|
Wildfly specific stuff for CCM.
|
||||||
</description>
|
</description>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue