IDEMPIERE-348 Zk Performance: remove use of polling background thread for update of dashboard. Use server side event to update calendar and recent items dashboard widget. Activities dashboard widget is still using polling but update of home tab label for activities count is now event driven.
This commit is contained in:
parent
7e24ff5ae5
commit
9d312ff605
|
@ -16,15 +16,22 @@ package org.compiere.model;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.base.event.EventManager;
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.idempiere.distributed.IMessageService;
|
||||
import org.idempiere.distributed.ITopic;
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
/**
|
||||
* Recent Item model
|
||||
|
@ -33,6 +40,8 @@ import org.compiere.util.Env;
|
|||
*/
|
||||
public class MRecentItem extends X_AD_RecentItem
|
||||
{
|
||||
public static final String ON_RECENT_ITEM_CHANGED_TOPIC = "onRecentItemChanged";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -166,6 +175,24 @@ public class MRecentItem extends X_AD_RecentItem
|
|||
ri.setAD_Window_ID(AD_Window_ID);
|
||||
ri.setAD_Tab_ID(AD_Tab_ID);
|
||||
ri.saveEx();
|
||||
publishChangedEvent(AD_User_ID);
|
||||
}
|
||||
|
||||
private static void publishChangedEvent(int AD_User_ID) {
|
||||
IMessageService service = Service.locator().locate(IMessageService.class).getService();
|
||||
if (service != null) {
|
||||
ITopic<Integer> topic = service.getTopic(ON_RECENT_ITEM_CHANGED_TOPIC);
|
||||
topic.publish(AD_User_ID);
|
||||
} else {
|
||||
postOnChangedEvent(AD_User_ID);
|
||||
}
|
||||
}
|
||||
|
||||
public static void postOnChangedEvent(int AD_User_ID) {
|
||||
Map<String, Integer> properties = new HashMap<String, Integer>();
|
||||
properties.put("AD_User_ID", AD_User_ID);
|
||||
Event event = new Event(ON_RECENT_ITEM_CHANGED_TOPIC, properties);
|
||||
EventManager.getInstance().postEvent(event);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -178,6 +205,7 @@ public class MRecentItem extends X_AD_RecentItem
|
|||
if (ri != null) {
|
||||
DB.executeUpdateEx("UPDATE AD_RecentItem SET Updated=SYSDATE WHERE AD_RecentItem_ID=?", new Object[] {ri.getAD_RecentItem_ID()}, null);
|
||||
deleteExtraRecentItems(ctx, AD_User_ID);
|
||||
publishChangedEvent(AD_User_ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,11 @@ package org.compiere.util;
|
|||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -85,6 +87,8 @@ public class Trx
|
|||
|
||||
private static Trx.TrxMonitor s_monitor = new Trx.TrxMonitor();
|
||||
|
||||
private List<TrxEventListener> listeners = new ArrayList<TrxEventListener>();
|
||||
|
||||
public static void startTrxMonitor()
|
||||
{
|
||||
Adempiere.getThreadPoolExecutor().scheduleWithFixedDelay(s_monitor, 5, 5, TimeUnit.MINUTES);
|
||||
|
@ -278,6 +282,7 @@ public class Trx
|
|||
m_connection.rollback();
|
||||
log.log(isLocalTrx(m_trxName) ? Level.FINE : Level.INFO, "**** " + m_trxName);
|
||||
m_active = false;
|
||||
fireAfterRollbackEvent(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -287,13 +292,22 @@ public class Trx
|
|||
if (throwException)
|
||||
{
|
||||
m_active = false;
|
||||
fireAfterRollbackEvent(false);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
m_active = false;
|
||||
fireAfterRollbackEvent(false);
|
||||
return false;
|
||||
} // rollback
|
||||
|
||||
private void fireAfterRollbackEvent(boolean success) {
|
||||
TrxEventListener[] copies = listeners.toArray(new TrxEventListener[0]);
|
||||
for(TrxEventListener l : copies) {
|
||||
l.afterRollback(this, success);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
* @return true if success, false if failed or transaction already rollback
|
||||
|
@ -347,6 +361,7 @@ public class Trx
|
|||
m_connection.commit();
|
||||
log.info ("**** " + m_trxName);
|
||||
m_active = false;
|
||||
fireAfterCommitEvent(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -356,13 +371,22 @@ public class Trx
|
|||
if (throwException)
|
||||
{
|
||||
m_active = false;
|
||||
fireAfterCommitEvent(false);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
m_active = false;
|
||||
fireAfterCommitEvent(false);
|
||||
return false;
|
||||
} // commit
|
||||
|
||||
private void fireAfterCommitEvent(boolean success) {
|
||||
TrxEventListener[] copies = listeners.toArray(new TrxEventListener[0]);
|
||||
for(TrxEventListener l : copies) {
|
||||
l.afterCommit(this, success);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
* @return true if success
|
||||
|
@ -417,10 +441,18 @@ public class Trx
|
|||
}
|
||||
m_connection = null;
|
||||
m_active = false;
|
||||
fireAfterCloseEvent();
|
||||
log.config(m_trxName);
|
||||
return true;
|
||||
} // close
|
||||
|
||||
private void fireAfterCloseEvent() {
|
||||
TrxEventListener[] copies = listeners.toArray(new TrxEventListener[0]);
|
||||
for(TrxEventListener l : copies) {
|
||||
l.afterClose(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
|
@ -589,6 +621,18 @@ public class Trx
|
|||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void addTrxEventListener(TrxEventListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public boolean removeTrxEventListener(TrxEventListener listener) {
|
||||
return listeners.remove(listener);
|
||||
}
|
||||
|
||||
static class TrxMonitor implements Runnable
|
||||
{
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************
|
||||
* 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.compiere.util;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public interface TrxEventListener {
|
||||
public void afterCommit(Trx trx, boolean success);
|
||||
public void afterRollback(Trx trx, boolean success);
|
||||
public void afterClose(Trx trx);
|
||||
}
|
|
@ -30,6 +30,7 @@ import java.util.TimeZone;
|
|||
import org.adempiere.webui.component.Window;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.compiere.model.X_R_RequestType;
|
||||
import org.compiere.util.Env;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.encoders.EncoderUtil;
|
||||
|
@ -116,7 +117,7 @@ public class CalendarWindow extends Window implements EventListener<Event> {
|
|||
lbxRequestTypes.addEventListener(Events.ON_SELECT, this);
|
||||
|
||||
lbxRequestTypes.appendItem("(Show All)", "0");
|
||||
ArrayList<X_R_RequestType> types = DPCalendar.getRequestTypes();
|
||||
ArrayList<X_R_RequestType> types = DPCalendar.getRequestTypes(Env.getCtx());
|
||||
for(X_R_RequestType type : types)
|
||||
lbxRequestTypes.appendItem(type.getName(), type.getR_RequestType_ID() + "");
|
||||
lbxRequestTypes.setSelectedIndex(0);
|
||||
|
@ -215,7 +216,7 @@ public class CalendarWindow extends Window implements EventListener<Event> {
|
|||
int R_RequestType_ID = Integer.parseInt(li.getValue().toString());
|
||||
|
||||
scm.clear();
|
||||
ArrayList<ADCalendarEvent> events = DPCalendar.getEvents(R_RequestType_ID);
|
||||
ArrayList<ADCalendarEvent> events = DPCalendar.getEvents(R_RequestType_ID, Env.getCtx());
|
||||
for (ADCalendarEvent event : events)
|
||||
scm.add(event);
|
||||
calendars.setModel(scm);
|
||||
|
@ -341,7 +342,7 @@ public class CalendarWindow extends Window implements EventListener<Event> {
|
|||
lbxRequestTypes.removeItemAt(i);
|
||||
|
||||
lbxRequestTypes.appendItem("(Show All)", "0");
|
||||
ArrayList<X_R_RequestType> types = DPCalendar.getRequestTypes();
|
||||
ArrayList<X_R_RequestType> types = DPCalendar.getRequestTypes(Env.getCtx());
|
||||
for(X_R_RequestType requestType : types)
|
||||
{
|
||||
Listitem item = lbxRequestTypes.appendItem(requestType.getName(), requestType.getR_RequestType_ID() + "");
|
||||
|
@ -352,7 +353,7 @@ public class CalendarWindow extends Window implements EventListener<Event> {
|
|||
lbxRequestTypes.setSelectedIndex(0);
|
||||
|
||||
scm.clear();
|
||||
ArrayList<ADCalendarEvent> events = DPCalendar.getEvents(R_RequestType_ID);
|
||||
ArrayList<ADCalendarEvent> events = DPCalendar.getEvents(R_RequestType_ID, Env.getCtx());
|
||||
for (ADCalendarEvent event : events)
|
||||
scm.add(event);
|
||||
calendars.setModel(scm);
|
||||
|
|
|
@ -15,9 +15,12 @@ package org.adempiere.webui.dashboard;
|
|||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.webui.component.Button;
|
||||
import org.adempiere.webui.desktop.IDesktop;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.model.MRole;
|
||||
|
@ -29,6 +32,8 @@ import org.compiere.util.Util;
|
|||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.EventQueue;
|
||||
import org.zkoss.zk.ui.event.EventQueues;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zul.Box;
|
||||
import org.zkoss.zul.Vbox;
|
||||
|
@ -221,27 +226,41 @@ public class DPActivities extends DashboardPanel implements EventListener<Event>
|
|||
@Override
|
||||
public void refresh(ServerPushTemplate template)
|
||||
{
|
||||
noOfNotice = getNoticeCount();
|
||||
noOfRequest = getRequestCount();
|
||||
noOfWorkflow = getWorkflowCount();
|
||||
noOfUnprocessed = getUnprocessedCount();
|
||||
|
||||
template.executeAsync(this);
|
||||
int notice = getNoticeCount();
|
||||
int request = getRequestCount();
|
||||
int workflow = getWorkflowCount();
|
||||
int unprocessed = getUnprocessedCount();
|
||||
if (noOfNotice != notice || noOfRequest != request
|
||||
|| noOfWorkflow != workflow || noOfUnprocessed != unprocessed )
|
||||
{
|
||||
noOfNotice = notice;
|
||||
noOfRequest = request;
|
||||
noOfWorkflow = workflow;
|
||||
noOfUnprocessed = unprocessed;
|
||||
template.executeAsync(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
//don't update if not visible
|
||||
Component c = this.getParent();
|
||||
while (c != null) {
|
||||
if (!c.isVisible())
|
||||
return;
|
||||
c = c.getParent();
|
||||
}
|
||||
btnNotice.setLabel(labelN + " : " + noOfNotice);
|
||||
btnRequest.setLabel(labelR + " : " + noOfRequest);
|
||||
btnWorkflow.setLabel(labelW + " : " + noOfWorkflow);
|
||||
if (isShowUnprocessed()) btnUnprocessed.setLabel(labelU + " : " + noOfUnprocessed);
|
||||
|
||||
EventQueue<Event> queue = EventQueues.lookup(IDesktop.ACTIVITIES_EVENT_QUEUE, true);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("notice", noOfNotice);
|
||||
map.put("request", noOfRequest);
|
||||
map.put("workflow", noOfWorkflow);
|
||||
map.put("unprocessed", noOfUnprocessed);
|
||||
Event event = new Event(IDesktop.ON_ACTIVITIES_CHANGED_EVENT, null, map);
|
||||
queue.publish(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPooling() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onEvent(Event event)
|
||||
|
|
|
@ -20,17 +20,34 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.base.event.AbstractEventHandler;
|
||||
import org.adempiere.base.event.EventManager;
|
||||
import org.adempiere.base.event.IEventTopics;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.model.I_R_Request;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.X_R_RequestType;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Trx;
|
||||
import org.compiere.util.TrxEventListener;
|
||||
import org.idempiere.distributed.IMessageService;
|
||||
import org.idempiere.distributed.ITopic;
|
||||
import org.idempiere.distributed.ITopicSubscriber;
|
||||
import org.osgi.service.event.EventHandler;
|
||||
import org.zkoss.calendar.Calendars;
|
||||
import org.zkoss.calendar.api.CalendarEvent;
|
||||
import org.zkoss.calendar.event.CalendarsEvent;
|
||||
import org.zkoss.calendar.impl.SimpleCalendarModel;
|
||||
import org.zkoss.util.Locales;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Desktop;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
|
@ -45,7 +62,7 @@ import org.zkoss.zul.Toolbarbutton;
|
|||
* @author Elaine
|
||||
* @date November 20, 2008
|
||||
*/
|
||||
public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
||||
public class DPCalendar extends DashboardPanel implements EventListener<Event>, EventHandler {
|
||||
|
||||
|
||||
/**
|
||||
|
@ -55,24 +72,29 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
private Calendars calendars;
|
||||
private SimpleCalendarModel scm;
|
||||
private Toolbarbutton btnCal, btnRefresh;
|
||||
|
||||
private Button btnCurrentDate;
|
||||
private Label lblDate;
|
||||
private Component divArrowLeft, divArrowRight;
|
||||
|
||||
private static final String ON_REQUEST_CHANGED_TOPIC = "onRequestChanged";
|
||||
|
||||
private EventWindow eventWin;
|
||||
private Properties ctx;
|
||||
private Desktop desktop;
|
||||
|
||||
private static RequestEventHandler eventHandler;
|
||||
private static TopicSubscriber subscriber;
|
||||
|
||||
public DPCalendar() {
|
||||
super();
|
||||
|
||||
scm = new SimpleCalendarModel();
|
||||
ArrayList<ADCalendarEvent> events = getEvents(0);
|
||||
for (ADCalendarEvent event : events)
|
||||
scm.add(event);
|
||||
ctx = new Properties();
|
||||
ctx.putAll(Env.getCtx());
|
||||
|
||||
Component component = Executions.createComponents("calendar_mini.zul", this, null);
|
||||
|
||||
calendars = (Calendars) component.getFellow("cal");
|
||||
calendars.setModel(scm);
|
||||
|
||||
btnCal = (Toolbarbutton) component.getFellow("btnCal");
|
||||
btnCal.addEventListener(Events.ON_CLICK, this);
|
||||
|
@ -96,6 +118,25 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
|
||||
calendars.addEventListener("onEventCreate", this);
|
||||
calendars.addEventListener("onEventEdit", this);
|
||||
|
||||
EventManager.getInstance().register(ON_REQUEST_CHANGED_TOPIC, this);
|
||||
createStaticListeners();
|
||||
}
|
||||
|
||||
private synchronized void createStaticListeners() {
|
||||
if (eventHandler == null) {
|
||||
eventHandler = new RequestEventHandler();
|
||||
eventHandler.bindEventManager(EventManager.getInstance());
|
||||
}
|
||||
|
||||
if (subscriber == null) {
|
||||
subscriber = new TopicSubscriber();
|
||||
IMessageService service = Service.locator().locate(IMessageService.class).getService();
|
||||
if (service != null) {
|
||||
ITopic<Map<String,String>> topic = service.getTopic("onRequestChanged");
|
||||
topic.subscribe(subscriber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onEvent(Event e) throws Exception {
|
||||
|
@ -143,7 +184,7 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
}
|
||||
}
|
||||
|
||||
public static ArrayList<ADCalendarEvent> getEvents(int RequestTypeID) {
|
||||
public static ArrayList<ADCalendarEvent> getEvents(int RequestTypeID, Properties ctx) {
|
||||
ArrayList<ADCalendarEvent> events = new ArrayList<ADCalendarEvent>();
|
||||
String sql = "SELECT DISTINCT r.R_Request_ID, r.DateNextAction, "
|
||||
+ "r.DateStartPlan, r.DateCompletePlan, r.StartTime, r.EndTime, "
|
||||
|
@ -162,10 +203,10 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
try {
|
||||
ps = DB.prepareStatement(sql, null);
|
||||
|
||||
ps.setInt(1, Env.getAD_User_ID(Env.getCtx()));
|
||||
ps.setInt(2, Env.getAD_User_ID(Env.getCtx()));
|
||||
ps.setInt(3, Env.getAD_User_ID(Env.getCtx()));
|
||||
ps.setInt(4, Env.getAD_Client_ID(Env.getCtx()));
|
||||
ps.setInt(1, Env.getAD_User_ID(ctx));
|
||||
ps.setInt(2, Env.getAD_User_ID(ctx));
|
||||
ps.setInt(3, Env.getAD_User_ID(ctx));
|
||||
ps.setInt(4, Env.getAD_Client_ID(ctx));
|
||||
if(RequestTypeID > 0)
|
||||
ps.setInt(5, RequestTypeID);
|
||||
|
||||
|
@ -313,7 +354,7 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
return events;
|
||||
}
|
||||
|
||||
public static ArrayList<X_R_RequestType> getRequestTypes() {
|
||||
public static ArrayList<X_R_RequestType> getRequestTypes(Properties ctx) {
|
||||
ArrayList<X_R_RequestType> types = new ArrayList<X_R_RequestType>();
|
||||
String sql = "SELECT * "
|
||||
+ "FROM R_RequestType "
|
||||
|
@ -325,12 +366,12 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
|
||||
try {
|
||||
ps = DB.prepareStatement(sql, null);
|
||||
ps.setInt(1, Env.getAD_Client_ID(Env.getCtx()));
|
||||
ps.setInt(1, Env.getAD_Client_ID(ctx));
|
||||
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
types.add(new X_R_RequestType(Env.getCtx(), rs, null));
|
||||
types.add(new X_R_RequestType(ctx, rs, null));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -345,15 +386,31 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
btnRefreshClicked();
|
||||
}
|
||||
|
||||
private void btnRefreshClicked() {
|
||||
scm.clear();
|
||||
ArrayList<ADCalendarEvent> events = getEvents(0);
|
||||
for (ADCalendarEvent event : events)
|
||||
scm.add(event);
|
||||
@Override
|
||||
public void refresh(ServerPushTemplate template) {
|
||||
refreshModel();
|
||||
template.executeAsync(this);
|
||||
desktop = getDesktop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
calendars.setModel(scm);
|
||||
calendars.invalidate();
|
||||
}
|
||||
|
||||
private void btnRefreshClicked() {
|
||||
refreshModel();
|
||||
updateUI();
|
||||
}
|
||||
|
||||
private void refreshModel() {
|
||||
scm = new SimpleCalendarModel();
|
||||
ArrayList<ADCalendarEvent> events = getEvents(0, ctx);
|
||||
for (ADCalendarEvent event : events)
|
||||
scm.add(event);
|
||||
}
|
||||
|
||||
private void updateDateLabel() {
|
||||
Date b = calendars.getBeginDate();
|
||||
Date e = calendars.getEndDate();
|
||||
|
@ -374,4 +431,114 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event> {
|
|||
calendars.previousPage();
|
||||
updateDateLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(org.osgi.service.event.Event event) {
|
||||
if (event.getTopic().equals(ON_REQUEST_CHANGED_TOPIC)) {
|
||||
String clientId = (String) event.getProperty(I_R_Request.COLUMNNAME_AD_Client_ID);
|
||||
String salesRepId = (String) event.getProperty(I_R_Request.COLUMNNAME_SalesRep_ID);
|
||||
String userId = (String) event.getProperty(I_R_Request.COLUMNNAME_AD_User_ID);
|
||||
String createdBy = (String) event.getProperty(I_R_Request.COLUMNNAME_CreatedBy);
|
||||
|
||||
String AD_Client_ID = Integer.toString(Env.getAD_Client_ID(ctx));
|
||||
String AD_User_ID = Integer.toString(Env.getAD_User_ID(ctx));
|
||||
if (clientId.equals(AD_Client_ID) && !"0".equals(AD_User_ID)) {
|
||||
if (salesRepId.equals(AD_User_ID) || userId.equals(AD_User_ID) || createdBy.equals(AD_User_ID)) {
|
||||
try {
|
||||
if (desktop != null && desktop.isAlive()) {
|
||||
ServerPushTemplate template = new ServerPushTemplate(desktop);
|
||||
refresh(template);
|
||||
} else {
|
||||
EventManager.getInstance().unregister(this);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
EventManager.getInstance().unregister(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TopicSubscriber implements ITopicSubscriber<Map<String, String>> {
|
||||
|
||||
@Override
|
||||
public void onMessage(Map<String, String> message) {
|
||||
org.osgi.service.event.Event requestChangedEvent = new org.osgi.service.event.Event(ON_REQUEST_CHANGED_TOPIC, message);
|
||||
EventManager.getInstance().postEvent(requestChangedEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class RequestEventHandler extends AbstractEventHandler {
|
||||
@Override
|
||||
protected void doHandleEvent(org.osgi.service.event.Event event) {
|
||||
PO po = getPO(event);
|
||||
I_R_Request request = (I_R_Request)po;
|
||||
Map<String, String> message = new HashMap<String, String>();
|
||||
message.put(I_R_Request.COLUMNNAME_SalesRep_ID, Integer.toString(request.getSalesRep_ID()));
|
||||
message.put(I_R_Request.COLUMNNAME_AD_User_ID, Integer.toString(request.getAD_User_ID()));
|
||||
message.put(I_R_Request.COLUMNNAME_CreatedBy, Integer.toString(request.getCreatedBy()));
|
||||
message.put(I_R_Request.COLUMNNAME_AD_Client_ID, Integer.toString(request.getAD_Client_ID()));
|
||||
RequestRunnable runnable = new RequestRunnable(message);
|
||||
Trx trx = po.get_TrxName() != null ? Trx.get(po.get_TrxName(), false) : null;
|
||||
if (trx != null && trx.isActive()) {
|
||||
trx.addTrxEventListener(new TrxListener(runnable));
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
registerTableEvent(IEventTopics.PO_AFTER_NEW, I_R_Request.Table_Name);
|
||||
registerTableEvent(IEventTopics.PO_AFTER_CHANGE, I_R_Request.Table_Name);
|
||||
registerTableEvent(IEventTopics.PO_AFTER_DELETE, I_R_Request.Table_Name);
|
||||
}
|
||||
}
|
||||
|
||||
static class RequestRunnable implements Runnable {
|
||||
|
||||
private Map<String, String> message;
|
||||
|
||||
protected RequestRunnable(Map<String, String> message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
IMessageService service = Service.locator().locate(IMessageService.class).getService();
|
||||
if (service != null) {
|
||||
ITopic<Map<String,String>> topic = service.getTopic(ON_REQUEST_CHANGED_TOPIC);
|
||||
topic.publish(message);
|
||||
} else {
|
||||
org.osgi.service.event.Event requestChangedEvent = new org.osgi.service.event.Event(ON_REQUEST_CHANGED_TOPIC, message);
|
||||
EventManager.getInstance().postEvent(requestChangedEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TrxListener implements TrxEventListener {
|
||||
|
||||
private Runnable runnable;
|
||||
|
||||
protected TrxListener(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRollback(Trx trx, boolean success) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCommit(Trx trx, boolean success) {
|
||||
if (success) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterClose(Trx trx) {
|
||||
trx.removeTrxEventListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,10 @@
|
|||
package org.adempiere.webui.dashboard;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.base.event.EventManager;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.model.MQuery;
|
||||
|
@ -24,7 +27,12 @@ import org.compiere.model.MTable;
|
|||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.distributed.IMessageService;
|
||||
import org.idempiere.distributed.ITopic;
|
||||
import org.idempiere.distributed.ITopicSubscriber;
|
||||
import org.osgi.service.event.EventHandler;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Desktop;
|
||||
import org.zkoss.zk.ui.event.DropEvent;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
|
@ -42,7 +50,7 @@ import org.zkoss.zul.Vbox;
|
|||
* @author Carlos Ruiz / GlobalQSS
|
||||
* @date January 27, 2012
|
||||
*/
|
||||
public class DPRecentItems extends DashboardPanel implements EventListener<Event> {
|
||||
public class DPRecentItems extends DashboardPanel implements EventListener<Event>, EventHandler {
|
||||
|
||||
private static final String AD_RECENT_ITEM_ID_ATTR = "AD_RecentItem_ID";
|
||||
|
||||
|
@ -53,12 +61,24 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
|
||||
public static final String DELETE_RECENTITEMS_DROPPABLE = "deleteRecentItems";
|
||||
|
||||
private static TopicSubscriber topicSubscriber;
|
||||
|
||||
private Box bxRecentItems;
|
||||
|
||||
private int AD_User_ID;
|
||||
|
||||
private Properties ctx;
|
||||
|
||||
private Desktop desktop;
|
||||
|
||||
public DPRecentItems()
|
||||
{
|
||||
super();
|
||||
|
||||
ctx = new Properties();
|
||||
ctx.putAll(Env.getCtx());
|
||||
AD_User_ID = Env.getAD_User_ID(ctx);
|
||||
|
||||
Panel panel = new Panel();
|
||||
this.appendChild(panel);
|
||||
|
||||
|
@ -75,7 +95,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
Image imgr = new Image("/images/Refresh24.png");
|
||||
recentItemsToolbar.appendChild(imgr);
|
||||
imgr.setStyle("text-align: right; cursor: pointer;");
|
||||
imgr.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Refresh")));
|
||||
imgr.setTooltiptext(Util.cleanAmp(Msg.getMsg(ctx, "Refresh")));
|
||||
imgr.addEventListener(Events.ON_CLICK, this);
|
||||
//
|
||||
|
||||
|
@ -83,10 +103,22 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
recentItemsToolbar.appendChild(img);
|
||||
img.setStyle("text-align: right;");
|
||||
img.setDroppable(DELETE_RECENTITEMS_DROPPABLE);
|
||||
img.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Delete")));
|
||||
img.setTooltiptext(Util.cleanAmp(Msg.getMsg(ctx, "Delete")));
|
||||
img.addEventListener(Events.ON_DROP, this);
|
||||
//
|
||||
EventManager.getInstance().register(MRecentItem.ON_RECENT_ITEM_CHANGED_TOPIC, this);
|
||||
createTopicSubscriber();
|
||||
}
|
||||
|
||||
private static synchronized void createTopicSubscriber() {
|
||||
if (topicSubscriber == null) {
|
||||
topicSubscriber = new TopicSubscriber();
|
||||
IMessageService service = Service.locator().locate(IMessageService.class).getService();
|
||||
if (service != null) {
|
||||
ITopic<Integer> topic = service.getTopic(MRecentItem.ON_RECENT_ITEM_CHANGED_TOPIC);
|
||||
topic.subscribe(topicSubscriber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createRecentItemsPanel()
|
||||
|
@ -101,7 +133,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
*/
|
||||
private void riDBremove(int AD_RecentItem_ID)
|
||||
{
|
||||
MRecentItem ri = MRecentItem.get(Env.getCtx(), AD_RecentItem_ID);
|
||||
MRecentItem ri = MRecentItem.get(ctx, AD_RecentItem_ID);
|
||||
ri.deleteEx(true);
|
||||
}
|
||||
|
||||
|
@ -144,8 +176,8 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
}
|
||||
|
||||
if (AD_RecentItem_ID > 0) {
|
||||
MRecentItem ri = MRecentItem.get(Env.getCtx(), AD_RecentItem_ID);
|
||||
String TableName = MTable.getTableName(Env.getCtx(), ri.getAD_Table_ID());
|
||||
MRecentItem ri = MRecentItem.get(ctx, AD_RecentItem_ID);
|
||||
String TableName = MTable.getTableName(ctx, ri.getAD_Table_ID());
|
||||
MQuery query = MQuery.getEqualQuery(TableName + "_ID", ri.getRecord_ID());
|
||||
|
||||
SessionManager.getAppDesktop().openWindow(ri.getAD_Window_ID(), query, null);
|
||||
|
@ -170,12 +202,11 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
bxRecentItems.removeChild(comp);
|
||||
}
|
||||
|
||||
int maxri = MSysConfig.getIntValue(MSysConfig.RecentItems_MaxShown, 10, Env.getAD_Client_ID(Env.getCtx()));
|
||||
int maxri = MSysConfig.getIntValue(MSysConfig.RecentItems_MaxShown, 10, Env.getAD_Client_ID(ctx));
|
||||
if (maxri <= 0)
|
||||
return;
|
||||
|
||||
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
|
||||
List<MRecentItem> ris = MRecentItem.getFromUser(Env.getCtx(), AD_User_ID);
|
||||
List<MRecentItem> ris = MRecentItem.getFromUser(ctx, AD_User_ID);
|
||||
int riShown = 0;
|
||||
for (MRecentItem ri : ris) {
|
||||
String label = ri.getLabel();
|
||||
|
@ -224,7 +255,33 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
public void updateUI() {
|
||||
refresh();
|
||||
bxRecentItems.invalidate();
|
||||
desktop = getDesktop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(org.osgi.service.event.Event event) {
|
||||
if (event.getTopic().equals(MRecentItem.ON_RECENT_ITEM_CHANGED_TOPIC) && event.getProperty("AD_User_ID") != null) {
|
||||
Object property = event.getProperty("AD_User_ID");
|
||||
if (property instanceof Number) {
|
||||
int id = ((Number)property).intValue();
|
||||
if (id == AD_User_ID) {
|
||||
try {
|
||||
if (desktop != null && desktop.isAlive()) {
|
||||
ServerPushTemplate template = new ServerPushTemplate(desktop);
|
||||
refresh(template);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
EventManager.getInstance().unregister(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TopicSubscriber implements ITopicSubscriber<Integer> {
|
||||
@Override
|
||||
public void onMessage(Integer message) {
|
||||
MRecentItem.postOnChangedEvent(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,4 +38,11 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
|
|||
|
||||
public void updateUI() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this dashboard widget uses polling to update its content
|
||||
*/
|
||||
public boolean isPooling() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.util.ServerContext;
|
||||
import org.adempiere.webui.desktop.IDesktop;
|
||||
import org.adempiere.webui.session.SessionContextListener;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.util.CLogger;
|
||||
|
@ -42,9 +40,9 @@ public class DashboardRunnable implements Runnable, Serializable
|
|||
|
||||
private Desktop desktop;
|
||||
private List<DashboardPanel> dashboardPanels;
|
||||
private IDesktop appDesktop;
|
||||
private Locale locale;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final CLogger logger = CLogger.getCLogger(DashboardRunnable.class);
|
||||
|
||||
/**
|
||||
|
@ -52,17 +50,15 @@ public class DashboardRunnable implements Runnable, Serializable
|
|||
* @param desktop zk desktop interface
|
||||
* @param appDesktop adempiere desktop interface
|
||||
*/
|
||||
public DashboardRunnable(Desktop desktop, IDesktop appDesktop) {
|
||||
public DashboardRunnable(Desktop desktop) {
|
||||
this.desktop = desktop;
|
||||
this.appDesktop = appDesktop;
|
||||
|
||||
dashboardPanels = new ArrayList<DashboardPanel>();
|
||||
locale = Locales.getCurrent();
|
||||
}
|
||||
|
||||
public DashboardRunnable(DashboardRunnable tmp, Desktop desktop,
|
||||
IDesktop appDesktop) {
|
||||
this(desktop, appDesktop);
|
||||
public DashboardRunnable(DashboardRunnable tmp, Desktop desktop) {
|
||||
this(desktop);
|
||||
this.dashboardPanels = tmp.dashboardPanels;
|
||||
}
|
||||
|
||||
|
@ -70,16 +66,17 @@ public class DashboardRunnable implements Runnable, Serializable
|
|||
{
|
||||
Locales.setThreadLocal(locale);
|
||||
try {
|
||||
refreshDashboard();
|
||||
refreshDashboard(true);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.INFO, e.getLocalizedMessage(), (e.getCause() != null ? e.getCause() : e));
|
||||
// logger.log(Level.INFO, e.getLocalizedMessage(), (e.getCause() != null ? e.getCause() : e));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh dashboard content
|
||||
*/
|
||||
public void refreshDashboard()
|
||||
public void refreshDashboard(boolean pooling)
|
||||
{
|
||||
|
||||
ServerPushTemplate template = new ServerPushTemplate(desktop);
|
||||
|
@ -102,12 +99,14 @@ public class DashboardRunnable implements Runnable, Serializable
|
|||
{
|
||||
ServerContext.setCurrentInstance(ctx);
|
||||
}
|
||||
|
||||
for(int i = 0; i < dashboardPanels.size(); i++)
|
||||
{
|
||||
if (pooling && !dashboardPanels.get(i).isPooling())
|
||||
continue;
|
||||
|
||||
dashboardPanels.get(i).refresh(template);
|
||||
}
|
||||
|
||||
appDesktop.onServerPush(template);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ public class DashboardController implements EventListener<Event> {
|
|||
if (!dashboardLayout.getDesktop().isServerPushEnabled())
|
||||
dashboardLayout.getDesktop().enableServerPush(true);
|
||||
|
||||
dashboardRunnable = new DashboardRunnable(parent.getDesktop(), desktopImpl);
|
||||
dashboardRunnable = new DashboardRunnable(parent.getDesktop());
|
||||
|
||||
// Dashboard content
|
||||
Vlayout dashboardColumnLayout = null;
|
||||
|
@ -416,7 +416,7 @@ public class DashboardController implements EventListener<Event> {
|
|||
|
||||
if (!dashboardRunnable.isEmpty())
|
||||
{
|
||||
dashboardRunnable.refreshDashboard();
|
||||
dashboardRunnable.refreshDashboard(false);
|
||||
|
||||
// default Update every one minutes
|
||||
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
|
||||
|
@ -617,7 +617,7 @@ public class DashboardController implements EventListener<Event> {
|
|||
}
|
||||
|
||||
if (!dashboardRunnable.isEmpty())
|
||||
dashboardRunnable.refreshDashboard();
|
||||
dashboardRunnable.refreshDashboard(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -626,14 +626,13 @@ public class DashboardController implements EventListener<Event> {
|
|||
*
|
||||
* @param page
|
||||
* @param desktop
|
||||
* @param appDesktop
|
||||
*/
|
||||
public void onSetPage(Page page, Desktop desktop, IDesktop appDesktop) {
|
||||
public void onSetPage(Page page, Desktop desktop) {
|
||||
if (dashboardFuture != null && !dashboardFuture.isDone()) {
|
||||
dashboardFuture.cancel(true);
|
||||
|
||||
DashboardRunnable tmp = dashboardRunnable;
|
||||
dashboardRunnable = new DashboardRunnable(tmp, desktop, appDesktop);
|
||||
dashboardRunnable = new DashboardRunnable(tmp, desktop);
|
||||
// default Update every one minutes
|
||||
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
|
||||
dashboardFuture = Adempiere.getThreadPoolExecutor().scheduleWithFixedDelay(dashboardRunnable, interval, interval, TimeUnit.MILLISECONDS);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.adempiere.webui.desktop;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.event.EventManager;
|
||||
|
@ -29,7 +30,6 @@ import org.adempiere.webui.apps.AEnv;
|
|||
import org.adempiere.webui.apps.BusyDialog;
|
||||
import org.adempiere.webui.component.Tabpanel;
|
||||
import org.adempiere.webui.component.ToolBarButton;
|
||||
import org.adempiere.webui.dashboard.DPActivities;
|
||||
import org.adempiere.webui.event.MenuListener;
|
||||
import org.adempiere.webui.event.ZKBroadCastManager;
|
||||
import org.adempiere.webui.panel.BroadcastMessageWindow;
|
||||
|
@ -57,6 +57,8 @@ import org.zkoss.zk.ui.Executions;
|
|||
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.EventQueue;
|
||||
import org.zkoss.zk.ui.event.EventQueues;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.event.OpenEvent;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
|
@ -75,7 +77,7 @@ import org.zkoss.zul.West;
|
|||
* @version $Revision: 0.10 $
|
||||
* @author Deepak Pansheriya/Vivek - Adding support for message broadcasting
|
||||
*/
|
||||
public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback,EventHandler,DesktopCleanup
|
||||
public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, EventHandler,DesktopCleanup
|
||||
{
|
||||
/**
|
||||
* generated serial version ID
|
||||
|
@ -119,6 +121,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
//subscribing to broadcast event
|
||||
bindEventManager();
|
||||
ZKBroadCastManager.getBroadCastMgr();
|
||||
|
||||
EventQueue<Event> queue = EventQueues.lookup(ACTIVITIES_EVENT_QUEUE, true);
|
||||
queue.subscribe(this);
|
||||
}
|
||||
|
||||
protected Component doCreatePart(Component parent)
|
||||
|
@ -242,18 +247,36 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (eventName.equals(ON_ACTIVITIES_CHANGED_EVENT))
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) event.getData();
|
||||
Integer notice = (Integer) map.get("notice");
|
||||
Integer request = (Integer) map.get("request");
|
||||
Integer workflow = (Integer) map.get("workflow");
|
||||
Integer unprocessed = (Integer) map.get("unprocessed");
|
||||
boolean change = false;
|
||||
if (notice != null && notice.intValue() != noOfNotice)
|
||||
{
|
||||
noOfNotice = notice.intValue(); change = true;
|
||||
}
|
||||
if (request != null && request.intValue() != noOfRequest)
|
||||
{
|
||||
noOfRequest = request.intValue(); change = true;
|
||||
}
|
||||
if (workflow != null && workflow.intValue() != noOfWorkflow)
|
||||
{
|
||||
noOfWorkflow = workflow.intValue(); change = true;
|
||||
}
|
||||
if (unprocessed != null && unprocessed.intValue() != noOfUnprocessed)
|
||||
{
|
||||
noOfUnprocessed = unprocessed.intValue(); change = true;
|
||||
}
|
||||
if (change)
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void onServerPush(ServerPushTemplate template)
|
||||
{
|
||||
noOfNotice = DPActivities.getNoticeCount();
|
||||
noOfRequest = DPActivities.getRequestCount();
|
||||
noOfWorkflow = DPActivities.getWorkflowCount();
|
||||
noOfUnprocessed = DPActivities.getUnprocessedCount();
|
||||
|
||||
template.executeAsync(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
|
@ -264,11 +287,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
this.page = page;
|
||||
|
||||
if (dashboardController != null) {
|
||||
dashboardController.onSetPage(page, layout.getDesktop(), this);
|
||||
dashboardController.onSetPage(page, layout.getDesktop());
|
||||
}
|
||||
|
||||
if (sideController != null) {
|
||||
sideController.onSetPage(page, layout.getDesktop(), this);
|
||||
sideController.onSetPage(page, layout.getDesktop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.adempiere.webui.apps.ProcessDialog;
|
|||
import org.adempiere.webui.component.Window;
|
||||
import org.adempiere.webui.panel.ADForm;
|
||||
import org.adempiere.webui.part.UIPart;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.util.WebDoc;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
|
@ -34,6 +33,8 @@ import org.zkoss.zk.ui.Page;
|
|||
public interface IDesktop extends UIPart {
|
||||
|
||||
public static final String WINDOWNO_ATTRIBUTE = "desktop.windowno";
|
||||
public static final String ACTIVITIES_EVENT_QUEUE = "ActivitiesEventQueue";
|
||||
public static final String ON_ACTIVITIES_CHANGED_EVENT = "onActivitiesChanged";
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -193,12 +194,4 @@ public interface IDesktop extends UIPart {
|
|||
* User logout from desktop, do clean up
|
||||
*/
|
||||
public void logout();
|
||||
|
||||
/**
|
||||
* Invoke by the server push thread. If the desktop argument is not null, must activate desktop
|
||||
* before making update to UI. For performance reason, keep the activate of desktop as short
|
||||
* as possible.
|
||||
* @param template
|
||||
*/
|
||||
public void onServerPush(ServerPushTemplate template);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue