Progress on the category management for cms admin

Former-commit-id: ec215c08aad419ee672cf71cb50a20be0dcff69c
pull/10/head
Jens Pelzetter 2021-02-15 21:08:56 +01:00
parent 10ce888689
commit 722f5c210f
5 changed files with 305 additions and 22 deletions

View File

@ -26,6 +26,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
@ -173,7 +174,7 @@ public class CategoriesController {
if (categoryPath.isEmpty()) {
activePath = "/";
} else {
activePath = categoryPath;
activePath = String.format("/%s", categoryPath);
}
categorySystemModel.setCategoryTree(
buildCategoryTree(domain, activePath)
@ -295,7 +296,7 @@ public class CategoriesController {
}
@POST
@Path("/{context}/categories/{categoryPath:(.+)?}/@title/edit/{locale}")
@Path("/{context}/categories/{categoryPath:(.+)?}/@title/locale")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String editTitle(
@ -441,7 +442,7 @@ public class CategoriesController {
}
@POST
@Path("/{context}/categories/{categoryPath:(.+)?}/@attributes")
@Path("/{context}/categories/{categoryPath:(.+)?}/@properties")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateCategory(
@ -923,7 +924,7 @@ public class CategoriesController {
);
}
final String path = categoryManager.getCategoryPath(category);
model.setActive(activePath.equals(path));
model.setActive(activePath.startsWith(path));
model.setPath(path);
if (!category.getSubCategories().isEmpty()) {
model.setSubCategories(
@ -976,6 +977,57 @@ public class CategoriesController {
model.setUniqueId(category.getUniqueId());
model.setUuid(category.getUuid());
model.setVisible(category.isVisible());
final List<Locale> availableLocales = globalizationHelper
.getAvailableLocales();
model.setLocalizedTitles(
category
.getTitle()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
entry -> entry.getValue()
)
)
);
final Set<Locale> titleLocales = category
.getTitle()
.getAvailableLocales();
model.setUnusedTitleLocales(
availableLocales
.stream()
.filter(locale -> !titleLocales.contains(locale))
.map(Locale::toString)
.collect(Collectors.toList())
);
model.setLocalizedDescriptions(
category
.getDescription()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
entry -> entry.getValue()
)
)
);
final Set<Locale> descriptionLocales = category
.getDescription()
.getAvailableLocales();
model.setUnusedDescriptionLocales(
availableLocales
.stream()
.filter(locale -> !descriptionLocales.contains(locale))
.map(Locale::toString)
.collect(Collectors.toList())
);
return model;
}

View File

@ -7,43 +7,61 @@ package org.librecms.ui.contentsections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryModel {
private long categoryId;
private String uuid;
private String uniqueId;
private String name;
private String path;
private String title;
private Map<String, String> localizedTitles;
private String description;
private Map<String, String> localizedDescriptions;
private boolean enabled;
private boolean visible;
private boolean abstractCategory;
private List<CategoryModel> subCategories;
private List<CategorizedObjectModel> objects;
private long categoryOrder;
private boolean hasUnusedTitleLocales;
private boolean hasUnusedDescriptionLocales;
private List<String> unusedTitleLocales;
private List<String> unusedDescriptionLocales;
public CategoryModel() {
subCategories = new ArrayList<>();
objects = new ArrayList<>();
localizedTitles = new HashMap<>();
localizedDescriptions = new HashMap<>();
}
public long getCategoryId() {
@ -53,11 +71,11 @@ public class CategoryModel {
public void setCategoryId(final long categoryId) {
this.categoryId = categoryId;
}
public String getUuid() {
return uuid;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}
@ -149,7 +167,56 @@ public class CategoryModel {
public void setCategoryOrder(final long categoryOrder) {
this.categoryOrder = categoryOrder;
}
public boolean isHasUnusedTitleLocales() {
return hasUnusedTitleLocales;
}
public void setHasUnusedTitleLocales(final boolean hasUnusedTitleLocales) {
this.hasUnusedTitleLocales = hasUnusedTitleLocales;
}
public Map<String, String> getLocalizedTitles() {
return localizedTitles;
}
public void setLocalizedTitles(Map<String, String> localizedTitles) {
this.localizedTitles = localizedTitles;
}
public Map<String, String> getLocalizedDescriptions() {
return localizedDescriptions;
}
public void setLocalizedDescriptions(
Map<String, String> localizedDescriptions) {
this.localizedDescriptions = localizedDescriptions;
}
public boolean isHasUnusedDescriptionLocales() {
return hasUnusedDescriptionLocales;
}
public void setHasUnusedDescriptionLocales(
boolean hasUnusedDescriptionLocales) {
this.hasUnusedDescriptionLocales = hasUnusedDescriptionLocales;
}
public List<String> getUnusedTitleLocales() {
return unusedTitleLocales;
}
public void setUnusedTitleLocales(List<String> unusedTitleLocales) {
this.unusedTitleLocales = unusedTitleLocales;
}
public List<String> getUnusedDescriptionLocales() {
return unusedDescriptionLocales;
}
public void setUnusedDescriptionLocales(
List<String> unusedDescriptionLocales) {
this.unusedDescriptionLocales = unusedDescriptionLocales;
}
}

View File

@ -58,7 +58,7 @@
<dl>
<div>
<dt>#{CmsAdminMessages['contentsection.categorysystems.category.properties.id']}</dt>
<dd>#{CategorySystemModel.selectedCategory.id}</dd>
<dd>#{CategorySystemModel.selectedCategory.categoryId}</dd>
</div>
<div>
<dt>#{CmsAdminMessages['contentsection.categorysystems.category.properties.uuid']}</dt>
@ -112,7 +112,147 @@
</dd>
</div>
</dl>
</div>
<div class="mb-4">
<button class="btn btn-primary"
data-toggle="modal"
data-target="#category-properties"
type="button">
<bootstrap:svgIcon icon="pen" />
<span>#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit']}</span>
</button>
<div aria-hidden="true"
aria-labelledby="category-properties-title"
class="modal fade"
id="category-properties"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@properties"
class="modal-content"
method="post">
<div class="modal-header">
<h3 class="modal-title"
id="category-properties-title">#{CmsAdminMessages.getMessage("contentsecton.categorysystems.category.properties.edit.dialog.title", [CategorySystemModel.selectedCategory.path])}</h3>
<button aria-label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.cancel']}"
data-dismiss="modal"
class="close"
type="button">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText help="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.name.help']}"
inputId="categoryName"
label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.name.label']}"
name="categoryName"
pattern="[\\w-.]*"
required="true"
value="#{CategorySystemModel.selectedCategory.name}" />
<bootstrap:formGroupText help="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.unique_id.help']}"
inputId="uniqueId"
label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.unique_id.label']}"
name="uniqueId"
pattern="[\\w-.]*"
required="true"
value="#{CategorySystemModel.selectedCategory.uniqueId}" />
<bootstrap:formCheck label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.enabled.label']}"
inputId="isEnabled"
name="isEnabled"
value="#{CategorySystemModel.selectedCategory.enabled}" />
<bootstrap:formCheck label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.visible.label']}"
inputId="isvisible"
name="isVisible"
value="#{CategorySystemModel.selectedCategory.visible}" />
<bootstrap:formCheck label="#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.abstract_category.label']}"
inputId="isAbstract"
name="isAbstract"
value="#{CategorySystemModel.selectedCategory.abstractCategory}" />
</div>
<div class="modal-footer">
<button class="btn btn-danger"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.cancel']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsAdminMessages['contentsecton.categorysystems.category.properties.edit.dialog.save']}
</button>
</div>
</form>
</div>
</div>
</div>
<h2>#{CmsAdminMessages.getMessage("contentsection.categorysystems.category.titles.heading", [CategorySystemModel.selectedCategory.name])}</h2>
<libreccm:localizedStringEditor addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/add"
addButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.label']}"
addDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.cancel']}"
addDialogLocaleSelectHelp="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.locale.help']}"
addDialogLocaleSelectLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.locale.label']}"
addDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.submit']}"
addDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.add.title']}"
addDialogValueHelp="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.value.help']}"
addDialogValueLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.add.value.label']}"
editButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.label']}"
editDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.cancel']}"
editDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.submit']}"
editDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.title']}"
editDialogValueHelp="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.value.help']}"
editDialogValueLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/edit"
editorId="category-title"
emptyText="#{CmsAdminMessages['contentsection.categorysystems.category.titles.none']}"
hasUnusedLocales="#{CategorySystemModel.selectedCategory.hasUnusedTitleLocales}"
objectIdentifier="#{CategorySystemModel.selectedCategory.path}"
removeButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.delete.label']}"
removeDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.delete.cancel']}"
removeDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.titles.delete.submit']}"
removeDialogText="#{CmsAdminMessages['contentsection.categorysystems.category.titles.delete.text']}"
removeDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.titles.delete.title']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/remove"
tableActionsHeading="#{CmsAdminMessages['contentsection.categorysystems.category.titles.actions.heading']}"
tableLocaleHeading="#{CmsAdminMessages['contentsection.categorysystems.category.titles.locale.heading']}"
tableValueHeading="#{CmsAdminMessages['contentsection.categorysystems.category.titles.value.heading']}"
title="#{CmsAdminMessages['contentsection.categorysystems.category.titles.locale.title']}"
unusedLocales="#{CategorySystemModel.selectedCategory.unusedTitleLocales}"
values="#{CategorySystemModel.selectedCategory.localizedTitles}" />
<h2>#{CmsAdminMessages.getMessage("contentsection.categorysystems.category.descriptions.heading", [CategorySystemModel.selectedCategory.name])}</h2>
<libreccm:localizedStringEditor addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/add"
addButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.label']}"
addDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.cancel']}"
addDialogLocaleSelectHelp="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.locale.help']}"
addDialogLocaleSelectLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.locale.label']}"
addDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.submit']}"
addDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.add.title']}"
addDialogValueHelp="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.value.help']}"
addDialogValueLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.add.value.label']}"
editButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.label']}"
editDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.cancel']}"
editDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.submit']}"
editDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.title']}"
editDialogValueHelp="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.value.help']}"
editDialogValueLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/edit"
editorId="category-title"
emptyText="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.none']}"
hasUnusedLocales="#{CategorySystemModel.selectedCategory.hasUnusedTitleLocales}"
objectIdentifier="#{CategorySystemModel.selectedCategory.path}"
removeButtonLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.delete.label']}"
removeDialogCancelLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.delete.cancel']}"
removeDialogSubmitLabel="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.delete.submit']}"
removeDialogText="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.delete.text']}"
removeDialogTitle="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.delete.title']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{CategorySystemModel.selectedCategory.path}/@title/remove"
tableActionsHeading="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.actions.heading']}"
tableLocaleHeading="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.locale.heading']}"
tableValueHeading="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.value.heading']}"
title="#{CmsAdminMessages['contentsection.categorysystems.category.descriptions.locale.title']}"
unusedLocales="#{CategorySystemModel.selectedCategory.unusedTitleLocales}"
values="#{CategorySystemModel.selectedCategory.localizedTitles}" />
</div>
</div>
</div>
</ui:define>

View File

@ -165,3 +165,15 @@ contentsection.categorysystems.category.properties.visible.no=No
contentsection.categorysystems.category.properties.abstract_category=Abstract category?
contentsection.categorysystems.category.properties.abstract_category.yes=Yes
contentsection.categorysystems.category.properties.abstract_category.no=No
contentsecton.categorysystems.category.properties.edit=Edit
contentsecton.categorysystems.category.properties.edit.dialog.title=Edit properties of category {0}
contentsecton.categorysystems.category.properties.edit.dialog.cancel=Cancel
contentsecton.categorysystems.category.properties.edit.dialog.save=Save
contentsecton.categorysystems.category.properties.edit.dialog.name.help=Name of the category. May only contain the letters, numbers and hypens.
contentsecton.categorysystems.category.properties.edit.dialog.name.label=Name
contentsecton.categorysystems.category.properties.edit.dialog.unique_id.help=Unique ID of the new category. Should be unique for the complete category system
contentsecton.categorysystems.category.properties.edit.dialog.unique_id.label=Unique ID
contentsecton.categorysystems.category.properties.edit.dialog.enabled.label=Enabled
contentsecton.categorysystems.category.properties.edit.dialog.visible.label=Visible?
contentsecton.categorysystems.category.properties.edit.dialog.abstract_category.label=Abstract?
contentsection.categorysystems.category.titles.heading=Localized Titles

View File

@ -165,3 +165,15 @@ contentsection.categorysystems.category.properties.visible.no=Nein
contentsection.categorysystems.category.properties.abstract_category=Abstrakte Kategorie?
contentsection.categorysystems.category.properties.abstract_category.yes=Ja
contentsection.categorysystems.category.properties.abstract_category.no=Nein
contentsecton.categorysystems.category.properties.edit=Bearbeiten
contentsecton.categorysystems.category.properties.edit.dialog.title=Eigenschaften der Kategorie {0} bearbeiten
contentsecton.categorysystems.category.properties.edit.dialog.cancel=Abbrechen
contentsecton.categorysystems.category.properties.edit.dialog.save=Speichern
contentsecton.categorysystems.category.properties.edit.dialog.name.help=Name der Kategorie. Darf nur Buchstaben, Zahlen und den Bindestrich enthalten.
contentsecton.categorysystems.category.properties.edit.dialog.name.label=Name
contentsecton.categorysystems.category.properties.edit.dialog.unique_id.help=Eindeutige ID der Kategorie. Sollte innerhalb des gesamten Kategoriensystems eindeutig sein.
contentsecton.categorysystems.category.properties.edit.dialog.unique_id.label=Eindeutige ID
contentsecton.categorysystems.category.properties.edit.dialog.enabled.label=Aktiv?
contentsecton.categorysystems.category.properties.edit.dialog.visible.label=Sichtbar?
contentsecton.categorysystems.category.properties.edit.dialog.abstract_category.label=Abstrakt?
contentsection.categorysystems.category.titles.heading=Lokalisierte Titel