CCM NG: Admin UI for Sites
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5099 8810af33-2d31-482b-a856-94f89814c4df
parent
7476e7f365
commit
657e7fddd5
|
|
@ -48,6 +48,7 @@ class SitesController implements Serializable {
|
||||||
.findAll()
|
.findAll()
|
||||||
.stream()
|
.stream()
|
||||||
.map(this::buildRow)
|
.map(this::buildRow)
|
||||||
|
.sorted()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,9 @@ public class SitesForm extends Form {
|
||||||
super.add(defaultSiteCheckbox);
|
super.add(defaultSiteCheckbox);
|
||||||
|
|
||||||
defaultThemeSelect = new SingleSelect(THEME_SELECT);
|
defaultThemeSelect = new SingleSelect(THEME_SELECT);
|
||||||
|
defaultThemeSelect.setLabel(new GlobalizedMessage(
|
||||||
|
"ui.admin.sites.default_theme",
|
||||||
|
ADMIN_BUNDLE));
|
||||||
try {
|
try {
|
||||||
defaultThemeSelect.addPrintListener(event -> {
|
defaultThemeSelect.addPrintListener(event -> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
class SitesTableRow implements Serializable {
|
class SitesTableRow implements Comparable<SitesTableRow>, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -8913595737414248135L;
|
private static final long serialVersionUID = -8913595737414248135L;
|
||||||
|
|
||||||
|
|
@ -98,5 +98,10 @@ class SitesTableRow implements Serializable {
|
||||||
protected void addApplication(final String application) {
|
protected void addApplication(final String application) {
|
||||||
applications.add(application);
|
applications.add(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final SitesTableRow other) {
|
||||||
|
return domainOfSite.compareTo(other.getDomainOfSite());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public class AdminView extends CustomComponent implements View {
|
||||||
private final JpqlConsole jpqlConsole;
|
private final JpqlConsole jpqlConsole;
|
||||||
|
|
||||||
private final ConfigurationTab configurationTab;
|
private final ConfigurationTab configurationTab;
|
||||||
|
|
||||||
private final SystemInformationTab sysInfoTab;
|
private final SystemInformationTab sysInfoTab;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -75,7 +75,7 @@ public class AdminView extends CustomComponent implements View {
|
||||||
tabUsersGroupsRoles = tabSheet
|
tabUsersGroupsRoles = tabSheet
|
||||||
.addTab(usersGroupsRoles,
|
.addTab(usersGroupsRoles,
|
||||||
bundle.getString("ui.admin.tab.users_groups_roles.title"));
|
bundle.getString("ui.admin.tab.users_groups_roles.title"));
|
||||||
|
|
||||||
final ServletContext servletContext = VaadinServlet
|
final ServletContext servletContext = VaadinServlet
|
||||||
.getCurrent()
|
.getCurrent()
|
||||||
.getServletContext();
|
.getServletContext();
|
||||||
|
|
@ -86,12 +86,15 @@ public class AdminView extends CustomComponent implements View {
|
||||||
jpqlConsole = null;
|
jpqlConsole = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SitesTab sitesTab = new SitesTab(controller);
|
||||||
|
tabSheet.addTab(sitesTab, "Sites");
|
||||||
|
|
||||||
configurationTab = new ConfigurationTab();
|
configurationTab = new ConfigurationTab();
|
||||||
tabSheet.addTab(configurationTab, "Configuration");
|
tabSheet.addTab(configurationTab, "Configuration");
|
||||||
|
|
||||||
sysInfoTab = new SystemInformationTab(controller);
|
sysInfoTab = new SystemInformationTab(controller);
|
||||||
tabSheet.addTab(sysInfoTab, "System Information");
|
tabSheet.addTab(sysInfoTab, "System Information");
|
||||||
|
|
||||||
final CssLayout footer = new CssLayout();
|
final CssLayout footer = new CssLayout();
|
||||||
footer.setHeight("5em");
|
footer.setHeight("5em");
|
||||||
|
|
||||||
|
|
@ -104,7 +107,4 @@ public class AdminView extends CustomComponent implements View {
|
||||||
super.setCompositionRoot(viewLayout);
|
super.setCompositionRoot(viewLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ class AdminViewController implements Serializable {
|
||||||
@Inject
|
@Inject
|
||||||
private JpqlConsoleController jpqlConsoleController;
|
private JpqlConsoleController jpqlConsoleController;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SitesController sitesController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UsersGroupsRolesController usersGroupsRolesController;
|
private UsersGroupsRolesController usersGroupsRolesController;
|
||||||
|
|
||||||
|
|
@ -64,6 +67,10 @@ class AdminViewController implements Serializable {
|
||||||
return jpqlConsoleController;
|
return jpqlConsoleController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected SitesController getSitesController() {
|
||||||
|
return sitesController;
|
||||||
|
}
|
||||||
|
|
||||||
protected UsersGroupsRolesController getUsersGroupsRolesController() {
|
protected UsersGroupsRolesController getUsersGroupsRolesController() {
|
||||||
return usersGroupsRolesController;
|
return usersGroupsRolesController;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* 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.libreccm.admin.ui;
|
||||||
|
|
||||||
|
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||||
|
|
||||||
|
import com.vaadin.server.UserError;
|
||||||
|
import com.vaadin.ui.Button;
|
||||||
|
import com.vaadin.ui.CheckBox;
|
||||||
|
import com.vaadin.ui.FormLayout;
|
||||||
|
import com.vaadin.ui.HorizontalLayout;
|
||||||
|
import com.vaadin.ui.NativeSelect;
|
||||||
|
import com.vaadin.ui.TextField;
|
||||||
|
import com.vaadin.ui.VerticalLayout;
|
||||||
|
import com.vaadin.ui.Window;
|
||||||
|
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||||
|
import org.libreccm.sites.Site;
|
||||||
|
import org.libreccm.theming.ThemeInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class SiteEditor extends Window {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 7016158691791408762L;
|
||||||
|
|
||||||
|
private final Site site;
|
||||||
|
private final AdminViewController controller;
|
||||||
|
|
||||||
|
private boolean dataHasChanged = false;
|
||||||
|
|
||||||
|
public SiteEditor(final AdminViewController controller) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.site = null;
|
||||||
|
this.controller = controller;
|
||||||
|
|
||||||
|
addWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SiteEditor(final Site site, final AdminViewController controller) {
|
||||||
|
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.site = site;
|
||||||
|
this.controller = controller;
|
||||||
|
|
||||||
|
addWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWidgets() {
|
||||||
|
|
||||||
|
final LocalizedTextsUtil adminTextsUtil = controller
|
||||||
|
.getGlobalizationHelper()
|
||||||
|
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||||
|
|
||||||
|
if (site == null) {
|
||||||
|
setCaption(adminTextsUtil.getText("ui.admin.sites.create_new"));
|
||||||
|
} else {
|
||||||
|
setCaption(adminTextsUtil.getText("ui.admin.sites.edit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
final TextField domainOfSiteField = new TextField(
|
||||||
|
adminTextsUtil.getText("ui.admin.sites.domain_of_site"));
|
||||||
|
domainOfSiteField.addValueChangeListener(event -> {
|
||||||
|
dataHasChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
final CheckBox isDefaultSiteCheckBox = new CheckBox(
|
||||||
|
adminTextsUtil.getText("ui.admin.sites.is_default_site"));
|
||||||
|
isDefaultSiteCheckBox.addValueChangeListener(event -> {
|
||||||
|
dataHasChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<String> themes = controller
|
||||||
|
.getSitesController()
|
||||||
|
.getThemes()
|
||||||
|
.getAvailableThemes()
|
||||||
|
.stream()
|
||||||
|
.map(ThemeInfo::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final NativeSelect<String> defaultThemeSelect = new NativeSelect<>(
|
||||||
|
adminTextsUtil.getText("ui.admin.sites.default_theme"), themes);
|
||||||
|
defaultThemeSelect.addValueChangeListener(event -> {
|
||||||
|
dataHasChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
final Button saveButton = new Button();
|
||||||
|
if (site == null) {
|
||||||
|
saveButton.setCaption(adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.buttons.save.create"));
|
||||||
|
} else {
|
||||||
|
saveButton.setCaption(adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.buttons.save.changed"));
|
||||||
|
}
|
||||||
|
saveButton.addClickListener(event -> {
|
||||||
|
if (dataHasChanged) {
|
||||||
|
|
||||||
|
final String domainOfSite = domainOfSiteField.getValue();
|
||||||
|
if (domainOfSite == null
|
||||||
|
|| domainOfSite.isEmpty()
|
||||||
|
|| domainOfSite.matches("\\s*")) {
|
||||||
|
|
||||||
|
domainOfSiteField.setComponentError(new UserError(
|
||||||
|
adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.domain_of_site.error.empty")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!controller.getSitesController().isUnique(domainOfSite)) {
|
||||||
|
domainOfSiteField.setComponentError(new UserError(
|
||||||
|
adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.domain_of_site.error.not_unique")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
site.setDomainOfSite(domainOfSite);
|
||||||
|
site.setDefaultSite(isDefaultSiteCheckBox.getValue());
|
||||||
|
site.setDefaultTheme(defaultThemeSelect.getValue());
|
||||||
|
|
||||||
|
controller
|
||||||
|
.getSitesController()
|
||||||
|
.getSiteRepository()
|
||||||
|
.save(site);
|
||||||
|
controller
|
||||||
|
.getSitesController()
|
||||||
|
.getSitesTableDataProvider()
|
||||||
|
.refreshAll();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final Button cancelButton = new Button(adminTextsUtil
|
||||||
|
.getText("ui.admin.sites.buttons.cancel"));
|
||||||
|
cancelButton.addClickListener(event -> {
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
|
||||||
|
super.setContent(new VerticalLayout(
|
||||||
|
new FormLayout(domainOfSiteField,
|
||||||
|
isDefaultSiteCheckBox,
|
||||||
|
defaultThemeSelect),
|
||||||
|
new HorizontalLayout(saveButton, cancelButton)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* 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.libreccm.admin.ui;
|
||||||
|
|
||||||
|
import com.vaadin.cdi.ViewScoped;
|
||||||
|
import org.libreccm.sites.Site;
|
||||||
|
import org.libreccm.sites.SiteRepository;
|
||||||
|
import org.libreccm.theming.Themes;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ViewScoped
|
||||||
|
class SitesController implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 112502641827852807L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SiteRepository siteRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SitesTableDataProvider sitesTableDataProvider;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Themes themes;
|
||||||
|
|
||||||
|
protected SitesTableDataProvider getSitesTableDataProvider() {
|
||||||
|
return sitesTableDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Themes getThemes() {
|
||||||
|
return themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SiteRepository getSiteRepository() {
|
||||||
|
return siteRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there no site with the provided domain.
|
||||||
|
*
|
||||||
|
* @param domainOfSite
|
||||||
|
*
|
||||||
|
* @return {@code true} if there is no site with the provided domain,
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected boolean isUnique(final String domainOfSite) {
|
||||||
|
|
||||||
|
return !siteRepository.findByDomain(domainOfSite).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected void delete(final long siteId) {
|
||||||
|
final Site site = siteRepository
|
||||||
|
.findById(siteId)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No site with ID %d in the database.",
|
||||||
|
siteId)));
|
||||||
|
siteRepository.delete(site);
|
||||||
|
sitesTableDataProvider.refreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* 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.libreccm.admin.ui;
|
||||||
|
|
||||||
|
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||||
|
|
||||||
|
import com.vaadin.icons.VaadinIcons;
|
||||||
|
import com.vaadin.shared.ui.ContentMode;
|
||||||
|
import com.vaadin.ui.Button;
|
||||||
|
import com.vaadin.ui.CustomComponent;
|
||||||
|
import com.vaadin.ui.Grid;
|
||||||
|
import com.vaadin.ui.HorizontalLayout;
|
||||||
|
import com.vaadin.ui.Label;
|
||||||
|
import com.vaadin.ui.UI;
|
||||||
|
import com.vaadin.ui.components.grid.HeaderCell;
|
||||||
|
import com.vaadin.ui.components.grid.HeaderRow;
|
||||||
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||||
|
import org.libreccm.sites.Site;
|
||||||
|
import org.libreccm.ui.ConfirmDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class SitesTab extends CustomComponent {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 9188476373782633282L;
|
||||||
|
|
||||||
|
private static final String COL_DOMAIN_OF_SITE = "domain_of_site";
|
||||||
|
private static final String COL_IS_DEFAULT_SITE = "is_default_site";
|
||||||
|
private static final String COL_DEFAULT_THEME = "default_theme";
|
||||||
|
private static final String COL_APPLICATIONS = "applications";
|
||||||
|
private static final String COL_EDIT = "edit";
|
||||||
|
private static final String COL_DELETE = "delete";
|
||||||
|
|
||||||
|
protected SitesTab(final AdminViewController adminViewController) {
|
||||||
|
|
||||||
|
super();
|
||||||
|
|
||||||
|
final LocalizedTextsUtil adminTextsUtil = adminViewController
|
||||||
|
.getGlobalizationHelper()
|
||||||
|
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||||
|
|
||||||
|
final SitesController controller = adminViewController
|
||||||
|
.getSitesController();
|
||||||
|
|
||||||
|
final Grid<SitesTableRowData> sitesGrid = new Grid<>();
|
||||||
|
sitesGrid
|
||||||
|
.addColumn(SitesTableRowData::getDomainOfSite)
|
||||||
|
.setCaption(adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.table.columns.domain.header"))
|
||||||
|
.setId(COL_DOMAIN_OF_SITE);
|
||||||
|
sitesGrid
|
||||||
|
.addColumn(SitesTableRowData::isDefaultSite)
|
||||||
|
.setCaption(adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.table.columns.default_site.header"))
|
||||||
|
.setId(COL_IS_DEFAULT_SITE);
|
||||||
|
sitesGrid
|
||||||
|
.addColumn(SitesTableRowData::getDefaultTheme)
|
||||||
|
.setCaption(adminTextsUtil.getText(
|
||||||
|
"ui.admin.sites.table.columns.default_theme.header"))
|
||||||
|
.setId(COL_DEFAULT_THEME);
|
||||||
|
sitesGrid
|
||||||
|
.addComponentColumn(row -> {
|
||||||
|
return new Label(String.join("\n",
|
||||||
|
row.getApplications()),
|
||||||
|
ContentMode.PREFORMATTED);
|
||||||
|
})
|
||||||
|
.setCaption(adminTextsUtil
|
||||||
|
.getText("ui.admin.sites.table.columns.applications.header"))
|
||||||
|
.setId(COL_APPLICATIONS);
|
||||||
|
sitesGrid
|
||||||
|
.addComponentColumn(row -> {
|
||||||
|
final Button editButton = new Button(adminTextsUtil
|
||||||
|
.getText("ui.admin.sites.table.buttons.edit"),
|
||||||
|
VaadinIcons.EDIT);
|
||||||
|
editButton.addClickListener(event -> {
|
||||||
|
final Site site = adminViewController
|
||||||
|
.getSitesController()
|
||||||
|
.getSiteRepository()
|
||||||
|
.findById(row.getSiteId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Site with ID %d in the database.",
|
||||||
|
row.getSiteId())));
|
||||||
|
final SiteEditor editor = new SiteEditor(
|
||||||
|
site, adminViewController);
|
||||||
|
editor.center();
|
||||||
|
editor.setWidth("66%");
|
||||||
|
editor.setHeight("80%");
|
||||||
|
UI.getCurrent().addWindow(editor);
|
||||||
|
});
|
||||||
|
editButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||||
|
|
||||||
|
return editButton;
|
||||||
|
})
|
||||||
|
.setId(COL_EDIT);
|
||||||
|
sitesGrid
|
||||||
|
.addComponentColumn(row -> {
|
||||||
|
if (row.isDeletable()) {
|
||||||
|
final Button deleteButton = new Button(adminTextsUtil
|
||||||
|
.getText("ui.admin.sites.table.buttons.delete"),
|
||||||
|
VaadinIcons.EDIT);
|
||||||
|
deleteButton.addClickListener(event -> {
|
||||||
|
|
||||||
|
final ConfirmDialog dialog = new ConfirmDialog(() -> {
|
||||||
|
adminViewController
|
||||||
|
.getSitesController()
|
||||||
|
.delete(row.getSiteId());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
deleteButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||||
|
ValoTheme.BUTTON_DANGER);
|
||||||
|
|
||||||
|
return deleteButton;
|
||||||
|
} else {
|
||||||
|
return new Label("");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setId(COL_DELETE);
|
||||||
|
final HeaderRow headerRow = sitesGrid.prependHeaderRow();
|
||||||
|
final HeaderCell headerCell = headerRow.join(COL_DOMAIN_OF_SITE,
|
||||||
|
COL_IS_DEFAULT_SITE,
|
||||||
|
COL_DEFAULT_THEME,
|
||||||
|
COL_APPLICATIONS,
|
||||||
|
COL_EDIT,
|
||||||
|
COL_DELETE);
|
||||||
|
final Button newSiteButton = new Button(adminTextsUtil
|
||||||
|
.getText("ui.admin.sites.add_new_site_link"),
|
||||||
|
VaadinIcons.PLUS_CIRCLE_O);
|
||||||
|
newSiteButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||||
|
newSiteButton.addClickListener(event -> {
|
||||||
|
final SiteEditor editor = new SiteEditor(adminViewController);
|
||||||
|
editor.center();
|
||||||
|
editor.setWidth("66%");
|
||||||
|
editor.setHeight("80%");
|
||||||
|
UI.getCurrent().addWindow(editor);
|
||||||
|
});
|
||||||
|
final HorizontalLayout headerLayout
|
||||||
|
= new HorizontalLayout(newSiteButton);
|
||||||
|
headerCell.setComponent(headerLayout);
|
||||||
|
sitesGrid.setDataProvider(adminViewController
|
||||||
|
.getSitesController()
|
||||||
|
.getSitesTableDataProvider());
|
||||||
|
sitesGrid.setWidth("100%");
|
||||||
|
|
||||||
|
super.setCompositionRoot(sitesGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* 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.libreccm.admin.ui;
|
||||||
|
|
||||||
|
import com.vaadin.cdi.ViewScoped;
|
||||||
|
import com.vaadin.data.provider.AbstractDataProvider;
|
||||||
|
import com.vaadin.data.provider.Query;
|
||||||
|
import org.libreccm.sites.Site;
|
||||||
|
import org.libreccm.sites.SiteRepository;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
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;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ViewScoped
|
||||||
|
public class SitesTableDataProvider
|
||||||
|
// extends AbstractBackEndDataProvider<SitesTableRowData, String> {
|
||||||
|
extends AbstractDataProvider<SitesTableRowData, String> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2696603483924152498L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SiteRepository siteRepository;
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// @Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
// public Stream<SitesTableRowData> fetchFromBackEnd(
|
||||||
|
// final Query<SitesTableRowData, String> query) {
|
||||||
|
//
|
||||||
|
// final CriteriaBuilder criteriaBuilder = entityManager
|
||||||
|
// .getCriteriaBuilder();
|
||||||
|
// final CriteriaQuery<Site> criteriaQuery = criteriaBuilder
|
||||||
|
// .createQuery(Site.class);
|
||||||
|
// final Root<Site> from = criteriaQuery.from(Site.class);
|
||||||
|
//
|
||||||
|
// criteriaQuery.orderBy(criteriaBuilder.asc(from.get("domainOfSite")));
|
||||||
|
//
|
||||||
|
// return entityManager
|
||||||
|
// .createQuery(criteriaQuery)
|
||||||
|
// .setFirstResult(query.getOffset())
|
||||||
|
// .setMaxResults(query.getLimit())
|
||||||
|
// .getResultList()
|
||||||
|
// .stream()
|
||||||
|
// .map(this::buildRow);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
// @Override
|
||||||
|
// public int sizeInBackEnd(final Query<SitesTableRowData, String> query) {
|
||||||
|
//
|
||||||
|
// return siteRepository.findAll().size();
|
||||||
|
// }
|
||||||
|
private SitesTableRowData buildRow(final Site site) {
|
||||||
|
|
||||||
|
final SitesTableRowData row = new SitesTableRowData();
|
||||||
|
|
||||||
|
row.setSiteId(site.getObjectId());
|
||||||
|
row.setDomainOfSite(site.getDomainOfSite());
|
||||||
|
row.setDefaultSite(site.isDefaultSite());
|
||||||
|
row.setDefaultTheme(site.getDefaultTheme());
|
||||||
|
row.setDeletable(site.getApplications().isEmpty());
|
||||||
|
|
||||||
|
final List<String> applications = site
|
||||||
|
.getApplications()
|
||||||
|
.stream()
|
||||||
|
.map(application -> application.getPrimaryUrl())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
row.setApplications(applications);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInMemory() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size(final Query<SitesTableRowData, String> query) {
|
||||||
|
return siteRepository.findAll().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public Stream<SitesTableRowData> fetch(
|
||||||
|
final Query<SitesTableRowData, String> query) {
|
||||||
|
|
||||||
|
final CriteriaBuilder criteriaBuilder = entityManager
|
||||||
|
.getCriteriaBuilder();
|
||||||
|
final CriteriaQuery<Site> criteriaQuery = criteriaBuilder
|
||||||
|
.createQuery(Site.class);
|
||||||
|
final Root<Site> from = criteriaQuery.from(Site.class);
|
||||||
|
|
||||||
|
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("domainOfSite")));
|
||||||
|
|
||||||
|
final List<Site> sites = entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.setFirstResult(query.getOffset())
|
||||||
|
.setMaxResults(query.getLimit())
|
||||||
|
.getResultList();
|
||||||
|
final List<SitesTableRowData> rows = new ArrayList<>();
|
||||||
|
for (final Site site : sites) {
|
||||||
|
final SitesTableRowData row = buildRow(site);
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows.stream();
|
||||||
|
|
||||||
|
// return entityManager
|
||||||
|
// .createQuery(criteriaQuery)
|
||||||
|
// .setFirstResult(query.getOffset())
|
||||||
|
// .setMaxResults(query.getLimit())
|
||||||
|
// .getResultList()
|
||||||
|
// .stream()
|
||||||
|
// .map(this::buildRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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.libreccm.admin.ui;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class SitesTableRowData implements Comparable<SitesTableRowData>, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4023882563583816258L;
|
||||||
|
|
||||||
|
private long siteId;
|
||||||
|
|
||||||
|
private String domainOfSite;
|
||||||
|
|
||||||
|
private boolean defaultSite;
|
||||||
|
|
||||||
|
private String defaultTheme;
|
||||||
|
|
||||||
|
private boolean deletable;
|
||||||
|
|
||||||
|
private List<String> applications;
|
||||||
|
|
||||||
|
protected SitesTableRowData() {
|
||||||
|
applications = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSiteId() {
|
||||||
|
return siteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSiteId(final long siteId) {
|
||||||
|
this.siteId = siteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomainOfSite() {
|
||||||
|
return domainOfSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomainOfSite(final String domainOfSite) {
|
||||||
|
this.domainOfSite = domainOfSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefaultSite() {
|
||||||
|
return defaultSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultSite(final boolean defaultSite) {
|
||||||
|
this.defaultSite = defaultSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultTheme() {
|
||||||
|
return defaultTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultTheme(final String defaultTheme) {
|
||||||
|
this.defaultTheme = defaultTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeletable() {
|
||||||
|
return deletable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeletable(final boolean deletable) {
|
||||||
|
this.deletable = deletable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getApplications() {
|
||||||
|
return Collections.unmodifiableList(applications);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setApplications(final List<String> applications) {
|
||||||
|
this.applications = new ArrayList<>(applications);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addApplication(final String application) {
|
||||||
|
applications.add(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final SitesTableRowData other) {
|
||||||
|
return domainOfSite.compareTo(other.getDomainOfSite());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -54,6 +54,8 @@ class SystemInformationTab extends CustomComponent {
|
||||||
|
|
||||||
protected SystemInformationTab(final AdminViewController controller) {
|
protected SystemInformationTab(final AdminViewController controller) {
|
||||||
|
|
||||||
|
super();
|
||||||
|
|
||||||
final LocalizedTextsUtil adminTextsUtil = controller
|
final LocalizedTextsUtil adminTextsUtil = controller
|
||||||
.getGlobalizationHelper()
|
.getGlobalizationHelper()
|
||||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.admin.ui;
|
package org.libreccm.admin.ui;
|
||||||
|
|
||||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
|
||||||
import com.vaadin.ui.CustomComponent;
|
import com.vaadin.ui.CustomComponent;
|
||||||
import com.vaadin.ui.TabSheet;
|
import com.vaadin.ui.TabSheet;
|
||||||
import com.vaadin.ui.UI;
|
|
||||||
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,9 @@ import javax.persistence.Table;
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Site.findByDomain",
|
name = "Site.findByDomain",
|
||||||
query = "SELECT s FROM Site s WHERE s.domainOfSite = :domain"
|
query = "SELECT s FROM Site s "
|
||||||
|
+ "WHERE s.domainOfSite = :domain "
|
||||||
|
+ "ORDER BY s.domainOfSite"
|
||||||
)
|
)
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
|
|
@ -72,12 +74,12 @@ public class Site extends CcmObject {
|
||||||
|
|
||||||
@OneToMany(mappedBy = "site")
|
@OneToMany(mappedBy = "site")
|
||||||
private List<SiteAwareApplication> applications;
|
private List<SiteAwareApplication> applications;
|
||||||
|
|
||||||
public Site() {
|
public Site() {
|
||||||
super();
|
super();
|
||||||
applications = new ArrayList<>();
|
applications = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDomainOfSite() {
|
public String getDomainOfSite() {
|
||||||
return domainOfSite;
|
return domainOfSite;
|
||||||
}
|
}
|
||||||
|
|
@ -101,11 +103,11 @@ public class Site extends CcmObject {
|
||||||
public void setDefaultTheme(final String defaultTheme) {
|
public void setDefaultTheme(final String defaultTheme) {
|
||||||
this.defaultTheme = defaultTheme;
|
this.defaultTheme = defaultTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SiteAwareApplication> getApplications() {
|
public List<SiteAwareApplication> getApplications() {
|
||||||
return Collections.unmodifiableList(applications);
|
return Collections.unmodifiableList(applications);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setApplications(final List<SiteAwareApplication> applications) {
|
protected void setApplications(final List<SiteAwareApplication> applications) {
|
||||||
this.applications = new ArrayList<>(applications);
|
this.applications = new ArrayList<>(applications);
|
||||||
}
|
}
|
||||||
|
|
@ -113,11 +115,11 @@ public class Site extends CcmObject {
|
||||||
protected void addApplication(final SiteAwareApplication application) {
|
protected void addApplication(final SiteAwareApplication application) {
|
||||||
applications.add(application);
|
applications.add(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeApplication(final SiteAwareApplication application) {
|
protected void removeApplication(final SiteAwareApplication application) {
|
||||||
applications.remove(application);
|
applications.remove(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 3;
|
int hash = 3;
|
||||||
|
|
@ -147,7 +149,7 @@ public class Site extends CcmObject {
|
||||||
if (!other.canEqual(this)) {
|
if (!other.canEqual(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultSite != other.isDefaultSite()) {
|
if (defaultSite != other.isDefaultSite()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -631,3 +631,5 @@ ui.admin.sites.domain_of_site=Domain of Site
|
||||||
ui.admin.sites.is_default_site=Is default site?
|
ui.admin.sites.is_default_site=Is default site?
|
||||||
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
||||||
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
||||||
|
ui.admin.sites.table.buttons.edit=Edit
|
||||||
|
ui.admin.sites.table.buttons.delete=Delete
|
||||||
|
|
|
||||||
|
|
@ -635,3 +635,5 @@ ui.admin.sites.domain_of_site=Domain der Site
|
||||||
ui.admin.sites.is_default_site=Ist Standard Site?
|
ui.admin.sites.is_default_site=Ist Standard Site?
|
||||||
ui.admin.sites.domain_of_site.error.not_unique=Die Domain der Site ist nicht eindeutig.
|
ui.admin.sites.domain_of_site.error.not_unique=Die Domain der Site ist nicht eindeutig.
|
||||||
ui.admin.sites.domain_of_site.error.empty=The Domain einer Site darf nicht leer sein.
|
ui.admin.sites.domain_of_site.error.empty=The Domain einer Site darf nicht leer sein.
|
||||||
|
ui.admin.sites.table.buttons.edit=Bearbeiten
|
||||||
|
ui.admin.sites.table.buttons.delete=L\u00f6schen
|
||||||
|
|
|
||||||
|
|
@ -628,3 +628,5 @@ ui.admin.sites.domain_of_site=Domain of Site
|
||||||
ui.admin.sites.is_default_site=Is default site?
|
ui.admin.sites.is_default_site=Is default site?
|
||||||
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
||||||
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
||||||
|
ui.admin.sites.table.buttons.edit=Edit
|
||||||
|
ui.admin.sites.table.buttons.delete=Delete
|
||||||
|
|
|
||||||
|
|
@ -619,3 +619,5 @@ ui.admin.sites.domain_of_site=Domain of Site
|
||||||
ui.admin.sites.is_default_site=Is default site?
|
ui.admin.sites.is_default_site=Is default site?
|
||||||
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
ui.admin.sites.domain_of_site.error.not_unique=The domain of the Site is not unique.
|
||||||
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
ui.admin.sites.domain_of_site.error.empty=The domain of a Site can't be empty.
|
||||||
|
ui.admin.sites.table.buttons.edit=Edit
|
||||||
|
ui.admin.sites.table.buttons.delete=Delete
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue