CCM NG: Some work on the Vaadin Prototype

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4982 8810af33-2d31-482b-a856-94f89814c4df

Former-commit-id: d8ec4573eb
pull/2/head
jensp 2017-09-03 17:47:12 +00:00
parent 5169fc7524
commit dab23efcd4
12 changed files with 657 additions and 39 deletions

View File

@ -205,12 +205,10 @@
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-themes</artifactId>
<!--<version>8.0.4</version>-->
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiled</artifactId>
<!--<version>8.0.4</version>-->
</dependency>
<dependency>
<groupId>com.vaadin</groupId>

View File

@ -95,6 +95,9 @@ public class AdminView extends CustomComponent implements View {
@Inject
private RolesTableDataProvider rolesTableDataProvider;
@Inject
private ConfigurationsTabController configurationsTabController;
private ResourceBundle bundle;
private final TabSheet tabSheet;
@ -104,6 +107,8 @@ public class AdminView extends CustomComponent implements View {
private final JpqlConsole jpqlConsole;
private final ConfigurationTab configurationTab;
public AdminView() {
tabSheet = new TabSheet();
@ -121,6 +126,9 @@ public class AdminView extends CustomComponent implements View {
} else {
jpqlConsole = null;
}
configurationTab = new ConfigurationTab();
tabSheet.addTab(configurationTab, "Configuration");
// final GridLayout header = new GridLayout(5, 1);
// header.setWidth("100%");
@ -183,6 +191,8 @@ public class AdminView extends CustomComponent implements View {
.getString("ui.admin.tab.users_groups_roles.title"));
usersGroupsRoles.localize();
configurationTab.init(configurationsTabController);
}
@Override
@ -191,9 +201,17 @@ public class AdminView extends CustomComponent implements View {
// usersGroupsRoles.setUsers(userRepo.findAll());
}
protected GlobalizationHelper getGlobalizationHelper() {
return globalizationHelper;
}
protected JpqlConsoleController getJpqlConsoleController() {
return jpqlConsoleController;
}
protected ConfigurationsTabController getConfigurationsTabController() {
return configurationsTabController;
}
public UserRepository getUserRepository() {
return userRepo;

View File

@ -0,0 +1,30 @@
/*
* 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;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ConfigurationSettingsGridRowData {
}

View File

@ -0,0 +1,266 @@
/*
* 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.data.provider.CallbackDataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.server.UserError;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import org.libreccm.configuration.ConfigurationInfo;
import org.libreccm.configuration.SettingInfo;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.LocalizedString;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class ConfigurationSettingsWindow extends Window {
private static final long serialVersionUID = 2706661932737914254L;
private final String COL_SETTING_LABEL = "setting_label";
private final String COL_SETTING_EDITOR = "setting_editor";
private final Class<?> configurationClass;
private final ConfigurationInfo configurationInfo;
private final ConfigurationTab configurationTab;
private Object configuration;
private final Button saveButton;
public ConfigurationSettingsWindow(final Class<?> configurationClass,
final ConfigurationInfo configurationInfo,
final ConfigurationTab configurationTab) {
super();
this.configurationClass = configurationClass;
this.configurationInfo = configurationInfo;
this.configurationTab = configurationTab;
final Locale locale = configurationTab
.getGlobalizationHelper()
.getNegotiatedLocale();
final Grid<SettingInfo> settingsGrid = new Grid<>(
new CallbackDataProvider<SettingInfo, String>(
query -> fetchSettingInfos(configurationClass,
configurationTab,
query),
query -> countSettings(configurationClass,
configurationTab,
query)));
settingsGrid
.addColumn(settingInfo -> settingInfo.getLabel(locale))
.setId(COL_SETTING_LABEL)
.setCaption("Setting");
settingsGrid
.addComponentColumn(settingInfo -> createSettingEditor(settingInfo))
.setId(COL_SETTING_EDITOR)
.setCaption("Edit");
settingsGrid.setWidth("100%");
super.setCaption(
String.format("Edit setting of configuration \"%s\"",
configurationInfo
.getTitle(locale,
configurationTab.getDefaultLocale())));
saveButton = new Button("Save");
saveButton.addClickListener(event -> {
configurationTab
.getConfigurationManager()
.saveConfiguration(configuration);
close();
});
saveButton.setEnabled(false);
final Button cancelButton = new Button("Cancel");
cancelButton.addClickListener(event -> close());
super.setContent(new VerticalLayout(
new HorizontalLayout(saveButton, cancelButton),
settingsGrid));
}
private Stream<SettingInfo> fetchSettingInfos(
final Class<?> configurationClass,
final ConfigurationTab configurationTab,
final Query<SettingInfo, String> query) {
final int fromIndex;
final int toIndex;
final int size = countSettings(configurationClass,
configurationTab,
query);
if (query.getOffset() > size - 1) {
fromIndex = size -1;
} else {
fromIndex = query.getOffset();
}
if (query.getOffset() + query.getLimit() > size) {
toIndex = size;
} else {
toIndex = query.getOffset() + query.getLimit();
}
return configurationTab
.getSettingManager()
.getAllSettings(configurationClass)
.subList(fromIndex, toIndex)
.stream()
.map(settingName -> {
return configurationTab
.getSettingManager()
.getSettingInfo(configurationClass, settingName);
});
}
private int countSettings(final Class<?> configurationClass,
final ConfigurationTab configurationTab,
final Query<SettingInfo, String> query) {
return configurationTab
.getSettingManager()
.getAllSettings(configurationClass)
.size();
}
private Component createSettingEditor(final SettingInfo settingInfo) {
final String type = settingInfo.getValueType();
final String name = settingInfo.getName();
if (Boolean.class.getName().equals(type)
|| Boolean.TYPE.getName().equals(type)) {
final CheckBox checkBox = new CheckBox();
checkBox.addValueChangeListener(event -> {
updateSettingValue(name, event.getValue());
});
return checkBox;
} else if (BigDecimal.class.getName().equals(type)) {
final TextField textField = new TextField();
textField.addValueChangeListener(event -> {
final String value = event.getValue();
if (value.matches("\\d*")) {
updateSettingValue(name, new BigDecimal(value));
} else {
textField.setComponentError(new UserError(
"The value is not numeric"));
}
});
return textField;
} else if (Double.class.getName().equals(type)
|| Double.TYPE.getName().equals(type)) {
final TextField textField = new TextField();
textField.addValueChangeListener(event -> {
try {
final Double value = Double.parseDouble(event.getValue());
updateSettingValue(name, value);
} catch (NumberFormatException ex) {
textField.setComponentError(new UserError(
"The value is not a double value."));
}
});
return textField;
} else if (Set.class.getName().equals(type)) {
return new Label("Not supported yet.");
} else if (LocalizedString.class.getName().equals(type)) {
return new Label("Not supported yet.");
} else if (Long.class.getName().equals(type)
|| Long.TYPE.getName().equals(type)) {
final TextField textField = new TextField();
textField.addValueChangeListener(event -> {
try {
final Long value = Long.parseLong(event.getValue());
updateSettingValue(name, value);
} catch (NumberFormatException ex) {
textField.setComponentError(new UserError(
"The value is not a double value."));
}
});
return textField;
} else if (List.class.getName().equals(type)) {
return new Label("Not supported yet.");
} else if (String.class.getName().equals(type)) {
final TextField textField = new TextField();
textField.addValueChangeListener(event -> {
updateSettingValue(name, event.getValue());
});
return textField;
} else {
return new Label("Unsupported value type");
}
}
private void updateSettingValue(final String settingName,
final Object value) {
if (configuration == null) {
//We can't do that in the constructor because this values are
//provided by CDI in other classes. Therefore they might be
//not available when the constructors runs.
configuration = configurationTab
.getConfigurationManager()
.findConfiguration(configurationClass);
saveButton.setEnabled(true);
}
try {
final Field field = configurationClass.getField(settingName);
field.setAccessible(true);
field.set(configuration, value);
} catch (IllegalAccessException | NoSuchFieldException ex) {
throw new UnexpectedErrorException(ex);
}
}
}

View File

@ -18,7 +18,16 @@
*/
package org.libreccm.admin.ui;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Grid;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.SettingManager;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.Locale;
/**
*
@ -27,12 +36,77 @@ import com.vaadin.ui.CustomComponent;
public class ConfigurationTab extends CustomComponent {
private static final long serialVersionUID = 7642627611731762410L;
public ConfigurationTab(final AdminView adminView) {
private static final String COL_CONF_TITLE = "title";
private static final String COL_CONF_CLASS = "configuration_class";
private static final String COL_CONF_DESC = "description";
private ConfigurationsTabController controller;
private final Grid<ConfigurationsGridRowData> configurationsGrid;
public ConfigurationTab() {
super();
configurationsGrid = new Grid<>();
configurationsGrid.addComponentColumn(rowData -> {
final Button button = new Button(
rowData.getTitle(),
event -> {
final ConfigurationSettingsWindow window
= new ConfigurationSettingsWindow(
rowData.getConfigurationClass(),
rowData.getConfigurationInfo(),
this);
window.setWidth("70%");
window.center();
UI.getCurrent().addWindow(window);
});
button.setStyleName(ValoTheme.BUTTON_LINK);
return button;
})
.setId(COL_CONF_TITLE);
configurationsGrid.addColumn(
ConfigurationsGridRowData::getName)
.setId(COL_CONF_CLASS)
.setCaption("Configuration class");
configurationsGrid.addColumn(
ConfigurationsGridRowData::getDescription)
.setCaption(COL_CONF_DESC)
.setCaption("Description");
configurationsGrid.setWidth("100%");
super.setCompositionRoot(configurationsGrid);
}
protected void init(final ConfigurationsTabController controller) {
this.controller = controller;
configurationsGrid
.setDataProvider(controller.getConfigurationsTableDataProvider());
}
protected GlobalizationHelper getGlobalizationHelper() {
return controller.getGlobalizationHelper();
}
protected Locale getDefaultLocale() {
return controller.getDefaultLocale();
}
protected ConfigurationManager getConfigurationManager() {
return controller.getConfigurationManager();
}
protected SettingManager getSettingManager() {
return controller.getSettingManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.admin.ui;
import org.libreccm.configuration.ConfigurationInfo;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class ConfigurationsGridRowData {
private Class<?> configurationClass;
private ConfigurationInfo configurationInfo;
private String name;
private String title;
private String description;
public ConfigurationsGridRowData() {
}
public Class<?> getConfigurationClass() {
return configurationClass;
}
public void setConfigurationClass(
Class<?> configurationClass) {
this.configurationClass = configurationClass;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(final String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public ConfigurationInfo getConfigurationInfo() {
return configurationInfo;
}
public void setConfigurationInfo(final ConfigurationInfo configurationInfo) {
this.configurationInfo = configurationInfo;
}
}

View File

@ -18,15 +18,59 @@
*/
package org.libreccm.admin.ui;
import com.arsdigita.kernel.KernelConfig;
import com.vaadin.cdi.ViewScoped;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.SettingManager;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.Locale;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class ConfigurationsTabController {
class ConfigurationsTabController {
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private ConfigurationManager confManager;
@Inject
private ConfigurationsTableDataProvider configurationsTableDataProvider;
@Inject
private ConfigurationManager configurationManager;
@Inject
private SettingManager settingManager;
protected GlobalizationHelper getGlobalizationHelper() {
return globalizationHelper;
}
protected Locale getDefaultLocale() {
return confManager
.findConfiguration(KernelConfig.class)
.getDefaultLocale();
}
protected ConfigurationsTableDataProvider getConfigurationsTableDataProvider() {
return configurationsTableDataProvider;
}
protected ConfigurationManager getConfigurationManager() {
return configurationManager;
}
protected SettingManager getSettingManager() {
return settingManager;
}
}

View File

@ -18,6 +18,8 @@
*/
package org.libreccm.admin.ui;
import com.arsdigita.kernel.KernelConfig;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractDataProvider;
import com.vaadin.data.provider.Query;
@ -25,7 +27,7 @@ import org.libreccm.configuration.ConfigurationInfo;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.SortedSet;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -36,7 +38,7 @@ import javax.inject.Inject;
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ViewScoped
public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<?>, String> {
class ConfigurationsTableDataProvider extends AbstractDataProvider<ConfigurationsGridRowData, String> {
private static final long serialVersionUID = -7001151229931864885L;
@ -54,7 +56,12 @@ public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<
}
@Override
public int size(final Query<Class<?>, String> query) {
public int size(final Query<ConfigurationsGridRowData, String> query) {
final Locale defaultLocale = confManager
.findConfiguration(KernelConfig.class)
.getDefaultLocale();
if (filter == null || filter.trim().isEmpty()) {
return confManager.findAllConfigurations().size();
} else {
@ -64,14 +71,13 @@ public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<
.filter(conf -> {
final ConfigurationInfo info = confManager
.getConfigurationInfo(conf);
// return c.getName().startsWith(filterTerm);
if (filter == null || filter.isEmpty()) {
return true;
} else {
return info
.getTitle(globalizationHelper.getNegotiatedLocale())
.startsWith(
filter);
.getTitle(globalizationHelper.getNegotiatedLocale(),
defaultLocale)
.startsWith(filter);
}
})
.count();
@ -79,28 +85,62 @@ public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<
}
@Override
public Stream<Class<?>> fetch(final Query<Class<?>, String> query) {
public Stream<ConfigurationsGridRowData> fetch(
final Query<ConfigurationsGridRowData, String> query) {
final int fromIndex;
final int toIndex;
final int size = size(query);
if (query.getOffset() > size - 1) {
fromIndex = size - 1;
} else {
fromIndex = query.getOffset();
}
if ((query.getOffset() + query.getLimit()) > size) {
toIndex = size;
} else {
toIndex = query.getOffset() + query.getLimit();
}
if (filter == null || filter.trim().isEmpty()) {
return confManager.findAllConfigurations().stream();
return confManager
.findAllConfigurations()
.stream()
.map(configurationClass -> createRowData(configurationClass))
.sorted((rowData1, rowData2) -> {
return rowData1
.getConfigurationClass()
.getSimpleName()
.compareTo(rowData2.getConfigurationClass()
.getSimpleName());
})
.collect(Collectors.toList())
.subList(fromIndex, toIndex)
.stream();
} else {
return confManager
.findAllConfigurations()
.stream()
.filter(conf -> {
final ConfigurationInfo info = confManager
.getConfigurationInfo(conf);
// return c.getName().startsWith(filterTerm);
.map(configurationClass -> createRowData(configurationClass))
.filter(rowData -> {
if (filter == null || filter.isEmpty()) {
return true;
} else {
return info
.getTitle(globalizationHelper.getNegotiatedLocale())
.startsWith(
filter);
return rowData
.getTitle()
.startsWith(filter);
}
})
.sorted((rowData1, rowData2) -> {
return rowData1
.getConfigurationClass()
.getSimpleName()
.compareTo(rowData2.getConfigurationClass()
.getSimpleName());
})
.collect(Collectors.toList())
.subList(query.getOffset(), query.getOffset() + query.getLimit())
.subList(fromIndex, toIndex)
.stream();
}
}
@ -109,4 +149,29 @@ public class ConfigurationsTableDataProvider extends AbstractDataProvider<Class<
this.filter = filter;
}
private ConfigurationsGridRowData createRowData(
final Class<?> configurationClass) {
final ConfigurationInfo info = confManager
.getConfigurationInfo(configurationClass);
final Locale defaultLocale = confManager
.findConfiguration(KernelConfig.class)
.getDefaultLocale();
final ConfigurationsGridRowData rowData
= new ConfigurationsGridRowData();
rowData.setConfigurationClass(configurationClass);
rowData.setName(info.getName());
rowData.setTitle(info
.getTitle(globalizationHelper.getNegotiatedLocale(),
defaultLocale));
rowData.setDescription(info
.getDescription(globalizationHelper.getNegotiatedLocale()));
rowData.setConfigurationInfo(info);
return rowData;
}
}

View File

@ -33,7 +33,6 @@ import com.vaadin.ui.components.grid.HeaderCell;
import com.vaadin.ui.components.grid.HeaderRow;
import com.vaadin.ui.renderers.ButtonRenderer;
import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.admin.ui.AdminView;
import org.libreccm.security.Role;
import org.libreccm.security.RoleRepository;
@ -226,10 +225,7 @@ public class RolesTable extends Grid<Role> {
final VerticalLayout layout = new VerticalLayout(text, buttons);
// final Panel panel = new Panel(
// bundle.getString("ui.admin.groups.delete.confirm.title"),
// layout);
setContent(layout);
super.setContent(layout);
}
private void deleteRole() {

View File

@ -115,6 +115,40 @@ public final class ConfigurationInfo {
this.descKey = descKey;
}
public String getTitle(final Locale locale,
final Locale fallback) {
final ResourceBundle bundle = getDescriptionBundle(locale);
if (bundle == null) {
return name;
} else {
try {
return bundle.getString(titleKey);
} catch (MissingResourceException ex) {
LOGGER.warn("Can't find resource for bundle '{}', "
+ "key '{}' and locale '{}'.",
descBundle,
titleKey,
locale);
if (fallback == null) {
return name;
} else {
return getTitle(fallback, null);
}
}
}
}
/**
*
* @param locale
*
* @return
*
* @deprecated Use {@link #getTitle(java.util.Locale, java.util.Locale)}
* instead.
*/
@Deprecated()
public String getTitle(final Locale locale) {
final ResourceBundle bundle = getDescriptionBundle(locale);

View File

@ -1081,7 +1081,7 @@
*/
.v-vaadin-version:after {
content: "8.1.1";
content: "8.1.3";
}
.v-widget {
@ -3072,6 +3072,10 @@ select:focus {
pointer-events: none;
}
.v-filterselect .v-icon.FontAwesome {
margin-left: 0px;
}
.v-filterselect-error .v-filterselect-input {
border-color: #ed473b !important;
background: #fffbfb;

16
pom.xml
View File

@ -255,7 +255,7 @@
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>8.1.1</version>
<version>8.1.3</version>
</plugin>
</plugins>
</pluginManagement>
@ -401,7 +401,15 @@
</dependency>
<!-- Vaadin dependencies for Vaadin prototype -->
<!-- Vaadin dependencies -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>8.1.3</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!--<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-cdi</artifactId>
<version>2.0.0</version>
@ -409,13 +417,13 @@
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiled</artifactId>
<version>8.1.1</version>
<version>8.1.2</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-themes</artifactId>
<version>8.1.1</version>
</dependency>
<version>8.1.2</version>
</dependency>-->
<!--
*********************