CCM NG: Pages Admin UI Part II

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5139 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2017-11-25 18:50:47 +00:00
parent 926e470d6a
commit 42fcd9264f
13 changed files with 797 additions and 37 deletions

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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<String> 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<PageModel> 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<org.librecms.pages.Page> 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());
}
}
}

View File

@ -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(

View File

@ -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;
@ -35,7 +36,7 @@ import javax.transaction.Transactional;
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PageRepository extends AbstractEntityRepository<Long, Page>{
public class PageRepository extends AbstractEntityRepository<Long, Page> {
private static final long serialVersionUID = -338101684757468443L;
@ -43,6 +44,7 @@ public class PageRepository extends AbstractEntityRepository<Long, Page>{
* Find the {@link Page} associated with a {@link Category}.
*
* @param category The {@link Category} associated with the {@link Page}.
*
* @return
*/
@RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES)
@ -50,29 +52,40 @@ public class PageRepository extends AbstractEntityRepository<Long, Page>{
public Optional<Page> findPageForCategory(final Category category) {
final TypedQuery<Page> 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<Page> getEntityClass() {
return Page.class;
@ -83,6 +96,4 @@ public class PageRepository extends AbstractEntityRepository<Long, Page>{
return page.getObjectId() == 0;
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class PagesCreator implements ApplicationCreator<CcmApplication> {
@Inject
private ApplicationRepository appRepo;
@Override
public CcmApplication createInstance(final String primaryUrl,
final ApplicationType type) {
return appRepo.retrieveApplicationForPath(primaryUrl).get();
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@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);
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/
public class BasicItemPropertiesStep<T extends ContentItem>
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);
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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<String> 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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
/**
*
@ -40,18 +43,44 @@ class CategoriesController {
@Inject
private CategoryManager categoryManager;
@Transactional(Transactional.TxType.REQUIRED)
protected List<Category> 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<Category> subCats = categoryToCheck.getSubCategories();
final List<Categorization> objects = categoryToCheck.getObjects();
return (subCats == null || subCats.isEmpty())
&& (objects == null || objects.isEmpty());
}
}

View File

@ -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<Category> subCats = category.getSubCategories();
final List<Categorization> objects = category.getObjects();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoriesController controller = cdiUtil
.findBean(CategoriesController.class);
return (subCats == null || subCats.isEmpty())
&& (objects == null || objects.isEmpty());
return controller.isDeletable(category);
}
@Override

View File

@ -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