CccNG/ccm-core: Some files for the Vaadin prototype
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4781 8810af33-2d31-482b-a856-94f89814c4dfccm-docs
parent
5fcf5d10fb
commit
721696ae44
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* 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.data.HasValue;
|
||||||
|
import com.vaadin.icons.VaadinIcons;
|
||||||
|
import com.vaadin.server.Page;
|
||||||
|
import com.vaadin.server.UserError;
|
||||||
|
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.Notification;
|
||||||
|
import com.vaadin.ui.Panel;
|
||||||
|
import com.vaadin.ui.TabSheet;
|
||||||
|
import com.vaadin.ui.TextField;
|
||||||
|
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.admin.ui.ConfirmDiscardDialog;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.security.Group;
|
||||||
|
import org.libreccm.security.GroupManager;
|
||||||
|
import org.libreccm.security.GroupRepository;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class GroupDetails extends Window {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4252189590984878037L;
|
||||||
|
|
||||||
|
private static final String COL_USER_NAME = "username";
|
||||||
|
private static final String COL_GIVEN_NAME = "given_name";
|
||||||
|
private static final String COL_FAMILY_NAME = "family_name";
|
||||||
|
private static final String COL_EMAIL = "email";
|
||||||
|
private static final String COL_REMOVE = "remove";
|
||||||
|
|
||||||
|
private final UsersGroupsRoles usersGroupsRoles;
|
||||||
|
private final Group group;
|
||||||
|
private final GroupRepository groupRepo;
|
||||||
|
private final GroupManager groupManager;
|
||||||
|
|
||||||
|
private boolean dataHasChanged = false;
|
||||||
|
|
||||||
|
private Label groupNameDisplay;
|
||||||
|
private TextField groupNameField;
|
||||||
|
private Button editButton;
|
||||||
|
private HorizontalLayout saveCancelButtons;
|
||||||
|
|
||||||
|
public GroupDetails(final Group group,
|
||||||
|
final UsersGroupsRoles usersGroupsRoles,
|
||||||
|
final GroupRepository groupRepo,
|
||||||
|
final GroupManager groupManager) {
|
||||||
|
|
||||||
|
super(String.format("Edit group %s", group.getName()));
|
||||||
|
|
||||||
|
this.group = group;
|
||||||
|
this.usersGroupsRoles = usersGroupsRoles;
|
||||||
|
this.groupRepo = groupRepo;
|
||||||
|
this.groupManager = groupManager;
|
||||||
|
|
||||||
|
addWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWidgets() {
|
||||||
|
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||||
|
UI.getCurrent().getLocale());
|
||||||
|
|
||||||
|
final GroupDetails.DataHasChangedListener dataHasChangedListener
|
||||||
|
= new GroupDetails.DataHasChangedListener();
|
||||||
|
|
||||||
|
groupNameDisplay = new Label();
|
||||||
|
groupNameDisplay.setCaption(bundle
|
||||||
|
.getString("ui.admin.group_edit.groupname.label"));
|
||||||
|
|
||||||
|
groupNameField = new TextField(bundle
|
||||||
|
.getString("ui.admin.group_edit.groupname.label"));
|
||||||
|
groupNameField.setRequiredIndicatorVisible(true);
|
||||||
|
|
||||||
|
editButton = new Button("ui.admin.group.edit");
|
||||||
|
editButton.addClickListener(event -> {
|
||||||
|
groupNameDisplay.setVisible(false);
|
||||||
|
groupNameField.setVisible(true);
|
||||||
|
editButton.setVisible(false);
|
||||||
|
saveCancelButtons.setVisible(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
final Button submit = new Button();
|
||||||
|
submit.setCaption(bundle.getString("ui.admin.save"));
|
||||||
|
submit.addClickListener(event -> saveGroup());
|
||||||
|
|
||||||
|
final Button cancel = new Button(bundle.getString("ui.admin.cancel"));
|
||||||
|
cancel.addClickListener(event -> {
|
||||||
|
groupNameField.setValue(group.getName());
|
||||||
|
groupNameField.setVisible(false);
|
||||||
|
saveCancelButtons.setVisible(false);
|
||||||
|
editButton.setVisible(true);
|
||||||
|
groupNameDisplay.setVisible(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
saveCancelButtons = new HorizontalLayout(submit, cancel);
|
||||||
|
|
||||||
|
final FormLayout formLayout = new FormLayout(groupNameDisplay,
|
||||||
|
groupNameField);
|
||||||
|
groupNameField.setVisible(false);
|
||||||
|
|
||||||
|
groupNameField.addValueChangeListener(dataHasChangedListener);
|
||||||
|
|
||||||
|
final VerticalLayout layout = new VerticalLayout(formLayout,
|
||||||
|
editButton,
|
||||||
|
saveCancelButtons);
|
||||||
|
saveCancelButtons.setVisible(false);
|
||||||
|
|
||||||
|
final Panel propertiesPanel = new Panel(layout);
|
||||||
|
propertiesPanel.setCaption(bundle
|
||||||
|
.getString("ui.admin.group_details.edit"));
|
||||||
|
|
||||||
|
groupNameDisplay.setValue(group.getName());
|
||||||
|
groupNameField.setValue(group.getName());
|
||||||
|
|
||||||
|
dataHasChanged = false;
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final GroupMembersController controller = cdiUtil
|
||||||
|
.findBean(GroupMembersController.class);
|
||||||
|
|
||||||
|
final Grid<User> membersGrid = new Grid<>();
|
||||||
|
membersGrid.addColumn(User::getName)
|
||||||
|
.setId(COL_USER_NAME)
|
||||||
|
.setCaption("User Name");
|
||||||
|
membersGrid.addColumn(User::getGivenName)
|
||||||
|
.setId(COL_GIVEN_NAME)
|
||||||
|
.setCaption("Given name");
|
||||||
|
membersGrid.addColumn(User::getFamilyName)
|
||||||
|
.setId(COL_FAMILY_NAME)
|
||||||
|
.setCaption("Family name");
|
||||||
|
membersGrid
|
||||||
|
.addColumn(user -> user.getPrimaryEmailAddress().getAddress())
|
||||||
|
.setId(COL_EMAIL)
|
||||||
|
.setCaption("E-Mail");
|
||||||
|
membersGrid.addColumn(user -> bundle.getString(
|
||||||
|
"ui.groups.members.remove"),
|
||||||
|
new ButtonRenderer<>(event -> {
|
||||||
|
controller
|
||||||
|
.removeMemberFromGroup(event.getItem(),
|
||||||
|
group);
|
||||||
|
membersGrid.getDataProvider().refreshAll();
|
||||||
|
}))
|
||||||
|
.setId(COL_REMOVE);
|
||||||
|
|
||||||
|
membersGrid.setWidth("100%");
|
||||||
|
|
||||||
|
final UserRepository userRepo = cdiUtil.findBean(UserRepository.class);
|
||||||
|
|
||||||
|
final HeaderRow membersGridHeader = membersGrid.prependHeaderRow();
|
||||||
|
final Button addMemberButton = new Button("Add member");
|
||||||
|
addMemberButton.setIcon(VaadinIcons.PLUS);
|
||||||
|
addMemberButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||||
|
addMemberButton.addClickListener(event -> {
|
||||||
|
final UserSelector userSelector = new UserSelector(
|
||||||
|
"Select users to add to group",
|
||||||
|
"Add selected users to group",
|
||||||
|
usersGroupsRoles,
|
||||||
|
userRepo.findByGroup(group),
|
||||||
|
(selectedUsers -> {
|
||||||
|
selectedUsers.forEach(user -> {
|
||||||
|
controller.addMembersToGroup(selectedUsers, group);
|
||||||
|
membersGrid.getDataProvider().refreshAll();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
userSelector.center();
|
||||||
|
UI.getCurrent().addWindow(userSelector);
|
||||||
|
});
|
||||||
|
final HeaderCell membersGridHeaderCell = membersGridHeader
|
||||||
|
.join(COL_USER_NAME,
|
||||||
|
COL_GIVEN_NAME,
|
||||||
|
COL_FAMILY_NAME,
|
||||||
|
COL_EMAIL,
|
||||||
|
COL_REMOVE);
|
||||||
|
membersGridHeaderCell
|
||||||
|
.setComponent(new HorizontalLayout(addMemberButton));
|
||||||
|
|
||||||
|
final GroupMembersTableDataProvider dataProvider = cdiUtil
|
||||||
|
.findBean(GroupMembersTableDataProvider.class);
|
||||||
|
dataProvider.setGroup(group);
|
||||||
|
membersGrid.setDataProvider(dataProvider);
|
||||||
|
|
||||||
|
final TabSheet tabs = new TabSheet();
|
||||||
|
tabs.addTab(membersGrid, "Members");
|
||||||
|
tabs.addTab(new Label("Roles Placeholder"), "Roles");
|
||||||
|
|
||||||
|
// final Panel membersPanel = new Panel("Members");
|
||||||
|
// membersPanel.setContent(membersGrid);
|
||||||
|
// final VerticalLayout windowLayout = new VerticalLayout(propertiesPanel,
|
||||||
|
// membersPanel);
|
||||||
|
final VerticalLayout windowLayout = new VerticalLayout(propertiesPanel,
|
||||||
|
tabs);
|
||||||
|
|
||||||
|
setContent(windowLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
if (dataHasChanged) {
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||||
|
UI.getCurrent().getLocale());
|
||||||
|
|
||||||
|
final ConfirmDiscardDialog dialog = new ConfirmDiscardDialog(
|
||||||
|
this,
|
||||||
|
bundle.getString("ui.admin.group_edit.discard_confirm"));
|
||||||
|
dialog.setModal(true);
|
||||||
|
UI.getCurrent().addWindow(dialog);
|
||||||
|
} else {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void saveGroup() {
|
||||||
|
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||||
|
UI.getCurrent().getLocale());
|
||||||
|
|
||||||
|
boolean valid = true;
|
||||||
|
|
||||||
|
if (groupNameField.getValue() == null
|
||||||
|
|| groupNameField.getValue().trim().isEmpty()) {
|
||||||
|
|
||||||
|
groupNameField.setComponentError(new UserError(
|
||||||
|
bundle.getString("ui.admin.group_edit.groupname.error.notempty")));
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String notificationText;
|
||||||
|
group.setName(groupNameField.getValue());
|
||||||
|
notificationText = String.format("Saved changes to group %s",
|
||||||
|
group.getName());
|
||||||
|
|
||||||
|
groupRepo.save(group);
|
||||||
|
|
||||||
|
dataHasChanged = false;
|
||||||
|
if (usersGroupsRoles != null) {
|
||||||
|
usersGroupsRoles.refreshGroups();
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
new Notification(notificationText, Notification.Type.TRAY_NOTIFICATION)
|
||||||
|
.show(Page.getCurrent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DataHasChangedListener
|
||||||
|
implements HasValue.ValueChangeListener<String> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -1410903365203533072L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChange(final HasValue.ValueChangeEvent<String> event) {
|
||||||
|
dataHasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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.Group;
|
||||||
|
import org.libreccm.security.GroupManager;
|
||||||
|
import org.libreccm.security.GroupRepository;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
class GroupMembersController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupRepository groupRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupManager groupManager;
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void addMembersToGroup(final Set<User> users, final Group group) {
|
||||||
|
|
||||||
|
users.forEach(user -> addMemberToGroup(user, group));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void addMemberToGroup(final User user, final Group group) {
|
||||||
|
|
||||||
|
final User theUser = userRepo
|
||||||
|
.findById(user.getPartyId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No user with id %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
user.getPartyId())));
|
||||||
|
|
||||||
|
final Group theGroup = groupRepo
|
||||||
|
.findById(group.getPartyId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No group with id %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
group.getPartyId())));
|
||||||
|
|
||||||
|
groupManager.addMemberToGroup(theUser, theGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void removeMemberFromGroup(final User member, final Group group) {
|
||||||
|
|
||||||
|
final User theMember = userRepo
|
||||||
|
.findById(member.getPartyId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No user with id %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
member.getPartyId())));
|
||||||
|
|
||||||
|
final Group theGroup = groupRepo
|
||||||
|
.findById(group.getPartyId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No group with id %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
group.getPartyId())));
|
||||||
|
|
||||||
|
groupManager.removeMemberFromGroup(theMember, theGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* 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.Group;
|
||||||
|
import org.libreccm.security.GroupMembership;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ViewScoped
|
||||||
|
public class GroupMembersTableDataProvider
|
||||||
|
extends AbstractDataProvider<User, String> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -1924910843845830008L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
private Group group;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInMemory() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size(Query<User, String> query) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(group,
|
||||||
|
"This data provider needs to be initalized "
|
||||||
|
+ "by calling setGroup(Group) before calling "
|
||||||
|
+ "the count method.");
|
||||||
|
|
||||||
|
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||||
|
// final Root<User> from = criteriaQuery.from(User.class);
|
||||||
|
// final Join<?, ?> memberships = from.join("groups");
|
||||||
|
//
|
||||||
|
// criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||||
|
//
|
||||||
|
// criteriaQuery.where(builder.equal(memberships.get("group"),
|
||||||
|
// group));
|
||||||
|
// criteriaQuery
|
||||||
|
// .where(builder
|
||||||
|
// .equal(builder.treat(from.get("groups"),
|
||||||
|
// GroupMembership.class).get("group"),
|
||||||
|
// group));
|
||||||
|
|
||||||
|
final Root<GroupMembership> from = criteriaQuery
|
||||||
|
.from(GroupMembership.class);
|
||||||
|
|
||||||
|
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||||
|
criteriaQuery.where(builder.equal(from.get("group"), group));
|
||||||
|
|
||||||
|
return entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.getSingleResult()
|
||||||
|
.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public Stream<User> fetch(final Query<User, String> query) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(group,
|
||||||
|
"This data provider needs to be initalized "
|
||||||
|
+ "by calling setGroup(Group) before calling "
|
||||||
|
+ "the fetch method.");
|
||||||
|
|
||||||
|
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||||
|
// final CriteriaQuery<User> criteriaQuery = builder
|
||||||
|
// .createQuery(User.class);
|
||||||
|
// final Root<User> from = criteriaQuery.from(User.class);
|
||||||
|
// final Join<User, GroupMembership> memberships = from
|
||||||
|
// .join("memberships");
|
||||||
|
//
|
||||||
|
// criteriaQuery.where(builder.equal(memberships.get("group"),
|
||||||
|
// group));
|
||||||
|
//
|
||||||
|
// return entityManager
|
||||||
|
// .createQuery(criteriaQuery)
|
||||||
|
// .setMaxResults(query.getLimit())
|
||||||
|
// .setFirstResult(query.getOffset())
|
||||||
|
// .getResultList()
|
||||||
|
// .stream();
|
||||||
|
|
||||||
|
final CriteriaQuery<GroupMembership> criteriaQuery = builder
|
||||||
|
.createQuery(GroupMembership.class);
|
||||||
|
final Root<GroupMembership> from = criteriaQuery
|
||||||
|
.from(GroupMembership.class);
|
||||||
|
final Join<?, ?> join = from.join("member");
|
||||||
|
criteriaQuery
|
||||||
|
.where(builder.equal(from.get("group"), group))
|
||||||
|
.orderBy(builder.asc(join.get("name")));
|
||||||
|
|
||||||
|
return entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.setMaxResults(query.getLimit())
|
||||||
|
.setFirstResult(query.getOffset())
|
||||||
|
.getResultList()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getMember());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroup(final Group group) {
|
||||||
|
Objects.requireNonNull(group);
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.ui.Window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class RoleDetails extends Window {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8109931561947913438L;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.User;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface UserSelectionAction {
|
||||||
|
|
||||||
|
void action(Set<User> selectedUsers);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* 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.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class UserSelector extends Window {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -6227551833159691370L;
|
||||||
|
|
||||||
|
private static final String COL_USER_NAME = "username";
|
||||||
|
private static final String COL_GIVEN_NAME = "given_name";
|
||||||
|
private static final String COL_FAMILY_NAME = "family_name";
|
||||||
|
private static final String COL_EMAIL = "email";
|
||||||
|
|
||||||
|
private final UserRepository userRepo;
|
||||||
|
|
||||||
|
private final UserSelectionAction groupSelectionAction;
|
||||||
|
|
||||||
|
public UserSelector(final String caption,
|
||||||
|
final String actionLabel,
|
||||||
|
final UsersGroupsRoles usersGroupsRoles,
|
||||||
|
final List<User> excludedUsers,
|
||||||
|
final UserSelectionAction action) {
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
userRepo = cdiUtil.findBean(UserRepository.class);
|
||||||
|
this.groupSelectionAction = action;
|
||||||
|
|
||||||
|
addWidgets(caption, actionLabel, excludedUsers, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWidgets(final String caption,
|
||||||
|
final String actionLabel,
|
||||||
|
final List<User> excludedUsers,
|
||||||
|
final UserSelectionAction action) {
|
||||||
|
|
||||||
|
setCaption(caption);
|
||||||
|
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||||
|
UI.getCurrent().getLocale());
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
|
||||||
|
final Grid<User> usersGrid = new Grid<>();
|
||||||
|
usersGrid.addColumn(User::getName)
|
||||||
|
.setId(COL_USER_NAME)
|
||||||
|
.setCaption("User Name");
|
||||||
|
usersGrid.addColumn(User::getGivenName)
|
||||||
|
.setId(COL_GIVEN_NAME)
|
||||||
|
.setCaption("Given name");
|
||||||
|
usersGrid.addColumn(User::getFamilyName)
|
||||||
|
.setId(COL_FAMILY_NAME)
|
||||||
|
.setCaption("Family name");
|
||||||
|
usersGrid
|
||||||
|
.addColumn(user -> user.getPrimaryEmailAddress().getAddress())
|
||||||
|
.setId(COL_EMAIL)
|
||||||
|
.setCaption("E-Mail");
|
||||||
|
|
||||||
|
usersGrid.setSelectionMode(Grid.SelectionMode.MULTI);
|
||||||
|
usersGrid.setWidth("100%");
|
||||||
|
|
||||||
|
final Button actionButton = new Button(actionLabel);
|
||||||
|
actionButton.addClickListener(event -> {
|
||||||
|
action.action(usersGrid.getSelectedItems());
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
actionButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||||
|
actionButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||||
|
|
||||||
|
final Button clearButton = new Button("Clear selection");
|
||||||
|
clearButton.addClickListener(event -> {
|
||||||
|
usersGrid.getSelectionModel().deselectAll();
|
||||||
|
});
|
||||||
|
clearButton.setIcon(VaadinIcons.BACKSPACE);
|
||||||
|
clearButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||||
|
|
||||||
|
final HeaderRow actions = usersGrid.prependHeaderRow();
|
||||||
|
final HeaderCell actionsCell = actions.join(COL_USER_NAME,
|
||||||
|
COL_GIVEN_NAME,
|
||||||
|
COL_FAMILY_NAME,
|
||||||
|
COL_EMAIL);
|
||||||
|
actionsCell.setComponent(new HorizontalLayout(actionButton,
|
||||||
|
clearButton));
|
||||||
|
|
||||||
|
final UserSelectorDataProvider dataProvider = cdiUtil
|
||||||
|
.findBean(UserSelectorDataProvider.class);
|
||||||
|
|
||||||
|
dataProvider.setExcludedUsers(excludedUsers);
|
||||||
|
|
||||||
|
usersGrid.setDataProvider(dataProvider);
|
||||||
|
|
||||||
|
setContent(usersGrid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* 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.User;
|
||||||
|
|
||||||
|
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.Expression;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ViewScoped
|
||||||
|
public class UserSelectorDataProvider extends AbstractDataProvider<User, String> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -9019928941945017145L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
private String userNameFilter;
|
||||||
|
|
||||||
|
private List<User> excludedUsers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInMemory() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public int size(final Query<User, String> query) {
|
||||||
|
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||||
|
final Root<User> from = criteriaQuery.from(User.class);
|
||||||
|
|
||||||
|
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||||
|
|
||||||
|
if (userNameFilter != null && !userNameFilter.trim().isEmpty()) {
|
||||||
|
criteriaQuery
|
||||||
|
.where(builder.like(builder.lower(from.get("name")),
|
||||||
|
String.format("%s%%", userNameFilter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludedUsers != null && !excludedUsers.isEmpty()) {
|
||||||
|
criteriaQuery.where(builder.not(from.in(excludedUsers)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.getSingleResult()
|
||||||
|
.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public Stream<User> fetch(final Query<User, String> query) {
|
||||||
|
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||||
|
final CriteriaQuery<User> criteriaQuery = builder
|
||||||
|
.createQuery(User.class);
|
||||||
|
final Root<User> from = criteriaQuery.from(User.class);
|
||||||
|
|
||||||
|
if (userNameFilter != null && !userNameFilter.trim().isEmpty()) {
|
||||||
|
criteriaQuery
|
||||||
|
.where(builder.like(builder.lower(from.get("name")),
|
||||||
|
String.format("%s%%", userNameFilter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludedUsers != null && !excludedUsers.isEmpty()) {
|
||||||
|
criteriaQuery.where(builder.not(from.in(excludedUsers)));
|
||||||
|
}
|
||||||
|
|
||||||
|
criteriaQuery.orderBy(builder.asc(from.get("name")));
|
||||||
|
|
||||||
|
return entityManager
|
||||||
|
.createQuery(criteriaQuery)
|
||||||
|
.setMaxResults(query.getLimit())
|
||||||
|
.setFirstResult(query.getOffset())
|
||||||
|
.getResultList()
|
||||||
|
.stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserNameFilter(final String userNameFilter) {
|
||||||
|
this.userNameFilter = userNameFilter;
|
||||||
|
refreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExcludedUsers(final List<User> excludedUsers) {
|
||||||
|
this.excludedUsers = excludedUsers;
|
||||||
|
refreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue