From 01d80efbb5ca883dc509cac909a98fdab5302673 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 4 Feb 2013 18:09:59 +0800 Subject: [PATCH] IDEMPIERE-608 Zk InfoSchedule: Replace TimeLine with Calendar component. --- .../src/org/compiere/util/TimeUtil.java | 19 + .../adempiere/webui/TimelineEventFeed.java | 145 ------- .../adwindow/AbstractADWindowContent.java | 19 +- .../org/adempiere/webui/component/Mask.java | 37 ++ .../adempiere/webui/dashboard/DPViews.java | 5 +- .../webui/editor/WAssignmentEditor.java | 9 +- .../webui/factory/DefaultInfoFactory.java | 2 +- .../org/adempiere/webui/panel/WSchedule.java | 320 ++++++++++----- .../adempiere/webui/window/InfoSchedule.java | 369 +++++++++--------- .../webui/window/WAssignmentDialog.java | 36 +- org.adempiere.ui.zk/WEB-INF/web.xml | 11 - 11 files changed, 512 insertions(+), 460 deletions(-) delete mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java diff --git a/org.adempiere.base/src/org/compiere/util/TimeUtil.java b/org.adempiere.base/src/org/compiere/util/TimeUtil.java index 7a7b42fd8f..8d2ef215ab 100644 --- a/org.adempiere.base/src/org/compiere/util/TimeUtil.java +++ b/org.adempiere.base/src/org/compiere/util/TimeUtil.java @@ -114,6 +114,25 @@ public class TimeUtil cal.set(Calendar.MILLISECOND, 0); return new Timestamp (cal.getTimeInMillis()); } // getNextDay + + /** + * Get earliest time of next day + * @param day day + * @return next day with 00:00 + */ + static public Timestamp getPreviousDay (Timestamp day) + { + if (day == null) + day = new Timestamp(System.currentTimeMillis()); + GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale()); + cal.setTimeInMillis(day.getTime()); + cal.add(Calendar.DAY_OF_YEAR, -1); // previous + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return new Timestamp (cal.getTimeInMillis()); + } // getNextDay /** * Get last date in month diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java deleted file mode 100644 index 1c33cd8e86..0000000000 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.adempiere.webui; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.sql.Timestamp; -import java.text.DateFormat; -import java.text.ParseException; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Properties; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.adempiere.util.ServerContext; -import org.adempiere.webui.component.ZkCssHelper; -import org.adempiere.webui.session.SessionContextListener; -import org.compiere.model.MAssignmentSlot; -import org.compiere.model.ScheduleUtil; -import org.compiere.util.Env; -import org.zkforge.timeline.util.TimelineUtil; -import org.zkoss.xel.fn.XmlFns; -import org.zkoss.xml.XMLs; - -public class TimelineEventFeed extends HttpServlet { - - /** - * generated serial version Id - */ - private static final long serialVersionUID = 5507229085571123451L; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - Properties ctx = (Properties)req.getSession().getAttribute(SessionContextListener.SESSION_CTX); - if (ctx == null) { - return; - } - - ServerContext.setCurrentInstance(ctx); - try { - doGet0(req, resp); - } finally { - ServerContext.dispose(); - } - } - - private void doGet0(HttpServletRequest req, HttpServletResponse resp) - throws IOException { - int resourceId = 0; - String resourceIdParam = req.getParameter("S_Resource_ID"); - if (resourceIdParam != null && resourceIdParam.trim().length() > 0) { - try { - resourceId = Integer.parseInt(resourceIdParam.trim()); - } catch (Exception e) { - return; - } - } else { - return; - } - - String uuid = req.getParameter("uuid"); - if (uuid == null || uuid.trim().length() == 0) return; - - //String timeLineId = req.getParameter("tlid"); - - Date date = null; - String dateParam = req.getParameter("date"); - if (dateParam != null && dateParam.trim().length() > 0) { - try { - date = DateFormat.getInstance().parse(dateParam); - } catch (ParseException e) { - return; - } - } else { - return; - } - - resp.setContentType("application/xml"); - ScheduleUtil m_model = new ScheduleUtil (Env.getCtx()); - - // Calculate Start Day - GregorianCalendar cal = new GregorianCalendar(); - cal.setTime(date); - cal.set(Calendar.HOUR, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - cal.set(Calendar.DAY_OF_MONTH, 1); - Timestamp startDate = new Timestamp(cal.getTimeInMillis()); - // Calculate End Date - cal.add(Calendar.MONTH, 1); - Timestamp endDate = new Timestamp (cal.getTimeInMillis()); - - MAssignmentSlot[] mas = m_model.getAssignmentSlots (resourceId, startDate, endDate, null, true, null); - if (mas == null || mas.length == 0) return; - - StringBuilder xml = new StringBuilder(); - xml.append("").append("\r\n"); - - for (MAssignmentSlot slot : mas) { - xml.append(""); - if (slot.getDescription() != null && slot.getDescription().trim().length() > 0) { - xml.append("\r\n") - .append(XMLs.encodeText(slot.getDescription() + "
")); - } - if (slot.getMAssignment() != null) { - //encode assignment id as coordinate x - String link = "Edit"; - xml.append("\r\n").append(XMLs.encodeText(link)); - } - xml.append("\r\n").append("
").append("\r\n"); - } - - xml.append("
").append("\r\n"); - - PrintWriter writer = resp.getWriter(); - BufferedWriter buffer = new BufferedWriter(writer); - buffer.write(xml.toString()); - buffer.flush(); - } -} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index dc91450399..a07aced2eb 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -46,6 +46,7 @@ import org.adempiere.webui.apps.form.WCreateFromFactory; import org.adempiere.webui.apps.form.WCreateFromWindow; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.ProcessInfoDialog; import org.adempiere.webui.component.Window; import org.adempiere.webui.component.ZkCssHelper; @@ -810,7 +811,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements private FindWindow findWindow; - private Div maskDiv; + private Div mask; /** * @see ToolbarListener#onLock() @@ -2527,23 +2528,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements isProcessMandatory); } // actionButton - private Div getMaskDiv() { - if (maskDiv == null) { - maskDiv = new Div(); - maskDiv.setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: 0; background-color: #e4e4e4; " + - "padding: 0; z-index:999; opacity:0.6; top: 0px; left: 0px;"); + private Div getMask() { + if (mask == null) { + mask = new Mask(); } - return maskDiv; + return mask; } public void hideBusyMask() { - if (maskDiv != null && maskDiv.getParent() != null) { - maskDiv.detach(); + if (mask != null && mask.getParent() != null) { + mask.detach(); } } public void showBusyMask() { - getComponent().getParent().appendChild(getMaskDiv()); + getComponent().getParent().appendChild(getMask()); } private void executeButtonProcess(final IProcessButton wButton, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java new file mode 100644 index 0000000000..589f70e413 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java @@ -0,0 +1,37 @@ +/****************************************************************************** + * Copyright (C) 2013 Heng Sin Low * + * Copyright (C) 2013 Trek Global * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.adempiere.webui.component; + +import org.zkoss.zul.Div; + +/** + * @author hengsin + * + */ +public class Mask extends Div { + + /** + * generated serial + */ + private static final long serialVersionUID = -9068605816183445421L; + + /** + * default constructor + */ + public Mask() { + setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: 0; background-color: #e4e4e4; " + + "padding: 0; z-index:999; opacity:0.6; top: 0px; left: 0px;"); + } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPViews.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPViews.java index 082500db29..8c1d444cb8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPViews.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPViews.java @@ -15,6 +15,7 @@ package org.adempiere.webui.dashboard; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.ToolBarButton; +import org.adempiere.webui.component.Window; import org.adempiere.webui.panel.InfoPanel; import org.adempiere.webui.window.InfoSchedule; import org.compiere.model.MRole; @@ -188,7 +189,9 @@ public class DPViews extends DashboardPanel implements EventListener { } else if (actionCommand.equals("InfoSchedule") && AEnv.canAccessInfo("SCHEDULE")) { - new InfoSchedule(null, false); + InfoSchedule is = new InfoSchedule(null, false); + is.setAttribute(Window.MODE_KEY, Mode.EMBEDDED); + AEnv.showWindow(is); } else if (actionCommand.equals("InfoOrder") && AEnv.canAccessInfo("ORDER")) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java index 218894f033..19270cb609 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java @@ -159,8 +159,10 @@ public class WAssignmentEditor extends WEditor implements ContextMenuListener { vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override public void onEvent(Event event) throws Exception { - MResourceAssignment ma = vad.getMResourceAssignment(); - processNewValue(oldValue, ma); + if (!vad.isCancelled()) { + MResourceAssignment ma = vad.getMResourceAssignment(); + processNewValue(oldValue, ma); + } } }); vad.setTitle(null); @@ -169,13 +171,14 @@ public class WAssignmentEditor extends WEditor implements ContextMenuListener { // Start InfoSchedule directly else { - @SuppressWarnings("unused") final InfoSchedule is = new InfoSchedule(ma, true, new Callback() { @Override public void onCallback(MResourceAssignment ma) { processNewValue(oldValue, ma); } }); + AEnv.showWindow(is); + is.focus(); } } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultInfoFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultInfoFactory.java index 4e8a8594e9..285dbbf556 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultInfoFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultInfoFactory.java @@ -96,7 +96,7 @@ public class DefaultInfoFactory implements IInfoFactory { } else if (tableName.equals("C_CashLine")) { info = new InfoCashLinePanel (WindowNo, value, multiSelection, whereClause, lookup); - } else if (tableName.equals("S_ResourceAssigment")) { + } else if (tableName.equals("S_ResourceAssignment")) { info = new InfoAssignmentWindow(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, AD_InfoWindow_ID, lookup); if (!info.loadedOK()) { info = new InfoAssignmentPanel (WindowNo, value, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java index a1ce7095e8..a116841f86 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java @@ -16,27 +16,39 @@ *****************************************************************************/ package org.adempiere.webui.panel; -import java.text.DateFormat; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; import java.util.logging.Level; -import org.adempiere.webui.LayoutUtils; -import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.ToolBarButton; -import org.adempiere.webui.event.DialogEvents; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.component.ZkCssHelper; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.window.InfoSchedule; -import org.adempiere.webui.window.WAssignmentDialog; -import org.compiere.model.MResourceAssignment; +import org.compiere.model.MAssignmentSlot; +import org.compiere.model.ScheduleUtil; import org.compiere.util.CLogger; import org.compiere.util.Env; -import org.zkforge.timeline.Bandinfo; -import org.zkforge.timeline.Timeline; -import org.zkforge.timeline.event.BandScrollEvent; +import org.compiere.util.Util; +import org.zkoss.calendar.Calendars; +import org.zkoss.calendar.event.CalendarsEvent; +import org.zkoss.calendar.impl.SimpleCalendarEvent; +import org.zkoss.calendar.impl.SimpleCalendarModel; +import org.zkoss.util.Locales; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; 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.event.MouseEvent; +import org.zkoss.zul.Borderlayout; +import org.zkoss.zul.Button; +import org.zkoss.zul.Label; +import org.zkoss.zul.North; +import org.zkoss.zul.South; /** * Visual and Control Part of Schedule. @@ -48,13 +60,14 @@ import org.zkoss.zk.ui.event.MouseEvent; * Zk Port * @author Low Heng Sin */ -public class WSchedule extends Panel implements EventListener +public class WSchedule extends Window implements EventListener { /** * */ private static final long serialVersionUID = 7714179510197450419L; + @SuppressWarnings("unused") private InfoSchedule infoSchedule; /** @@ -79,19 +92,36 @@ public class WSchedule extends Panel implements EventListener /** Logger */ private static CLogger log = CLogger.getCLogger(WSchedule.class); - Timeline timeLine; - private Bandinfo hourBand; - private Bandinfo dayBand; private ToolBarButton button; - private Bandinfo mthBand; - @SuppressWarnings("unused") private Date m_center; - private MResourceAssignment _assignmentDialogResult; + private Component calendarContainer; + private Calendars calendars; + private SimpleCalendarModel scm; + + private Button btnCurrentDate; + private Label lblDate; + + private int S_Resource_ID; + + private Component divArrowLeft; + + private Component divArrowRight; + + private Component divTabDay; + + private Component divTabWeek; + + private Component divTabWeekdays; + + private Component divTabMonth; + + private Borderlayout borderlayout; + /** * Static init *
@@ -104,57 +134,71 @@ public class WSchedule extends Panel implements EventListener
 	{
 		this.getChildren().clear();
 				
-		timeLine = new Timeline();
-		timeLine.setHeight("400px");
-		timeLine.setWidth("100%");
-		timeLine.setId("resoureSchedule");
+		calendarContainer = Executions.createComponents("calendar.zul", this, null);
 		
-		this.appendChild(timeLine);		
+		borderlayout = (Borderlayout) calendarContainer.getFellow("main");
+		borderlayout.setStyle("position: absolute; width: 98%; margin: auto;");
+		borderlayout.setHeight("100%");
+		if (borderlayout.getSouth() != null) {
+			borderlayout.getSouth().detach();
+		}
+
+		Component tmp = calendarContainer.getFellow("btnSwitchTimeZone");
+		if (tmp != null)
+			tmp.detach();
+		tmp = calendarContainer.getFellow("btnRefresh");
+		if (tmp != null)
+			tmp.detach();
+		tmp = calendarContainer.getFellow("lbxRequestTypes");
+		if (tmp != null)
+			tmp.getParent().detach();
+		tmp = calendarContainer.getFellow("FDOW");
+		if (tmp != null)
+			tmp.detach();
 		
-		initBandInfo();
+		calendars = (Calendars) calendarContainer.getFellow("cal");
+		TimeZone timezone = SessionManager.getAppDesktop().getClientInfo().timeZone;
+		calendars.addTimeZone(timezone.getID(), timezone);
+		
+		calendars.addEventListener(CalendarsEvent.ON_EVENT_CREATE, this);
+		calendars.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
+		calendars.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
+		
+		this.appendChild(calendarContainer);		
+		
+		btnCurrentDate = (Button) calendarContainer.getFellow("btnCurrentDate");
+		btnCurrentDate.addEventListener(Events.ON_CLICK, this);
+		
+		lblDate = (Label) calendarContainer.getFellow("lblDate");
+		lblDate.addEventListener(Events.ON_CREATE, this);
+		
+		divArrowLeft = calendarContainer.getFellow("divArrowLeft");
+		divArrowLeft.addEventListener("onMoveDate", this);
+		
+		divArrowRight = calendarContainer.getFellow("divArrowRight");
+		divArrowRight.addEventListener("onMoveDate", this);
+		
+		divTabDay = calendarContainer.getFellow("divTabDay");
+		divTabDay.addEventListener("onUpdateView", this);
+		
+		divTabWeek = calendarContainer.getFellow("divTabWeek");
+		divTabWeek.addEventListener("onUpdateView", this);
+		
+		divTabWeekdays = calendarContainer.getFellow("divTabWeekdays");
+		divTabWeekdays.addEventListener("onUpdateView", this);
+		
+		divTabMonth = calendarContainer.getFellow("divTabMonth");
+		divTabMonth.addEventListener("onUpdateView", this);
 		
 		button = new ToolBarButton();
 		button.setLabel("Edit");
 		button.setStyle("visibility: hidden; height: 0px; width: 0px");
 		button.addEventListener(Events.ON_CLICK, this);
 		this.appendChild(button);
+		
+		divTabClicked(7);
 	}	//	jbInit
 
-	private void initBandInfo() {
-		if (hourBand != null)
-			hourBand.detach();		
-		hourBand = new Bandinfo();
-		timeLine.appendChild(hourBand);
-		hourBand.setIntervalUnit("hour");
-		hourBand.setWidth("40%");
-		hourBand.setIntervalPixels(40);
-		hourBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
-		hourBand.setId("WScheduleHourBand");
-		
-		if (dayBand != null)
-			dayBand.detach();
-		dayBand = new Bandinfo();
-		timeLine.appendChild(dayBand);
-		dayBand.setIntervalUnit("day");
-		dayBand.setWidth("35%");
-		dayBand.setIntervalPixels(100);
-		dayBand.setSyncWith(hourBand.getId());		
-		dayBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
-		// listening band scroll event
-		dayBand.addEventListener("onBandScroll", this);
-		dayBand.setId("WScheduleDayBand");
-		
-		if (mthBand != null)
-			mthBand.detach();
-		mthBand = new Bandinfo();
-		timeLine.appendChild(mthBand);
-		mthBand.setIntervalUnit("month");
-		mthBand.setWidth("25%");
-		mthBand.setIntervalPixels(150);
-		mthBand.setSyncWith(dayBand.getId());		
-		mthBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
-	}
-
 	/**
 	 * 	Recreate View
 	 * 	@param S_Resource_ID Resource
@@ -162,56 +206,130 @@ public class WSchedule extends Panel implements EventListener
 	 */
 	public void recreate (int S_Resource_ID, Date date)
 	{
-		hourBand.setDate(date);
-		// Elaine 2008/12/12
-		dayBand.setDate(date);
-		mthBand.setDate(date);
-//		if (m_center == null || date.getTime() != m_center.getTime())
-//			hourBand.scrollToCenter(date);
-		//
-				
-		String feedUrl = "timeline?S_Resource_ID=" + S_Resource_ID + "&date=" + DateFormat.getInstance().format(date)
-			+ "&uuid=" + button.getUuid() + "&tlid=" + timeLine.getUuid();
-		hourBand.setEventSourceUrl(feedUrl);
-		dayBand.setEventSourceUrl(feedUrl);
+		this.S_Resource_ID = S_Resource_ID;
+		calendars.setCurrentDate(date);
+		
+		updateModel();
 	}	//	recreate
 
-	public void onAssignmentCallback() {
-		if (_assignmentDialogResult != null)
-			infoSchedule.mAssignmentCallback(_assignmentDialogResult);
-		_assignmentDialogResult = null;
+	private void updateModel() {
+		ScheduleUtil m_model = new ScheduleUtil (Env.getCtx());
+		
+		//		Calculate Start Day
+		GregorianCalendar cal = new GregorianCalendar();
+		cal.setTime(calendars.getCurrentDate());
+		cal.set(Calendar.HOUR, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		cal.set(Calendar.DAY_OF_MONTH, 1);
+		Timestamp startDate = new Timestamp(cal.getTimeInMillis());
+		//	Calculate End Date
+		cal.add(Calendar.MONTH, 1);
+		Timestamp endDate = new Timestamp (cal.getTimeInMillis());
+		
+		scm = new SimpleCalendarModel();
+		if (S_Resource_ID > 0) {
+			MAssignmentSlot[] list = m_model.getAssignmentSlots (S_Resource_ID, startDate, endDate, null, true, null);
+			
+			for(MAssignmentSlot mas : list) {
+				SimpleCalendarEvent event = new SimpleCalendarEvent();
+				event.setBeginDate(mas.getStartTime());
+				event.setEndDate(mas.getEndTime());
+				event.setTitle(mas.getName());
+				event.setContent(mas.getDescription());
+				event.setHeaderColor('#'+ZkCssHelper.createHexColorString(mas.getColor(true)));
+				event.setContentColor('#'+ZkCssHelper.createHexColorString(mas.getColor(true)));
+				if (!mas.isAssignment() || mas.getMAssignment().isConfirmed())
+					event.setLocked(true);
+				scm.add(event);
+			}
+		}
+		
+		calendars.setModel(scm);
+	}
+	
+	public SimpleCalendarModel getModel() {
+		return scm;
 	}
 	
 	public void onEvent(Event event) throws Exception {
-		if (event instanceof MouseEvent) {
-			MouseEvent me = (MouseEvent) event;
-			if (me.getX() > 0) {
-				MResourceAssignment assignment = new MResourceAssignment(Env.getCtx(), me.getX(), null);
-				final WAssignmentDialog assignmentDialog = new WAssignmentDialog(assignment, false, infoSchedule.isCreateNew());
-				assignmentDialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
-					@Override
-					public void onEvent(Event event) throws Exception {
-						if (!assignmentDialog.isCancelled()) {
-							_assignmentDialogResult =  assignmentDialog.getMResourceAssignment();
-							Events.echoEvent("onAssignmentCallback", WSchedule.this, null);				
-						}						
-					}
-				});	
-				assignmentDialog.setTitle(null);
-				LayoutUtils.openPopupWindow(this, assignmentDialog, "at_pointer");
-				Events.postEvent(new Event(Events.ON_CLICK, assignmentDialog.getDateFrom()));
+		String type = event.getName();
+		if (type.equals(Events.ON_CLICK)) {
+			if (event.getTarget() == btnCurrentDate) {
+				btnCurrentDateClicked();
 			}
-		} else if (event instanceof BandScrollEvent){
-			BandScrollEvent e = (BandScrollEvent) event;
-			@SuppressWarnings("unused")
-			Date end = e.getMax();
-			@SuppressWarnings("unused")
-			Date start = e.getMin();
-			Date mid = e.getCenter();
-			if (mid != null) {
-				m_center = mid;
-				infoSchedule.dateCallback(mid);
+		} else if (type.equals(Events.ON_CREATE)) {
+			if (event.getTarget() == lblDate)
+				updateDateLabel();
+		} else if (type.equals("onMoveDate")) {
+			if (event.getTarget() == divArrowLeft)
+				divArrowClicked(false);
+			else if (event.getTarget() == divArrowRight)
+				divArrowClicked(true);
+		} else if (type.equals("onUpdateView")) {
+			String text = String.valueOf(event.getData());
+			int days = "Day".equals(text) ? 1: "5 Days".equals(text) ? 5: "Week".equals(text) ? 7: 0;
+			divTabClicked(days);
+		} else {
+			Events.sendEvent(this, event);
+		}
+	}
+	
+	private void btnCurrentDateClicked() {
+		calendars.setCurrentDate(Calendar.getInstance(calendars.getDefaultTimeZone()).getTime());
+		updateDateLabel();
+	}
+	
+	private void updateDateLabel() {
+		Date b = calendars.getBeginDate();
+		Date e = calendars.getEndDate();
+		SimpleDateFormat sdfV = new SimpleDateFormat("yyyy/MMM/dd", Locales.getCurrent());
+		sdfV.setTimeZone(calendars.getDefaultTimeZone());
+		lblDate.setValue(sdfV.format(b) + " - " + sdfV.format(e));
+	}
+	
+	private void divArrowClicked(boolean isNext) {
+		if (isNext)
+			calendars.nextPage();
+		else
+			calendars.previousPage();
+		updateDateLabel();
+		updateModel();
+	}
+	
+	private void divTabClicked(int days) {		
+		if (days > 0) {
+			calendars.setMold("default");
+			calendars.setDays(days);
+		} else {
+			calendars.setMold("month");
+		}
+		updateDateLabel();
+	}
+
+	public void addNorthPane(Component pane) {
+		if (borderlayout != null) {
+			if (borderlayout.getNorth() != null) {
+				borderlayout.getNorth().detach();
 			}
+			North north = new North();
+			north.appendChild(pane);
+			borderlayout.appendChild(north);
+		}
+	}
+	
+	public void addSouthPane(Component pane, String height) {
+		if (borderlayout != null) {
+			if (borderlayout.getSouth() != null) {
+				borderlayout.getSouth().detach();
+			}
+			South south = new South();
+			south.appendChild(pane);
+			if (!Util.isEmpty(height)) {
+				south.setHeight(height);
+			}
+			borderlayout.appendChild(south);
 		}
 	}
 }	//	WSchedule
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
index 327ce7ec63..8d4988ce0c 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
@@ -21,27 +21,19 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Timestamp;
-import java.util.Calendar;
 import java.util.Date;
-import java.util.GregorianCalendar;
 import java.util.logging.Level;
 
 import org.adempiere.util.Callback;
 import org.adempiere.webui.LayoutUtils;
-import org.adempiere.webui.apps.AEnv;
-import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.ConfirmPanel;
-import org.adempiere.webui.component.DatetimeBox;
-import org.adempiere.webui.component.Grid;
-import org.adempiere.webui.component.GridFactory;
 import org.adempiere.webui.component.Label;
 import org.adempiere.webui.component.ListItem;
 import org.adempiere.webui.component.Listbox;
-import org.adempiere.webui.component.Row;
-import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Mask;
 import org.adempiere.webui.component.Window;
+import org.adempiere.webui.component.ZkCssHelper;
 import org.adempiere.webui.event.DialogEvents;
-import org.adempiere.webui.panel.StatusBarPanel;
 import org.adempiere.webui.panel.WSchedule;
 import org.compiere.model.MAssignmentSlot;
 import org.compiere.model.MResourceAssignment;
@@ -53,12 +45,16 @@ import org.compiere.util.Env;
 import org.compiere.util.KeyNamePair;
 import org.compiere.util.Msg;
 import org.compiere.util.TimeUtil;
+import org.zkoss.calendar.event.CalendarsEvent;
+import org.zkoss.calendar.impl.SimpleCalendarEvent;
+import org.zkoss.zk.ui.Component;
 import org.zkoss.zk.ui.Page;
 import org.zkoss.zk.ui.event.Event;
 import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
 import org.zkoss.zul.Div;
-import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Hlayout;
+import org.zkoss.zul.Space;
 import org.zkoss.zul.Vbox;
 
 
@@ -83,6 +79,7 @@ public class InfoSchedule extends Window implements EventListener
 	 */
 	private static final long serialVersionUID = -5948901371276429661L;
 	private Callback m_callback;
+	private Component m_parent;
 
 	/**
 	 *  Constructor
@@ -94,29 +91,34 @@ public class InfoSchedule extends Window implements EventListener
 		this(mAssignment, createNew, (Callback)null);
 	}
 	
+	public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Callback callback)
+	{
+		this(mAssignment, createNew, (Component)null, callback);
+	}
+	
 	/**
 	 *  Constructor
 	 *  @param mAssignment optional assignment
 	 *  @param createNew if true, allows to create new assignments
 	 *  @param listener
 	 */
-	public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Callback callback)
+	public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Component parent, Callback callback)
 	{
 		super();
 		setTitle(Msg.getMsg(Env.getCtx(), "InfoSchedule"));
 		if (createNew)
 		{
-			setAttribute(Window.MODE_KEY, Window.MODE_POPUP);
-			this.setWidth("600px");
+			setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
+			this.setWidth("700px");
+			this.setHeight("600px");
+			this.setSizable(true);
 		}
 		else
 		{
-			setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED);
 			this.setWidth("100%");
 			this.setHeight("100%");
 		}
 		
-//		this.setHeight("600px");
 		this.setClosable(true);
 		this.setBorder("normal");
 		this.setStyle("position: absolute");
@@ -131,11 +133,16 @@ public class InfoSchedule extends Window implements EventListener
 			m_dateFrom = new Timestamp(System.currentTimeMillis());
 		m_createNew = createNew;
 		m_callback = callback;
+		m_parent = parent;
 		if (callback != null) {
 			this.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
 				@Override
 				public void onEvent(Event event) throws Exception {
-					m_callback.onCallback(getMResourceAssignment());
+					if (!m_cancel) {
+						m_callback.onCallback(getMResourceAssignment());
+					} else {
+						m_callback.onCallback(null);
+					}
 				}
 			});
 		}
@@ -148,7 +155,7 @@ public class InfoSchedule extends Window implements EventListener
 		{
 			log.log(Level.SEVERE, "InfoSchedule", ex);
 		}
-		AEnv.showWindow(this);
+//		AEnv.showWindow(this);
 		displayCalendar();
 	}	//	InfoSchedule
 
@@ -172,21 +179,18 @@ public class InfoSchedule extends Window implements EventListener
 	private static CLogger log = CLogger.getCLogger(InfoSchedule.class);
 
 	private Vbox mainLayout = new Vbox();
-	private Grid parameterPanel = GridFactory.newGridLayout();
+	private Hlayout parameterPanel = new Hlayout();
 	private Label labelResourceType = new Label();
 	private Listbox fieldResourceType = new Listbox();
 	private Label labelResource = new Label();
 	private Listbox fieldResource = new Listbox();
-	// Elaine 2008/12/12
-	private Button bPrevious = new Button();
-	private Label labelDate = new Label();
-	private DatetimeBox fieldDate = new DatetimeBox();
-	private Button bNext = new Button();
 	//
 	private WSchedule schedulePane = new WSchedule(this);
-	private StatusBarPanel statusBar = new StatusBarPanel();
 	private ConfirmPanel confirmPanel = null;
-	private Button btnNew;
+	private WAssignmentDialog vad;
+	
+	private boolean m_cancel = false;
+	private Mask mask;
 
 	/**
 	 * 	Static Layout
@@ -200,54 +204,36 @@ public class InfoSchedule extends Window implements EventListener
 		
 		labelResourceType.setValue(Msg.translate(Env.getCtx(), "S_ResourceType_ID"));
 		labelResource.setValue(Msg.translate(Env.getCtx(), "S_Resource_ID"));
-		labelDate.setValue(Msg.translate(Env.getCtx(), "Date"));
 		
-		// Elaine 2008/12/12
-		bPrevious.setLabel("<");
-		bNext.setLabel(">");
-		//
-		
-		mainLayout.appendChild(parameterPanel);
-		
-		Rows rows = new Rows();
-		rows.setParent(parameterPanel);
-		Row row = new Row();
-		rows.appendChild(row);
-		
-		row.appendChild(labelResourceType);
-		row.appendChild(fieldResourceType);				
-		
-		row = new Row();
-		rows.appendChild(row);
-		row.appendChild(labelResource);
-		row.appendChild(fieldResource);
-		
-		// Elaine 2008/12/12
-		row = new Row();
-		rows.appendChild(row);		
-		row.appendChild(labelDate);
-		Hbox hbox = new Hbox();
-		hbox.appendChild(bPrevious);
-		hbox.appendChild(fieldDate);
-		hbox.appendChild(bNext);
-		row.appendChild(hbox);
-		//
+		parameterPanel.setValign("middle");
+		parameterPanel.appendChild(labelResourceType);
+		parameterPanel.appendChild(fieldResourceType);
+		parameterPanel.appendChild(new Space());
+		parameterPanel.appendChild(labelResource);
+		parameterPanel.appendChild(fieldResource);
 		
 		mainLayout.appendChild(schedulePane);
-		
-		schedulePane.setWidth("100%");
-		schedulePane.setHeight("400px");
-		Div div = new Div();
+		schedulePane.addNorthPane(parameterPanel);
+				
 		if (m_createNew) 
 		{
+			Div div = new Div();
 			confirmPanel = new ConfirmPanel(true);
-			div.appendChild(confirmPanel);
+			div.appendChild(confirmPanel);			
+			schedulePane.addSouthPane(div, "80px");
+			
+			schedulePane.addEventListener(CalendarsEvent.ON_EVENT_CREATE, this);
+			schedulePane.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
+			schedulePane.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
+		} 
+		else 
+		{
+			schedulePane.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
+			schedulePane.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
 		}
-		div.appendChild(statusBar);
-		mainLayout.appendChild(div);
 		
 		fieldResourceType.setMold("select");
-		fieldResource.setMold("select");
+		fieldResource.setMold("select");				
 	}	//	jbInit
 
 	/**
@@ -262,25 +248,9 @@ public class InfoSchedule extends Window implements EventListener
 		fieldResourceType.addEventListener(Events.ON_SELECT, this);
 		fieldResource.addEventListener(Events.ON_SELECT, this);
 
-		//	Date - Elaine 2008/12/12
-		fieldDate.setValue(m_dateFrom);
-		fieldDate.getDatebox().addEventListener(Events.ON_BLUR, this);
-		fieldDate.getTimebox().addEventListener(Events.ON_BLUR, this);
-//		fieldDate.addEventListener(Events.ON_BLUR, this);
-		bPrevious.addEventListener(Events.ON_CLICK, this);
-		bNext.addEventListener(Events.ON_CLICK, this);
-		//
-		
 		//		
 		if (createNew) {
 			confirmPanel.addActionListener(Events.ON_CLICK, this);
-			btnNew = new Button();
-	        btnNew.setName("btnNew");
-	        btnNew.setId("New");
-	        btnNew.setImage("/images/New24.png");
-	        
-			confirmPanel.addComponentsLeft(btnNew);			
-			btnNew.addEventListener(Events.ON_CLICK, this);
 		}		
 	}	//	dynInit
 
@@ -415,10 +385,8 @@ public class InfoSchedule extends Window implements EventListener
 		int S_Resource_ID = pp.getKey();
 		m_mAssignment.setS_Resource_ID(S_Resource_ID);
 
-		// Elaine 2008/12/12
-		Date date = fieldDate.getValue();
+		Date date = m_dateFrom;
 		if (date == null) date = new Timestamp(System.currentTimeMillis());
-//		Date date = m_dateFrom;
 		//
 
 		//	Set Info
@@ -442,12 +410,19 @@ public class InfoSchedule extends Window implements EventListener
 	 * 	Callback.
 	 * 	Called from WSchedule after WAssignmentDialog finished
 	 * 	@param assignment New/Changed Assignment
+	 * @param b 
 	 */
-	public void mAssignmentCallback (MResourceAssignment assignment)
+	public void mAssignmentCallback (MResourceAssignment assignment, boolean createNew, boolean cancelled)
 	{
-		m_mAssignment = assignment;
-		if (m_createNew)
-			dispose();
+		hideBusyMask();
+		if (!cancelled) 
+		{
+			m_mAssignment = assignment;		
+			if (createNew)
+				dispose();
+			else
+				displayCalendar();
+		}
 		else
 			displayCalendar();
 	}	//	mAssignmentCallback
@@ -465,57 +440,26 @@ public class InfoSchedule extends Window implements EventListener
 		if (m_loading)
 			return;
 
-		if (event.getTarget().getId().equals("Ok"))
+		if (event.getTarget().getId().equals("Ok")) {
+			m_cancel = false;
 			dispose();
-		else if (event.getTarget().getId().equals("Cancel"))
+		} else if (event.getTarget().getId().equals("Cancel")) {
+			m_cancel = true;
 			dispose();
 		//
-		else if (event.getTarget() == fieldResourceType)
+		} else if (event.getTarget() == fieldResourceType)
 		{
 			fillResource();
 			displayCalendar();
 		}
-		// Elaine 2008/12/12
-		else if (event.getTarget()== fieldResource 
-				|| event.getTarget() == fieldDate.getDatebox() 
-				|| event.getTarget() == fieldDate.getTimebox())
-			displayCalendar();
 		//
-		else if (event.getTarget() == bPrevious)
-			adjustDate(-1);
-		else if (event.getTarget() == bNext)
-			adjustDate(+1);
-		//
-		else if (event.getTarget().getId().equals("New"))
-			doAdd();
+		else if (event instanceof CalendarsEvent)
+			doEdit((CalendarsEvent)event);
 		//
 		
 	}
 	
-	// Elaine 2008/12/12
-	/**
-	 * 	Adjust Date
-	 * 	@param diff difference
-	 */
-	private void adjustDate (int diff)
-	{
-		Date date = fieldDate.getValue();
-		GregorianCalendar cal = new GregorianCalendar();
-		cal.setTime(date);
-		
-//		if (timePane.getSelectedIndex() == 0)
-			cal.add(java.util.Calendar.DAY_OF_YEAR, diff);
-//		else if (timePane.getSelectedIndex() == 1)
-//			cal.add(java.util.Calendar.WEEK_OF_YEAR, diff);
-//		else
-//			cal.add(java.util.Calendar.MONTH, diff);
-		//
-		fieldDate.setValue(new Timestamp(cal.getTimeInMillis()));
-		displayCalendar ();
-	}	//	adjustDate
-	//
-
-	private void doAdd() {
+	private void doEdit(CalendarsEvent event) {
 		ListItem listItem = fieldResource.getSelectedItem();
 		if (listItem == null)
 			return;
@@ -524,50 +468,35 @@ public class InfoSchedule extends Window implements EventListener
 		int S_Resource_ID = pp.getKey();
 		
 		ScheduleUtil schedule = new ScheduleUtil (Env.getCtx());
-		Timestamp start = m_dateFrom;
-		java.sql.Date startDate = new java.sql.Date(start.getTime());
-		Calendar cal = new GregorianCalendar();
-		cal.setTimeInMillis(startDate.getTime());
-		start = new Timestamp(startDate.getTime());
-		start = new Timestamp(cal.getTimeInMillis());
-		cal.set(Calendar.HOUR_OF_DAY, 0);
-		cal.set(Calendar.MINUTE, 0);
-		cal.set(Calendar.SECOND, 0);
-		cal.set(Calendar.MILLISECOND, 0);
-		start = new Timestamp(cal.getTimeInMillis());
-		cal.add(Calendar.DAY_OF_MONTH, 1);
-		Timestamp end = new Timestamp(cal.getTimeInMillis());
-		MAssignmentSlot[] mas = schedule.getAssignmentSlots(S_Resource_ID, start, end, null, true, null);
-		MAssignmentSlot[] mts = schedule.getDayTimeSlots ();
+		Timestamp start = new Timestamp(event.getBeginDate() != null ? event.getBeginDate().getTime() : event.getCalendarEvent().getBeginDate().getTime());
+		Timestamp end =new Timestamp(event.getEndDate() != null ? event.getEndDate().getTime() : event.getCalendarEvent().getEndDate().getTime());
+		double hours = (end.getTime() - start.getTime())/ 1000d / 60d / 60d;
 		
+		MAssignmentSlot[] mas = schedule.getAssignmentSlots(S_Resource_ID, TimeUtil.getPreviousDay(start), TimeUtil.getNextDay(end), null, true, null);
 		MAssignmentSlot slot = null;
-		for (int i = 0; i < mts.length; i++) {
-			slot = mts[i];
-			for(int j = 0; j < mas.length; j++) {
-				if (mts[i].getStartTime().getTime() == mas[j].getStartTime().getTime()) {
-					slot = null;
+		for(int i = 0; i < mas.length; i++) {
+			if (mas[i].getStartTime().getTime() == start.getTime()) {
+				slot = mas[i];
+				break;
+			}
+			if (mas[i].getEndTime() != null) {
+				if (start.getTime() > mas[i].getStartTime().getTime()
+					&& start.getTime() < mas[i].getEndTime().getTime()) {
+					slot = mas[i];
+					break;
+				} else if (end.getTime() > mas[i].getStartTime().getTime()
+						&& end.getTime() < mas[i].getEndTime().getTime()) {
+					slot = mas[i];
+					break;
+				} else if (start.getTime() < mas[i].getStartTime().getTime()
+					&& end.getTime() >= mas[i].getEndTime().getTime()) {
+					slot = mas[i];
 					break;
 				}
-				if (mas[j].getEndTime() != null) {
-					if (mts[i].getStartTime().getTime() > mas[j].getStartTime().getTime()
-						&& mts[i].getStartTime().getTime() < mas[j].getEndTime().getTime()) {
-						slot = null;
-						break;
-					} else if (mts[i].getEndTime().getTime() > mas[j].getStartTime().getTime()
-							&& mts[i].getEndTime().getTime() < mas[j].getEndTime().getTime()) {
-						slot = null;
-						break;
-					} else if (mts[i].getStartTime().getTime() < mas[j].getStartTime().getTime()
-						&& mts[i].getEndTime().getTime() >= mas[j].getEndTime().getTime()) {
-						slot = null;
-						break;
-					}
-				}
 			}
-			if (slot != null) 
-				break;
 		}
-		if (slot != null) {
+
+		if (slot == null) {
 			MResourceAssignment ma;
 			if (m_mAssignment == null)
 				ma = new MResourceAssignment(Env.getCtx(), 0, null);
@@ -575,19 +504,88 @@ public class InfoSchedule extends Window implements EventListener
 				ma = m_mAssignment;
 			ma.setS_Resource_ID(S_Resource_ID);
 			
-			ma.setAssignDateFrom(TimeUtil.getDayTime(start, slot.getStartTime()));
-			ma.setQty(new BigDecimal(1));
-			final WAssignmentDialog vad =  new WAssignmentDialog (ma, false, m_createNew);
-			vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
-				@Override
-				public void onEvent(Event event) throws Exception {
-					mAssignmentCallback(vad.getMResourceAssignment());
+			ma.setAssignDateFrom(start);
+			ma.setQty(new BigDecimal(hours));
+			if (m_parent == null || m_callback == null) {
+				final boolean createNew = true;
+				if (vad != null && vad.getPage() != null)
+					vad.detach();
+				
+				vad =  new WAssignmentDialog (ma, false, createNew);
+				if (event.getBeginDate() != null && event.getEndDate() != null) {
+					SimpleCalendarEvent newEvent = new SimpleCalendarEvent();
+					newEvent.setBeginDate(event.getBeginDate());
+					newEvent.setEndDate(event.getEndDate());
+					if (event.getCalendarEvent() != null) {
+						newEvent.setContent(event.getCalendarEvent().getContent());
+						newEvent.setContentColor(event.getCalendarEvent().getContentColor());
+						newEvent.setHeaderColor(event.getCalendarEvent().getHeaderColor());
+						newEvent.setTitle(event.getCalendarEvent().getTitle());						
+						schedulePane.getModel().remove(event.getCalendarEvent());
+					}
+					schedulePane.getModel().add(newEvent);
 				}
-			});					
-			vad.setTitle(null);
-			LayoutUtils.openPopupWindow(btnNew, vad, "before_start");
+				vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
+					@Override
+					public void onEvent(Event event) throws Exception {
+						mAssignmentCallback(vad.getMResourceAssignment(), createNew, vad.isCancelled());
+					}
+				});					
+				vad.setTitle(null);
+				ZkCssHelper.appendStyle(vad, "position: absolute");
+				showBusyMask();
+				this.appendChild(vad);
+				LayoutUtils.openOverlappedWindow(this, vad, "middle_center");
+				vad.focus();
+			} else {
+				m_cancel = false;
+				m_mAssignment = ma;
+				dispose();
+			}
 		} else {
-			FDialog.error(0, this, "No available time slot for the selected day.");
+			if (!slot.isAssignment())
+				FDialog.error(0, this, "No available time slot for the selected day.");
+			
+			MResourceAssignment ma = slot.getMAssignment();
+			ma.setAssignDateFrom(start);
+			ma.setQty(new BigDecimal(hours));
+			
+			if (m_parent == null || m_callback == null) {
+				if (event.getBeginDate() != null && event.getEndDate() != null) {
+					SimpleCalendarEvent newEvent = new SimpleCalendarEvent();
+					newEvent.setBeginDate(event.getBeginDate());
+					newEvent.setEndDate(event.getEndDate());
+					if (event.getCalendarEvent() != null) {
+						newEvent.setContent(event.getCalendarEvent().getContent());
+						newEvent.setContentColor(event.getCalendarEvent().getContentColor());
+						newEvent.setHeaderColor(event.getCalendarEvent().getHeaderColor());
+						newEvent.setTitle(event.getCalendarEvent().getTitle());
+						schedulePane.getModel().remove(event.getCalendarEvent());
+					}
+					schedulePane.getModel().add(newEvent);
+				}
+				
+				final boolean createNew = false;
+				if (vad != null && vad.getPage() != null)
+					vad.detach();
+				vad =  new WAssignmentDialog (ma, false, createNew);
+				vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
+					@Override
+					public void onEvent(Event event) throws Exception {
+						mAssignmentCallback(vad.getMResourceAssignment(), createNew, vad.isCancelled());
+					}
+				});					
+				vad.setTitle(null);
+				ZkCssHelper.appendStyle(vad, "position: absolute");
+				showBusyMask();
+				this.appendChild(vad);
+				LayoutUtils.openOverlappedWindow(this, vad, "middle_center");
+				vad.focus();
+			} else {
+				m_cancel = false;
+				m_mAssignment = ma;
+				dispose();
+			}
 		}
 	}
 
@@ -601,7 +599,6 @@ public class InfoSchedule extends Window implements EventListener
 	 */
 	public void dateCallback(Date date) {
 		m_dateFrom = new Timestamp(date.getTime());
-		fieldDate.setValue(m_dateFrom); // Elaine 2008/12/15
 	}
 
 	/* (non-Javadoc)
@@ -614,8 +611,24 @@ public class InfoSchedule extends Window implements EventListener
 			displayCalendar();
 		}
 	}
-	
 
+	private Div getMask() {
+		if (mask == null) {
+			mask = new Mask();
+		}
+		return mask;
+	}
+	
+	protected void showBusyMask() {
+		appendChild(getMask());
+	}
+	
+	protected void hideBusyMask() {
+		if (mask != null && mask.getParent() != null) {
+			mask.detach();
+		}
+	}
+	
 	/**
 SELECT o.DocumentNo, ol.Line, ol.Description
 FROM C_OrderLine ol, C_Order o
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java
index 00cb9fba13..7868c38cc9 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java
@@ -30,6 +30,7 @@ import java.util.logging.Level;
 
 import org.adempiere.util.Callback;
 import org.adempiere.webui.LayoutUtils;
+import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.ConfirmPanel;
 import org.adempiere.webui.component.Datebox;
@@ -135,7 +136,7 @@ public class WAssignmentDialog extends Window implements EventListener
 	private Datebox fDateFrom = new Datebox();
 	private Timebox fTimeFrom = new Timebox();
 	private Label lQty = new Label(Msg.translate(Env.getCtx(), "Qty"));
-	private NumberBox fQty = new NumberBox(true);
+	private NumberBox fQty = new NumberBox(false);
 	private Label lUOM = new Label();
 	private Label lName = new Label(Msg.translate(Env.getCtx(), "Name"));
 	private Label lDescription = new Label(Msg.translate(Env.getCtx(), "Description"));
@@ -143,7 +144,8 @@ public class WAssignmentDialog extends Window implements EventListener
 	private Textbox fDescription = new Textbox();
 	private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, false, false, false, true /*, true*/);
 	private Button delete = confirmPanel.createButton("Delete");
-	private boolean m_cancel = false;
+	private boolean m_cancel = true;
+	private boolean m_zoom;
 
 	/**
 	 * 	Static Init
@@ -376,6 +378,7 @@ public class WAssignmentDialog extends Window implements EventListener
 		//	Zoom - InfoResource
 		else if (e.getTarget().getId().equals("Zoom"))
 		{
+			m_zoom = true;
 			setVisible(false);
 			Events.echoEvent("onShowSchedule", this, null);
 		}
@@ -402,6 +405,7 @@ public class WAssignmentDialog extends Window implements EventListener
 		//	OK - Save
 		else if (e.getTarget().getId().equals("Ok"))
 		{
+			m_cancel = false;
 			if (cmd_save())
 				detach();
 		}		
@@ -409,22 +413,21 @@ public class WAssignmentDialog extends Window implements EventListener
 
 	public void onShowSchedule() 
 	{
-		@SuppressWarnings("unused")
-		InfoSchedule is = new InfoSchedule (m_mAssignment, true, new Callback() {			
+		InfoSchedule is = new InfoSchedule (m_mAssignment, true, this, new Callback() {			
 			@Override
 			public void onCallback(MResourceAssignment result) {
+				m_zoom = false;
 				if (result != null)
 				{
 					m_mAssignment = result;
-				//	setDisplay();
-					detach();
+					setDisplay();
 				}	
-				else
-				{
-					setVisible(true);
-				}
+				setVisible(true);
+				WAssignmentDialog.this.focus();
 			}
 		});
+		AEnv.showWindow(is);
+		is.focus();
 	}
 	
 	private void getDateAndTimeFrom(Calendar date) {
@@ -444,4 +447,17 @@ public class WAssignmentDialog extends Window implements EventListener
 	public Datebox getDateFrom() {
 		return fDateFrom;
 	}
+
+	@Override
+	public boolean setVisible(boolean visible) {		
+		boolean b = super.setVisible(visible);
+		if (!m_zoom && b && !visible) {
+			if (getModeType() == Mode.POPUP) {
+				this.detach();
+			}
+		}
+		return b;
+	}
+	
+	
 }	//	VAssignmentDialog
diff --git a/org.adempiere.ui.zk/WEB-INF/web.xml b/org.adempiere.ui.zk/WEB-INF/web.xml
index dfb47865cb..9f2c804276 100644
--- a/org.adempiere.ui.zk/WEB-INF/web.xml
+++ b/org.adempiere.ui.zk/WEB-INF/web.xml
@@ -106,17 +106,6 @@
 		/zkau/*
 	
 	
-	
-		servlet to provide timeline xml event feed
-		timelineFeed
-		
-			org.adempiere.webui.TimelineEventFeed
-		
-	
-	
-		timelineFeed
-		/timeline
-