From 1b4b6e571b2f1329fdeef31d00148c430cfc71cd Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sat, 28 Nov 2020 20:26:04 +0100 Subject: [PATCH] Content Section management for Admin application --- ccm-bundle-devel-wildfly/pom.xml | 8 ++ ccm-cms/pom.xml | 16 +++ .../ContentSectionAdminMessages.java | 127 +++++++++++++++++ .../ContentSectionApplicationController.java | 134 ++++++++++++++++++ .../ContentSectionTableRow.java | 57 ++++++++ ccm-cms/src/main/java/org/librecms/Cms.java | 4 +- .../content-sections/content-sections.xhtml | 115 +++++++++++++++ .../ContentSectionResources.properties | 18 +++ .../ContentSectionResources_de.properties | 18 +++ ccm-shortcuts/pom.xml | 1 + .../shortcuts/ShortcutAdminMessages.java | 1 - .../ShortcutsApplicationController.java | 5 +- 12 files changed, 500 insertions(+), 4 deletions(-) create mode 100644 ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionAdminMessages.java create mode 100644 ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionApplicationController.java create mode 100644 ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionTableRow.java create mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/content-sections/content-sections.xhtml diff --git a/ccm-bundle-devel-wildfly/pom.xml b/ccm-bundle-devel-wildfly/pom.xml index 1cdb1c0f4..3fb923da7 100644 --- a/ccm-bundle-devel-wildfly/pom.xml +++ b/ccm-bundle-devel-wildfly/pom.xml @@ -232,6 +232,14 @@ resources/ + + org.librecms + ccm-cms + jar + + WEB-INF/ + + org.librecms ccm-cms diff --git a/ccm-cms/pom.xml b/ccm-cms/pom.xml index b2da1d216..9c339d900 100644 --- a/ccm-cms/pom.xml +++ b/ccm-cms/pom.xml @@ -71,6 +71,22 @@ provided + + javax.mvc + javax.mvc-api + provided + + + org.eclipse.krazo + krazo-core + provided + + + org.eclipse.krazo.ext + krazo-freemarker + provided + + com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider diff --git a/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionAdminMessages.java b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionAdminMessages.java new file mode 100644 index 000000000..6411f3690 --- /dev/null +++ b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionAdminMessages.java @@ -0,0 +1,127 @@ +/* + * 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.libreccm.ui.admin.contentsections; + +import org.libreccm.l10n.GlobalizationHelper; +import org.librecms.CmsConstants; + +import java.text.MessageFormat; +import java.util.AbstractMap; +import java.util.List; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("ContentSectionAdminMessages") +public class ContentSectionAdminMessages extends AbstractMap { + + /** + * Provides access to the locale negoiated by LibreCCM. + */ + @Inject + private GlobalizationHelper globalizationHelper; + + /** + * The {@link ResourceBundle} to use. + */ + private ResourceBundle messages; + + /** + * Loads the resource bundle. + */ + @PostConstruct + private void init() { + messages = ResourceBundle.getBundle( + CmsConstants.CONTENT_SECTION_DESC_BUNDLE, + globalizationHelper.getNegotiatedLocale() + ); + } + + /** + * Retrieves a message from the resource bundle. + * + * @param key The key of the message. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage(final String key) { + if (messages.containsKey(key)) { + return messages.getString(key); + } else { + return String.format("???%s???", key); + } + } + + /** + * Retrieves a message with placeholders. + * + * @param key The key of the message. + * @param parameters The parameters for the placeholders. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage( + final String key, final List parameters + ) { + return getMessage(key, parameters.toArray()); + } + + /** + * The translated message or {@code ???message???} if the the key is not + * found in the resource bundle (message is replaced with the key). + * + * @param key The key of the message. + * @param parameters The parameters for the placeholders. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage( + final String key, final Object[] parameters + ) { + if (messages.containsKey(key)) { + return MessageFormat.format(messages.getString(key), parameters); + } else { + return String.format("???%s???", key); + } + } + + @Override + public String get(final Object key) { + return get((String) key); + } + + public String get(final String key) { + return getMessage(key); + } + + @Override + public Set> entrySet() { + return messages + .keySet() + .stream() + .collect( + Collectors.toMap(key -> key, key -> messages.getString(key)) + ) + .entrySet(); + } + +} diff --git a/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionApplicationController.java b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionApplicationController.java new file mode 100644 index 000000000..5cc918e27 --- /dev/null +++ b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionApplicationController.java @@ -0,0 +1,134 @@ +/* + * 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.libreccm.ui.admin.contentsections; + +import org.libreccm.core.CoreConstants; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.ui.admin.applications.ApplicationController; +import org.librecms.contentsection.ContentSection; +import org.librecms.contentsection.ContentSectionManager; +import org.librecms.contentsection.ContentSectionRepository; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Controller +@Path("/applications/content-sections") +public class ContentSectionApplicationController + implements ApplicationController { + + @Inject + private Models models; + + @Inject + private ContentSectionManager sectionManager; + + @Inject + private ContentSectionRepository sectionRepository; + + @GET + @Path("/") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String getApplication() { + final List contentSections = sectionRepository.findAll(); + + models.put( + "sections", + sectionRepository + .findAll() + .stream() + .map(this::buildContentSectionTableRow) + .sorted() + .collect(Collectors.toList()) + ); + + return "org/libreccm/ui/admin/applications/content-sections/content-sections.xhtml"; + } + + @POST + @Path("/add") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String addContentSection( + @FormParam("label") final String label + ) { + sectionManager.createContentSection(label); + + return "redirect:applications/content-sections"; + } + + @POST + @Path("/{sectionId}/update") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String updateContentSection( + @PathParam("sectionId") final long sectionId, + @FormParam("label") final String label + ) { + final Optional result = sectionRepository + .findById(sectionId); + + if (result.isPresent()) { + sectionManager.renameContentSection(result.get(), label); + } + + return "redirect:applications/content-sections"; + } + + @POST + @Path("/{sectionId}/delete") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String deleteContentSection( + @PathParam("sectionId") final long sectionId, + @FormParam("confirmed") final String confirmed + ) { + final Optional result = sectionRepository + .findById(sectionId); + + if (result.isPresent() && "true".equals(confirmed)) { + sectionRepository.delete(result.get()); + } + + return "redirect:applications/content-sections"; + } + + private ContentSectionTableRow buildContentSectionTableRow( + final ContentSection section + ) { + final ContentSectionTableRow row = new ContentSectionTableRow(); + row.setSectionId(section.getObjectId()); + row.setUuid(section.getUuid()); + row.setLabel(section.getLabel()); + + return row; + } + +} diff --git a/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionTableRow.java b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionTableRow.java new file mode 100644 index 000000000..35acea6e7 --- /dev/null +++ b/ccm-cms/src/main/java/org/libreccm/ui/admin/contentsections/ContentSectionTableRow.java @@ -0,0 +1,57 @@ +/* + * 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.libreccm.ui.admin.contentsections; + +import java.util.Comparator; + +/** + * + * @author Jens Pelzetter + */ +public class ContentSectionTableRow implements + Comparable { + + private long sectionId; + + private String uuid; + + private String label; + + public long getSectionId() { + return sectionId; + } + + protected void setSectionId(long sectionId) { + this.sectionId = sectionId; + } + + public String getUuid() { + return uuid; + } + + protected void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getLabel() { + return label; + } + + protected void setLabel(final String label) { + this.label = label; + } + + @Override + public int compareTo(final ContentSectionTableRow other) { + return Comparator + .nullsFirst( + Comparator + .comparing(ContentSectionTableRow::getLabel) + .thenComparing(ContentSectionTableRow::getSectionId) + ).compare(this, other); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/Cms.java b/ccm-cms/src/main/java/org/librecms/Cms.java index 4d532f286..39a5dbeef 100644 --- a/ccm-cms/src/main/java/org/librecms/Cms.java +++ b/ccm-cms/src/main/java/org/librecms/Cms.java @@ -23,6 +23,7 @@ import org.libreccm.modules.RequiredModule; import org.libreccm.modules.ShutdownEvent; import org.libreccm.modules.UnInstallEvent; import org.libreccm.pagemodel.PageModelComponentModel; +import org.libreccm.ui.admin.contentsections.ContentSectionApplicationController; import org.libreccm.web.ApplicationType; import org.libreccm.web.CcmApplication; import org.librecms.assets.AssetTypes; @@ -80,7 +81,8 @@ import java.util.Properties; settingsPane = SettingsPane.class, descBundle = CmsConstants.CONTENT_SECTION_DESC_BUNDLE, creator = ContentSectionCreator.class, - servletPath = "/templates/servlet/content-section" + servletPath = "/templates/servlet/content-section", + applicationController = ContentSectionApplicationController.class ), @ApplicationType( name = "org.librecms.pages.Pages", diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/content-sections/content-sections.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/content-sections/content-sections.xhtml new file mode 100644 index 000000000..9f8002d56 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/content-sections/content-sections.xhtml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + +
+

#{ContentSectionAdminMessages['application_title']}

+ +
+ + +

#{ContentSectionAdminMessages['contentsections.ui.admin.instances.add_form.title']}

+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + + + +
#{ContentSectionAdminMessages['contentsections.ui.admin.instances_table.col_name.header']}#{ContentSectionAdminMessages['contentsections.ui.admin.instances_table.col_name.actions']}
#{section.label} + + +

#{ContentSectionAdminMessages['contentsections.ui.admin.instances.add_form.title']}

+
+ + + + + + + +
+
+ +
+
+
+ +
+ \ No newline at end of file diff --git a/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources.properties b/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources.properties index 1c197ca17..3096a0db1 100644 --- a/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources.properties @@ -17,3 +17,21 @@ application_title=Content Section application_desc=A content section is used to group similar content. +contentsections.ui.admin.instances_table.col_name.header=Name +contentsections.ui.admin.instances_table.col_name.actions=Actions +contentsections.ui.admin.instances.add_form.title=Create new Content Section +contentsections.ui.admin.instances.add=Add Content Section +contentsections.ui.admin.instances.add_form.name.help=The name of the new Content Section. Also used as URL stub, therefore only characters in an URL can be used. +contentsections.ui.admin.instances.add_form.name.label=Name +contentsections.ui.admin.instances.add_form.cancel=Cancel +contentsections.ui.admin.instances.add_form.submit=Create Content Section +contentsections.ui.admin.instances.delete_dialog.button_text=Delete +contentsections.ui.admin.instances.delete_dialog.cancel=Cancel +contentsections.ui.admin.instances.delete_dialog.confirm=Delete Content Section +contentsections.ui.admin.instances.delete_dialog.title=Content Section l\u00f6schen best\u00e4tigen +contentsections.ui.admin.instances.delete_dialog.message=Are you sure to delete the Content Section {0}? +contentsections.ui.admin.instances.edit=Edit +contentsections.ui.admin.instances.edit_form.name.help=The name of the Content Section. Also used as URL stub, therefore only characters in an URL can be used. +contentsections.ui.admin.instances.edit_form.name.label=Name +contentsections.ui.admin.instances.edit_form.cancel=Cancel +contentsections.ui.admin.instances.edit_form.submit=Save diff --git a/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources_de.properties b/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources_de.properties index 1c197ca17..490a34f1e 100644 --- a/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/contentsection/ContentSectionResources_de.properties @@ -17,3 +17,21 @@ application_title=Content Section application_desc=A content section is used to group similar content. +contentsections.ui.admin.instances_table.col_name.header=Name +contentsections.ui.admin.instances_table.col_name.actions=Aktionen +contentsections.ui.admin.instances.add_form.title=Neue Content Section anlegen +contentsections.ui.admin.instances.add=Content Section hinzuf\u00fcgen +contentsections.ui.admin.instances.add_form.name.help=Der Name der neuen Content Section. Wird auch als URL-Fragment genutzt, daher sind Zeichen erlaubt, die in einer URL vorkommen d\u00fcrfen. +contentsections.ui.admin.instances.add_form.name.label=Name +contentsections.ui.admin.instances.add_form.cancel=Abbrechen +contentsections.ui.admin.instances.add_form.submit=Content Section anlegen +contentsections.ui.admin.instances.delete_dialog.button_text=L\u00f6schen +contentsections.ui.admin.instances.delete_dialog.cancel=Abbrechen +contentsections.ui.admin.instances.delete_dialog.confirm=Content Section l\u00f6schen +contentsections.ui.admin.instances.delete_dialog.title=Content Section l\u00f6schen best\u00e4tigen +contentsections.ui.admin.instances.delete_dialog.message=Sind Sie sicher dass Sie die Content Section {0} l\u00f6schen wollen? +contentsections.ui.admin.instances.edit=Bearbeiten +contentsections.ui.admin.instances.edit_form.name.help=Der Name der Content Section. Wird auch als URL-Fragment genutzt, daher sind Zeichen erlaubt, die in einer URL vorkommen d\u00fcrfen. +contentsections.ui.admin.instances.edit_form.name.label=Name +contentsections.ui.admin.instances.edit_form.cancel=Abbrechen +contentsections.ui.admin.instances.edit_form.submit=Speichern diff --git a/ccm-shortcuts/pom.xml b/ccm-shortcuts/pom.xml index 92b3992c7..fc21ab4ff 100644 --- a/ccm-shortcuts/pom.xml +++ b/ccm-shortcuts/pom.xml @@ -76,6 +76,7 @@ javax.mvc javax.mvc-api + provided org.eclipse.krazo diff --git a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java index 0d65d7cd1..29ccbb774 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java @@ -20,7 +20,6 @@ package org.libreccm.ui.admin.applications.shortcuts; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.shortcuts.ShortcutsConstants; -import org.libreccm.ui.admin.AdminConstants; import java.text.MessageFormat; import java.util.AbstractMap; diff --git a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java index 5824d0bc5..3a2eafe9f 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java @@ -113,12 +113,13 @@ public class ShortcutsApplicationController implements ApplicationController { @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) public String removeShortcut( - @PathParam("shortcutId") final long shortcutId + @PathParam("shortcutId") final long shortcutId, + @FormParam("confirmed") final String confirmed ) { final Optional result = shortcutRepository .findById(shortcutId); - if (result.isPresent()) { + if (result.isPresent() && "true".equals(confirmed)) { shortcutRepository.delete(result.get()); }