CCM NG: Admin UI for Pages Vaadin variant

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5156 8810af33-2d31-482b-a856-94f89814c4df
ccm-docs
jensp 2017-12-06 15:25:58 +00:00
parent 1d2c424e95
commit 133f39e233
16 changed files with 1327 additions and 6 deletions

View File

@ -243,7 +243,20 @@ class PagesForm extends Form {
final FormData data = event.getFormData();
final String primaryUrl = data.getString(PRIMARY_URL_FIELD);
final String primaryUrl;
if (data.getString(PRIMARY_URL_FIELD).startsWith("/")
&& data.getString(PRIMARY_URL_FIELD).endsWith("/")) {
primaryUrl = data.getString(PRIMARY_URL_FIELD);
} else if(data.getString(PRIMARY_URL_FIELD).startsWith("/")) {
primaryUrl = String.format("%s/",
data.getString(PRIMARY_URL_FIELD));
} else if(data.getString(PRIMARY_URL_FIELD).endsWith("/")) {
primaryUrl = String.format("/%s",
data.getString(PRIMARY_URL_FIELD));
} else {
primaryUrl = String.format("/%s/",
data.getString(PRIMARY_URL_FIELD));
}
final String selectedSiteId = data.getString(SITE_SELECT);
final String selectedDomainId = data.getString(
CATEGORY_DOMAIN_SELECT);

View File

@ -32,8 +32,6 @@ import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import static org.primefaces.component.calendar.Calendar.PropertyKeys.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>

View File

@ -50,6 +50,7 @@ class CmsView extends CustomComponent implements View {
final ContentSectionsGrid sectionsGrid = new ContentSectionsGrid(controller);
sectionsGrid.setWidth("100%");
tabSheet.addTab(sectionsGrid, "Content Section");
tabSheet.addTab(new PagesTab(controller), "Pages");
tabSheet.addTab(new Label("Placeholder"), "Search");
tabSheet.addTab(new Label("Placeholder"), "My tasks");

View File

@ -22,6 +22,10 @@ import com.vaadin.cdi.ViewScoped;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.PermissionManager;
import org.librecms.pages.PageManager;
import org.librecms.pages.PageRepository;
import org.librecms.pages.PagesManager;
import org.librecms.pages.PagesRepository;
import javax.inject.Inject;
@ -35,6 +39,10 @@ class CmsViewController {
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private PagesController pagesController;
@Inject
private PermissionManager permissionManager;
@ -48,6 +56,11 @@ class CmsViewController {
return globalizationHelper;
}
protected PagesController getPagesController() {
return pagesController;
}
protected PermissionManager getPermissionManager() {
return permissionManager;
}

View File

@ -0,0 +1,81 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import org.libreccm.pagemodel.PageModel;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
class PageModelSelectDataProvider
extends AbstractBackEndDataProvider<PageModel, String> {
private static final long serialVersionUID = 3102935928982631262L;
@Inject
private EntityManager entityManager;
@Override
protected Stream<PageModel> fetchFromBackEnd(
final Query<PageModel, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<PageModel> criteriaQuery = builder
.createQuery(PageModel.class);
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
criteriaQuery.select(from);
return entityManager
.createQuery(criteriaQuery)
.setFirstResult(query.getOffset())
.setMaxResults(query.getLimit())
.getResultList()
.stream();
}
@Override
protected int sizeInBackEnd(final Query<PageModel, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = builder
.createQuery(Long.class);
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
criteriaQuery.select(builder.count(from));
return entityManager
.createQuery(criteriaQuery)
.getSingleResult()
.intValue();
}
}

View File

@ -0,0 +1,127 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider;
import com.vaadin.data.provider.HierarchicalQuery;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.Domain;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
class PagesCategoryTreeDataProvider
extends AbstractBackEndHierarchicalDataProvider<Category, String> {
private static final long serialVersionUID = -4953505403671944088L;
@Inject
private EntityManager entityManager;
private Domain domain;
protected Domain getDomain() {
return domain;
}
protected void setDomain(final Domain domain) {
this.domain = domain;
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
protected Stream<Category> fetchChildrenFromBackEnd(
final HierarchicalQuery<Category, String> query) {
if (query.getParentOptional().isPresent()) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Category> criteriaQuery = builder
.createQuery(Category.class);
final Root<Category> from = criteriaQuery.from(Category.class);
criteriaQuery.where(builder.equal(from.get("parentCategory"),
query.getParentOptional().get()));
final TypedQuery<Category> entityQuery = entityManager
.createQuery(criteriaQuery);
return entityQuery
.setFirstResult(query.getOffset())
.setMaxResults(query.getLimit())
.getResultList()
.stream();
} else {
return Stream.of(domain.getRoot());
}
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public int getChildCount(
final HierarchicalQuery<Category, String> query) {
if (query.getParentOptional().isPresent()) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = builder
.createQuery(Long.class);
final Root<Category> from = criteriaQuery.from(Category.class);
criteriaQuery.select(builder.count(from));
criteriaQuery.where(builder.equal(from.get("parentCategory"),
query.getParentOptional().get()));
final TypedQuery<Long> entityQuery = entityManager
.createQuery(criteriaQuery);
return entityQuery.getSingleResult().intValue();
} else {
return 1;
}
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public boolean hasChildren(final Category item) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = builder
.createQuery(Long.class);
final Root<Category> from = criteriaQuery.from(Category.class);
criteriaQuery.select(builder.count(from));
criteriaQuery.where(builder.equal(from.get("parentCategory"), item));
final TypedQuery<Long> entityQuery = entityManager
.createQuery(criteriaQuery);
return entityQuery.getSingleResult().intValue() > 0;
}
}

View File

@ -0,0 +1,165 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.Domain;
import org.libreccm.categorization.DomainRepository;
import org.libreccm.sites.Site;
import org.libreccm.sites.SiteRepository;
import org.librecms.pages.Page;
import org.librecms.pages.PageManager;
import org.librecms.pages.PageRepository;
import org.librecms.pages.Pages;
import org.librecms.pages.PagesManager;
import org.librecms.pages.PagesRepository;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
class PagesController {
@Inject
private CategoryRepository categoryRepo;
@Inject
private DomainRepository domainRepo;
@Inject
private PageModelSelectDataProvider pageModelSelectDataProvider;
@Inject
private PageManager pageManager;
@Inject
private PageRepository pageRepo;
@Inject
private PagesCategoryTreeDataProvider pagesCategoryTreeDataProvider;
@Inject
private PagesEditorDomainSelectDataProvider pagesEditorDomainSelectDataProvider;
@Inject
private PagesEditorSiteSelectDataProvider pagesEditorSiteSelectDataProvider;
@Inject
private PagesGridDataProvider pagesGridDataProvider;
@Inject
private PagesManager pagesManager;
@Inject
private PagesRepository pagesRepo;
@Inject
private SiteRepository siteRepo;
protected PageModelSelectDataProvider getPageModelSelectDataProvider() {
return pageModelSelectDataProvider;
}
protected PageManager getPageManager() {
return pageManager;
}
protected PageRepository getPageRepo() {
return pageRepo;
}
protected PagesCategoryTreeDataProvider getPagesCategoryTreeDataProvider() {
return pagesCategoryTreeDataProvider;
}
protected PagesEditorDomainSelectDataProvider getPagesEditorDomainSelectDataProvider() {
return pagesEditorDomainSelectDataProvider;
}
protected PagesEditorSiteSelectDataProvider getPagesEditorSiteSelectDataProvider() {
return pagesEditorSiteSelectDataProvider;
}
protected PagesGridDataProvider getPagesGridDataProvider() {
return pagesGridDataProvider;
}
protected PagesManager getPagesManager() {
return pagesManager;
}
protected PagesRepository getPagesRepo() {
return pagesRepo;
}
@Transactional(Transactional.TxType.REQUIRED)
protected Optional<Page> findPage(final Category category) {
Objects.requireNonNull(category);
final Category theCategory = categoryRepo
.findById(category.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Category with ID %d in the database.",
category.getObjectId())));
return pageRepo.findPageForCategory(theCategory);
}
@Transactional(Transactional.TxType.REQUIRED)
protected Pages createPages(final String name,
final Site site,
final Domain domain) {
Objects.requireNonNull(name);
Objects.requireNonNull(site);
Objects.requireNonNull(domain);
if (name.isEmpty()
|| name.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of a Pages instance can't be empty.");
}
final Site forSite = siteRepo
.findById(site.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Site with ID %d in the database.",
site.getObjectId())));
final Domain withDomain = domainRepo
.findById(domain.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Domain with ID %d in the database.",
domain.getObjectId())));
return pagesManager.createPages(name, forSite, withDomain);
}
}

View File

@ -0,0 +1,260 @@
/*
* 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;
import com.vaadin.event.selection.SingleSelectionEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.categorization.Category;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.l10n.LocalizedTextsUtil;
import org.libreccm.pagemodel.PageModel;
import org.librecms.CmsConstants;
import org.librecms.pages.Page;
import org.librecms.pages.PageManager;
import org.librecms.pages.Pages;
import java.util.Objects;
import java.util.Optional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PagesDetails extends Window {
private static final long serialVersionUID = 6306677625483502088L;
private final CmsViewController controller;
private final Pages pages;
private final GlobalizationHelper globalizationHelper;
private final LocalizedTextsUtil textsUtil;
private Category selectedCategory;
private final Panel panel;
private final ComboBox<PageModel> indexPageModelSelect;
private final ComboBox<PageModel> itemPageModelSelect;
private final Button saveButton;
private final Button cancelButton;
public PagesDetails(final Pages pages, final CmsViewController controller) {
super();
globalizationHelper = controller.getGlobalizationHelper();
textsUtil = globalizationHelper
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
this.pages = pages;
this.controller = controller;
final PagesCategoryTreeDataProvider treeDataProvider = controller
.getPagesController()
.getPagesCategoryTreeDataProvider();
treeDataProvider.setDomain(pages.getCategoryDomain());
final Tree<Category> categoryTree = new Tree<>();
categoryTree.setDataProvider(treeDataProvider);
categoryTree.addItemClickListener(this::categoryTreeClicked);
categoryTree.setItemCaptionGenerator(this::createCategoryTreeCaption);
indexPageModelSelect = new ComboBox<>(textsUtil
.getText("cms.ui.pages.pagemodels.index_page"));
indexPageModelSelect.setDataProvider(controller
.getPagesController()
.getPageModelSelectDataProvider());
indexPageModelSelect
.setItemCaptionGenerator(this::createPageModelCaption);
indexPageModelSelect.setTextInputAllowed(false);
indexPageModelSelect.setEmptySelectionAllowed(true);
indexPageModelSelect.setEmptySelectionCaption(textsUtil
.getText("cms.ui.pages.assigned_page_model.inherit"));
indexPageModelSelect
.setItemCaptionGenerator(this::createPageModelCaption);
itemPageModelSelect = new ComboBox<>(textsUtil
.getText("cms.ui.pages.pagemodels.item_page"));
itemPageModelSelect.setDataProvider(controller
.getPagesController()
.getPageModelSelectDataProvider());
itemPageModelSelect
.setItemCaptionGenerator(this::createPageModelCaption);
itemPageModelSelect.setTextInputAllowed(false);
itemPageModelSelect.setEmptySelectionAllowed(true);
itemPageModelSelect.setEmptySelectionCaption(textsUtil
.getText("cms.ui.pages.assigned_page_model.inherit"));
indexPageModelSelect.addSelectionListener(this::selectionChange);
itemPageModelSelect.addSelectionListener(this::selectionChange);
saveButton = new Button(textsUtil
.getText("cms.ui.pages.pagemodels.save"));
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
saveButton.addClickListener(this::saveButtonClicked);
cancelButton = new Button(textsUtil
.getText("cms.ui.pages.pagemodels.cancel"));
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
cancelButton.addClickListener(this::cancelButtonClicked);
saveButton.setEnabled(false);
cancelButton.setEnabled(false);
super.setCaption(textsUtil.getText("cms.ui.pages.title",
new String[]{pages.getPrimaryUrl()}));
panel = new Panel(new VerticalLayout(
new FormLayout(indexPageModelSelect,
itemPageModelSelect),
new HorizontalLayout(saveButton, cancelButton)));
final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(
categoryTree, panel);
splitPanel.setSplitPosition(25.0f);
super.setContent(splitPanel);
init();
}
private void init() {
selectedCategory = pages.getCategoryDomain().getRoot();
updateWidgets(selectedCategory);
}
private String createCategoryTreeCaption(final Category category) {
if (category.getTitle().getValues().isEmpty()) {
return category.getName();
} else {
return globalizationHelper
.getValueFromLocalizedString(category.getTitle());
}
}
private String createPageModelCaption(final PageModel pageModel) {
if (pageModel.getTitle().getValues().isEmpty()) {
return pageModel.getName();
} else {
return globalizationHelper
.getValueFromLocalizedString(pageModel.getTitle());
}
}
private void categoryTreeClicked(
final Tree.ItemClick<Category> event) {
final Category category = event.getItem();
selectedCategory = category;
updateWidgets(category);
}
private void selectionChange(final SingleSelectionEvent<PageModel> event) {
saveButton.setEnabled(true);
cancelButton.setEnabled(true);
}
private void updateWidgets(final Category category) {
Objects.requireNonNull(category);
final Optional<Page> page = controller
.getPagesController()
.findPage(category);
if (page.isPresent()) {
panel.setCaption(textsUtil
.getText("cms.ui.pages.page_config_for_category",
new String[]{globalizationHelper
.getValueFromLocalizedString(category
.getTitle())}));
indexPageModelSelect.setSelectedItem(page.get().getIndexPageModel());
itemPageModelSelect.setSelectedItem(page.get().getItemPageModel());
// indexPageModelSelect.setValue(page.get().getIndexPageModel());
// itemPageModelSelect.setValue(page.get().getItemPageModel());
} else {
indexPageModelSelect.setSelectedItem(null);
itemPageModelSelect.setSelectedItem(null);
}
saveButton.setEnabled(false);
cancelButton.setEnabled(false);
}
private void saveButtonClicked(final Button.ClickEvent event) {
final Page page = findOrCreatePage();
final Optional<PageModel> selectedIndexPageModel
= indexPageModelSelect
.getSelectedItem();
if (selectedIndexPageModel.isPresent()) {
page.setIndexPageModel(selectedIndexPageModel.get());
} else {
page.setIndexPageModel(null);
}
final Optional<PageModel> selectedItemPageModel
= itemPageModelSelect
.getSelectedItem();
if (selectedItemPageModel.isPresent()) {
page.setItemPageModel(selectedItemPageModel.get());
} else {
page.setItemPageModel(null);
}
controller.getPagesController().getPageRepo().save(page);
updateWidgets(selectedCategory);
}
private Page findOrCreatePage() {
final Optional<Page> page = controller
.getPagesController()
.findPage(selectedCategory);
if (page.isPresent()) {
return page.get();
} else {
final PageManager pageManager = controller
.getPagesController()
.getPageManager();
return pageManager.createPageForCategory(selectedCategory);
}
}
private void cancelButtonClicked(final Button.ClickEvent event) {
updateWidgets(selectedCategory);
}
}

View File

@ -0,0 +1,184 @@
/*
* 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;
import com.vaadin.server.UserError;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.categorization.Domain;
import org.libreccm.l10n.LocalizedTextsUtil;
import org.libreccm.sites.Site;
import org.librecms.CmsConstants;
import org.librecms.pages.Pages;
import org.librecms.pages.PagesManager;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PagesEditor extends Window {
private static final long serialVersionUID = -7895690663139812879L;
private final CmsViewController controller;
private final LocalizedTextsUtil textsUtil;
private Pages pages;
private final TextField nameField;
private final ComboBox<Site> siteSelect;
private final ComboBox<Domain> categorySystemSelect;
PagesEditor(final CmsViewController controller) {
super();
this.controller = controller;
textsUtil = controller
.getGlobalizationHelper()
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
nameField = new TextField(textsUtil
.getText("cms.ui.pages.form.primary_url_field.label"));
siteSelect = new ComboBox<>(textsUtil
.getText("cms.ui.pages.form.site_select.error"));
siteSelect.setDataProvider(controller
.getPagesController()
.getPagesEditorSiteSelectDataProvider());
siteSelect.setEmptySelectionAllowed(false);
siteSelect.setItemCaptionGenerator(this::buildSiteCaption);
categorySystemSelect = new ComboBox<>(textsUtil
.getText("cms.ui.pages.form.category_domain_select.label"));
categorySystemSelect.setEmptySelectionAllowed(false);
categorySystemSelect.setDataProvider(controller
.getPagesController()
.getPagesEditorDomainSelectDataProvider());
categorySystemSelect.setItemCaptionGenerator(Domain::getDomainKey);
final FormLayout formLayout = new FormLayout(nameField,
siteSelect,
categorySystemSelect);
final Button saveButton = new Button(textsUtil
.getText("cms.ui.pages.editor.save"));
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
saveButton.addClickListener(this::saveButtonClicked);
final Button cancelButton = new Button(textsUtil
.getText("cms.ui.pages.editor.cancel"));
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
cancelButton.addClickListener(event -> close());
super.setContent(new VerticalLayout(formLayout,
new HorizontalLayout(saveButton,
cancelButton)));
}
PagesEditor(final Pages pages,
final CmsViewController controller) {
this(controller);
this.pages = pages;
nameField.setValue(pages.getPrimaryUrl());
siteSelect.setEnabled(false);
categorySystemSelect.setEnabled(false);
}
private String buildSiteCaption(final Site site) {
if (site.isDefaultSite()) {
return String.format("%s *",
site.getDomainOfSite());
} else {
return site.getDomainOfSite();
}
}
private void saveButtonClicked(final Button.ClickEvent event) {
if (nameField.getValue() == null
|| nameField.getValue().isEmpty()
|| nameField.getValue().matches("\\s*")) {
nameField.setComponentError(new UserError(textsUtil
.getText("cms.ui.pages.form.primary_url_field.error")));
return;
}
if (pages == null
&& !siteSelect.getSelectedItem().isPresent()) {
siteSelect.setComponentError(new UserError(textsUtil
.getText("cms.ui.pages.form.site_select.error")));
return;
}
if (pages == null
&& !categorySystemSelect.getSelectedItem().isPresent()) {
categorySystemSelect.setComponentError(new UserError(textsUtil
.getText("cms.ui.pages.form.category_domain_select.error")));
return;
}
if (pages == null) {
final PagesController pagesController = controller
.getPagesController();
pages = pagesController
.createPages(generatePrimaryUrl(nameField.getValue()),
siteSelect.getValue(),
categorySystemSelect.getValue());
} else {
pages.setPrimaryUrl(generatePrimaryUrl(nameField.getValue()));
controller.getPagesController().getPagesRepo().save(pages);
}
controller.getPagesController().getPagesGridDataProvider().refreshAll();
close();
}
private String generatePrimaryUrl(final String name) {
if (name.startsWith("/") && name.endsWith("/")) {
return name;
} else if (name.startsWith("/") && !name.endsWith("/")) {
return String.format("%s/", name);
} else if (!name.startsWith("/") && name.endsWith("/")) {
return String.format("/%s", name);
} else {
return String.format("/%s/", name);
}
}
}

View File

@ -0,0 +1,100 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import org.libreccm.categorization.Domain;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
class PagesEditorDomainSelectDataProvider
extends AbstractBackEndDataProvider<Domain, String> {
private static final long serialVersionUID = 7172310455833118907L;
@Inject
private EntityManager entityManager;
@Override
protected Stream<Domain> fetchFromBackEnd(
final Query<Domain, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Domain> criteriaQuery = builder
.createQuery(Domain.class);
final Root<Domain> from = criteriaQuery.from(Domain.class);
if (query.getFilter().isPresent()) {
criteriaQuery.where(builder.like(from.get("domainKey"),
":filter%"));
}
final TypedQuery<Domain> entityQuery = entityManager
.createQuery(criteriaQuery);
if (query.getFilter().isPresent()) {
entityQuery.setParameter("filter", query.getFilter().get());
}
return entityQuery
.setFirstResult(query.getOffset())
.setMaxResults(query.getLimit())
.getResultList()
.stream();
}
@Override
protected int sizeInBackEnd(final Query<Domain, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = builder
.createQuery(Long.class);
final Root<Domain> from = criteriaQuery.from(Domain.class);
criteriaQuery.select(builder.count(from));
if (query.getFilter().isPresent()) {
criteriaQuery.where(builder.like(from.get("domainKey"),
":filter%"));
}
final TypedQuery<Long> entityQuery = entityManager
.createQuery(criteriaQuery);
if (query.getFilter().isPresent()) {
entityQuery.setParameter("filter", query.getFilter().get());
}
return entityQuery.getSingleResult().intValue();
}
}

View File

@ -0,0 +1,100 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import org.libreccm.sites.Site;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class PagesEditorSiteSelectDataProvider extends AbstractBackEndDataProvider<Site, String> {
private static final long serialVersionUID = 8334700797163099258L;
@Inject
private EntityManager entityManager;
@Override
protected Stream<Site> fetchFromBackEnd(final Query<Site, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Site> criteriaQuery = builder
.createQuery(Site.class);
final Root<Site> from = criteriaQuery.from(Site.class);
if (query.getFilter().isPresent()) {
criteriaQuery.where(builder.like(from.get("domainOfSite"),
":filter%"));
}
final TypedQuery<Site> entityQuery = entityManager
.createQuery(criteriaQuery);
if (query.getFilter().isPresent()) {
entityQuery.setParameter("filter", query.getFilter().get());
}
return entityQuery
.setFirstResult(query.getOffset())
.setMaxResults(query.getLimit())
.getResultList()
.stream();
}
@Override
protected int sizeInBackEnd(final Query<Site, String> query) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = builder
.createQuery(Long.class);
final Root<Site> from = criteriaQuery.from(Site.class);
criteriaQuery.select(builder.count(from));
if (query.getFilter().isPresent()) {
criteriaQuery.where(builder.like(from.get("domainOfSite"),
":filter%"));
}
final TypedQuery<Long> entityQuery = entityManager
.createQuery(criteriaQuery);
if (query.getFilter().isPresent()) {
entityQuery.setParameter("filter", query.getFilter().get());
}
return entityQuery.getSingleResult().intValue();
}
}

View File

@ -0,0 +1,58 @@
/*
* 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;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import org.librecms.pages.Pages;
import org.librecms.pages.PagesRepository;
import java.util.stream.Stream;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class PagesGridDataProvider
extends AbstractBackEndDataProvider<Pages, String> {
private static final long serialVersionUID = -2388748600960614488L;
@Inject
private PagesRepository pagesRepo;
@Override
protected Stream<Pages> fetchFromBackEnd(final Query<Pages, String> query) {
return pagesRepo
.findAll()
.stream();
}
@Override
protected int sizeInBackEnd(final Query<Pages, String> query) {
return pagesRepo.findAll().size();
}
}

View File

@ -0,0 +1,200 @@
/*
* 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;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.components.grid.HeaderCell;
import com.vaadin.ui.components.grid.HeaderRow;
import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.l10n.LocalizedTextsUtil;
import org.libreccm.ui.ConfirmDialog;
import org.librecms.CmsConstants;
import org.librecms.pages.Pages;
import org.librecms.pages.PagesRepository;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PagesTab extends CustomComponent {
private static final long serialVersionUID = 8237082714759130342L;
private static final String COL_NAME = "name";
private static final String COL_SITE = "site";
private static final String COL_EDIT = "edit";
private static final String COL_DEL = "del";
private final CmsViewController controller;
private final LocalizedTextsUtil textsUtil;
PagesTab(final CmsViewController controller) {
super();
this.controller = controller;
textsUtil = controller
.getGlobalizationHelper()
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
final Grid<Pages> pagesGrid = new Grid<>();
// pagesGrid
// .addColumn(Pages::getPrimaryUrl)
// .setCaption("cms.ui.contentcenter.pagestable.columns.name.header")
// .setId(COL_NAME);
pagesGrid
.addComponentColumn(this::buildDetailsLink)
.setCaption(textsUtil
.getText("cms.ui.contentcenter.pagestable.columns.name.header"))
.setId(COL_NAME);
pagesGrid
.addColumn(pages -> pages.getSite().getDomainOfSite())
.setCaption(textsUtil
.getText("cms.ui.contentcenter.pagestable.columns.site.header"))
.setId(COL_SITE);
pagesGrid
.addComponentColumn(this::buildEditButton)
.setCaption(textsUtil
.getText("cms.ui.contentcenter.pagestable.columns.edit.header"))
.setId(COL_EDIT);
pagesGrid
.addComponentColumn(this::buildDeleteButton)
.setCaption(textsUtil
.getText("cms.ui.contentcenter.pagestable.columns.delete.header"))
.setId(COL_DEL);
final Button addPagesButton = new Button(textsUtil
.getText("cms.ui.contentcenter.pages.add_link"));
addPagesButton.addStyleName(ValoTheme.BUTTON_TINY);
addPagesButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
addPagesButton.addClickListener(this::addPagesButtonClicked);
final HeaderRow headerRow = pagesGrid.prependHeaderRow();
final HeaderCell headerCell = headerRow
.join(COL_NAME, COL_SITE, COL_EDIT, COL_DEL);
headerCell.setComponent(new HorizontalLayout(addPagesButton));
pagesGrid.setDataProvider(controller
.getPagesController()
.getPagesGridDataProvider());
pagesGrid.setWidth("100%");
super.setCompositionRoot(new VerticalLayout(pagesGrid));
}
private Component buildDetailsLink(final Pages pages) {
final Button button = new Button(pages.getPrimaryUrl());
button.addStyleName(ValoTheme.BUTTON_LINK);
button.addClickListener(event -> detailsLinkClicked(event, pages));
return button;
}
private Component buildEditButton(final Pages pages) {
final Button button = new Button(textsUtil
.getText("cms.ui.contentcenter.pages.edit.label"));
button.setIcon(VaadinIcons.EDIT);
button.addStyleName(ValoTheme.BUTTON_TINY);
button.addClickListener(event -> editButtonClicked(event, pages));
return button;
}
private Component buildDeleteButton(final Pages pages) {
final Button button = new Button(textsUtil
.getText("cms.ui.contentcenter.pages.delete.label"));
button.setIcon(VaadinIcons.MINUS_CIRCLE_O);
button.addStyleNames(ValoTheme.BUTTON_TINY,
ValoTheme.BUTTON_DANGER);
button.addClickListener(event -> deleteButtonClicked(event, pages));
return button;
}
private void addPagesButtonClicked(final Button.ClickEvent event) {
final PagesEditor editor = new PagesEditor(controller);
editor.setModal(true);
editor.setWidth("40%");
editor.setHeight("60%");
UI.getCurrent().addWindow(editor);
}
private void detailsLinkClicked(final Button.ClickEvent event,
final Pages pages) {
final PagesDetails pagesDetails = new PagesDetails(pages, controller);
pagesDetails.setModal(true);
pagesDetails.setWidth("90%");
pagesDetails.setHeight("90%");
UI.getCurrent().addWindow(pagesDetails);
}
private void editButtonClicked(final Button.ClickEvent event,
final Pages pages) {
final PagesEditor pagesEditor = new PagesEditor(pages, controller);
pagesEditor.setModal(true);
pagesEditor.setWidth("40%");
pagesEditor.setHeight("80%");
UI.getCurrent().addWindow(pagesEditor);
}
private void deleteButtonClicked(final Button.ClickEvent event,
final Pages pages) {
final ConfirmDialog confirmDialog
= new ConfirmDialog(() -> deletePages(pages));
confirmDialog.setMessage(textsUtil
.getText("cms.ui.contentcenter.pages.delete.confirm"));
confirmDialog.setModal(true);
UI.getCurrent().addWindow(confirmDialog);
}
private Void deletePages(final Pages pages) {
final PagesRepository pagesRepo = controller
.getPagesController()
.getPagesRepo();
pagesRepo.delete(pages);
controller
.getPagesController()
.getPagesGridDataProvider()
.refreshAll();
return null;
}
}

View File

@ -496,3 +496,10 @@ cms.ui.pages.page_config_for_category=Page Configuration for category {0}
cms.ui.pages.assigned_page_model.inherit=Inherit from parent
cms.ui.pages.no_category_selected=No category selected
pages_application.title=Pages
cms.ui.contentcenter.pagestable.columns.name.header=Name
cms.ui.pages.editor.save=Save
cms.ui.pages.editor.cancel=Cancel
cms.ui.pages.pagemodels.index_page=Index Page Model
cms.ui.pages.pagemodels.item_page=Item Page Model
cms.ui.pages.pagemodels.save=Save
cms.ui.pages.pagemodels.cancel=Cancel

View File

@ -493,3 +493,10 @@ 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
cms.ui.pages.no_category_selected=Keine Kategorie ausgew\u00e4hlt
pages_application.title=Pages
cms.ui.contentcenter.pagestable.columns.name.header=Name
cms.ui.pages.editor.save=Speichern
cms.ui.pages.editor.cancel=Abbrechen
cms.ui.pages.pagemodels.index_page=Index Page Model
cms.ui.pages.pagemodels.item_page=Item Page Model
cms.ui.pages.pagemodels.save=Speichern
cms.ui.pages.pagemodels.cancel=Abbrechen

View File

@ -452,3 +452,10 @@ cms.ui.pages.page_config_for_category=Page Configuration for category {0}
cms.ui.pages.assigned_page_model.inherit=Inherit from parent
cms.ui.pages.no_category_selected=No category selected
pages_application.title=Pages
cms.ui.contentcenter.pagestable.columns.name.header=Name
cms.ui.pages.editor.save=Save
cms.ui.pages.editor.cancel=Cancel
cms.ui.pages.pagemodels.index_page=Index Page Model
cms.ui.pages.pagemodels.item_page=Item Page Model
cms.ui.pages.pagemodels.save=Save
cms.ui.pages.pagemodels.cancel=Cancel