CCM NG: Admin UI for Pages Vaadin variant
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5156 8810af33-2d31-482b-a856-94f89814c4df
parent
3032773dc4
commit
c6fb5ff65a
|
|
@ -243,7 +243,20 @@ class PagesForm extends Form {
|
||||||
|
|
||||||
final FormData data = event.getFormData();
|
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 selectedSiteId = data.getString(SITE_SELECT);
|
||||||
final String selectedDomainId = data.getString(
|
final String selectedDomainId = data.getString(
|
||||||
CATEGORY_DOMAIN_SELECT);
|
CATEGORY_DOMAIN_SELECT);
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
import static org.primefaces.component.calendar.Calendar.PropertyKeys.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class CmsView extends CustomComponent implements View {
|
||||||
final ContentSectionsGrid sectionsGrid = new ContentSectionsGrid(controller);
|
final ContentSectionsGrid sectionsGrid = new ContentSectionsGrid(controller);
|
||||||
sectionsGrid.setWidth("100%");
|
sectionsGrid.setWidth("100%");
|
||||||
tabSheet.addTab(sectionsGrid, "Content Section");
|
tabSheet.addTab(sectionsGrid, "Content Section");
|
||||||
|
tabSheet.addTab(new PagesTab(controller), "Pages");
|
||||||
tabSheet.addTab(new Label("Placeholder"), "Search");
|
tabSheet.addTab(new Label("Placeholder"), "Search");
|
||||||
tabSheet.addTab(new Label("Placeholder"), "My tasks");
|
tabSheet.addTab(new Label("Placeholder"), "My tasks");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ import com.vaadin.cdi.ViewScoped;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.security.PermissionChecker;
|
import org.libreccm.security.PermissionChecker;
|
||||||
import org.libreccm.security.PermissionManager;
|
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;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
|
@ -35,6 +39,10 @@ class CmsViewController {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PagesController pagesController;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PermissionManager permissionManager;
|
private PermissionManager permissionManager;
|
||||||
|
|
||||||
|
|
@ -48,6 +56,11 @@ class CmsViewController {
|
||||||
return globalizationHelper;
|
return globalizationHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected PagesController getPagesController() {
|
||||||
|
return pagesController;
|
||||||
|
}
|
||||||
|
|
||||||
protected PermissionManager getPermissionManager() {
|
protected PermissionManager getPermissionManager() {
|
||||||
return permissionManager;
|
return permissionManager;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.assigned_page_model.inherit=Inherit from parent
|
||||||
cms.ui.pages.no_category_selected=No category selected
|
cms.ui.pages.no_category_selected=No category selected
|
||||||
pages_application.title=Pages
|
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
|
||||||
|
|
|
||||||
|
|
@ -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.assigned_page_model.inherit=PageModel der \u00fcbergeordneten Seite verwenden
|
||||||
cms.ui.pages.no_category_selected=Keine Kategorie ausgew\u00e4hlt
|
cms.ui.pages.no_category_selected=Keine Kategorie ausgew\u00e4hlt
|
||||||
pages_application.title=Pages
|
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
|
||||||
|
|
|
||||||
|
|
@ -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.assigned_page_model.inherit=Inherit from parent
|
||||||
cms.ui.pages.no_category_selected=No category selected
|
cms.ui.pages.no_category_selected=No category selected
|
||||||
pages_application.title=Pages
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue