/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.explorer.ui.management.identity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.explorer.ExplorerApp;
import org.activiti.explorer.I18nManager;
import org.activiti.explorer.Messages;
import org.activiti.explorer.data.LazyLoadingContainer;
import org.activiti.explorer.data.LazyLoadingQuery;
import org.activiti.explorer.ui.Images;
import org.activiti.explorer.ui.custom.ConfirmationDialogPopupWindow;
import org.activiti.explorer.ui.custom.DetailPanel;
import org.activiti.explorer.ui.custom.SelectUsersPopupWindow;
import org.activiti.explorer.ui.event.ConfirmationEvent;
import org.activiti.explorer.ui.event.ConfirmationEventListener;
import org.activiti.explorer.ui.event.SubmitEvent;
import org.activiti.explorer.ui.event.SubmitEventListener;
import org.activiti.explorer.ui.mainlayout.ExplorerLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;
/**
* @author Joram Barrez
*/
public class GroupDetailPanel extends DetailPanel implements MemberShipChangeListener {
private static final long serialVersionUID = 1L;
protected IdentityService identityService;
protected I18nManager i18nManager;
protected GroupPage groupPage;
protected Group group;
protected VerticalLayout panelLayout;
protected boolean editingDetails;
protected HorizontalLayout detailLayout;
protected GridLayout detailsGrid;
protected TextField nameTextField;
protected ComboBox typeCombobox;
protected HorizontalLayout membersLayout;
protected Table membersTable;
protected Label noMembersTable;
public GroupDetailPanel(GroupPage groupPage, String groupId) {
this.groupPage = groupPage;
this.identityService = ProcessEngines.getDefaultProcessEngine().getIdentityService();
this.group = identityService.createGroupQuery().groupId(groupId).singleResult();
this.i18nManager = ExplorerApp.get().getI18nManager();
init();
}
protected void init() {
setSizeFull();
addStyleName(Reindeer.PANEL_LIGHT);
initPageTitle();
initGroupDetails();
initMembers();
initActions();
}
protected void initActions() {
Button createGroupButton = new Button(i18nManager.getMessage(Messages.GROUP_CREATE));
createGroupButton.setIcon(Images.GROUP_16);
createGroupButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
NewGroupPopupWindow popup = new NewGroupPopupWindow();
ExplorerApp.get().getViewManager().showPopupWindow(popup);
}
});
groupPage.getToolBar().removeAllButtons();
groupPage.getToolBar().addButton(createGroupButton);
}
protected void initPageTitle() {
HorizontalLayout layout = new HorizontalLayout();
layout.setWidth(100, UNITS_PERCENTAGE);
layout.addStyleName(ExplorerLayout.STYLE_TITLE_BLOCK);
layout.setSpacing(true);
layout.setMargin(false, false, true, false);
addDetailComponent(layout);
Embedded groupImage = new Embedded(null, Images.GROUP_50);
layout.addComponent(groupImage);
Label groupName = new Label(getGroupName(group));
groupName.setSizeUndefined();
groupName.addStyleName(Reindeer.LABEL_H2);
layout.addComponent(groupName);
layout.setComponentAlignment(groupName, Alignment.MIDDLE_LEFT);
layout.setExpandRatio(groupName, 1.0f);
}
protected String getGroupName(Group theGroup) {
if(theGroup.getName() == null) {
return theGroup.getId();
}
return group.getName();
}
protected void initGroupDetails() {
Label groupDetailsHeader = new Label(i18nManager.getMessage(Messages.GROUP_HEADER_DETAILS));
groupDetailsHeader.addStyleName(ExplorerLayout.STYLE_H3);
groupDetailsHeader.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
addDetailComponent(groupDetailsHeader);
detailLayout = new HorizontalLayout();
detailLayout.setSpacing(true);
detailLayout.setMargin(true, false, true, false);
addDetailComponent(detailLayout);
populateGroupDetails();
}
protected void populateGroupDetails() {
initGroupProperties();
initGroupActions();
}
protected void initGroupProperties() {
detailsGrid = new GridLayout(2, 3);
detailsGrid.setSpacing(true);
detailLayout.setMargin(true, true, true, false);
detailLayout.addComponent(detailsGrid);
// id
Label idLabel = new Label(i18nManager.getMessage(Messages.GROUP_ID) + ": ");
idLabel.addStyleName(ExplorerLayout.STYLE_LABEL_BOLD);
detailsGrid.addComponent(idLabel);
Label idValueLabel = new Label(group.getId());
detailsGrid.addComponent(idValueLabel);
// name
Label nameLabel = new Label(i18nManager.getMessage(Messages.GROUP_NAME) + ": ");
nameLabel.addStyleName(ExplorerLayout.STYLE_LABEL_BOLD);
detailsGrid.addComponent(nameLabel);
if (!editingDetails) {
Label nameValueLabel = new Label(group.getName());
detailsGrid.addComponent(nameValueLabel);
} else {
nameTextField = new TextField(null, group.getName());
detailsGrid.addComponent(nameTextField);
}
// Type
Label typeLabel = new Label(i18nManager.getMessage(Messages.GROUP_TYPE) + ": ");
typeLabel.addStyleName(ExplorerLayout.STYLE_LABEL_BOLD);
detailsGrid.addComponent(typeLabel);
if (!editingDetails) {
Label typeValueLabel = new Label(group.getType());
detailsGrid.addComponent(typeValueLabel);
} else {
typeCombobox = new ComboBox(null, Arrays.asList("assignment", "security-role"));
typeCombobox.setNullSelectionAllowed(false);
typeCombobox.setInvalidAllowed(false);
typeCombobox.select(group.getType());
detailsGrid.addComponent(typeCombobox);
}
}
protected void initGroupActions() {
VerticalLayout actionsLayout = new VerticalLayout();
actionsLayout.setSpacing(true);
actionsLayout.setMargin(false, false, false, true);
detailLayout.addComponent(actionsLayout);
if (editingDetails) {
initSaveButton(actionsLayout);
} else {
initEditButton(actionsLayout);
initDeleteButton(actionsLayout);
}
}
protected void initEditButton(VerticalLayout actionsLayout) {
Button editButton = new Button(i18nManager.getMessage(Messages.USER_EDIT));
editButton.addStyleName(Reindeer.BUTTON_SMALL);
actionsLayout.addComponent(editButton);
editButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
editingDetails = true;
detailLayout.removeAllComponents();
populateGroupDetails();
}
});
}
protected void initSaveButton(VerticalLayout actionsLayout) {
Button saveButton = new Button(i18nManager.getMessage(Messages.USER_SAVE));
saveButton.addStyleName(Reindeer.BUTTON_SMALL);
actionsLayout.addComponent(saveButton);
saveButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
String originalName = group.getName();
// Update data
if (nameTextField.getValue() != null) {
group.setName(nameTextField.getValue().toString());
group.setType(typeCombobox.getValue().toString());
}
identityService.saveGroup(group);
// Update UI
editingDetails = false;
detailLayout.removeAllComponents();
populateGroupDetails();
// Refresh task list (only if name was changed)
if ( (originalName != null && !originalName.equals(group.getName()))
|| (originalName == null && group.getName() != null)) {
groupPage.notifyGroupChanged(group.getId());
}
}
});
}
protected void initDeleteButton(VerticalLayout actionsLayout) {
Button deleteButton = new Button(i18nManager.getMessage(Messages.GROUP_DELETE));
deleteButton.addStyleName(Reindeer.BUTTON_SMALL);
actionsLayout.addComponent(deleteButton);
deleteButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
ConfirmationDialogPopupWindow confirmPopup =
new ConfirmationDialogPopupWindow(i18nManager.getMessage(Messages.GROUP_CONFIRM_DELETE, group.getId()));
confirmPopup.addListener(new ConfirmationEventListener() {
protected void rejected(ConfirmationEvent event) {
}
protected void confirmed(ConfirmationEvent event) {
// Delete group from database
identityService.deleteGroup(group.getId());
// Update ui
groupPage.refreshSelectNext();
}
});
ExplorerApp.get().getViewManager().showPopupWindow(confirmPopup);
}
});
}
protected void initMembers() {
HorizontalLayout membersHeader = new HorizontalLayout();
membersHeader.setSpacing(true);
membersHeader.setWidth(100, UNITS_PERCENTAGE);
membersHeader.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
addDetailComponent(membersHeader);
initMembersTitle(membersHeader);
initAddMembersButton(membersHeader);
membersLayout = new HorizontalLayout();
membersLayout.setWidth(100, UNITS_PERCENTAGE);
addDetailComponent(membersLayout);
initMembersTable();
}
protected void initMembersTitle(HorizontalLayout membersHeader) {
Label usersHeader = new Label(i18nManager.getMessage(Messages.GROUP_HEADER_USERS));
usersHeader.addStyleName(ExplorerLayout.STYLE_H3);
membersHeader.addComponent(usersHeader);
}
protected void initAddMembersButton(HorizontalLayout membersHeader) {
Button addButton = new Button();
addButton.addStyleName(ExplorerLayout.STYLE_ADD);
membersHeader.addComponent(addButton);
membersHeader.setComponentAlignment(addButton, Alignment.MIDDLE_RIGHT);
addButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
final SelectUsersPopupWindow selectUsersPopup = new SelectUsersPopupWindow(
i18nManager.getMessage(Messages.GROUP_SELECT_MEMBERS, group.getId()),
true, false, getCurrentMembers());
ExplorerApp.get().getViewManager().showPopupWindow(selectUsersPopup);
// Listen to submit events (that contain the selected users)
selectUsersPopup.addListener(new SubmitEventListener() {
protected void submitted(SubmitEvent event) {
Collection<String> userIds = selectUsersPopup.getSelectedUserIds();
if (userIds.size() > 0) {
for (String userId : userIds) {
identityService.createMembership(userId, group.getId());
}
notifyMembershipChanged();
}
}
protected void cancelled(SubmitEvent event) {
}
});
}
});
}
// Hacky - must be put in custom service
protected List<String> getCurrentMembers() {
List<User> users = identityService.createUserQuery().memberOfGroup(group.getId()).list();
List<String> userIds = new ArrayList<String>();
for (User user : users) {
userIds.add(user.getId());
}
return userIds;
}
protected void initMembersTable() {
LazyLoadingQuery query = new GroupMembersQuery(group.getId(), this);
if (query.size() > 0) {
membersTable = new Table();
membersTable.setWidth(100, UNITS_PERCENTAGE);
membersTable.setHeight(400, UNITS_PIXELS);
membersTable.setEditable(false);
membersTable.setSelectable(false);
membersTable.setSortDisabled(false);
LazyLoadingContainer container = new LazyLoadingContainer(query, 10);
membersTable.setContainerDataSource(container);
membersTable.addContainerProperty("id", Button.class, null);
membersTable.addContainerProperty("firstName", String.class, null);
membersTable.addContainerProperty("lastName", String.class, null);
membersTable.addContainerProperty("email", String.class, null);
membersTable.addContainerProperty("actions", Component.class, null);
membersLayout.addComponent(membersTable);
} else {
noMembersTable = new Label(i18nManager.getMessage(Messages.GROUP_NO_MEMBERS));
membersLayout.addComponent(noMembersTable);
}
}
public void notifyMembershipChanged() {
membersLayout.removeAllComponents();
initMembersTable();
}
}