Java tutorial
/** * This file is part of mycollab-web. * * mycollab-web is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * mycollab-web 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with mycollab-web. If not, see <http://www.gnu.org/licenses/>. */ package com.mycollab.module.project.ui.components; import com.mycollab.common.domain.MonitorItem; import com.mycollab.common.domain.criteria.MonitorSearchCriteria; import com.mycollab.common.i18n.FollowerI18nEnum; import com.mycollab.common.i18n.GenericI18Enum; import com.mycollab.common.service.MonitorItemService; import com.mycollab.core.arguments.*; import com.mycollab.core.utils.StringUtils; import com.mycollab.module.project.CurrentProjectVariables; import com.mycollab.module.project.ProjectMemberStatusConstants; import com.mycollab.module.project.domain.SimpleProjectMember; import com.mycollab.module.project.domain.criteria.ProjectMemberSearchCriteria; import com.mycollab.module.project.service.ProjectMemberService; import com.mycollab.module.user.CommonTooltipGenerator; import com.mycollab.module.user.domain.SimpleUser; import com.mycollab.db.arguments.*; import com.mycollab.spring.AppContextUtil; import com.mycollab.vaadin.MyCollabUI; import com.mycollab.vaadin.UserUIContext; import com.mycollab.vaadin.AsyncInvoker; import com.mycollab.vaadin.ui.ELabel; import com.mycollab.vaadin.ui.NotificationUtil; import com.mycollab.vaadin.ui.UIConstants; import com.mycollab.vaadin.ui.UserAvatarControlFactory; import com.mycollab.vaadin.web.ui.WebThemes; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.*; import com.vaadin.ui.themes.ValoTheme; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.jouni.restrain.Restrain; import org.vaadin.viritin.layouts.MCssLayout; import org.vaadin.viritin.layouts.MHorizontalLayout; import org.vaadin.viritin.layouts.MVerticalLayout; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.List; /** * @author MyCollab Ltd. * @since 4.3.3 */ public class ProjectFollowersComp<V extends ValuedBean> extends MVerticalLayout { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(ProjectFollowersComp.class); private MonitorItemService monitorItemService; private List<SimpleUser> followers; private String type; private Integer typeId; private V bean; private String permissionItem; private CssLayout watcherLayout; public ProjectFollowersComp(String type, String permissionItem) { super(); this.withMargin(false); monitorItemService = AppContextUtil.getSpringBean(MonitorItemService.class); this.type = type; this.permissionItem = permissionItem; this.setWidth("100%"); } public void displayFollowers(final V bean) { this.bean = bean; try { typeId = (Integer) PropertyUtils.getProperty(bean, "id"); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { LOG.error("Error", e); return; } this.removeAllComponents(); MHorizontalLayout header = new MHorizontalLayout().withStyleName("info-hdr"); header.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); Label followerHeader = new Label( FontAwesome.EYE.getHtml() + " " + UserUIContext.getMessage(FollowerI18nEnum.OPT_SUB_INFO_WATCHERS), ContentMode.HTML); header.addComponent(followerHeader); if (hasEditPermission()) { final PopupView addPopupView = new PopupView(UserUIContext.getMessage(GenericI18Enum.ACTION_MODIFY), new MVerticalLayout()); addPopupView.addPopupVisibilityListener(popupVisibilityEvent -> { PopupView.Content content = addPopupView.getContent(); if (popupVisibilityEvent.isPopupVisible()) { MVerticalLayout popupComponent = (MVerticalLayout) content.getPopupComponent(); popupComponent.removeAllComponents(); popupComponent.with(new ELabel(UserUIContext.getMessage(FollowerI18nEnum.OPT_SUB_INFO_WATCHERS)) .withStyleName(ValoTheme.LABEL_H3), new ModifyWatcherPopup()); } else { MVerticalLayout popupComponent = (MVerticalLayout) content.getPopupComponent(); ModifyWatcherPopup popup = (ModifyWatcherPopup) popupComponent.getComponent(1); List<MonitorItem> unsavedItems = popup.getUnsavedItems(); monitorItemService.saveMonitorItems(unsavedItems); loadWatchers(); } }); header.addComponent(addPopupView); } header.addComponent(ELabel.fontIcon(FontAwesome.QUESTION_CIRCLE).withStyleName(WebThemes.INLINE_HELP) .withDescription(UserUIContext.getMessage(FollowerI18nEnum.FOLLOWER_EXPLAIN_HELP))); this.addComponent(header); watcherLayout = new MCssLayout().withFullWidth().withStyleName(WebThemes.FLEX_DISPLAY); this.addComponent(watcherLayout); loadWatchers(); } private void loadWatchers() { AsyncInvoker.access(getUI(), new AsyncInvoker.PageCommand() { @Override public void run() { watcherLayout.removeAllComponents(); followers = monitorItemService.getWatchers(type, typeId); for (SimpleUser follower : followers) { watcherLayout.addComponent(new FollowerComp(follower)); } } }); } private boolean hasEditPermission() { return CurrentProjectVariables.canWrite(permissionItem); } private void unFollowItem(String username) { try { MonitorSearchCriteria criteria = new MonitorSearchCriteria(); criteria.setTypeId(new NumberSearchField((Integer) PropertyUtils.getProperty(bean, "id"))); criteria.setType(StringSearchField.and(type)); criteria.setUser(StringSearchField.and(username)); monitorItemService.removeByCriteria(criteria, MyCollabUI.getAccountId()); for (SimpleUser user : followers) { if (username.equals(user.getUsername())) { followers.remove(user); break; } } } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { LOG.error("Error", e); } } private class FollowerComp extends CssLayout { FollowerComp(final SimpleUser user) { final Image userAvatarBtn = UserAvatarControlFactory .createUserAvatarEmbeddedComponent(user.getAvatarid(), 32); userAvatarBtn.addStyleName(UIConstants.CIRCLE_BOX); userAvatarBtn.setDescription(CommonTooltipGenerator.generateTooltipUser(UserUIContext.getUserLocale(), user, MyCollabUI.getSiteUrl(), UserUIContext.getUserTimeZone())); addComponent(userAvatarBtn); this.addStyleName("removeable-btn"); this.setWidthUndefined(); this.addLayoutClickListener(layoutClickEvent -> { if (layoutClickEvent.getClickedComponent() == userAvatarBtn) { } else if (!hasEditPermission()) { NotificationUtil.showMessagePermissionAlert(); } else { unFollowItem(user.getUsername()); ((ComponentContainer) FollowerComp.this.getParent()).removeComponent(FollowerComp.this); } }); } } private class ModifyWatcherPopup extends MVerticalLayout { private List<SimpleProjectMember> projectMembers; private List<SimpleProjectMember> unsavedMembers = new ArrayList<>(); ModifyWatcherPopup() { new Restrain(this).setMaxHeight("600px"); this.addStyleName(WebThemes.SCROLLABLE_CONTAINER); ProjectMemberSearchCriteria criteria = new ProjectMemberSearchCriteria(); criteria.setProjectId(new NumberSearchField(CurrentProjectVariables.getProjectId())); criteria.setStatuses(new SetSearchField<>(ProjectMemberStatusConstants.ACTIVE)); criteria.addOrderField(new SearchCriteria.OrderField("memberFullName", SearchCriteria.ASC)); ProjectMemberService projectMemberService = AppContextUtil.getSpringBean(ProjectMemberService.class); projectMembers = projectMemberService.findPageableListByCriteria(new BasicSearchRequest<>(criteria)); for (SimpleProjectMember member : projectMembers) { this.addComponent(new FollowerRow(member)); } this.setWidth("100%"); } List<MonitorItem> getUnsavedItems() { List<MonitorItem> items = new ArrayList<>(unsavedMembers.size()); for (SimpleProjectMember member : unsavedMembers) { MonitorItem item = new MonitorItem(); item.setExtratypeid(CurrentProjectVariables.getProjectId()); item.setMonitorDate(new GregorianCalendar().getTime()); item.setSaccountid(MyCollabUI.getAccountId()); item.setType(type); item.setTypeid(typeId); item.setUser(member.getUsername()); items.add(item); } return items; } private class FollowerRow extends MHorizontalLayout { private CheckBox isSelectedBox; private boolean isWatching = false; private FollowerRow(final SimpleProjectMember member) { isSelectedBox = new CheckBox(); Image avatarResource = UserAvatarControlFactory .createUserAvatarEmbeddedComponent(member.getMemberAvatarId(), 16); Label icon = new Label(StringUtils.trim(member.getDisplayName(), 20, true)); icon.setDescription(member.getDisplayName()); this.with(isSelectedBox, avatarResource, icon); for (SimpleUser follower : followers) { if (follower.getUsername().equals(member.getUsername())) { isSelectedBox.setValue(true); isWatching = true; } } isSelectedBox.addValueChangeListener(valueChangeEvent -> { if (isSelectedBox.getValue()) { if (!isWatching) { unsavedMembers.add(member); } } else { if (isWatching) { unFollowItem(member.getUsername()); isWatching = false; } else { unsavedMembers.remove(member); } } }); } } } }