diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesForm.java
index 0528db3f0..e35335fef 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesForm.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesForm.java
@@ -131,7 +131,7 @@ class PagesForm extends Form {
target.addOption(new Option(Long.toString(site.getObjectId()),
label));
}
-
+
if (selectedPages.getSelectedKey(event.getPageState()) != null) {
target.setDisabled();
}
@@ -153,7 +153,7 @@ class PagesForm extends Form {
target.addOption(new Option(Long.toString(domain.getObjectId()),
new Text(domain.getDomainKey())));
}
-
+
if (selectedPages.getSelectedKey(event.getPageState()) != null) {
target.setDisabled();
}
@@ -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);
diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesPaneController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesPaneController.java
index f39c37c9e..0bb6a530d 100644
--- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesPaneController.java
+++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/contentcenter/PagesPaneController.java
@@ -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 Jens Pelzetter
@@ -90,7 +88,7 @@ class PagesPaneController {
pagesId)));
pages.setPrimaryUrl(primaryUrl);
-
+
pagesRepo.save(pages);
}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsView.java b/ccm-cms/src/main/java/org/librecms/ui/CmsView.java
index 1dd49b246..0a14330df 100644
--- a/ccm-cms/src/main/java/org/librecms/ui/CmsView.java
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsView.java
@@ -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");
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java b/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java
index 6c89ce0cf..be252c5cd 100644
--- a/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java
@@ -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;
}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PageModelSelectDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/PageModelSelectDataProvider.java
new file mode 100644
index 000000000..b2b675f40
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PageModelSelectDataProvider.java
@@ -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 Jens Pelzetter
+ */
+@ViewScoped
+class PageModelSelectDataProvider
+ extends AbstractBackEndDataProvider {
+
+ private static final long serialVersionUID = 3102935928982631262L;
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Override
+ protected Stream fetchFromBackEnd(
+ final Query query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(PageModel.class);
+ final Root 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 query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Long.class);
+ final Root from = criteriaQuery.from(PageModel.class);
+
+ criteriaQuery.select(builder.count(from));
+
+ return entityManager
+ .createQuery(criteriaQuery)
+ .getSingleResult()
+ .intValue();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesCategoryTreeDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/PagesCategoryTreeDataProvider.java
new file mode 100644
index 000000000..455bd5452
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesCategoryTreeDataProvider.java
@@ -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 Jens Pelzetter
+ */
+@ViewScoped
+class PagesCategoryTreeDataProvider
+ extends AbstractBackEndHierarchicalDataProvider {
+
+ 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 fetchChildrenFromBackEnd(
+ final HierarchicalQuery query) {
+
+ if (query.getParentOptional().isPresent()) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Category.class);
+
+ final Root from = criteriaQuery.from(Category.class);
+ criteriaQuery.where(builder.equal(from.get("parentCategory"),
+ query.getParentOptional().get()));
+ final TypedQuery 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 query) {
+
+ if (query.getParentOptional().isPresent()) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Long.class);
+
+ final Root from = criteriaQuery.from(Category.class);
+ criteriaQuery.select(builder.count(from));
+ criteriaQuery.where(builder.equal(from.get("parentCategory"),
+ query.getParentOptional().get()));
+ final TypedQuery 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 criteriaQuery = builder
+ .createQuery(Long.class);
+
+ final Root from = criteriaQuery.from(Category.class);
+ criteriaQuery.select(builder.count(from));
+ criteriaQuery.where(builder.equal(from.get("parentCategory"), item));
+ final TypedQuery entityQuery = entityManager
+ .createQuery(criteriaQuery);
+ return entityQuery.getSingleResult().intValue() > 0;
+ }
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesController.java b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java
new file mode 100644
index 000000000..790d93dbc
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java
@@ -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 Jens Pelzetter
+ */
+@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 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);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesDetails.java b/ccm-cms/src/main/java/org/librecms/ui/PagesDetails.java
new file mode 100644
index 000000000..02b153078
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesDetails.java
@@ -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 Jens Pelzetter
+ */
+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 indexPageModelSelect;
+ private final ComboBox 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 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 event) {
+
+ final Category category = event.getItem();
+ selectedCategory = category;
+ updateWidgets(category);
+ }
+
+ private void selectionChange(final SingleSelectionEvent event) {
+
+ saveButton.setEnabled(true);
+ cancelButton.setEnabled(true);
+ }
+
+ private void updateWidgets(final Category category) {
+
+ Objects.requireNonNull(category);
+
+ final Optional 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 selectedIndexPageModel
+ = indexPageModelSelect
+ .getSelectedItem();
+ if (selectedIndexPageModel.isPresent()) {
+ page.setIndexPageModel(selectedIndexPageModel.get());
+ } else {
+ page.setIndexPageModel(null);
+ }
+
+ final Optional 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 = 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);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesEditor.java b/ccm-cms/src/main/java/org/librecms/ui/PagesEditor.java
new file mode 100644
index 000000000..21a2ea346
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesEditor.java
@@ -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 Jens Pelzetter
+ */
+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 siteSelect;
+ private final ComboBox 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);
+ }
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesEditorDomainSelectDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/PagesEditorDomainSelectDataProvider.java
new file mode 100644
index 000000000..76f026737
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesEditorDomainSelectDataProvider.java
@@ -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 Jens Pelzetter
+ */
+@ViewScoped
+class PagesEditorDomainSelectDataProvider
+ extends AbstractBackEndDataProvider {
+
+ private static final long serialVersionUID = 7172310455833118907L;
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Override
+ protected Stream fetchFromBackEnd(
+ final Query query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Domain.class);
+
+ final Root from = criteriaQuery.from(Domain.class);
+ if (query.getFilter().isPresent()) {
+ criteriaQuery.where(builder.like(from.get("domainKey"),
+ ":filter%"));
+ }
+
+ final TypedQuery 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 query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Long.class);
+
+ final Root from = criteriaQuery.from(Domain.class);
+ criteriaQuery.select(builder.count(from));
+ if (query.getFilter().isPresent()) {
+ criteriaQuery.where(builder.like(from.get("domainKey"),
+ ":filter%"));
+ }
+
+ final TypedQuery entityQuery = entityManager
+ .createQuery(criteriaQuery);
+
+ if (query.getFilter().isPresent()) {
+ entityQuery.setParameter("filter", query.getFilter().get());
+ }
+
+ return entityQuery.getSingleResult().intValue();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesEditorSiteSelectDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/PagesEditorSiteSelectDataProvider.java
new file mode 100644
index 000000000..d1f143f23
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesEditorSiteSelectDataProvider.java
@@ -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 Jens Pelzetter
+ */
+@ViewScoped
+public class PagesEditorSiteSelectDataProvider extends AbstractBackEndDataProvider {
+
+ private static final long serialVersionUID = 8334700797163099258L;
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Override
+ protected Stream fetchFromBackEnd(final Query query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Site.class);
+
+ final Root from = criteriaQuery.from(Site.class);
+
+ if (query.getFilter().isPresent()) {
+ criteriaQuery.where(builder.like(from.get("domainOfSite"),
+ ":filter%"));
+ }
+
+ final TypedQuery 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 query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Long.class);
+
+ final Root from = criteriaQuery.from(Site.class);
+ criteriaQuery.select(builder.count(from));
+
+ if (query.getFilter().isPresent()) {
+ criteriaQuery.where(builder.like(from.get("domainOfSite"),
+ ":filter%"));
+ }
+
+ final TypedQuery entityQuery = entityManager
+ .createQuery(criteriaQuery);
+
+ if (query.getFilter().isPresent()) {
+ entityQuery.setParameter("filter", query.getFilter().get());
+ }
+
+ return entityQuery.getSingleResult().intValue();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesGridDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/PagesGridDataProvider.java
new file mode 100644
index 000000000..5b1ec0ce9
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesGridDataProvider.java
@@ -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 Jens Pelzetter
+ */
+@ViewScoped
+public class PagesGridDataProvider
+ extends AbstractBackEndDataProvider {
+
+ private static final long serialVersionUID = -2388748600960614488L;
+
+ @Inject
+ private PagesRepository pagesRepo;
+
+ @Override
+ protected Stream fetchFromBackEnd(final Query query) {
+
+ return pagesRepo
+ .findAll()
+ .stream();
+ }
+
+ @Override
+ protected int sizeInBackEnd(final Query query) {
+
+ return pagesRepo.findAll().size();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesTab.java b/ccm-cms/src/main/java/org/librecms/ui/PagesTab.java
new file mode 100644
index 000000000..75ed2beb3
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesTab.java
@@ -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 Jens Pelzetter
+ */
+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 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;
+ }
+
+}
diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties
index f5b79d227..eddd91888 100644
--- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties
+++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties
@@ -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
diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties
index dbe8ea021..c141513e0 100644
--- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties
+++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties
@@ -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
diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties
index 12faa82b2..f64ce5a73 100644
--- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties
+++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties
@@ -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