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.esofthead.mycollab.module.project.view.task; import com.esofthead.mycollab.common.UrlEncodeDecoder; import com.esofthead.mycollab.common.domain.OptionVal; import com.esofthead.mycollab.common.domain.criteria.TimelineTrackingSearchCriteria; import com.esofthead.mycollab.common.i18n.GenericI18Enum; import com.esofthead.mycollab.common.json.QueryAnalyzer; import com.esofthead.mycollab.common.service.OptionValService; import com.esofthead.mycollab.core.MyCollabException; import com.esofthead.mycollab.core.arguments.BasicSearchRequest; import com.esofthead.mycollab.core.arguments.NumberSearchField; import com.esofthead.mycollab.core.arguments.SearchCriteria; import com.esofthead.mycollab.core.arguments.SetSearchField; import com.esofthead.mycollab.core.db.query.LazyValueInjector; import com.esofthead.mycollab.core.db.query.SearchFieldInfo; import com.esofthead.mycollab.core.utils.BeanUtility; import com.esofthead.mycollab.core.utils.StringUtils; import com.esofthead.mycollab.eventmanager.ApplicationEventListener; import com.esofthead.mycollab.eventmanager.EventBusFactory; import com.esofthead.mycollab.module.project.CurrentProjectVariables; import com.esofthead.mycollab.module.project.ProjectRolePermissionCollections; import com.esofthead.mycollab.module.project.ProjectTypeConstants; import com.esofthead.mycollab.module.project.domain.SimpleTask; import com.esofthead.mycollab.module.project.domain.criteria.TaskSearchCriteria; import com.esofthead.mycollab.module.project.events.TaskEvent; import com.esofthead.mycollab.module.project.i18n.TaskI18nEnum; import com.esofthead.mycollab.module.project.service.ProjectTaskService; import com.esofthead.mycollab.module.project.view.task.components.*; import com.esofthead.mycollab.shell.events.ShellEvent; import com.esofthead.mycollab.spring.AppContextUtil; import com.esofthead.mycollab.vaadin.AppContext; import com.esofthead.mycollab.vaadin.AsyncInvoker; import com.esofthead.mycollab.vaadin.events.HasMassItemActionHandler; import com.esofthead.mycollab.vaadin.events.HasSearchHandlers; import com.esofthead.mycollab.vaadin.events.HasSelectableItemHandlers; import com.esofthead.mycollab.vaadin.events.HasSelectionOptionHandlers; import com.esofthead.mycollab.vaadin.mvp.AbstractPageView; import com.esofthead.mycollab.vaadin.mvp.ViewComponent; import com.esofthead.mycollab.vaadin.web.ui.QueryParamHandler; import com.esofthead.mycollab.vaadin.web.ui.ToggleButtonGroup; import com.esofthead.mycollab.vaadin.web.ui.UIConstants; import com.esofthead.mycollab.vaadin.web.ui.ValueComboBox; import com.esofthead.mycollab.vaadin.web.ui.table.AbstractPagedBeanTable; import com.google.common.eventbus.Subscribe; import com.vaadin.data.Property; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.*; import com.vaadin.ui.Button.ClickEvent; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.viritin.layouts.MHorizontalLayout; import org.vaadin.viritin.layouts.MVerticalLayout; import java.util.Collections; import java.util.List; /** * @author MyCollab Ltd. * @since 1.0 */ @ViewComponent public class TaskDashboardViewImpl extends AbstractPageView implements TaskDashboardView { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(TaskDashboardViewImpl.class); static final String GROUP_DUE_DATE = "Due Date"; static final String GROUP_START_DATE = "Start Date"; static final String GROUP_CREATED_DATE = "Created Date"; static final String PLAIN_LIST = "Plain"; static final String GROUP_USER = "User"; private int currentPage = 0; private String groupByState; private String sortDirection; private TaskSearchCriteria baseCriteria; private TaskSearchCriteria statisticSearchCriteria; private TaskSearchPanel taskSearchPanel; private MVerticalLayout wrapBody; private VerticalLayout rightColumn; private TaskGroupOrderComponent taskGroupOrderComponent; private ApplicationEventListener<TaskEvent.SearchRequest> searchHandler = new ApplicationEventListener<TaskEvent.SearchRequest>() { @Override @Subscribe public void handle(TaskEvent.SearchRequest event) { TaskSearchCriteria criteria = (TaskSearchCriteria) event.getData(); if (criteria != null) { queryTask(criteria); } } }; private ApplicationEventListener<TaskEvent.NewTaskAdded> newTaskAddedHandler = new ApplicationEventListener<TaskEvent.NewTaskAdded>() { @Override @Subscribe public void handle(TaskEvent.NewTaskAdded event) { final ProjectTaskService projectTaskService = AppContextUtil.getSpringBean(ProjectTaskService.class); SimpleTask task = projectTaskService.findById((Integer) event.getData(), AppContext.getAccountId()); if (task != null && taskGroupOrderComponent != null) { taskGroupOrderComponent.insertTasks(Collections.singletonList(task)); } displayTaskStatistic(); int totalTasks = projectTaskService.getTotalCount(baseCriteria); taskSearchPanel.setTotalCountNumber(totalTasks); } }; private ApplicationEventListener<ShellEvent.AddQueryParam> addQueryHandler = QueryParamHandler .queryParamHandler(); public TaskDashboardViewImpl() { this.withMargin(new MarginInfo(false, true, true, true)); taskSearchPanel = new TaskSearchPanel(); MHorizontalLayout groupWrapLayout = new MHorizontalLayout(); groupWrapLayout.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); groupWrapLayout.addComponent(new Label("Sort")); final ComboBox sortCombo = new ValueComboBox(false, AppContext.getMessage(GenericI18Enum.OPT_SORT_DESCENDING), AppContext.getMessage(GenericI18Enum.OPT_SORT_ASCENDING)); sortCombo.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent valueChangeEvent) { String sortValue = (String) sortCombo.getValue(); if (AppContext.getMessage(GenericI18Enum.OPT_SORT_ASCENDING).equals(sortValue)) { sortDirection = SearchCriteria.ASC; } else { sortDirection = SearchCriteria.DESC; } queryAndDisplayTasks(); } }); sortDirection = SearchCriteria.DESC; groupWrapLayout.addComponent(sortCombo); groupWrapLayout.addComponent(new Label("Group by")); final ComboBox groupCombo = new ValueComboBox(false, GROUP_DUE_DATE, GROUP_START_DATE, GROUP_CREATED_DATE, PLAIN_LIST, GROUP_USER); groupCombo.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent valueChangeEvent) { groupByState = (String) groupCombo.getValue(); queryAndDisplayTasks(); } }); groupByState = GROUP_DUE_DATE; groupWrapLayout.addComponent(groupCombo); taskSearchPanel.addHeaderRight(groupWrapLayout); Button printBtn = new Button("", new Button.ClickListener() { @Override public void buttonClick(ClickEvent clickEvent) { UI.getCurrent().addWindow(new TaskCustomizeReportOutputWindow(new LazyValueInjector() { @Override protected Object doEval() { return baseCriteria; } })); } }); printBtn.setIcon(FontAwesome.PRINT); printBtn.addStyleName(UIConstants.BUTTON_OPTION); printBtn.setDescription(AppContext.getMessage(GenericI18Enum.ACTION_EXPORT)); groupWrapLayout.addComponent(printBtn); Button newTaskBtn = new Button(AppContext.getMessage(TaskI18nEnum.NEW), new Button.ClickListener() { private static final long serialVersionUID = 1L; @Override public void buttonClick(final ClickEvent event) { if (CurrentProjectVariables.canWrite(ProjectRolePermissionCollections.TASKS)) { SimpleTask newTask = new SimpleTask(); newTask.setProjectid(CurrentProjectVariables.getProjectId()); newTask.setSaccountid(AppContext.getAccountId()); newTask.setLogby(AppContext.getUsername()); UI.getCurrent().addWindow(new TaskAddWindow(newTask)); } } }); newTaskBtn.setEnabled(CurrentProjectVariables.canWrite(ProjectRolePermissionCollections.TASKS)); newTaskBtn.setIcon(FontAwesome.PLUS); newTaskBtn.setStyleName(UIConstants.BUTTON_ACTION); groupWrapLayout.addComponent(newTaskBtn); Button advanceDisplayBtn = new Button("List"); advanceDisplayBtn.setWidth("100px"); advanceDisplayBtn.setIcon(FontAwesome.SITEMAP); advanceDisplayBtn.setDescription("Advance View"); Button kanbanBtn = new Button("Kanban", new Button.ClickListener() { @Override public void buttonClick(ClickEvent clickEvent) { displayKanbanView(); } }); kanbanBtn.setWidth("100px"); kanbanBtn.setDescription("Kanban View"); kanbanBtn.setIcon(FontAwesome.TH); ToggleButtonGroup viewButtons = new ToggleButtonGroup(); viewButtons.addButton(advanceDisplayBtn); viewButtons.addButton(kanbanBtn); viewButtons.withDefaultButton(advanceDisplayBtn); groupWrapLayout.addComponent(viewButtons); MHorizontalLayout mainLayout = new MHorizontalLayout().withFullHeight().withFullWidth(); wrapBody = new MVerticalLayout().withMargin(new MarginInfo(false, true, true, false)); rightColumn = new MVerticalLayout().withWidth("370px") .withMargin(new MarginInfo(true, false, false, false)); mainLayout.with(wrapBody, rightColumn).expand(wrapBody); this.with(taskSearchPanel, mainLayout); } @Override public void attach() { EventBusFactory.getInstance().register(searchHandler); EventBusFactory.getInstance().register(newTaskAddedHandler); EventBusFactory.getInstance().register(addQueryHandler); super.attach(); } @Override public void detach() { EventBusFactory.getInstance().unregister(searchHandler); EventBusFactory.getInstance().unregister(newTaskAddedHandler); EventBusFactory.getInstance().unregister(addQueryHandler); super.detach(); } public void displayView(String query) { baseCriteria = new TaskSearchCriteria(); baseCriteria.setProjectId(new NumberSearchField(CurrentProjectVariables.getProjectId())); statisticSearchCriteria = BeanUtility.deepClone(baseCriteria); OptionValService optionValService = AppContextUtil.getSpringBean(OptionValService.class); List<OptionVal> options = optionValService.findOptionValsExcludeClosed(ProjectTypeConstants.TASK, CurrentProjectVariables.getProjectId(), AppContext.getAccountId()); if (CollectionUtils.isNotEmpty(options)) { SetSearchField<String> statuses = new SetSearchField<>(); for (OptionVal option : options) { statuses.addValue(option.getTypeval()); } statisticSearchCriteria.setStatuses(statuses); } if (StringUtils.isNotBlank(query)) { try { String jsonQuery = UrlEncodeDecoder.decode(query); List<SearchFieldInfo> searchFieldInfos = QueryAnalyzer.toSearchFieldInfos(jsonQuery, ProjectTypeConstants.TASK); taskSearchPanel.displaySearchFieldInfos(searchFieldInfos); TaskSearchCriteria searchCriteria = SearchFieldInfo.buildSearchCriteria(baseCriteria, searchFieldInfos); searchCriteria.setProjectId(new NumberSearchField(CurrentProjectVariables.getProjectId())); queryTask(searchCriteria); } catch (Exception e) { LOG.error("Error", e); taskSearchPanel.selectQueryInfo(TaskSavedFilterComboBox.OPEN_TASKS); } } else { taskSearchPanel.selectQueryInfo(TaskSavedFilterComboBox.OPEN_TASKS); } } @Override public void showNoItemView() { } private void displayTaskStatistic() { rightColumn.removeAllComponents(); final TaskStatusTrendChartWidget taskStatusTrendChartWidget = new TaskStatusTrendChartWidget(); rightColumn.addComponent(taskStatusTrendChartWidget); UnresolvedTaskByAssigneeWidget unresolvedTaskByAssigneeWidget = new UnresolvedTaskByAssigneeWidget(); unresolvedTaskByAssigneeWidget.setSearchCriteria(statisticSearchCriteria); rightColumn.addComponent(unresolvedTaskByAssigneeWidget); UnresolvedTaskByPriorityWidget unresolvedTaskByPriorityWidget = new UnresolvedTaskByPriorityWidget(); unresolvedTaskByPriorityWidget.setSearchCriteria(statisticSearchCriteria); rightColumn.addComponent(unresolvedTaskByPriorityWidget); UnresolvedTaskByStatusWidget unresolvedTaskByStatusWidget = new UnresolvedTaskByStatusWidget(); unresolvedTaskByStatusWidget.setSearchCriteria(statisticSearchCriteria); rightColumn.addComponent(unresolvedTaskByStatusWidget); AsyncInvoker.access(new AsyncInvoker.PageCommand() { @Override public void run() { TimelineTrackingSearchCriteria timelineTrackingSearchCriteria = new TimelineTrackingSearchCriteria(); timelineTrackingSearchCriteria .setExtraTypeIds(new SetSearchField<>(CurrentProjectVariables.getProjectId())); taskStatusTrendChartWidget.display(timelineTrackingSearchCriteria); } }); } @Override public void queryTask(final TaskSearchCriteria searchCriteria) { baseCriteria = searchCriteria; queryAndDisplayTasks(); displayTaskStatistic(); } private void queryAndDisplayTasks() { wrapBody.removeAllComponents(); if (GROUP_DUE_DATE.equals(groupByState)) { baseCriteria.setOrderFields( Collections.singletonList(new SearchCriteria.OrderField("deadline", sortDirection))); taskGroupOrderComponent = new DueDateOrderComponent(); } else if (GROUP_START_DATE.equals(groupByState)) { baseCriteria.setOrderFields( Collections.singletonList(new SearchCriteria.OrderField("startdate", sortDirection))); taskGroupOrderComponent = new StartDateOrderComponent(); } else if (PLAIN_LIST.equals(groupByState)) { baseCriteria.setOrderFields( Collections.singletonList(new SearchCriteria.OrderField("lastupdatedtime", sortDirection))); taskGroupOrderComponent = new SimpleListOrderComponent(); } else if (GROUP_CREATED_DATE.equals(groupByState)) { baseCriteria.setOrderFields( Collections.singletonList(new SearchCriteria.OrderField("createdtime", sortDirection))); taskGroupOrderComponent = new CreatedDateOrderComponent(); } else if (GROUP_USER.equals(groupByState)) { baseCriteria.setOrderFields( Collections.singletonList(new SearchCriteria.OrderField("createdtime", sortDirection))); taskGroupOrderComponent = new UserOrderComponent(); } else { throw new MyCollabException("Do not support group view by " + groupByState); } wrapBody.addComponent(taskGroupOrderComponent); final ProjectTaskService projectTaskService = AppContextUtil.getSpringBean(ProjectTaskService.class); int totalTasks = projectTaskService.getTotalCount(baseCriteria); taskSearchPanel.setTotalCountNumber(totalTasks); currentPage = 0; int pages = totalTasks / 20; if (currentPage < pages) { Button moreBtn = new Button(AppContext.getMessage(GenericI18Enum.ACTION_MORE), new Button.ClickListener() { @Override public void buttonClick(ClickEvent clickEvent) { int totalTasks = projectTaskService.getTotalCount(baseCriteria); int pages = totalTasks / 20; currentPage++; List<SimpleTask> otherTasks = projectTaskService.findPagableListByCriteria( new BasicSearchRequest<>(baseCriteria, currentPage + 1, 20)); taskGroupOrderComponent.insertTasks(otherTasks); if (currentPage == pages) { wrapBody.removeComponent(wrapBody.getComponent(1)); } } }); moreBtn.addStyleName(UIConstants.BUTTON_ACTION); wrapBody.addComponent(moreBtn); } List<SimpleTask> tasks = projectTaskService .findPagableListByCriteria(new BasicSearchRequest<>(baseCriteria, currentPage + 1, 20)); taskGroupOrderComponent.insertTasks(tasks); } private void displayKanbanView() { EventBusFactory.getInstance().post(new TaskEvent.GotoKanbanView(this, null)); } @Override public void enableActionControls(int numOfSelectedItem) { } @Override public void disableActionControls() { } @Override public HasSearchHandlers<TaskSearchCriteria> getSearchHandlers() { return taskSearchPanel; } @Override public HasSelectionOptionHandlers getOptionSelectionHandlers() { return null; } @Override public HasMassItemActionHandler getPopupActionHandlers() { return null; } @Override public HasSelectableItemHandlers<SimpleTask> getSelectableItemHandlers() { return null; } @Override public AbstractPagedBeanTable<TaskSearchCriteria, SimpleTask> getPagedBeanTable() { return null; } }