From 09e6d4fb9b1bf306b17d6f676daef7f81e05324a Mon Sep 17 00:00:00 2001 From: jensp Date: Sat, 25 Nov 2017 18:50:47 +0000 Subject: [PATCH] CCM NG: Pages Admin UI Part II git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5139 8810af33-2d31-482b-a856-94f89814c4df --- .../cms/ui/pages/PagesAdminPage.java | 358 ++++++++++++++++++ ccm-cms/src/main/java/org/librecms/Cms.java | 25 +- .../org/librecms/pages/PageRepository.java | 41 +- .../java/org/librecms/pages/PagesCreator.java | 44 +++ .../java/org/librecms/pages/PagesServlet.java | 113 ++++++ .../ui/authoring/BasicItemPropertiesStep.java | 84 ++++ .../authoring/BasicItemPropertiesWidget.java | 85 +++++ .../org/librecms/CmsResources.properties | 3 + .../org/librecms/CmsResources_de.properties | 3 + .../org/librecms/CmsResources_fr.properties | 3 + .../categories/CategoriesController.java | 49 ++- .../admin/categories/SubCategoriesTable.java | 24 +- .../org/libreccm/categorization/Category.java | 2 + 13 files changed, 797 insertions(+), 37 deletions(-) create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java create mode 100644 ccm-cms/src/main/java/org/librecms/pages/PagesCreator.java create mode 100644 ccm-cms/src/main/java/org/librecms/pages/PagesServlet.java create mode 100644 ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesStep.java create mode 100644 ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesWidget.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java new file mode 100644 index 000000000..d0a7fcb6f --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/pages/PagesAdminPage.java @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.pages; + +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormData; +import com.arsdigita.bebop.FormModel; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.SaveCancelSection; +import com.arsdigita.bebop.TabbedPane; +import com.arsdigita.bebop.Text; +import com.arsdigita.bebop.Tree; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.PrintEvent; +import com.arsdigita.bebop.form.Option; +import com.arsdigita.bebop.form.SingleSelect; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.bebop.tree.TreeModel; +import com.arsdigita.bebop.tree.TreeModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.toolbox.ui.LayoutPanel; +import com.arsdigita.ui.admin.categories.CategoriesTreeModel; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.categorization.Category; +import org.libreccm.categorization.CategoryRepository; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.UnexpectedErrorException; +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.pagemodel.PageModel; +import org.libreccm.pagemodel.PageModelRepository; +import org.librecms.CmsConstants; +import org.librecms.pages.PageManager; +import org.librecms.pages.PageRepository; +import org.librecms.pages.Pages; + +import java.util.List; +import java.util.Optional; +import java.util.TooManyListenersException; + +/** + * + * @author Jens Pelzetter + */ +public class PagesAdminPage extends Page { + + private static final String INDEX_PAGE_MODEL_SELECT = "indexPageModelSelect"; + private static final String ITEM_PAGE_MODEL_SELECT = "itemPageModelSelect"; + private static final String INHERIT_PAGEMODEL = "--inherit--"; + + private final ParameterSingleSelectionModel selectedCategory; + + private final Tree categoryTree; + private final Label nothingSelectedLabel; + private final Form pageModelForm; + private final SingleSelect indexPageModelSelect; + private final SingleSelect itemPageModelSelect; + private final SaveCancelSection saveCancelSection; + + private Pages pagesInstance; + + public PagesAdminPage() { + + super.setAttribute("application", "admin"); + super.setClassAttr("simplePage"); + super.setTitle(new Label(new GlobalizedMessage("cms.ui.pages.title", + CmsConstants.CMS_BUNDLE))); + + selectedCategory = new ParameterSingleSelectionModel<>( + new StringParameter("selectedCategory")); + super.addGlobalStateParam(selectedCategory.getStateParameter()); + + categoryTree = new Tree(new CategoryTreeModelBuilder()); + + final LayoutPanel panel = new LayoutPanel(); + panel.setLeft(categoryTree); + + pageModelForm = new Form("pageModelForm"); + final Label heading = new Label(); + heading.addPrintListener(this::printPageModelFormHeading); + heading.setClassAttr("heading"); + pageModelForm.add(heading); + super.setVisibleDefault(pageModelForm, false); + + nothingSelectedLabel = new Label(new GlobalizedMessage( + "cms.ui.pages.no_category_selected", + CmsConstants.CMS_BUNDLE)); + nothingSelectedLabel.addPrintListener(this::printNothingSelectedLabel); + super.setVisibleDefault(nothingSelectedLabel, true); + pageModelForm.add(nothingSelectedLabel); + + indexPageModelSelect = new SingleSelect(INDEX_PAGE_MODEL_SELECT); + try { + indexPageModelSelect.addPrintListener(this::populatePageModelSelect); + } catch (TooManyListenersException ex) { + throw new UnexpectedErrorException(ex); + } + pageModelForm.add(indexPageModelSelect); + + itemPageModelSelect = new SingleSelect(ITEM_PAGE_MODEL_SELECT); + try { + itemPageModelSelect.addPrintListener(this::populatePageModelSelect); + } catch (TooManyListenersException ex) { + throw new UnexpectedErrorException(ex); + } + pageModelForm.add(itemPageModelSelect); + + saveCancelSection = new SaveCancelSection(); + pageModelForm.add(saveCancelSection); + + pageModelForm.addInitListener(this::initPageModelForm); + pageModelForm.addValidationListener(this::validatePageModelForm); + pageModelForm.addProcessListener(this::processPageModelForm); + + final BoxPanel rightPanel = new BoxPanel(BoxPanel.VERTICAL); +// rightPanel.add(nothingSelectedLabel); + rightPanel.add(pageModelForm); + panel.setRight(rightPanel); + + final TabbedPane tabbedPane = new TabbedPane(); + tabbedPane.addTab(new Label(new GlobalizedMessage( + "cms.ui.pages.tab.pages", + CmsConstants.CMS_BUNDLE)), + panel); + super.add(tabbedPane); + + super.lock(); + } + + public Pages getPagesInstance() { + return pagesInstance; + } + + public void setPagesInstance(final Pages pagesInstance) { + this.pagesInstance = pagesInstance; + } + +// @Override +// public void register(final Page page) { +// +// super.register(page); +// +// page.setVisibleDefault(nothingSelectedLabel, true); +// page.setVisibleDefault(pageModelForm, false); +// +// page.addGlobalStateParam(selectedCategory.getStateParameter()); +// +// } + private void printNothingSelectedLabel(final PrintEvent event) { + + final PageState state = event.getPageState(); + final Label target = (Label) event.getTarget(); + + target.setVisible(state, !selectedCategory.isSelected(state)); + } + + private void printPageModelFormHeading(final PrintEvent event) { + + final PageState state = event.getPageState(); + final Label target = (Label) event.getTarget(); + + target.setVisible(state, !selectedCategory.isSelected(state)); + if (selectedCategory.isSelected(state)) { + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoryRepository categoryRepo = cdiUtil + .findBean(CategoryRepository.class); + + final Category category = categoryRepo + .findById(Long.parseLong(selectedCategory.getSelectedKey(state))) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No Category with ID %s in the database.", + selectedCategory.getSelectedKey(state)))); + + target.setLabel(new GlobalizedMessage( + "cms.ui.pages.page_config_for_category", + CmsConstants.CMS_BUNDLE, + new Object[]{category.getName()})); + } + } + + private void populatePageModelSelect(final PrintEvent event) { + + final PageState state = event.getPageState(); + + final SingleSelect target = (SingleSelect) event.getTarget(); + + if (!selectedCategory.isSelected(state)) { + target.setVisible(state, false); + return; + } + + target.clearOptions(); + + target.addOption(new Option(INHERIT_PAGEMODEL, + new Label(new GlobalizedMessage( + "cms.ui.pages.assigned_page_model.inherit", + CmsConstants.CMS_BUNDLE)))); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PageModelRepository pageModelRepo = cdiUtil + .findBean(PageModelRepository.class); + final List pageModels = pageModelRepo + .findByApplication(pagesInstance); + final GlobalizationHelper globalizationHelper = cdiUtil + .findBean(GlobalizationHelper.class); + + for (final PageModel pageModel : pageModels) { + target.addOption(new Option( + Long.toString(pageModel.getPageModelId()), + new Text(globalizationHelper.getValueFromLocalizedString( + pageModel + .getTitle())))); + } + + } + + private void initPageModelForm(final FormSectionEvent event) + throws FormProcessException { + + final PageState state = event.getPageState(); + +// pageModelForm.setVisible(state, selectedCategory.isSelected(state)); + saveCancelSection.setVisible(state, selectedCategory.isSelected(state)); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoryRepository categoryRepo = cdiUtil + .findBean(CategoryRepository.class); + final PageRepository pageRepo = cdiUtil + .findBean(PageRepository.class); + + final Category category = categoryRepo + .findById(Long.parseLong(selectedCategory.getSelectedKey(state))) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No Category with ID %s in the database.", + selectedCategory.getSelectedKey(state)))); + + final Optional page = pageRepo + .findPageForCategory(category); + + if (page.isPresent()) { + + indexPageModelSelect.setValue(state, + Long.toString(page + .get() + .getIndexPageModel() + .getPageModelId())); + itemPageModelSelect.setValue(state, + Long.toString(page + .get() + .getItemPageModel() + .getPageModelId())); + } else { + indexPageModelSelect.setValue(state, INHERIT_PAGEMODEL); + itemPageModelSelect.setValue(state, INHERIT_PAGEMODEL); + } + } + + private void validatePageModelForm(final FormSectionEvent event) + throws FormProcessException { + + //Nothing for now + } + + private void processPageModelForm(final FormSectionEvent event) + throws FormProcessException { + + final PageState state = event.getPageState(); + + if (saveCancelSection.getSaveButton().isSelected(state)) { + + final FormData data = event.getFormData(); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoryRepository categoryRepo = cdiUtil + .findBean(CategoryRepository.class); + final PageManager pageManager = cdiUtil + .findBean(PageManager.class); + final PageRepository pageRepo = cdiUtil + .findBean(PageRepository.class); + final PageModelRepository pageModelRepo = cdiUtil + .findBean(PageModelRepository.class); + + final Category category = categoryRepo + .findById(Long.parseLong(selectedCategory.getSelectedKey(state))) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No Category with ID %s in the database.", + selectedCategory.getSelectedKey(state)))); + + final org.librecms.pages.Page page = pageRepo + .findPageForCategory(category) + .orElse(pageManager.createPageForCategory(category)); + + final String selectedIndexPageModelId = data + .getString(INDEX_PAGE_MODEL_SELECT); + final String selectedItemPageModelId = data + .getString(ITEM_PAGE_MODEL_SELECT); + + if (!INHERIT_PAGEMODEL.equals(selectedIndexPageModelId)) { + final PageModel model = pageModelRepo + .findById(Long.parseLong(selectedIndexPageModelId)) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No PageModel with ID %s in the database.", + selectedIndexPageModelId))); + page.setIndexPageModel(model); + } + + if (!INHERIT_PAGEMODEL.equals(selectedItemPageModelId)) { + final PageModel model = pageModelRepo + .findById(Long.parseLong(selectedIndexPageModelId)) + .orElseThrow(() -> new UnexpectedErrorException(String + .format("No PageModel with ID %s in the database.", + selectedItemPageModelId))); + page.setItemPageModel(model); + } + + pageRepo.save(page); + } + + categoryTree.clearSelection(state); + selectedCategory.clearSelection(state); + } + + private class CategoryTreeModelBuilder + extends LockableImpl + implements TreeModelBuilder { + + @Override + public TreeModel makeModel(final Tree tree, + final PageState state) { + + return new CategoriesTreeModel(pagesInstance.getCategoryDomain()); + } + + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/Cms.java b/ccm-cms/src/main/java/org/librecms/Cms.java index cd3549c2a..7a15c87d0 100644 --- a/ccm-cms/src/main/java/org/librecms/Cms.java +++ b/ccm-cms/src/main/java/org/librecms/Cms.java @@ -6,7 +6,6 @@ package org.librecms; import com.arsdigita.cms.ContentCenterAppCreator; import com.arsdigita.cms.ContentCenterServlet; import com.arsdigita.cms.ContentCenterSetup; -import com.arsdigita.cms.ui.authoring.ItemCategoryForm; import com.arsdigita.cms.ui.pagemodel.CategorizedItemComponentForm; import com.arsdigita.cms.ui.pagemodel.CategoryTreeComponentForm; import com.arsdigita.cms.ui.pagemodel.FixedContentItemComponentForm; @@ -26,7 +25,17 @@ import org.libreccm.modules.UnInstallEvent; import org.libreccm.pagemodel.PageModelComponentModel; import org.libreccm.web.ApplicationType; import org.libreccm.web.CcmApplication; -import org.librecms.assets.*; +import org.librecms.assets.AssetTypes; +import org.librecms.assets.AudioAsset; +import org.librecms.assets.Bookmark; +import org.librecms.assets.ExternalAudioAsset; +import org.librecms.assets.ExternalVideoAsset; +import org.librecms.assets.FileAsset; +import org.librecms.assets.Image; +import org.librecms.assets.LegalMetadata; +import org.librecms.assets.SideNote; +import org.librecms.assets.VideoAsset; + import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSectionCreator; import org.librecms.contentsection.ContentSectionSetup; @@ -42,6 +51,8 @@ import org.librecms.pagemodel.CategoryTreeComponent; import org.librecms.pagemodel.FixedContentItemComponent; import org.librecms.pagemodel.GreetingItemComponent; import org.librecms.pagemodel.ItemListComponent; +import org.librecms.pages.Pages; +import org.librecms.pages.PagesCreator; import java.io.IOException; import java.io.InputStream; @@ -69,6 +80,16 @@ import java.util.Properties; creator = ContentSectionCreator.class, servletPath = "/templates/servlet/content-section" ) + , + @ApplicationType( + name = "org.librecms.pages.Pages", + applicationClass = Pages.class, + instanceForm = ApplicationInstanceForm.class, + settingsPane = SettingsPane.class, + descBundle = CmsConstants.CMS_BUNDLE, + creator = PagesCreator.class, + servletPath = "/templates/servlet/pages" + ) }, pageModelComponentModels = { @PageModelComponentModel( diff --git a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java index 53299f1fd..95117c800 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java @@ -23,6 +23,7 @@ import org.libreccm.core.AbstractEntityRepository; import org.libreccm.security.RequiresPrivilege; import java.util.Optional; +import java.util.UUID; import javax.enterprise.context.RequestScoped; import javax.persistence.NoResultException; @@ -31,48 +32,60 @@ import javax.transaction.Transactional; /** * Repository for {@link Page} entities. - * + * * @author Jens Pelzetter */ @RequestScoped -public class PageRepository extends AbstractEntityRepository{ +public class PageRepository extends AbstractEntityRepository { private static final long serialVersionUID = -338101684757468443L; /** * Find the {@link Page} associated with a {@link Category}. - * + * * @param category The {@link Category} associated with the {@link Page}. - * @return + * + * @return */ @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) @Transactional(Transactional.TxType.REQUIRED) public Optional findPageForCategory(final Category category) { - + final TypedQuery query = getEntityManager() - .createNamedQuery("Page.findForCategory", Page.class); + .createNamedQuery("Page.findForCategory", Page.class); query.setParameter("category", category); - + try { return Optional.of(query.getSingleResult()); - } catch(NoResultException ex) { + } catch (NoResultException ex) { return Optional.empty(); } } - + + @Override + protected void initNewEntity(final Page entity) { + + super.initNewEntity(entity); + + if (isNew(entity)) { + entity.setUuid(UUID.randomUUID().toString()); + } + } + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) @Transactional(Transactional.TxType.REQUIRED) + @Override public void save(final Page page) { super.save(page); } - + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) @Transactional(Transactional.TxType.REQUIRED) + @Override public void delete(final Page page) { super.delete(page); } - - + @Override public Class getEntityClass() { return Page.class; @@ -82,7 +95,5 @@ public class PageRepository extends AbstractEntityRepository{ public boolean isNew(final Page page) { return page.getObjectId() == 0; } - - - + } diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesCreator.java b/ccm-cms/src/main/java/org/librecms/pages/PagesCreator.java new file mode 100644 index 000000000..2016b7af3 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesCreator.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.pages; + +import org.libreccm.web.ApplicationCreator; +import org.libreccm.web.ApplicationRepository; +import org.libreccm.web.ApplicationType; +import org.libreccm.web.CcmApplication; + +import javax.inject.Inject; + +/** + * + * @author Jens Pelzetter + */ +public class PagesCreator implements ApplicationCreator { + + @Inject + private ApplicationRepository appRepo; + + @Override + public CcmApplication createInstance(final String primaryUrl, + final ApplicationType type) { + + return appRepo.retrieveApplicationForPath(primaryUrl).get(); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesServlet.java b/ccm-cms/src/main/java/org/librecms/pages/PagesServlet.java new file mode 100644 index 000000000..cb217839a --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesServlet.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.pages; + +import com.arsdigita.cms.ui.pages.PagesAdminPage; +import com.arsdigita.templating.PresentationManager; +import com.arsdigita.templating.Templating; +import com.arsdigita.web.BaseApplicationServlet; +import com.arsdigita.web.LoginSignal; +import com.arsdigita.xml.Document; + +import org.apache.shiro.authz.AuthorizationException; +import org.libreccm.security.PermissionChecker; +import org.libreccm.security.Shiro; +import org.libreccm.web.ApplicationRepository; +import org.libreccm.web.CcmApplication; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Jens Pelzetter + */ +@WebServlet(urlPatterns = {"/templates/servlet/pages/*"}) +public class PagesServlet extends BaseApplicationServlet { + + private static final long serialVersionUID = -303317198251922697L; + + @Inject + private ApplicationRepository applicationRepo; + + @Inject + private PagesRepository pagesRepo; + + @Inject + private PermissionChecker permissionChecker; + + @Inject + private Shiro shiro; + + @Override + protected void doService(final HttpServletRequest request, + final HttpServletResponse response, + final CcmApplication application) + throws ServletException, IOException { + + if (!shiro.getSubject().isAuthenticated()) { + throw new LoginSignal(request); + } + + if (!permissionChecker.isPermitted(PagesPrivileges.ADMINISTER_PAGES)) { + throw new AuthorizationException("The current user is not " + + "permitted to administer pages."); + } + + final PagesAdminPage page = new PagesAdminPage(); + +// final URL originalUrl = (URL) request +// .getAttribute(BaseServlet.REQUEST_URL_ATTRIBUTE); +// final String pathInfo = originalUrl.getPathInfo(); + +// final String appPath; +// if (pathInfo.startsWith("/") && pathInfo.endsWith("/")) { +// appPath = pathInfo.substring(1, pathInfo.length() - 1); +// } else if (pathInfo.startsWith("/")) { +// appPath = pathInfo.substring(1); +// } else if (pathInfo.endsWith("/")) { +// appPath = pathInfo.substring(pathInfo.length() - 1); +// } else { +// appPath = pathInfo; +// } +// +// final CcmApplication application = applicationRepo +// .retrieveApplicationForPath(appPath) +// .orElseThrow(() -> new ServletException(String +// .format("No application for path %s", appPath))); + if (!(application instanceof Pages)) { + throw new ServletException( + "Provided application is not an instance of Pages"); + } + + page.setPagesInstance((Pages) application); + + final Document document = page.buildDocument(request, response); + + final PresentationManager presentationManager = Templating + .getPresentationManager(); + presentationManager.servePage(document, request, response); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesStep.java b/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesStep.java new file mode 100644 index 000000000..d53cbd793 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesStep.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.authoring; + +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.TextField; +import org.libreccm.ui.LocalizedStringWidget; +import org.librecms.contentsection.ContentItem; +import org.librecms.ui.ContentSectionViewController; + +import java.io.Serializable; +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + * @param + */ +public class BasicItemPropertiesStep + extends CustomComponent + implements Serializable { + + private static final long serialVersionUID = 3881230433270571344L; + + private final ContentSectionViewController controller; + private final ContentItem item; + + private final TextField nameField; + private final LocalizedStringWidget titleWidget; + + public BasicItemPropertiesStep(final ContentSectionViewController controller, + final T item) { + + Objects.requireNonNull(controller); + Objects.requireNonNull(item); + + this.controller = controller; + this.item = item; + + nameField = new TextField("Name"); + nameField.setValue(item.getName().getValue()); + nameField.addValueChangeListener(event -> { + }); + + titleWidget = new LocalizedStringWidget( + controller.getLocalizedStringWidgetController(), + item.getTitle(), + false); + titleWidget.setCaption("Title"); + + final Button saveButton = new Button("Save"); + saveButton.addClickListener(event -> { + }); + + final Button cancelButton = new Button("Cancel"); + cancelButton.addClickListener(event -> { + }); + + final FormLayout layout = new FormLayout(nameField, + titleWidget, + saveButton, + cancelButton); + super.setCompositionRoot(layout); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesWidget.java b/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesWidget.java new file mode 100644 index 000000000..66b995655 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/authoring/BasicItemPropertiesWidget.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.authoring; + +import com.vaadin.data.HasValue; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.TextField; +import org.libreccm.ui.LocalizedStringWidget; +import org.librecms.contentsection.ContentItem; +import org.librecms.ui.ContentSectionViewController; + +import java.io.Serializable; +import java.util.Locale; + +/** + * + * @author Jens Pelzetter + */ +public class BasicItemPropertiesWidget + extends CustomComponent + implements Serializable { + + private static final long serialVersionUID = 6560855454431178274L; + + private final ContentSectionViewController controller; + private final ContentItem item; + + private final TextField nameField; + private final LocalizedStringWidget titleWidget; + + public BasicItemPropertiesWidget( + final ContentSectionViewController controller, + final ContentItem item) { + + this.controller = controller; + this.item = item; + + this.nameField = new TextField("Title"); + nameField.setValue(item.getName().getValue()); + nameField.addValueChangeListener(this::nameValueChanged); + + this.titleWidget = new LocalizedStringWidget(controller + .getLocalizedStringWidgetController(), + item.getTitle(), + false); + titleWidget.setCaption("Title"); + } + + protected void nameValueChanged( + final HasValue.ValueChangeEvent event) { + + final String result = nameField + .getValue() + .toLowerCase(Locale.ROOT) + .replace(' ', '-') + .replace('&', '-') + .replace('/', '-') + .replace('#', '-') + .replace('?', '-') + .replace("ä", "ae") + .replace("ö", "oe") + .replace("ü", "ue") + .replace("ß", "ss") + .replaceAll("-{2,}", "-"); + + nameField.setValue(result); + } + +} diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index 30a45f8db..4e0221b4d 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -491,3 +491,6 @@ cms.ui.pages.form.category_domain_select.error=A Page tree needs a category syst cms.ui.contentcenter.pagestable.columns.edit.header=Edit cms.ui.contentcenter.pages.edit.label=Edit cms.ui.contentcenter.pages.add_link=Add page tree +cms.ui.pages.title=Administer pages +cms.ui.pages.page_config_for_category=Page Configuration for category {0} +cms.ui.pages.assigned_page_model.inherit=Inherit from parent diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index e843f1321..b6d5a3b24 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -488,3 +488,6 @@ cms.ui.pages.form.category_domain_select.error=Ein Seitenbaum ben\u00f6tigt ein cms.ui.contentcenter.pagestable.columns.edit.header=Bearbeiten cms.ui.contentcenter.pages.edit.label=Bearbeiten cms.ui.contentcenter.pages.add_link=Seitenbaum hinzuf\u00fcgen +cms.ui.pages.title=Seitenbaum verwalten +cms.ui.pages.page_config_for_category=Seiten-Konfiguration f\u00fcr Kategorie {0} +cms.ui.pages.assigned_page_model.inherit=PageModel der \u00fcbergeordneten Seite verwenden diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index aabfaa36c..e065dbbc3 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -447,3 +447,6 @@ cms.ui.pages.form.category_domain_select.error=A Page tree needs a category syst cms.ui.contentcenter.pagestable.columns.edit.header=Edit cms.ui.contentcenter.pages.edit.label=Edit cms.ui.contentcenter.pages.add_link=Add page tree +cms.ui.pages.title=Administer pages +cms.ui.pages.page_config_for_category=Page Configuration for category {0} +cms.ui.pages.assigned_page_model.inherit=Inherit from parent diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/CategoriesController.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/CategoriesController.java index 5b0cdf93c..fa658c715 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/CategoriesController.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/CategoriesController.java @@ -18,14 +18,17 @@ */ package com.arsdigita.ui.admin.categories; +import org.libreccm.categorization.Categorization; import org.libreccm.categorization.Category; import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; +import java.util.ArrayList; import java.util.List; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; +import javax.transaction.Transactional; /** * @@ -33,25 +36,51 @@ import javax.inject.Inject; */ @RequestScoped class CategoriesController { - + @Inject private CategoryRepository categoryRepo; - + @Inject private CategoryManager categoryManager; - + + @Transactional(Transactional.TxType.REQUIRED) protected List getSubCategories(final Category ofCategory) { - + final Category category = categoryRepo - .findById(ofCategory.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String + .findById(ofCategory.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String .format("No Category with ID %d in the database.", ofCategory.getObjectId()))); - - return category.getSubCategories(); + + return new ArrayList<>(category.getSubCategories()); } - + + @Transactional(Transactional.TxType.REQUIRED) protected boolean hasChildren(final Category category) { - return categoryManager.hasSubCategories(category); + + final Category categoryToCheck = categoryRepo + .findById(category.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Category with ID %d in the database.", + category.getObjectId()))); + + return categoryManager.hasSubCategories(categoryToCheck); } + + @Transactional(Transactional.TxType.REQUIRED) + protected boolean isDeletable(final Category category) { + + final Category categoryToCheck = categoryRepo + .findById(category.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Category with ID %d in the database.", + category.getObjectId()))); + + final List subCats = categoryToCheck.getSubCategories(); + final List objects = categoryToCheck.getObjects(); + + return (subCats == null || subCats.isEmpty()) + && (objects == null || objects.isEmpty()); + } + } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/SubCategoriesTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/SubCategoriesTable.java index 605f5cc86..91af7e41a 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/SubCategoriesTable.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/categories/SubCategoriesTable.java @@ -268,16 +268,20 @@ public class SubCategoriesTable extends Table { private int index = -1; public SubCategoriesTableModel(final PageState state) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoriesController controller = cdiUtil + .findBean(CategoriesController.class); final CategoryRepository categoryRepo = CdiUtil. createCdiUtil().findBean(CategoryRepository.class); final Category category = categoryRepo.findById(Long.parseLong( selectedCategoryId.getSelectedKey(state))).get(); - subCategories = new ArrayList<>(category.getSubCategories()); - subCategories.sort((c1, c2) -> { - return Long.compare(c1.getCategoryOrder(), - c2.getCategoryOrder()); - }); + subCategories = controller.getSubCategories(category); + +// subCategories.sort((c1, c2) -> { +// return Long.compare(c1.getCategoryOrder(), +// c2.getCategoryOrder()); +// }); } @Override @@ -333,11 +337,11 @@ public class SubCategoriesTable extends Table { } private boolean isDeletable(final Category category) { - final List subCats = category.getSubCategories(); - final List objects = category.getObjects(); - - return (subCats == null || subCats.isEmpty()) - && (objects == null || objects.isEmpty()); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CategoriesController controller = cdiUtil + .findBean(CategoriesController.class); + + return controller.isDeletable(category); } @Override diff --git a/ccm-core/src/main/java/org/libreccm/categorization/Category.java b/ccm-core/src/main/java/org/libreccm/categorization/Category.java index 5844c8359..576401fb5 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/Category.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/Category.java @@ -55,6 +55,7 @@ import javax.persistence.NamedEntityGraphs; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; +import javax.persistence.OrderBy; import javax.persistence.Table; /** @@ -235,6 +236,7 @@ public class Category extends CcmObject implements Serializable, Portable { */ @RecursivePermissions @OneToMany(mappedBy = "parentCategory", fetch = FetchType.LAZY) + @OrderBy("categoryOrder ASC") @XmlElementWrapper(name = "subcategories", namespace = CAT_XML_NS) @XmlElement(name = "category") @JsonIgnore