From 90eef07d02db40bae8faf034d354eb0a7100e267 Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 12 Jul 2017 09:08:51 +0000 Subject: [PATCH] CCM NG/ccm-core: Vaadin Prototype Editing roles and their members git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4865 8810af33-2d31-482b-a856-94f89814c4df --- .../GroupSelectorDataProvider.java | 2 + .../PartySelectionAction.java | 34 +++++ .../ui/usersgroupsroles/PartySelector.java | 107 +++++++++++++ .../PartySelectorDataProvider.java | 123 +++++++++++++++ .../ui/usersgroupsroles/RoleDetails.java | 144 +++++++++++++++++- .../admin/ui/usersgroupsroles/RoleEditor.java | 2 + .../RolePartiesController.java | 92 +++++++++++ .../RolePartiesDataProvider.java | 114 ++++++++++++++ .../RoleSelectorDataProvider.java | 4 +- .../admin/ui/usersgroupsroles/RolesTable.java | 15 +- .../ui/usersgroupsroles/UserDetails.java | 13 +- .../ui/usersgroupsroles/UserSelector.java | 4 - .../UserSelectorDataProvider.java | 6 +- .../java/org/libreccm/security/Party.java | 12 +- .../libreccm/security/PartyRepository.java | 11 +- .../ui/admin/AdminResources.properties | 2 + .../ui/admin/AdminResources_de.properties | 2 + .../ui/admin/AdminResources_en.properties | 2 + .../ui/admin/AdminResources_fr.properties | 2 + 19 files changed, 665 insertions(+), 26 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectionAction.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelector.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectorDataProvider.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesController.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesDataProvider.java diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupSelectorDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupSelectorDataProvider.java index 3dc3d9f96..5a664562a 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupSelectorDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupSelectorDataProvider.java @@ -113,10 +113,12 @@ public class GroupSelectorDataProvider extends AbstractDataProvider excludedGroups) { this.excludedGroups = excludedGroups; + refreshAll(); } } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectionAction.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectionAction.java new file mode 100644 index 000000000..af283b37a --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectionAction.java @@ -0,0 +1,34 @@ +/* + * 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.usersgroupsroles; + +import org.libreccm.security.Party; + +import java.util.Set; + +/** + * + * @author Jens Pelzetter + */ +@FunctionalInterface +public interface PartySelectionAction { + + void action(Set selectedParties); + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelector.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelector.java new file mode 100644 index 000000000..bb1a7059b --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelector.java @@ -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.usersgroupsroles; + +import com.arsdigita.ui.admin.AdminUiConstants; + +import com.vaadin.icons.VaadinIcons; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.UI; +import com.vaadin.ui.Window; +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.security.Party; + +import java.util.List; +import java.util.ResourceBundle; + +/** + * + * @author Jens Pelzetter + */ +public class PartySelector extends Window { + + private static final long serialVersionUID = 6915710902238111484L; + + private static final String COL_PARTY_NAME = "partyname"; + + public PartySelector(final String caption, + final String actionLabel, + final UsersGroupsRoles usersGroupsRoles, + final List excludedParties, + final PartySelectionAction action) { + + addWidgets(caption, actionLabel, excludedParties, action); + } + + private void addWidgets(final String caption, + final String actionLabel, + final List excludedParties, + final PartySelectionAction action) { + + setCaption(caption); + + final ResourceBundle bundle = ResourceBundle + .getBundle(AdminUiConstants.ADMIN_BUNDLE, + UI.getCurrent().getLocale()); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + + final Grid partiesGrid = new Grid<>(); + partiesGrid + .addColumn(Party::getName) + .setId(COL_PARTY_NAME) + .setCaption("Party name"); + + partiesGrid.setSelectionMode(Grid.SelectionMode.MULTI); + partiesGrid.setWidth("100%"); + + final Button actionButton = new Button(actionLabel); + actionButton.addClickListener(event -> { + action.action(partiesGrid.getSelectedItems()); + close(); + }); + actionButton.setIcon(VaadinIcons.PLUS_CIRCLE_O); + actionButton.setStyleName(ValoTheme.BUTTON_TINY); + + final Button clearButton = new Button("Clear selection"); + clearButton.addClickListener(event -> { + partiesGrid.getSelectionModel().deselectAll(); + }); + clearButton.setIcon(VaadinIcons.BACKSPACE); + clearButton.setStyleName(ValoTheme.BUTTON_TINY); + + final HeaderRow actions = partiesGrid.prependHeaderRow(); + final HeaderCell actionsCell = actions.getCell(COL_PARTY_NAME); + actionsCell.setComponent(new HorizontalLayout(actionButton, + clearButton)); + + final PartySelectorDataProvider dataProvider = cdiUtil + .findBean(PartySelectorDataProvider.class); + dataProvider.setExcludedParties(excludedParties); + partiesGrid.setDataProvider(dataProvider); + + setContent(partiesGrid); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectorDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectorDataProvider.java new file mode 100644 index 000000000..0b60e512c --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/PartySelectorDataProvider.java @@ -0,0 +1,123 @@ +/* + * 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.usersgroupsroles; + +import com.vaadin.cdi.ViewScoped; +import com.vaadin.data.provider.AbstractDataProvider; +import com.vaadin.data.provider.Query; +import org.libreccm.security.Party; + +import java.util.List; +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 Jens Pelzetter + */ +@ViewScoped +public class PartySelectorDataProvider extends AbstractDataProvider { + + private static final long serialVersionUID = -3271211882810011968L; + + @Inject + private EntityManager entityManager; + + private String partyNameFilter; + + private List excludedParties; + + @Override + public boolean isInMemory() { + return false; + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public int size(final Query query) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(Long.class); + final Root from = criteriaQuery.from(Party.class); + criteriaQuery + .select(builder.count(from)) + .distinct(true); + + if (partyNameFilter != null && !partyNameFilter.trim().isEmpty()) { + criteriaQuery + .where(builder.like(builder.lower(from.get("name")), + String.format("%s%%", partyNameFilter))); + } + + if (excludedParties != null && !excludedParties.isEmpty()) { + criteriaQuery.where(builder.not(from.in(excludedParties))); + } + + return entityManager + .createQuery(criteriaQuery) + .getSingleResult() + .intValue(); + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public Stream fetch(final Query query) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(Party.class); + final Root from = criteriaQuery.from(Party.class); + criteriaQuery.distinct(true); + + if (partyNameFilter != null && !partyNameFilter.trim().isEmpty()) { + criteriaQuery + .where(builder.like(builder.lower(from.get("name")), + String.format("%s%%", partyNameFilter))); + } + + if (excludedParties != null && !excludedParties.isEmpty()) { + criteriaQuery.where(builder.not(from.in(excludedParties))); + } + + return entityManager + .createQuery(criteriaQuery) + .setMaxResults(query.getLimit()) + .setFirstResult(query.getOffset()) + .getResultList() + .stream(); + } + + public void setPartyNameFilter(final String partyNameFilter) { + this.partyNameFilter = partyNameFilter; + refreshAll(); + } + + public void setExcludedParties(final List excludedParties) { + this.excludedParties = excludedParties; + refreshAll(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleDetails.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleDetails.java index f962c0718..b7262ef63 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleDetails.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleDetails.java @@ -18,7 +18,30 @@ */ package org.libreccm.admin.ui.usersgroupsroles; +import com.arsdigita.ui.admin.AdminUiConstants; + +import com.vaadin.icons.VaadinIcons; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; +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.cdi.utils.CdiUtil; +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; + +import java.util.ResourceBundle; /** * @@ -27,7 +50,122 @@ import com.vaadin.ui.Window; public class RoleDetails extends Window { private static final long serialVersionUID = 8109931561947913438L; - - - + + private static final String COL_MEMBER_NAME = "partyname"; + private static final String COL_MEMBER_REMOVE = "member_remove"; + + private final UsersGroupsRoles usersGroupsRoles; + private final Role role; + private final RoleRepository roleRepo; + private final RoleManager roleManager; + + public RoleDetails(final Role role, + final UsersGroupsRoles usersGroupsRoles, + final RoleRepository roleRepo, + final RoleManager roleManager) { + + super(String.format("Details of role %s", role.getName())); + + this.usersGroupsRoles = usersGroupsRoles; + this.role = role; + this.roleRepo = roleRepo; + this.roleManager = roleManager; + + addWidgets(); + } + + private void addWidgets() { + + final ResourceBundle bundle = ResourceBundle + .getBundle(AdminUiConstants.ADMIN_BUNDLE, + UI.getCurrent().getLocale()); + + final Label roleName = new Label(role.getName()); + roleName.setCaption(bundle + .getString("ui.admin.role_edit.rolename.label")); + + //description + final Label roleDescription = new Label(role.getName()); + roleDescription.setCaption(bundle + .getString("ui.admin.role_edit.description.label")); + + final FormLayout formLayout = new FormLayout(roleName, + roleDescription); + + final Button editButton = new Button( + bundle.getString("ui.admin.roles.table.edit"), + event -> { + final RoleEditor editor = new RoleEditor(role, + usersGroupsRoles, + roleRepo, + roleManager); + editor.center(); + UI.getCurrent().addWindow(editor); + }); + + final VerticalLayout layout = new VerticalLayout(formLayout, + editButton); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + + final RolePartiesController partiesController = cdiUtil.findBean( + RolePartiesController.class); + final Grid partiesGrid = new Grid<>(); + partiesGrid + .addColumn(Party::getName) + .setId(COL_MEMBER_NAME) + .setCaption("Name"); + partiesGrid + .addColumn(party -> bundle + .getString("ui.role.parties.remove"), + new ButtonRenderer<>(event -> { + partiesController + .removePartyFromRole(event.getItem(), role); + partiesGrid.getDataProvider().refreshAll(); + })) + .setId(COL_MEMBER_REMOVE); + + partiesGrid.setWidth("100%"); + + final PartyRepository partyRepo = cdiUtil + .findBean(PartyRepository.class); + + final HeaderRow partiesGridHeader = partiesGrid.prependHeaderRow(); + final Button addPartyButton = new Button("Add member"); + addPartyButton.setIcon(VaadinIcons.PLUS); + addPartyButton.setStyleName(ValoTheme.BUTTON_TINY); + addPartyButton.addClickListener(event -> { + final PartySelector partySelector = new PartySelector( + "Select parties to add to role", + "Add selected parties to role", + usersGroupsRoles, + partyRepo.findByRole(role), + selectedParties -> { + selectedParties.forEach(party -> { + partiesController.assignPartyToRole(party, role); + }); + partiesGrid.getDataProvider().refreshAll(); + }); + partySelector.center(); + partySelector.setWidth("80%"); + UI.getCurrent().addWindow(partySelector); + }); + final HeaderCell partiesGridHeaderCell = partiesGridHeader + .join(COL_MEMBER_NAME, COL_MEMBER_REMOVE); + partiesGridHeaderCell + .setComponent(new HorizontalLayout(addPartyButton)); + + final RolePartiesDataProvider partiesDataProvider = cdiUtil + .findBean(RolePartiesDataProvider.class); + partiesDataProvider.setRole(role); + partiesGrid.setDataProvider(partiesDataProvider); + + final TabSheet tabs = new TabSheet(); + tabs.addTab(layout, "Details"); + tabs.addTab(partiesGrid, "Members"); + + + setContent(tabs); + } + } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleEditor.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleEditor.java index feea5eed6..3333f826d 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleEditor.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleEditor.java @@ -144,6 +144,8 @@ public class RoleEditor extends Window { } setContent(layout); + + dataHasChanged = false; } @Override diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesController.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesController.java new file mode 100644 index 000000000..efbac3ae7 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesController.java @@ -0,0 +1,92 @@ +/* + * 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.usersgroupsroles; + +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; + +import java.util.Set; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +class RolePartiesController { + + @Inject + private PartyRepository partyRepo; + + @Inject + private RoleRepository roleRepo; + + @Inject + private RoleManager roleManager; + + @Transactional(Transactional.TxType.REQUIRED) + protected void assignPartiesToRole(final Set parties, + final Role role) { + + parties.forEach(party -> assignPartyToRole(party, role)); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void assignPartyToRole(final Party party, final Role role) { + + final Party theParty = partyRepo + .findById(party.getPartyId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Party with ID %d in the database.", + party.getPartyId()))); + + final Role theRole = roleRepo + .findById(role.getRoleId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Role with ID %d in the database.", + role.getRoleId()))); + + roleManager.assignRoleToParty(theRole, theParty); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void removePartyFromRole(final Party party, final Role role) { + + final Party theParty = partyRepo + .findById(party.getPartyId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Party with ID %d in the database.", + party.getPartyId()))); + + final Role theRole = roleRepo + .findById(role.getRoleId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Role with ID %d in the database.", + role.getRoleId()))); + + roleManager.removeRoleFromParty(theRole, theParty); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesDataProvider.java new file mode 100644 index 000000000..822a31cd1 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolePartiesDataProvider.java @@ -0,0 +1,114 @@ +/* + * 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.usersgroupsroles; + +import com.vaadin.cdi.ViewScoped; +import com.vaadin.data.provider.AbstractDataProvider; +import com.vaadin.data.provider.Query; +import org.libreccm.security.Party; +import org.libreccm.security.Role; +import org.libreccm.security.RoleMembership; + +import java.util.Objects; +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.Join; +import javax.persistence.criteria.Root; + +/** + * + * @author Jens Pelzetter + */ +@ViewScoped +public class RolePartiesDataProvider extends AbstractDataProvider { + + private static final long serialVersionUID = -2770993810657270285L; + + @Inject + private EntityManager entityManager; + + private Role role; + + @Override + public boolean isInMemory() { + return false; + } + + @Override + public int size(final Query query) { + + Objects.requireNonNull(role, + "This data provider needs to be initalized " + + "by calling setRole(Role) before calling " + + "the count method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(Long.class); + + final Root from = criteriaQuery + .from(RoleMembership.class); + + criteriaQuery + .select(builder.count(from)) + .where(builder.equal(from.get("role"), role)); + + return entityManager + .createQuery(criteriaQuery) + .getSingleResult() + .intValue(); + } + + @Override + public Stream fetch(final Query query) { + + Objects.requireNonNull(role, + "This data provider needs to be initalized " + + "by calling setRole(Role) before calling " + + "the count method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery =builder + .createQuery(RoleMembership.class); + final Root from = criteriaQuery + .from(RoleMembership.class); + final Join join = from.join("role"); + criteriaQuery + .where(builder.equal(from.get("role"), role)) + .orderBy(builder.asc(join.get("name"))); + + + return entityManager + .createQuery(criteriaQuery) + .setMaxResults(query.getLimit()) + .setFirstResult(query.getOffset()) + .getResultList() + .stream() + .map(RoleMembership::getMember); + } + + public void setRole(final Role role) { + this.role = role; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleSelectorDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleSelectorDataProvider.java index c3d43d6e9..8559c66a3 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleSelectorDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RoleSelectorDataProvider.java @@ -114,12 +114,12 @@ public class RoleSelectorDataProvider extends AbstractDataProvider public void setRoleNameFilter(final String roleNameFilter) { this.roleNameFilter = roleNameFilter; -// refreshAll(); + refreshAll(); } public void setExcludedRoles(final List excludedRoles) { this.excludedRoles = new ArrayList<>(excludedRoles); -// refreshAll(); + refreshAll(); } } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java index 9521062b7..f8eddd8a2 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/RolesTable.java @@ -90,19 +90,26 @@ public class RolesTable extends Grid { return ""; } } - }) .setId(COL_DESCRIPTION) .setCaption("Description"); addColumn(user -> bundle.getString("ui.admin.roles.table.edit"), new ButtonRenderer<>(event -> { - final RoleEditor roleEditor = new RoleEditor( + final RoleDetails roleDetails = new RoleDetails( event.getItem(), usersGroupsRoles, view.getRoleRepository(), view.getRoleManager()); - roleEditor.center(); - UI.getCurrent().addWindow(roleEditor); + roleDetails.center(); + roleDetails.setWidth("80%"); + UI.getCurrent().addWindow(roleDetails); +// final RoleEditor roleEditor = new RoleEditor( +// event.getItem(), +// usersGroupsRoles, +// view.getRoleRepository(), +// view.getRoleManager()); +// roleEditor.center(); +// UI.getCurrent().addWindow(roleEditor); })) .setId(COL_EDIT); addColumn(user -> bundle.getString("ui.admin.roles.table.delete"), diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java index 953912017..5e0bb6280 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java @@ -174,27 +174,26 @@ public class UserDetails extends Window { "Add user to selected groups", usersGroupsRoles, groupRepo.findByMember(user), - (selectedGroups -> { + selectedGroups -> { selectedGroups.forEach(group -> { groupsController.addUserToGroup(user, group); }); groupsGrid.getDataProvider().refreshAll(); - })); + }); groupSelector.center(); groupSelector.setWidth("80%"); UI.getCurrent().addWindow(groupSelector); }); final HeaderCell groupsGridHeaderCell = groupsGridHeader - .join(COL_GROUP_NAME, - COL_GROUP_REMOVE); + .join(COL_GROUP_NAME, COL_GROUP_REMOVE); groupsGridHeaderCell .setComponent(new HorizontalLayout(addGroupButton)); - + final UserGroupsTableDataProvider groupsDataProvider = cdiUtil - .findBean(UserGroupsTableDataProvider.class); + .findBean(UserGroupsTableDataProvider.class); groupsDataProvider.setUser(user); groupsGrid.setDataProvider(groupsDataProvider); - + final UserRolesController rolesController = cdiUtil .findBean(UserRolesController.class); final Grid rolesGrid = new Grid<>(); diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelector.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelector.java index acebe5b60..0d0572349 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelector.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelector.java @@ -31,7 +31,6 @@ import com.vaadin.ui.components.grid.HeaderRow; import com.vaadin.ui.themes.ValoTheme; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.security.User; -import org.libreccm.security.UserRepository; import java.util.List; import java.util.ResourceBundle; @@ -118,13 +117,10 @@ public class UserSelector extends Window { final UserSelectorDataProvider dataProvider = cdiUtil .findBean(UserSelectorDataProvider.class); - dataProvider.setExcludedUsers(excludedUsers); - usersGrid.setDataProvider(dataProvider); setContent(usersGrid); - } } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelectorDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelectorDataProvider.java index ae847d489..bb0de47c6 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelectorDataProvider.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserSelectorDataProvider.java @@ -59,10 +59,10 @@ public class UserSelectorDataProvider extends AbstractDataProvider public int size(final Query query) { final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - CriteriaQuery criteriaQuery = builder.createQuery(Long.class); + final CriteriaQuery criteriaQuery = builder.createQuery(Long.class); final Root from = criteriaQuery.from(User.class); - criteriaQuery = criteriaQuery.select(builder.count(from)); - criteriaQuery = criteriaQuery.distinct(true); + criteriaQuery.select(builder.count(from)); + criteriaQuery.distinct(true); if (userNameFilter != null && !userNameFilter.trim().isEmpty()) { criteriaQuery diff --git a/ccm-core/src/main/java/org/libreccm/security/Party.java b/ccm-core/src/main/java/org/libreccm/security/Party.java index 3feeecc8d..3e087954d 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Party.java +++ b/ccm-core/src/main/java/org/libreccm/security/Party.java @@ -37,9 +37,9 @@ import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; + import java.io.Serializable; import java.util.Collections; import java.util.HashSet; @@ -62,12 +62,20 @@ import static org.libreccm.core.CoreConstants.DB_SCHEMA; @NamedQueries({ @NamedQuery( name = "Party.findByName", - query = "SELECT p FROM Party p WHERE p.name = :name"), + query = "SELECT p FROM Party p WHERE p.name = :name") + , @NamedQuery( name = "Party.searchByName", query = "SELECT p FROM Party p " + "WHERE LOWER(p.name) LIKE CONCAT(LOWER(:term), '%') " + "ORDER BY p.name") + , + @NamedQuery( + name = "Party.findByRole", + query = "SELECT p FROM Party p " + + "JOIN p.roleMemberships m " + + "WHERE m.role = :role") + }) @NamedEntityGraphs({ @NamedEntityGraph(name = "Party.withRoleMemberships", diff --git a/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java b/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java index bdf6986dd..714b64877 100644 --- a/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java +++ b/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java @@ -68,6 +68,14 @@ public class PartyRepository extends AbstractEntityRepository { } } + public List findByRole(final Role role) { + final TypedQuery query = getEntityManager() + .createNamedQuery("Party.findByRole", Party.class); + query.setParameter("role", role); + + return query.getResultList(); + } + public List searchByName(final String term) { final TypedQuery query = getEntityManager().createNamedQuery( "Party.searchByName", Party.class); @@ -82,7 +90,7 @@ public class PartyRepository extends AbstractEntityRepository { public void save(final Party party) { super.save(party); } - + @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -90,4 +98,5 @@ public class PartyRepository extends AbstractEntityRepository { public void delete(final Party party) { super.delete(party); } + } diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index d66199aa5..9c7def82e 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -613,3 +613,5 @@ ui.admin.importexport.import.report=Report from last import process ui.groups.roles.remove=Remove ui.user.groups.remove=Remove ui.user.roles.remove=Remove +ui.role.parties.remove=Remove +ui.admin.role_edit.description.label=Description diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index 4beebd5f1..27de1d2e7 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -617,3 +617,5 @@ ui.admin.importexport.import.report=Bericht des letzten Import-Prozesses ui.groups.roles.remove=Entfernen ui.user.groups.remove=Entfernen ui.user.roles.remove=Entfernen +ui.role.parties.remove=Entfernen +ui.admin.role_edit.description.label=Beschreibung diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index 4415456a4..e5beb9eb6 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -610,3 +610,5 @@ ui.admin.importexport.import.report=Report from last import process ui.groups.roles.remove=Remove ui.user.groups.remove=Remove ui.user.roles.remove=Remove +ui.role.parties.remove=Remove +ui.admin.role_edit.description.label=Description diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index 6b2177d81..0ee4911f5 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -601,3 +601,5 @@ ui.admin.importexport.import.report=Report from last import process ui.groups.roles.remove=Remove ui.user.groups.remove=Remove ui.user.roles.remove=Remove +ui.role.parties.remove=Remove +ui.admin.role_edit.description.label=Description