diff --git a/checkstyle.xml b/checkstyle.xml index 2e94cee8..b4ac18a1 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -96,7 +96,7 @@ - + diff --git a/forms/pom.xml b/forms/pom.xml index ebbbd2e6..5548dc25 100644 --- a/forms/pom.xml +++ b/forms/pom.xml @@ -30,15 +30,15 @@ UTF-8 1.8 - 8.6.1 - 8.6.0 - 2.0.10 + 8.8.0 + 8.7.0 + 2.0.11 1.13 - 2.0.15 - v20190528 + 2.0.17 + v20200406 3.1 2.4.8 - 1.80.0 + 1.82.0 @@ -66,21 +66,21 @@ 0.0.1-SNAPSHOT - - org.devgateway.toolkit - reporting - 0.0.1-SNAPSHOT - - - bcprov-jdk14 - bouncycastle - - - bcprov-jdk14 - org.bouncycastle - - - + + + + + + + + + + + + + + + org.devgateway.toolkit @@ -120,17 +120,6 @@ - - org.springframework.boot - spring-boot-starter-integration - - - xercesImpl - xerces - - - - org.springframework.boot spring-boot-starter-web @@ -152,11 +141,6 @@ spring-boot-starter-security - - org.springframework.data - spring-data-rest-hal-browser - - org.springframework.boot spring-boot-starter-test @@ -292,6 +276,7 @@ **/*.css **/*.js **/*.png + **/*.svg **/*.gif **/*.html **/*.properties @@ -397,10 +382,6 @@ derby ${derby.version} - - org.hibernate - hibernate-ehcache - org.hibernate hibernate-entitymanager diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/FormsSecurityConfig.java b/forms/src/main/java/org/devgateway/toolkit/forms/FormsSecurityConfig.java index abad38dc..789cca44 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/FormsSecurityConfig.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/FormsSecurityConfig.java @@ -48,7 +48,7 @@ public void configure(final WebSecurity web) throws Exception { web.ignoring().antMatchers("/img/**", "/css*/**", "/js*/**", "/assets*/**", "/wicket/resource/**/*.js", "/wicket/resource/**/*.css", "/wicket/resource/**/*.png", "/wicket/resource/**/*.jpg", "/wicket/resource/**/*.woff", "/wicket/resource/**/*.woff2", "/wicket/resource/**/*.ttf", - "/favicon.ico", + "/favicon.ico", "/wicket/resource/**/*.svg", "/wicket/resource/**/*.gif", "/login/**", "/forgotPassword/**", "/resources/**", "/resources/public/**"); } diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/WebConstants.java b/forms/src/main/java/org/devgateway/toolkit/forms/WebConstants.java index 40112e28..9dee3c26 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/WebConstants.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/WebConstants.java @@ -30,7 +30,14 @@ private WebConstants() { public static final String PARAM_VIEW_MODE = "viewMode"; + public static final String DISABLE_FORM_LEAVING_JS + = "if(typeof disableFormLeavingConfirmation === 'function') disableFormLeavingConfirmation();"; + + public static final String PARAM_PRINT = "print"; + public static final String PARAM_ID = "id"; + public static final String V_POSITION = "vPosition"; + public static final String MAX_HEIGHT = "maxPosition"; public static final String PARAM_REVISION_ID = "revisionId"; public static final String PARAM_ENTITY_CLASS = "class"; diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/security/SecurityConstants.java b/forms/src/main/java/org/devgateway/toolkit/forms/security/SecurityConstants.java index 3acaedc6..220de14d 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/security/SecurityConstants.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/security/SecurityConstants.java @@ -23,5 +23,11 @@ public final class SecurityConstants { public static final class Roles { public static final String ROLE_ADMIN = "ROLE_ADMIN"; public static final String ROLE_USER = "ROLE_USER"; + public static final String ROLE_VALIDATOR = "ROLE_VALIDATOR"; + } + + public static final class Action { + public static final String EDIT = "EDIT"; + public static final String VIEW = "VIEW"; } } diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/util/MarkupCacheService.java b/forms/src/main/java/org/devgateway/toolkit/forms/util/MarkupCacheService.java index c72b584e..0d668aa8 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/util/MarkupCacheService.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/util/MarkupCacheService.java @@ -11,13 +11,14 @@ *******************************************************************************/ package org.devgateway.toolkit.forms.util; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Element; + import org.apache.wicket.markup.Markup; import org.apache.wicket.markup.MarkupCache; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.cache.Cache; +import javax.cache.CacheManager; import java.util.Collection; /** @@ -30,6 +31,10 @@ */ @Component public class MarkupCacheService { + + @Autowired + private CacheManager cm; + /** * start-key used to identify the reports markup */ @@ -61,12 +66,11 @@ public final void flushMarkupCache() { */ public void addPentahoReportToCache(final String outputType, final String reportName, final String parameters, final byte[] buffer) { - final CacheManager cm = CacheManager.getInstance(); // get the reports cache "reportsCache", declared in ehcache.xml - final Cache cache = cm.getCache("reportsCache"); + final Cache cache = cm.getCache("reportsCache", String.class, byte[].class); - cache.put(new Element(createCacheKey(outputType, reportName, parameters), buffer)); + cache.put(createCacheKey(outputType, reportName, parameters), buffer); } /** @@ -78,15 +82,14 @@ public void addPentahoReportToCache(final String outputType, final String report * @return */ public byte[] getPentahoReportFromCache(final String outputType, final String reportName, final String parameters) { - final CacheManager cm = CacheManager.getInstance(); // get the reports cache "reportsCache", declared in ehcache.xml - final Cache cache = cm.getCache("reportsCache"); + final Cache cache = cm.getCache("reportsCache", String.class, byte[].class); final String key = createCacheKey(outputType, reportName, parameters); - if (cache.isKeyInCache(key)) { - return (byte[]) cache.get(key).getObjectValue(); + if (cache.containsKey(key)) { + return cache.get(key); } return null; @@ -96,10 +99,9 @@ public byte[] getPentahoReportFromCache(final String outputType, final String re * Remove from cache all reports content */ public void clearPentahoReportsCache() { - final CacheManager cm = CacheManager.getInstance(); // get the reports cache "reportsCache", declared in ehcache.xml - final Cache cache = cm.getCache("reportsCache"); + final Cache cache = cm.getCache("reportsCache"); if (cache != null) { cache.removeAll(); @@ -110,16 +112,15 @@ public void clearPentahoReportsCache() { * Remove from cache all APIs/Services content. */ public void clearAllCaches() { - final CacheManager cm = CacheManager.getInstance(); // get the reports cache "reportsApiCache", declared in ehcache.xml - final Cache cache = cm.getCache("reportsApiCache"); + final Cache cache = cm.getCache("reportsApiCache"); if (cache != null) { cache.removeAll(); } // get the reports cache "excelExportCache", declared in ehcache.xml - final Cache excelExportCache = cm.getCache("excelExportCache"); + final Cache excelExportCache = cm.getCache("excelExportCache"); if (excelExportCache != null) { excelExportCache.removeAll(); } diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/form/OptionallyRequiredTextAreaFieldComponent.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/form/OptionallyRequiredTextAreaFieldComponent.java new file mode 100644 index 00000000..4b629141 --- /dev/null +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/form/OptionallyRequiredTextAreaFieldComponent.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2015 Development Gateway, Inc and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the MIT License (MIT) + * which accompanies this distribution, and is available at + * https://opensource.org/licenses/MIT + * + * Contributors: + * Development Gateway - initial API and implementation + */ +/** + * + */ +package org.devgateway.toolkit.forms.wicket.components.form; + +import org.apache.wicket.markup.html.form.TextArea; +import org.apache.wicket.model.IModel; +import org.apache.wicket.validation.validator.StringValidator; +import org.devgateway.toolkit.forms.WebConstants; + +/** + * @author mpostelnicu + * + * A {@link TextAreaFieldBootstrapFormComponent} that has TextArea{@link #isRequired()} exposed + * + */ +public abstract class OptionallyRequiredTextAreaFieldComponent extends TextAreaFieldBootstrapFormComponent { + private StringValidator validator = WebConstants.StringValidators.MAXIMUM_LENGTH_VALIDATOR_ONE_LINE_TEXTAREA; + + private static final long serialVersionUID = 1L; + + public OptionallyRequiredTextAreaFieldComponent(final String id, final IModel labelModel, + final IModel model) { + super(id, labelModel, model); + } + + public OptionallyRequiredTextAreaFieldComponent(final String id, final IModel labelModel) { + super(id, labelModel, null); + } + + /** + * @param id + */ + public OptionallyRequiredTextAreaFieldComponent(final String id) { + super(id); + } + + public boolean isRequired() { + return false; + } + + @Override + protected TextArea inputField(final String id, final IModel model) { + TextArea textArea = new TextArea(id, initFieldModel()) { + @Override + public boolean isRequired() { + return OptionallyRequiredTextAreaFieldComponent.this.isRequired(); + } + }; + return textArea; + } + +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java index 6b2b957b..c34709b5 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java @@ -1,12 +1,15 @@ package org.devgateway.toolkit.forms.wicket.components.table; -import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.ChoiceFilteredPropertyColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm; import org.apache.wicket.model.IModel; import org.devgateway.toolkit.forms.wicket.components.form.Select2ChoiceBootstrapFormComponent; import org.devgateway.toolkit.forms.wicket.providers.GenericChoiceProvider; +import org.wicketstuff.select2.ChoiceProvider; import java.util.List; @@ -17,28 +20,92 @@ * @since 12/20/16 */ public class SelectFilteredBootstrapPropertyColumn extends ChoiceFilteredPropertyColumn { + private DataTable dataTable; + private boolean disableFilter = false; + private ChoiceProvider choiceProvider; public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, final S sortProperty, final String propertyExpression, - final IModel extends List extends Y>> filterChoices) { - super(displayModel, sortProperty, propertyExpression, filterChoices); + final ChoiceProvider choiceProvider, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, choiceProvider, dataTable, false); + } + + public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, filterChoices, dataTable, false); } public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, null); + this.disableFilter = disableFilter; + this.dataTable = dataTable; + this.choiceProvider = choiceProvider; + } + + + public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, final String propertyExpression, - final IModel extends List extends Y>> filterChoices) { - super(displayModel, propertyExpression, filterChoices); + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, filterChoices); + this.disableFilter = disableFilter; + this.dataTable = dataTable; } @Override public Component getFilter(final String componentId, final FilterForm> form) { + ChoiceProvider provider; + + if (choiceProvider != null) { + provider = choiceProvider; + } else { + provider = new GenericChoiceProvider<>((List) getFilterChoices().getObject()); + } final Select2ChoiceBootstrapFormComponent selectorField = - new Select2ChoiceBootstrapFormComponent<>(componentId, - new GenericChoiceProvider<>((List) getFilterChoices().getObject()), - getFilterModel(form)); + new Select2ChoiceBootstrapFormComponent<>(componentId, provider, getFilterModel(form)); selectorField.hideLabel(); - selectorField.getField().add(AttributeModifier.replace("onchange", "this.form.submit();")); + if (disableFilter) { + selectorField.setEnabled(false); + } + + selectorField.getField().add(new AjaxComponentUpdatingBehavior(form, "change")); + return selectorField; } + + private class AjaxComponentUpdatingBehavior extends AjaxFormComponentUpdatingBehavior { + private final FilterForm> form; + + AjaxComponentUpdatingBehavior(final FilterForm> form, final String event) { + super(event); + this.form = form; + } + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + // update the table component + dataTable.setCurrentPage(0); + target.add(dataTable); + } + } + + @Override + public void detach() { + super.detach(); + if (choiceProvider != null) { + choiceProvider.detach(); + } + } } diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java new file mode 100644 index 00000000..f3ac7afb --- /dev/null +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java @@ -0,0 +1,104 @@ +package org.devgateway.toolkit.forms.wicket.components.table; + +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; +import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.ChoiceFilteredPropertyColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm; +import org.apache.wicket.model.IModel; +import org.devgateway.toolkit.forms.wicket.components.form.Select2MultiChoiceBootstrapFormComponent; +import org.devgateway.toolkit.forms.wicket.providers.GenericChoiceProvider; +import org.wicketstuff.select2.ChoiceProvider; + +import java.util.Collection; +import java.util.List; + +/** + * @author idobre + * @since 2019-03-11 + * + * A ChoiceFilteredPropertyColumn that uses Select2MultiChoiceBootstrapFormComponent as a filter. + */ +public class SelectMultiFilteredBootstrapPropertyColumn extends ChoiceFilteredPropertyColumn { + private final DataTable dataTable; + private boolean disableFilter = false; + private ChoiceProvider choiceProvider; + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, choiceProvider, dataTable, false); + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, null); + this.disableFilter = disableFilter; + this.dataTable = dataTable; + this.choiceProvider = choiceProvider; + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + super(displayModel, sortProperty, propertyExpression, filterChoices); + + this.dataTable = dataTable; + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + super(displayModel, propertyExpression, filterChoices); + + this.dataTable = dataTable; + } + + @Override + public Component getFilter(final String componentId, final FilterForm> form) { + ChoiceProvider provider; + + if (choiceProvider != null) { + provider = choiceProvider; + } else { + provider = new GenericChoiceProvider<>((List) getFilterChoices().getObject()); + } + + + final Select2MultiChoiceBootstrapFormComponent selectorField = + new Select2MultiChoiceBootstrapFormComponent<>(componentId, + provider, + (IModel>) getFilterModel(form)); + selectorField.hideLabel(); + + selectorField.getField().add(new AjaxComponentUpdatingBehavior(form, "change")); + + return selectorField; + } + + private class AjaxComponentUpdatingBehavior extends AjaxFormComponentUpdatingBehavior { + private final FilterForm> form; + + AjaxComponentUpdatingBehavior(final FilterForm> form, final String event) { + super(event); + this.form = form; + } + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + // update the table component + dataTable.setCurrentPage(0); + target.add(dataTable); + } + } +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java index 4159bdfe..48640689 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java @@ -28,6 +28,9 @@ import org.devgateway.toolkit.persistence.service.TextSearchableService; import java.io.Serializable; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; /** * @author idobre @@ -49,6 +52,21 @@ public static boolean isViewMode() { .toBoolean(false); } + /** + * Returns true if the {@link WebConstants#PARAM_PRINT} is used as a parameter + * + * @return + */ + public static boolean isPrintMode() { + return RequestCycle.get().getRequest().getRequestParameters().getParameterValue(WebConstants.PARAM_PRINT) + .toBoolean(false); + } + + public static Date getDateFromLocalDate(final LocalDate localDate) { + return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } + + public static void enableDisableEvent(final Component c, final IEvent> event) { if (event.getPayload() instanceof EditingDisabledEvent) { c.setEnabled(false); diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java new file mode 100644 index 00000000..e2122a67 --- /dev/null +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java @@ -0,0 +1,93 @@ +package org.devgateway.toolkit.forms.wicket.components.util; + +import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; +import org.devgateway.toolkit.persistence.dao.Person; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import static org.devgateway.toolkit.forms.security.SecurityConstants.Roles.ROLE_ADMIN; + +public class FormSecurityUtil { + + protected FormSecurityUtil() { + } + + + public static boolean rolesContainsAny(final Collection roleSet, final String... roles) { + for (final String role : roles) { + if (roleSet.contains(role)) { + return true; + } + } + return false; + } + + public static boolean rolesContainsAny(final String... roles) { + return rolesContainsAny(Objects.requireNonNull(getStringRolesForCurrentPerson()), roles); + } + + public static boolean rolesContainsAll(final Collection roleSet, final String... roles) { + return roleSet.containsAll(Arrays.asList(roles)); + } + + public static boolean rolesContainsAll(final String... roles) { + return rolesContainsAll(Objects.requireNonNull(getStringRolesForCurrentPerson()), roles); + } + + /** + * returns the principal object. In our case the principal should be + * {@link Person} + * + * @return the principal or null + * @see Principal + */ + public static Person getCurrentAuthenticatedPerson() { + if (SecurityContextHolder.getContext().getAuthentication() == null) { + return null; + } + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return null; + } + final Object principal = authentication.getPrincipal(); + if (principal instanceof Person) { + return (Person) principal; + } + return null; + } + + public static Set getStringRolesForCurrentPerson() { + if (!AbstractAuthenticatedWebSession.get().isSignedIn()) { + return Collections.emptySet(); + } + return AbstractAuthenticatedWebSession.get().getRoles(); + } + + public static boolean hasAnyUserRoles(String... roles) { + List rList = Arrays.asList(roles); + return getStringRolesForCurrentPerson().stream().anyMatch(rList::contains); + } + + public static boolean hasUserRole(String role) { + return hasAnyUserRoles(role); + } + + public static boolean isCurrentUserAdmin() { + return hasUserRole(ROLE_ADMIN); + } + + public static boolean isCurrentRoleOnlyUser(String userRole, String validatorRole) { + if (hasAnyUserRoles(ROLE_ADMIN, validatorRole)) { + return false; + } + return hasUserRole(userRole); + } +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java index b81f4942..c24f0f93 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java @@ -33,6 +33,7 @@ import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.markup.head.MetaDataHeaderItem; import org.apache.wicket.markup.head.filter.HeaderResponseContainer; import org.apache.wicket.markup.html.GenericWebPage; import org.apache.wicket.markup.html.TransparentWebMarkupContainer; @@ -46,6 +47,7 @@ import org.apache.wicket.protocol.http.WebSession; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.JavaScriptResourceReference; +import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.resource.JQueryResourceReference; import org.apache.wicket.util.string.StringValue; import org.devgateway.toolkit.forms.WebConstants; @@ -94,24 +96,6 @@ public Boolean fluidContainer() { return false; } - public static class HALRedirectPage extends RedirectPage { - private static final long serialVersionUID = -750983217518258464L; - - public HALRedirectPage() { - super(WebApplication.get().getServletContext().getContextPath() + "/api/browser/"); - } - - } - - public static class JminixRedirectPage extends RedirectPage { - private static final long serialVersionUID = -750983217518258464L; - - public JminixRedirectPage() { - super(WebApplication.get().getServletContext().getContextPath() + "/jminix/"); - } - - } - public static class UIRedirectPage extends RedirectPage { private static final long serialVersionUID = -750983217518258464L; @@ -213,6 +197,16 @@ protected List newSubMenuButtons(final String buttonMarkupId) { return languageDropDown; } + protected MetaDataHeaderItem getFavicon() { + PackageResourceReference faviconRef = + new PackageResourceReference(BaseStyles.class, "assets/img/icons/toolkit-favicon.svg"); + MetaDataHeaderItem icon = MetaDataHeaderItem.forLinkTag("icon", + urlFor(faviconRef, null).toString()); + icon.addTagAttribute("type", "image/svg+xml"); + return icon; + + } + protected NavbarButton newLogoutMenu() { // logout menu final NavbarButton logoutMenu = @@ -288,24 +282,6 @@ JavamelodyPage.class, new StringResourceModel("navbar.javamelody", new StringResourceModel("navbar.springendpoints", this, null)) .setIconType(FontAwesomeIconType.anchor)); - list.add(new MenuBookmarkablePageLink(JminixRedirectPage.class, null, - new StringResourceModel("navbar.jminix", this, null)).setIconType(FontAwesomeIconType.bug)); - - final MenuBookmarkablePageLink halBrowserLink = - new MenuBookmarkablePageLink(HALRedirectPage.class, null, - new StringResourceModel("navbar.halbrowser", this, null)) { - private static final long serialVersionUID = 1L; - - @Override - protected void onComponentTag(final ComponentTag tag) { - super.onComponentTag(tag); - tag.put("target", "_blank"); - } - }; - halBrowserLink.setIconType(FontAwesomeIconType.rss).setEnabled(true); - - list.add(halBrowserLink); - final MenuBookmarkablePageLink uiBrowserLink = new MenuBookmarkablePageLink( UIRedirectPage.class, null, new StringResourceModel("navbar.ui", this, null)) { @@ -331,7 +307,7 @@ protected void onComponentTag(final ComponentTag tag) { }; adminMenu.setIconType(FontAwesomeIconType.cog); - MetaDataRoleAuthorizationStrategy.authorize(adminMenu, Component.RENDER, SecurityConstants.Roles.ROLE_ADMIN); + MetaDataRoleAuthorizationStrategy.authorize(adminMenu, Component.RENDER, SecurityConstants.Roles.ROLE_USER); return adminMenu; } @@ -352,6 +328,8 @@ protected Navbar newNavbar(final String markupId) { * @see org.devgateway.toolkit.forms.wicket.styles.BaseStyles */ navbar.setPosition(Navbar.Position.TOP); + navbar.setBrandImage(new PackageResourceReference(BaseStyles.class, "assets/img/toolkit-logo-0048.png"), + new StringResourceModel("brandImageAltText", this, null)); navbar.setInverted(true); navbar.addComponents(NavbarComponents.transform(Navbar.ComponentPosition.RIGHT, newHomeMenu(), newAdminMenu(), @@ -366,10 +344,13 @@ protected Navbar newNavbar(final String markupId) { public void renderHead(final IHeaderResponse response) { super.renderHead(response); + //favicon + response.render(getFavicon()); + // Load Styles. - response.render(CssHeaderItem.forReference(BaseStyles.INSTANCE)); response.render(CssHeaderItem.forReference(BootstrapCssReference.instance())); response.render(CssHeaderItem.forReference(FontAwesomeCssReference.instance())); + response.render(CssHeaderItem.forReference(BaseStyles.INSTANCE)); // Load Scripts. response.render(RespondJavaScriptReference.headerItem()); diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties index 084d268d..5651c713 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties @@ -20,8 +20,8 @@ navbar.ui=React UI navbar.adminSettings=Settings navbar.springendpoints=Spring Endpoints navbar.lang=Language -navbar.jminix=JMX Console navbar.javamelody=Javamelody +brandImageAltText=DG-Toolkit fileUnit.B=B fileUnit.KB=KB diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html index 8585bf67..bd60a80b 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html @@ -13,7 +13,10 @@ + + +
+ * All rights reserved. This program and the accompanying materials + * are made available under the terms of the MIT License (MIT) + * which accompanies this distribution, and is available at + * https://opensource.org/licenses/MIT + *
+ * Contributors: + * Development Gateway - initial API and implementation + */ +/** + * + */ +package org.devgateway.toolkit.forms.wicket.components.form; + +import org.apache.wicket.markup.html.form.TextArea; +import org.apache.wicket.model.IModel; +import org.apache.wicket.validation.validator.StringValidator; +import org.devgateway.toolkit.forms.WebConstants; + +/** + * @author mpostelnicu + * + * A {@link TextAreaFieldBootstrapFormComponent} that has TextArea{@link #isRequired()} exposed + * + */ +public abstract class OptionallyRequiredTextAreaFieldComponent extends TextAreaFieldBootstrapFormComponent { + private StringValidator validator = WebConstants.StringValidators.MAXIMUM_LENGTH_VALIDATOR_ONE_LINE_TEXTAREA; + + private static final long serialVersionUID = 1L; + + public OptionallyRequiredTextAreaFieldComponent(final String id, final IModel labelModel, + final IModel model) { + super(id, labelModel, model); + } + + public OptionallyRequiredTextAreaFieldComponent(final String id, final IModel labelModel) { + super(id, labelModel, null); + } + + /** + * @param id + */ + public OptionallyRequiredTextAreaFieldComponent(final String id) { + super(id); + } + + public boolean isRequired() { + return false; + } + + @Override + protected TextArea inputField(final String id, final IModel model) { + TextArea textArea = new TextArea(id, initFieldModel()) { + @Override + public boolean isRequired() { + return OptionallyRequiredTextAreaFieldComponent.this.isRequired(); + } + }; + return textArea; + } + +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java index 6b2b957b..c34709b5 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectFilteredBootstrapPropertyColumn.java @@ -1,12 +1,15 @@ package org.devgateway.toolkit.forms.wicket.components.table; -import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.ChoiceFilteredPropertyColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm; import org.apache.wicket.model.IModel; import org.devgateway.toolkit.forms.wicket.components.form.Select2ChoiceBootstrapFormComponent; import org.devgateway.toolkit.forms.wicket.providers.GenericChoiceProvider; +import org.wicketstuff.select2.ChoiceProvider; import java.util.List; @@ -17,28 +20,92 @@ * @since 12/20/16 */ public class SelectFilteredBootstrapPropertyColumn extends ChoiceFilteredPropertyColumn { + private DataTable dataTable; + private boolean disableFilter = false; + private ChoiceProvider choiceProvider; public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, final S sortProperty, final String propertyExpression, - final IModel extends List extends Y>> filterChoices) { - super(displayModel, sortProperty, propertyExpression, filterChoices); + final ChoiceProvider choiceProvider, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, choiceProvider, dataTable, false); + } + + public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, filterChoices, dataTable, false); } public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, null); + this.disableFilter = disableFilter; + this.dataTable = dataTable; + this.choiceProvider = choiceProvider; + } + + + public SelectFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, final String propertyExpression, - final IModel extends List extends Y>> filterChoices) { - super(displayModel, propertyExpression, filterChoices); + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, filterChoices); + this.disableFilter = disableFilter; + this.dataTable = dataTable; } @Override public Component getFilter(final String componentId, final FilterForm> form) { + ChoiceProvider provider; + + if (choiceProvider != null) { + provider = choiceProvider; + } else { + provider = new GenericChoiceProvider<>((List) getFilterChoices().getObject()); + } final Select2ChoiceBootstrapFormComponent selectorField = - new Select2ChoiceBootstrapFormComponent<>(componentId, - new GenericChoiceProvider<>((List) getFilterChoices().getObject()), - getFilterModel(form)); + new Select2ChoiceBootstrapFormComponent<>(componentId, provider, getFilterModel(form)); selectorField.hideLabel(); - selectorField.getField().add(AttributeModifier.replace("onchange", "this.form.submit();")); + if (disableFilter) { + selectorField.setEnabled(false); + } + + selectorField.getField().add(new AjaxComponentUpdatingBehavior(form, "change")); + return selectorField; } + + private class AjaxComponentUpdatingBehavior extends AjaxFormComponentUpdatingBehavior { + private final FilterForm> form; + + AjaxComponentUpdatingBehavior(final FilterForm> form, final String event) { + super(event); + this.form = form; + } + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + // update the table component + dataTable.setCurrentPage(0); + target.add(dataTable); + } + } + + @Override + public void detach() { + super.detach(); + if (choiceProvider != null) { + choiceProvider.detach(); + } + } } diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java new file mode 100644 index 00000000..f3ac7afb --- /dev/null +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/table/SelectMultiFilteredBootstrapPropertyColumn.java @@ -0,0 +1,104 @@ +package org.devgateway.toolkit.forms.wicket.components.table; + +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; +import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.ChoiceFilteredPropertyColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm; +import org.apache.wicket.model.IModel; +import org.devgateway.toolkit.forms.wicket.components.form.Select2MultiChoiceBootstrapFormComponent; +import org.devgateway.toolkit.forms.wicket.providers.GenericChoiceProvider; +import org.wicketstuff.select2.ChoiceProvider; + +import java.util.Collection; +import java.util.List; + +/** + * @author idobre + * @since 2019-03-11 + * + * A ChoiceFilteredPropertyColumn that uses Select2MultiChoiceBootstrapFormComponent as a filter. + */ +public class SelectMultiFilteredBootstrapPropertyColumn extends ChoiceFilteredPropertyColumn { + private final DataTable dataTable; + private boolean disableFilter = false; + private ChoiceProvider choiceProvider; + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable) { + this(displayModel, sortProperty, propertyExpression, choiceProvider, dataTable, false); + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final ChoiceProvider choiceProvider, + final DataTable dataTable, + final boolean disableFilter) { + super(displayModel, sortProperty, propertyExpression, null); + this.disableFilter = disableFilter; + this.dataTable = dataTable; + this.choiceProvider = choiceProvider; + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final S sortProperty, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + super(displayModel, sortProperty, propertyExpression, filterChoices); + + this.dataTable = dataTable; + } + + public SelectMultiFilteredBootstrapPropertyColumn(final IModel displayModel, + final String propertyExpression, + final IModel extends List extends Y>> filterChoices, + final DataTable dataTable) { + super(displayModel, propertyExpression, filterChoices); + + this.dataTable = dataTable; + } + + @Override + public Component getFilter(final String componentId, final FilterForm> form) { + ChoiceProvider provider; + + if (choiceProvider != null) { + provider = choiceProvider; + } else { + provider = new GenericChoiceProvider<>((List) getFilterChoices().getObject()); + } + + + final Select2MultiChoiceBootstrapFormComponent selectorField = + new Select2MultiChoiceBootstrapFormComponent<>(componentId, + provider, + (IModel>) getFilterModel(form)); + selectorField.hideLabel(); + + selectorField.getField().add(new AjaxComponentUpdatingBehavior(form, "change")); + + return selectorField; + } + + private class AjaxComponentUpdatingBehavior extends AjaxFormComponentUpdatingBehavior { + private final FilterForm> form; + + AjaxComponentUpdatingBehavior(final FilterForm> form, final String event) { + super(event); + this.form = form; + } + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + // update the table component + dataTable.setCurrentPage(0); + target.add(dataTable); + } + } +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java index 4159bdfe..48640689 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/ComponentUtil.java @@ -28,6 +28,9 @@ import org.devgateway.toolkit.persistence.service.TextSearchableService; import java.io.Serializable; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; /** * @author idobre @@ -49,6 +52,21 @@ public static boolean isViewMode() { .toBoolean(false); } + /** + * Returns true if the {@link WebConstants#PARAM_PRINT} is used as a parameter + * + * @return + */ + public static boolean isPrintMode() { + return RequestCycle.get().getRequest().getRequestParameters().getParameterValue(WebConstants.PARAM_PRINT) + .toBoolean(false); + } + + public static Date getDateFromLocalDate(final LocalDate localDate) { + return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } + + public static void enableDisableEvent(final Component c, final IEvent> event) { if (event.getPayload() instanceof EditingDisabledEvent) { c.setEnabled(false); diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java new file mode 100644 index 00000000..e2122a67 --- /dev/null +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/components/util/FormSecurityUtil.java @@ -0,0 +1,93 @@ +package org.devgateway.toolkit.forms.wicket.components.util; + +import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; +import org.devgateway.toolkit.persistence.dao.Person; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import static org.devgateway.toolkit.forms.security.SecurityConstants.Roles.ROLE_ADMIN; + +public class FormSecurityUtil { + + protected FormSecurityUtil() { + } + + + public static boolean rolesContainsAny(final Collection roleSet, final String... roles) { + for (final String role : roles) { + if (roleSet.contains(role)) { + return true; + } + } + return false; + } + + public static boolean rolesContainsAny(final String... roles) { + return rolesContainsAny(Objects.requireNonNull(getStringRolesForCurrentPerson()), roles); + } + + public static boolean rolesContainsAll(final Collection roleSet, final String... roles) { + return roleSet.containsAll(Arrays.asList(roles)); + } + + public static boolean rolesContainsAll(final String... roles) { + return rolesContainsAll(Objects.requireNonNull(getStringRolesForCurrentPerson()), roles); + } + + /** + * returns the principal object. In our case the principal should be + * {@link Person} + * + * @return the principal or null + * @see Principal + */ + public static Person getCurrentAuthenticatedPerson() { + if (SecurityContextHolder.getContext().getAuthentication() == null) { + return null; + } + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return null; + } + final Object principal = authentication.getPrincipal(); + if (principal instanceof Person) { + return (Person) principal; + } + return null; + } + + public static Set getStringRolesForCurrentPerson() { + if (!AbstractAuthenticatedWebSession.get().isSignedIn()) { + return Collections.emptySet(); + } + return AbstractAuthenticatedWebSession.get().getRoles(); + } + + public static boolean hasAnyUserRoles(String... roles) { + List rList = Arrays.asList(roles); + return getStringRolesForCurrentPerson().stream().anyMatch(rList::contains); + } + + public static boolean hasUserRole(String role) { + return hasAnyUserRoles(role); + } + + public static boolean isCurrentUserAdmin() { + return hasUserRole(ROLE_ADMIN); + } + + public static boolean isCurrentRoleOnlyUser(String userRole, String validatorRole) { + if (hasAnyUserRoles(ROLE_ADMIN, validatorRole)) { + return false; + } + return hasUserRole(userRole); + } +} diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java index b81f4942..c24f0f93 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.java @@ -33,6 +33,7 @@ import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.markup.head.MetaDataHeaderItem; import org.apache.wicket.markup.head.filter.HeaderResponseContainer; import org.apache.wicket.markup.html.GenericWebPage; import org.apache.wicket.markup.html.TransparentWebMarkupContainer; @@ -46,6 +47,7 @@ import org.apache.wicket.protocol.http.WebSession; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.JavaScriptResourceReference; +import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.resource.JQueryResourceReference; import org.apache.wicket.util.string.StringValue; import org.devgateway.toolkit.forms.WebConstants; @@ -94,24 +96,6 @@ public Boolean fluidContainer() { return false; } - public static class HALRedirectPage extends RedirectPage { - private static final long serialVersionUID = -750983217518258464L; - - public HALRedirectPage() { - super(WebApplication.get().getServletContext().getContextPath() + "/api/browser/"); - } - - } - - public static class JminixRedirectPage extends RedirectPage { - private static final long serialVersionUID = -750983217518258464L; - - public JminixRedirectPage() { - super(WebApplication.get().getServletContext().getContextPath() + "/jminix/"); - } - - } - public static class UIRedirectPage extends RedirectPage { private static final long serialVersionUID = -750983217518258464L; @@ -213,6 +197,16 @@ protected List newSubMenuButtons(final String buttonMarkupId) { return languageDropDown; } + protected MetaDataHeaderItem getFavicon() { + PackageResourceReference faviconRef = + new PackageResourceReference(BaseStyles.class, "assets/img/icons/toolkit-favicon.svg"); + MetaDataHeaderItem icon = MetaDataHeaderItem.forLinkTag("icon", + urlFor(faviconRef, null).toString()); + icon.addTagAttribute("type", "image/svg+xml"); + return icon; + + } + protected NavbarButton newLogoutMenu() { // logout menu final NavbarButton logoutMenu = @@ -288,24 +282,6 @@ JavamelodyPage.class, new StringResourceModel("navbar.javamelody", new StringResourceModel("navbar.springendpoints", this, null)) .setIconType(FontAwesomeIconType.anchor)); - list.add(new MenuBookmarkablePageLink(JminixRedirectPage.class, null, - new StringResourceModel("navbar.jminix", this, null)).setIconType(FontAwesomeIconType.bug)); - - final MenuBookmarkablePageLink halBrowserLink = - new MenuBookmarkablePageLink(HALRedirectPage.class, null, - new StringResourceModel("navbar.halbrowser", this, null)) { - private static final long serialVersionUID = 1L; - - @Override - protected void onComponentTag(final ComponentTag tag) { - super.onComponentTag(tag); - tag.put("target", "_blank"); - } - }; - halBrowserLink.setIconType(FontAwesomeIconType.rss).setEnabled(true); - - list.add(halBrowserLink); - final MenuBookmarkablePageLink uiBrowserLink = new MenuBookmarkablePageLink( UIRedirectPage.class, null, new StringResourceModel("navbar.ui", this, null)) { @@ -331,7 +307,7 @@ protected void onComponentTag(final ComponentTag tag) { }; adminMenu.setIconType(FontAwesomeIconType.cog); - MetaDataRoleAuthorizationStrategy.authorize(adminMenu, Component.RENDER, SecurityConstants.Roles.ROLE_ADMIN); + MetaDataRoleAuthorizationStrategy.authorize(adminMenu, Component.RENDER, SecurityConstants.Roles.ROLE_USER); return adminMenu; } @@ -352,6 +328,8 @@ protected Navbar newNavbar(final String markupId) { * @see org.devgateway.toolkit.forms.wicket.styles.BaseStyles */ navbar.setPosition(Navbar.Position.TOP); + navbar.setBrandImage(new PackageResourceReference(BaseStyles.class, "assets/img/toolkit-logo-0048.png"), + new StringResourceModel("brandImageAltText", this, null)); navbar.setInverted(true); navbar.addComponents(NavbarComponents.transform(Navbar.ComponentPosition.RIGHT, newHomeMenu(), newAdminMenu(), @@ -366,10 +344,13 @@ protected Navbar newNavbar(final String markupId) { public void renderHead(final IHeaderResponse response) { super.renderHead(response); + //favicon + response.render(getFavicon()); + // Load Styles. - response.render(CssHeaderItem.forReference(BaseStyles.INSTANCE)); response.render(CssHeaderItem.forReference(BootstrapCssReference.instance())); response.render(CssHeaderItem.forReference(FontAwesomeCssReference.instance())); + response.render(CssHeaderItem.forReference(BaseStyles.INSTANCE)); // Load Scripts. response.render(RespondJavaScriptReference.headerItem()); diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties index 084d268d..5651c713 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/BasePage.properties @@ -20,8 +20,8 @@ navbar.ui=React UI navbar.adminSettings=Settings navbar.springendpoints=Spring Endpoints navbar.lang=Language -navbar.jminix=JMX Console navbar.javamelody=Javamelody +brandImageAltText=DG-Toolkit fileUnit.B=B fileUnit.KB=KB diff --git a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html index 8585bf67..bd60a80b 100644 --- a/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html +++ b/forms/src/main/java/org/devgateway/toolkit/forms/wicket/page/EditAdminSettingsPage.html @@ -13,7 +13,10 @@ + + +