/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.adm.ui.employee; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.vaadin.addon.jpacontainer.JPAContainer; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.event.Action; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.ui.AbstractComponentContainer; import com.vaadin.ui.AbstractSelect; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.CustomTable; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.Panel; import com.vaadin.ui.PasswordField; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import org.tepi.filtertable.FilterTable; import org.vaadin.dialogs.ConfirmDialog; import ru.codeinside.adm.AdminServiceProvider; import ru.codeinside.adm.UserItem; import ru.codeinside.adm.database.Group; import ru.codeinside.adm.database.Role; import ru.codeinside.adm.ui.FilterDecorator_; import ru.codeinside.adm.ui.LazyLoadingContainer2; import ru.codeinside.adm.ui.RepeatPasswordValidator; import ru.codeinside.gses.vaadin.MaskedTextField; import ru.codeinside.gses.webui.components.EmployeeInfo; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; public abstract class TableEmployee extends VerticalLayout { static final Action ACTION_VIEW = new Action("Просмотр информации пользователя"); static final Action ACTION_EDIT = new Action("Редактировать пользователя"); static final Action ACTION_LOCK = new Action("Заблокировать пользователя"); static final Action ACTION_UNLOCK = new Action("Разблокировать пользователя"); static final Action[] ACTIONS = new Action[]{ACTION_VIEW, ACTION_EDIT}; private static final long serialVersionUID = -8903404478050765452L; protected boolean lockedFilterValue; public Layout hr; static public OptionGroup createRoleOptionGroup(String caption) { final OptionGroup roles = new OptionGroup(caption, ImmutableSet.copyOf(Role.values())); for (final Role role : Role.values()) { roles.setItemCaption(role, role.description); } roles.setMultiSelect(true); roles.setNullSelectionAllowed(true); roles.setImmediate(true); return roles; } public static void addListener(final FilterTable one, final FilterTable two) { one.addListener(new Property.ValueChangeListener() { private static final long serialVersionUID = 1L; public void valueChange(ValueChangeEvent event) { Object value = event.getProperty().getValue(); if (value != null) { one.removeItem(value); for (Group group : AdminServiceProvider.get().findGroupByName(value.toString())) { two.addItem(new Object[]{group.getName(), group.getTitle()}, group.getName()); } } } }); } public static void table(final HorizontalLayout executorGroups, FilterTable table) { table.addContainerProperty("Код", String.class, ""); table.addContainerProperty("Название", String.class, ""); table.setHeight("250px"); table.setWidth("350px"); table.setSelectable(true); table.setMultiSelect(false); table.setImmediate(true); table.setFilterBarVisible(true); table.setFilterDecorator(new FilterDecorator_()); executorGroups.addComponent(table); } public static void setRolesEnabled(OptionGroup optionGroup, Component certificateBlock, Component executorGroups, HorizontalLayout supervisorGroupsEmp, HorizontalLayout supervisorGroupsOrg) { Set<Role> roles = (Set) optionGroup.getValue(); Boolean e = roles.isEmpty(); Boolean c = roles.contains(Role.Administrator); for (Object role : optionGroup.getItemIds()) { if (role == Role.Administrator) { optionGroup.setItemEnabled(role, e || c); } else { optionGroup.setItemEnabled(role, e || !c); } } certificateBlock.setVisible(roles.contains(Role.Executor) || roles.contains(Role.Declarant) || roles.contains(Role.Supervisor) || roles.contains(Role.SuperSupervisor)); executorGroups.setVisible(roles.contains(Role.Executor)); supervisorGroupsEmp.setVisible(roles.contains(Role.Supervisor)); supervisorGroupsOrg.setVisible(roles.contains(Role.Supervisor)); } public static TextField addTextField(AbstractComponentContainer container, String widthColumn, String content) { HorizontalLayout l; l = new HorizontalLayout(); Label label = new Label(content); label.setWidth(widthColumn); l.addComponent(label); l.setComponentAlignment(label, Alignment.MIDDLE_LEFT); final TextField field = new TextField(); l.addComponent(field); container.addComponent(l); return field; } public static MaskedTextField addMaskedTextField(AbstractComponentContainer container, String widthColumn, String content) { HorizontalLayout l; l = new HorizontalLayout(); Label label = new Label(content); label.setWidth(widthColumn); l.addComponent(label); l.setComponentAlignment(label, Alignment.MIDDLE_LEFT); final MaskedTextField field = new MaskedTextField(); l.addComponent(field); container.addComponent(l); return field; } public static PasswordField addPasswordField(AbstractComponentContainer container, String widthColumn, String content) { HorizontalLayout l; l = new HorizontalLayout(); Label label = new Label(content); label.setWidth(widthColumn); l.addComponent(label); l.setComponentAlignment(label, Alignment.MIDDLE_LEFT); final PasswordField field = new PasswordField(); l.addComponent(field); container.addComponent(l); return field; } final static class RolesColumn implements CustomTable.ColumnGenerator { final static Joiner joiner = Joiner.on(", "); @Override public Object generateCell(CustomTable source, Object itemId, Object columnId) { Object object = source.getContainerProperty(itemId, columnId).getValue(); if (object instanceof Set) { final Set<Role> roles = (Set) object; final TreeSet<String> result = new TreeSet<String>(); for (Role role : roles) { result.add(role.name() + "(" + role.description + ")"); } return joiner.join(result); } return null; } } protected void addContextMenu(final CustomTable table) { table.addActionHandler(new Action.Handler() { private static final long serialVersionUID = 1L; public Action[] getActions(Object target, Object sender) { ArrayList<Action> result = new ArrayList<Action>(ACTIONS.length + 1); result.addAll(Arrays.asList(ACTIONS)); if (lockedFilterValue) { result.add(ACTION_UNLOCK); } else { result.add(ACTION_LOCK); } return result.toArray(new Action[result.size()]); } public void handleAction(Action action, Object sender, Object target) { final Item item = table.getItem(table.getValue()); if (item != null) { if (ACTION_EDIT == action) { edit(table); table.refreshRowCache(); } else if (ACTION_VIEW == action) { view(table); table.refreshRowCache(); } else if (ACTION_LOCK == action) { lockUserActionHandler(table); table.refreshRowCache(); } else if (ACTION_UNLOCK == action) { unlockUserActionHandler(table); table.refreshRowCache(); } } } }); } protected void unlockUserActionHandler(final CustomTable table) { ConfirmDialog.show(table.getWindow(), "Снятие Блокировки", "Подтвердите снятие блокировки", "Подтверждаю", "Отмена", new ConfirmDialog.Listener() { public void onClose(ConfirmDialog dialog) { if (dialog.isConfirmed()) { changeLockAttribute(table, false); } } }); } protected void lockUserActionHandler(final CustomTable table) { ConfirmDialog.show(table.getWindow(), "Блокировка", "Подтвердите блокировку", "Подтверждаю", "Отмена", new ConfirmDialog.Listener() { public void onClose(ConfirmDialog dialog) { if (dialog.isConfirmed()) { changeLockAttribute(table, true); } } }); } private void changeLockAttribute(CustomTable table, boolean newLockedPropertyValue) { final Item item = table.getItem(table.getValue()); final String login = (String) item.getItemProperty("login").getValue(); final UserItem userItem = AdminServiceProvider.get().getUserItem(login); userItem.setLocked(newLockedPropertyValue); AdminServiceProvider.get().setUserItem(login, userItem); refresh(table); if (newLockedPropertyValue) { getWindow().showNotification("Пользователь " + login + " заблокирован"); } else { getWindow().showNotification("Пользователь " + login + " разблокирован"); } } protected void edit(final CustomTable table) { final Item item = table.getItem(table.getValue()); final String login = (String) item.getItemProperty("login").getValue(); final UserItem userItem = AdminServiceProvider.get().getUserItem(login); final Pattern snilsPattern = Pattern.compile("\\d{11}"); final Pattern splitSnilsPattern = Pattern.compile("(\\d{3})(\\d{3})(\\d{3})(\\d{2})"); final Panel layout = new Panel(); ((Layout.SpacingHandler) layout.getContent()).setSpacing(true); layout.setSizeFull(); layout.addComponent(new Label("Информация пользователя " + login)); String widthColumn = "100px"; final PasswordField fieldPass = addPasswordField(layout, widthColumn, "Пароль"); final PasswordField fieldPassRepeat = addPasswordField(layout, widthColumn, "Подтверждение пароля"); fieldPassRepeat.addValidator(new RepeatPasswordValidator(fieldPass)); final MaskedTextField fieldSnils = addMaskedTextField(layout, widthColumn, "СНИЛС"); fieldSnils.setMask("###-###-### ##"); final TextField fieldFIO = addTextField(layout, widthColumn, "ФИО"); final String snils = userItem.getSnils() == null ? "" : userItem.getSnils(); final Matcher maskMatcher = snilsPattern.matcher(snils); final Matcher splitMatcher = splitSnilsPattern.matcher(snils); if (maskMatcher.matches()) { String maskedSnils = splitMatcher.replaceAll("$1-$2-$3 $4"); fieldSnils.setValue(maskedSnils); } fieldFIO.setValue(userItem.getFio()); HorizontalLayout l1 = new HorizontalLayout(); Label labelRole = new Label("Права"); labelRole.setWidth(widthColumn); l1.addComponent(labelRole); l1.setComponentAlignment(labelRole, Alignment.MIDDLE_LEFT); final OptionGroup roleOptionGroup = TableEmployee.createRoleOptionGroup(null); roleOptionGroup.setValue(userItem.getRoles()); l1.addComponent(roleOptionGroup); layout.addComponent(l1); final CertificateBlock certificateBlock = new CertificateBlock(userItem); layout.addComponent(certificateBlock); final ExecutorGroupsBlock executorGroupsBlock = new ExecutorGroupsBlock(userItem); layout.addComponent(executorGroupsBlock); final HorizontalLayout supervisorGroupsEmp = new HorizontalLayout(); supervisorGroupsEmp.setMargin(true, true, true, false); supervisorGroupsEmp.setSpacing(true); supervisorGroupsEmp.setCaption("Назначить группы сотрудников для контроля"); final FilterTable allSupervisorGroupsEmp = new FilterTable(); allSupervisorGroupsEmp.setCaption("Доступные"); table(supervisorGroupsEmp, allSupervisorGroupsEmp); final FilterTable currentSupervisorGroupsEmp = new FilterTable(); currentSupervisorGroupsEmp.setCaption("Отобранные"); table(supervisorGroupsEmp, currentSupervisorGroupsEmp); for (String groupName : AdminServiceProvider.get().getEmpGroupNames()) { for (Group group : AdminServiceProvider.get().findGroupByName(groupName)) { if (userItem.getEmployeeGroups().contains(groupName)) { currentSupervisorGroupsEmp.addItem(new Object[]{groupName, group.getTitle()}, groupName); } else { allSupervisorGroupsEmp.addItem(new Object[]{groupName, group.getTitle()}, groupName); } } } addListener(allSupervisorGroupsEmp, currentSupervisorGroupsEmp); addListener(currentSupervisorGroupsEmp, allSupervisorGroupsEmp); layout.addComponent(supervisorGroupsEmp); final HorizontalLayout supervisorGroupsOrg = new HorizontalLayout(); supervisorGroupsOrg.setMargin(true, true, true, false); supervisorGroupsOrg.setSpacing(true); supervisorGroupsOrg.setCaption("Назначить группы организаций для контроля"); final FilterTable allSupervisorGroupsOrg = new FilterTable(); allSupervisorGroupsOrg.setCaption("Доступные"); table(supervisorGroupsOrg, allSupervisorGroupsOrg); final FilterTable currentSupervisorGroupsOrg = new FilterTable(); currentSupervisorGroupsOrg.setCaption("Отобранные"); table(supervisorGroupsOrg, currentSupervisorGroupsOrg); for (String groupName : AdminServiceProvider.get().getOrgGroupNames()) { for (Group group : AdminServiceProvider.get().findGroupByName(groupName)) { if (userItem.getOrganizationGroups().contains(groupName)) { currentSupervisorGroupsOrg.addItem(new Object[]{groupName, group.getTitle()}, groupName); } else { allSupervisorGroupsOrg.addItem(new Object[]{groupName, group.getTitle()}, groupName); } } } addListener(allSupervisorGroupsOrg, currentSupervisorGroupsOrg); addListener(currentSupervisorGroupsOrg, allSupervisorGroupsOrg); layout.addComponent(supervisorGroupsOrg); setRolesEnabled(roleOptionGroup, certificateBlock, executorGroupsBlock, supervisorGroupsEmp, supervisorGroupsOrg); roleOptionGroup.addListener(new Listener() { private static final long serialVersionUID = 1L; public void componentEvent(Event event) { setRolesEnabled(roleOptionGroup, certificateBlock, executorGroupsBlock, supervisorGroupsEmp, supervisorGroupsOrg); } }); Button cancel = new Button("Отмена", new Button.ClickListener() { private static final long serialVersionUID = 1L; @Override public void buttonClick(Button.ClickEvent event) { removeComponent(layout); addComponent(table); table.setValue(null); if (hr != null) { hr.setVisible(true); } setExpandRatio(table, 1f); } }); Button apply = new Button("Применить", new Button.ClickListener() { private static final long serialVersionUID = 1L; public void buttonClick(ClickEvent event) { String password = (String) fieldPass.getValue(); String passwordRepeat = (String) fieldPassRepeat.getValue(); if (!fieldPassRepeat.isValid() || !(password.equals(passwordRepeat))) { getWindow().showNotification("Новый пароль не совпадает с подтверждением пароля", Window.Notification.TYPE_ERROR_MESSAGE); return; } String snilsFieldValue = fieldSnils.getValue() == null ? "" : (String) fieldSnils.getValue(); String snilsValue = snilsFieldValue.replaceAll("\\D+", ""); Matcher snilsMatcher = snilsPattern.matcher(snilsValue); if (!snilsFieldValue.isEmpty() && !snilsMatcher.matches()) { getWindow().showNotification("СНИЛС введён неверно", Window.Notification.TYPE_ERROR_MESSAGE); return; } if (!AdminServiceProvider.get().isUniqueSnils(login, snilsValue)) { getWindow().showNotification("Значение СНИЛС не уникально", Window.Notification.TYPE_ERROR_MESSAGE); return; } String fio = (String) fieldFIO.getValue(); Set<Role> roles = (Set) roleOptionGroup.getValue(); TreeSet<String> groupExecutor = executorGroupsBlock.getGroups(); TreeSet<String> groupSupervisorEmp = new TreeSet<String>( (Collection<String>) currentSupervisorGroupsEmp.getItemIds()); TreeSet<String> groupSupervisorOrg = new TreeSet<String>( (Collection<String>) currentSupervisorGroupsOrg.getItemIds()); boolean modified = false; if (certificateBlock.isCertificateWasRemoved()) { userItem.setX509(null); modified = true; } if (!password.equals("") && password.equals(passwordRepeat)) { userItem.setPassword1(password); userItem.setPassword2(passwordRepeat); modified = true; } if (!fio.trim().equals("") && !fio.equals(userItem.getFio())) { userItem.setFio(fio); userItem.setX509(null); modified = true; } if (!snilsValue.equals(userItem.getSnils())) { userItem.setSnils(snilsValue); modified = true; } if (!roles.equals(userItem.getRoles())) { userItem.setRoles(roles); modified = true; } if (!groupExecutor.equals(userItem.getGroups())) { userItem.setGroups(groupExecutor); modified = true; } if (!groupSupervisorEmp.equals(userItem.getEmployeeGroups())) { userItem.setEmployeeGroups(groupSupervisorEmp); modified = true; } if (!groupSupervisorOrg.equals(userItem.getOrganizationGroups())) { userItem.setOrganizationGroups(groupSupervisorOrg); modified = true; } if (modified) { // TODO : обновление userInfoPanel // if (getApplication().getUser().equals(login)) { // ((AdminApp) getApplication()).getUserInfoPanel().setRole( // userItem.getRoles().toString()); // } AdminServiceProvider.get().setUserItem(login, userItem); final Container container = table.getContainerDataSource(); if (container instanceof LazyLoadingContainer2) { ((LazyLoadingContainer2) container).fireItemSetChange(); } getWindow().showNotification("Пользователь " + login + " изменен"); } else { getWindow().showNotification("Изменений нет"); } removeComponent(layout); addComponent(table); table.setValue(null); if (hr != null) { hr.setVisible(true); } setExpandRatio(table, 1f); refresh(table); } }); cancel.setClickShortcut(KeyCode.ESCAPE, 0); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.addComponent(apply); buttons.addComponent(cancel); layout.addComponent(buttons); removeComponent(table); addComponent(layout); setExpandRatio(layout, 1f); } protected void view(final AbstractSelect table) { final String login = (String) table.getItem(table.getValue()).getItemProperty("login").getValue(); Button cancel = new Button("Назад"); EmployeeInfo info = new EmployeeInfo(login, cancel); cancel.addListener(new BackAction(info, table)); cancel.setClickShortcut(KeyCode.ESCAPE, 0); addComponent(info); setExpandRatio(info, 1f); removeComponent(table); } public void refreshList() { for (Component child : ImmutableList.copyOf(this.getComponentIterator())) { if (child instanceof CustomTable) { refresh((CustomTable) child); } } } protected void refresh(final CustomTable table) { table.setValue(null); Container container = table.getContainerDataSource(); if (container instanceof JPAContainer) { ((JPAContainer) container).getEntityProvider().refresh(); } table.refreshRowCache(); } final class BackAction implements Button.ClickListener { private final EmployeeInfo info; private final AbstractSelect table; public BackAction(EmployeeInfo info, AbstractSelect table) { this.info = info; this.table = table; } @Override public void buttonClick(ClickEvent event) { removeComponent(info); addComponent(table); setExpandRatio(table, 1f); if (hr != null) { hr.setVisible(true); } if (table instanceof CustomTable) { refresh((CustomTable) table); } } } }