package com.constellio.app.ui.pages.management.permissions;
import static com.constellio.app.ui.i18n.i18n.$;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.constellio.app.ui.entities.RoleVO;
import com.constellio.app.ui.framework.buttons.WindowButton;
import com.constellio.app.ui.framework.components.BaseForm;
import com.constellio.app.ui.framework.components.fields.BaseTextField;
import com.constellio.app.ui.pages.base.BaseViewImpl;
import com.constellio.model.frameworks.validation.ValidationException;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.fieldgroup.PropertyId;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.Align;
import com.vaadin.ui.Table.CellStyleGenerator;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
public class PermissionsManagementViewImpl extends BaseViewImpl implements PermissionsManagementView {
public static final String CREATE_ROLE = "create-role";
public static final String SAVE = "save";
public static final String REVERT = "revert";
private final PermissionsManagementPresenter presenter;
private RoleMatrix matrix;
private VerticalLayout layout;
private Button save;
private Button revert;
public PermissionsManagementViewImpl() {
presenter = new PermissionsManagementPresenter(this);
}
@Override
protected String getTitle() {
return $("PermissionsManagementView.viewTitle");
}
@Override
protected ClickListener getBackButtonClickListener() {
return new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
navigateTo().adminModule();
}
};
}
@Override
protected List<Button> buildActionMenuButtons(ViewChangeEvent event) {
List<Button> buttons = super.buildActionMenuButtons(event);
CreateRoleButton create = new CreateRoleButton();
create.addStyleName(CREATE_ROLE);
buttons.add(create);
save = new Button($("PermissionsManagementView.save"));
save.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
presenter.saveRequested(matrix.getModifiedRoles());
}
});
save.addStyleName(SAVE);
save.setEnabled(false);
buttons.add(save);
revert = new Button($("PermissionsManagementView.revert"));
revert.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
presenter.revertRequested();
}
});
revert.addStyleName(REVERT);
revert.setEnabled(false);
buttons.add(revert);
return buttons;
}
@Override
public void setSaveAndRevertButtonStatus(boolean enabled) {
save.setEnabled(enabled);
revert.setEnabled(enabled);
}
@Override
public void addRole(RoleVO role) {
matrix.addRole(role);
buildAllGroups();
}
@Override
public void refreshView() {
matrix = new RoleMatrix(presenter.getRoles());
buildAllGroups();
}
@Override
protected Component buildMainComponent(ViewChangeEvent event) {
layout = new VerticalLayout();
layout.setSpacing(true);
refreshView();
return layout;
}
private void buildAllGroups() {
layout.removeAllComponents();
for (String group : presenter.getPermissionGroups()) {
layout.addComponent(buildPermissionGroup(group));
}
}
private Component buildPermissionGroup(String group) {
Label caption = new Label($("perm.group." + group));
caption.addStyleName(ValoTheme.LABEL_H2);
Table table = new Table();
for (String permission : presenter.getPermissionsInGroup(group)) {
table.addItem(permission);
}
table.setPageLength(table.size());
matrix.attachTo(table);
VerticalLayout layout = new VerticalLayout(caption, table);
layout.setSpacing(true);
return layout;
}
public class RoleMatrix implements ColumnGenerator, CellStyleGenerator {
public static final String PERMISSION_NAME_COLUMN = "permissionName";
private final Map<Object, RoleVO> roles;
public RoleMatrix(List<RoleVO> roles) {
this.roles = new HashMap<>(roles.size());
for (RoleVO role : roles) {
this.roles.put(role.getCode(), role);
}
}
public void attachTo(Table table) {
table.addGeneratedColumn(PERMISSION_NAME_COLUMN, this);
table.setColumnHeader(PERMISSION_NAME_COLUMN, "");
table.setColumnWidth(PERMISSION_NAME_COLUMN, 280);
for (RoleVO role : roles.values()) {
String code = role.getCode();
table.addGeneratedColumn(code, this);
table.setColumnWidth(code, 60);
table.setColumnAlignment(code, Align.CENTER);
}
table.setCellStyleGenerator(this);
}
public void addRole(RoleVO role) {
roles.put(role.getCode(), role);
}
public List<RoleVO> getModifiedRoles() {
ArrayList<RoleVO> result = new ArrayList<>();
for (RoleVO role : roles.values()) {
if (role.isDirty()) {
result.add(role);
}
}
return result;
}
@Override
public String getStyle(Table source, Object itemId, Object propertyId) {
if (propertyId == null || PERMISSION_NAME_COLUMN.equals(propertyId)) {
return null;
}
return roles.get(propertyId).isPermissionDirty((String) itemId) ?
"permission-dirty" : "permission-clean";
}
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
String permission = (String) itemId;
return columnId.equals(PERMISSION_NAME_COLUMN) ?
buildCaption(permission) :
buildCheckBox(roles.get(columnId), permission, source);
}
private Object buildCaption(String permission) {
return new Label($("perm." + permission), ContentMode.HTML);
}
private Object buildCheckBox(final RoleVO role, final String permission, final Table table) {
final CheckBox checkBox = new CheckBox();
checkBox.setValue(role.hasPermission(permission));
checkBox.addStyleName(role.getCode() + "-" + permission.replaceAll("\\.", "_"));
checkBox.addValueChangeListener(new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
if (checkBox.getValue()) {
role.addPermission(permission);
} else {
role.removePermission(permission);
}
presenter.permissionsChanged(isDirty());
table.refreshRowCache();
}
});
return checkBox;
}
private boolean isDirty() {
for (RoleVO role : roles.values()) {
if (role.isDirty()) {
return true;
}
}
return false;
}
}
public class CreateRoleButton extends WindowButton {
public static final String ROLE_CODE = "role-code";
public static final String ROLE_TITLE = "role-title";
@PropertyId("code") private BaseTextField code;
@PropertyId("title") private BaseTextField title;
public CreateRoleButton() {
super($("PermissionsManagementView.createRole"), $("PermissionsManagementView.createRole"));
}
@Override
protected Component buildWindowContent() {
code = new BaseTextField($("PermissionsManagementView.code"));
code.setRequired(true);
code.setId(ROLE_CODE);
title = new BaseTextField($("PermissionsManagementView.title"));
title.setRequired(true);
title.setId(ROLE_TITLE);
return new BaseForm<RoleVO>(new RoleVO(), this, code, title) {
@Override
protected void saveButtonClick(RoleVO role)
throws ValidationException {
getWindow().close();
presenter.roleCreationRequested(role);
}
@Override
protected void cancelButtonClick(RoleVO role) {
getWindow().close();
}
};
}
}
}