diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java index 74e75ab1e..ba3f5db5f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java @@ -279,6 +279,11 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader(); getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader); + Component additionalFilter = (Component) getVariable("additionalFilter", true); + if(additionalFilter != null) { + getFellow("additionalFilterInsertionPoint").appendChild(additionalFilter); + } + timeTrackerHeader.afterCompose(); timeTrackerComponent.afterCompose(); listZoomLevels = (Listbox) getFellow("listZoomLevels"); diff --git a/ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul b/ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul index 0c53d1ebd..d01623ea8 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul @@ -47,6 +47,8 @@ resourcesLoadPanel = self; ${i18n:_('Show resources between')}: + + diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java index a38138593..07029225a 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java @@ -24,6 +24,7 @@ import java.util.List; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.planner.entities.TaskElement; +import org.navalplanner.business.resources.entities.Resource; import org.zkoss.ganttz.data.resourceload.LoadTimeLine; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.Interval; @@ -43,4 +44,6 @@ public interface IResourceLoadModel { Order getOrderByTask(TaskElement task); boolean userCanRead(Order order, String loginName); + + void setResourcesToShow(List resourcesList); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java index 9d5e64861..a2cdb966a 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java @@ -29,6 +29,9 @@ import java.util.List; import org.apache.commons.lang.Validate; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.planner.entities.TaskElement; +import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.web.common.components.bandboxsearch.BandboxMultipleSearch; +import org.navalplanner.web.common.components.finders.FilterPair; import org.navalplanner.web.planner.order.BankHolidaysMarker; import org.navalplanner.web.planner.order.IOrderPlanningGate; import org.navalplanner.web.security.SecurityUtils; @@ -44,7 +47,12 @@ import org.zkoss.ganttz.resourceload.ResourcesLoadPanel.IToolbarCommand; import org.zkoss.ganttz.timetracker.TimeTracker; import org.zkoss.ganttz.timetracker.zoom.SeveralModificators; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.Composer; +import org.zkoss.zul.Button; +import org.zkoss.zul.Hbox; import org.zkoss.zul.Messagebox; /** @@ -74,6 +82,8 @@ public class ResourceLoadController implements Composer { private IOrderPlanningGate planningControllerEntryPoints; + private BandboxMultipleSearch bandBox; + public ResourceLoadController() { } @@ -165,13 +175,54 @@ public class ResourceLoadController implements Composer { if (resourcesLoadPanel != null) { resourcesLoadPanel.init(resourceLoadModel.getLoadTimeLines(), timeTracker); + if(bandBox != null && resourcesLoadPanel.getFilter()) { + //if the worker bandbox filter is active, we disable the name filter + resourcesLoadPanel.setNameFilterDisabled( + !bandBox.getSelectedElements().isEmpty()); + } } else { resourcesLoadPanel = new ResourcesLoadPanel(resourceLoadModel .getLoadTimeLines(), timeTracker, parent); + if(filterBy == null) { + addWorkersBandbox(); + } addListeners(); } } + private void addWorkersBandbox() { + bandBox = new BandboxMultipleSearch(); + bandBox.setId("workerBandboxMultipleSearch"); + bandBox.setWidthBandbox("285px"); + bandBox.setWidthListbox("300px"); + bandBox.setFinder("workerMultipleFiltersFinder"); + bandBox.afterCompose(); + + Button button = new Button(); + button.setImage("/common/img/ico_filter.png"); + button.setTooltip(_("Filter by worker")); + button.addEventListener(Events.ON_CLICK, new EventListener() { + @Override + @SuppressWarnings("unchecked") + public void onEvent(Event event) throws Exception { + List filterPairList = bandBox.getSelectedElements(); + List workersList = new ArrayList(); + for(FilterPair filterPair : filterPairList) { + workersList.add((Resource)filterPair.getValue()); + } + resourceLoadModel.setResourcesToShow(workersList); + reload(resourcesLoadPanel.getFilter()); + } + }); + + Hbox hbox = new Hbox(); + hbox.appendChild(bandBox); + hbox.appendChild(button); + hbox.setAlign("center"); + + resourcesLoadPanel.setVariable("additionalFilter", hbox, true); + } + public void filterBy(Order order) { this.filterBy = order; } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java index ffa936038..11601dbbe 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java @@ -103,6 +103,8 @@ public class ResourceLoadModel implements IResourceLoadModel { private boolean filterByResources = true; + private List resourcesToShowList = new ArrayList(); + @Override @Transactional(readOnly = true) public void initGlobalView(boolean filterByResources) { @@ -198,6 +200,10 @@ public class ResourceLoadModel implements IResourceLoadModel { } private List resourcesToShow() { + if(!resourcesToShowList.isEmpty()) { + return getResourcesToShowReattached(); + } + // if we haven't manually specified some resources to show, we load them if (filter()) { return resourcesForActiveTasks(); } else { @@ -649,6 +655,27 @@ public class ResourceLoadModel implements IResourceLoadModel { .getStart()), new LocalDate(interval.getFinish())); } + @Override + public void setResourcesToShow(List resourcesList) { + this.resourcesToShowList.clear(); + this.resourcesToShowList.addAll(resourcesList); + } + + private List getResourcesToShowReattached() { + List list = new ArrayList(); + for(Resource worker : resourcesToShowList) { + try { + //for some reason, resourcesDAO.reattach(worker) doesn't work + //and we have to retrieve them again with find + list.add(resourcesDAO.find(worker.getId())); + } + catch(InstanceNotFoundException e) { + //maybe it was removed by another transaction + //we just ignore the exception to not show the Resource + } + } + return list; + } } class PeriodsBuilder {