Fixed dashboard widget size not restore correctly after maximized.

Refactor dashboard implementation to remove duplicate code.
This commit is contained in:
Heng Sin Low 2012-03-02 15:17:34 +08:00
parent a4527128a9
commit a4f27e1f7c
5 changed files with 370 additions and 722 deletions

View File

@ -242,20 +242,4 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
win.doHighlighted();
}
protected String stripHtml(String htmlString, boolean all) {
htmlString = htmlString
.replace("<html>", "")
.replace("</html>", "")
.replace("<body>", "")
.replace("</body>", "")
.replace("<head>", "")
.replace("</head>", "");
if (all)
htmlString = htmlString
.replace(">", "&gt;")
.replace("<", "&lt;");
return htmlString;
}
}

View File

@ -0,0 +1,324 @@
/**
*
*/
package org.adempiere.webui.desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.adempiere.webui.apps.graph.WGraph;
import org.adempiere.webui.apps.graph.WPerformanceDetail;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.dashboard.DashboardRunnable;
import org.compiere.model.I_AD_Menu;
import org.compiere.model.MDashboardContent;
import org.compiere.model.MGoal;
import org.compiere.model.X_PA_DashboardContent;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
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.Events;
import org.zkoss.zk.ui.event.MaximizeEvent;
import org.zkoss.zul.Anchorchildren;
import org.zkoss.zul.Anchorlayout;
import org.zkoss.zul.Html;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Panelchildren;
import org.zkoss.zul.Style;
import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Vlayout;
/**
* @author hengsin
*
*/
public class DashboardController implements EventListener<MaximizeEvent> {
private final static CLogger logger = CLogger.getCLogger(DashboardController.class);
private Component prevParent;
private Component prevNext;
private List<Panel> panelList = new ArrayList<Panel>();
private List<Anchorchildren> columnList = new ArrayList<Anchorchildren>();
private Anchorlayout dashboardLayout;
private Anchorchildren maximizedHolder;
private Thread dashboardThread;
private DashboardRunnable dashboardRunnable;
public DashboardController() {
dashboardLayout = new Anchorlayout();
dashboardLayout.setWidth("99%");
dashboardLayout.setHeight("99%");
dashboardLayout.setStyle("position: absolute;");
dashboardLayout.setVflex("true");
maximizedHolder = new Anchorchildren();
maximizedHolder.setAnchor("99% 99%");
}
public void render(Component parent, IDesktop desktopImpl) {
Style style = new Style();
//, .z-anchorchildren
style.setContent(".z-anchorlayout-body { overflow:auto } .z-anchorchildren { overflow:visible } ");
style.setPage(parent.getPage());
parent.appendChild(dashboardLayout);
if (!dashboardLayout.getDesktop().isServerPushEnabled())
dashboardLayout.getDesktop().enableServerPush(true);
dashboardRunnable = new DashboardRunnable(parent.getDesktop(), desktopImpl);
// Dashboard content
Vlayout dashboardColumnLayout = null;
int currentColumnNo = 0;
int noOfCols = 0;
int width = 0;
try
{
noOfCols = MDashboardContent.getForSessionColumnCount();
width = noOfCols <= 0 ? 100 : 100 / noOfCols;
for (final MDashboardContent dp : MDashboardContent.getForSession())
{
int columnNo = dp.getColumnNo();
if(dashboardColumnLayout == null || currentColumnNo != columnNo)
{
dashboardColumnLayout = new Vlayout();
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor((width-2) + "%" + " 100%");
dashboardColumn.appendChild(dashboardColumnLayout);
columnList.add(dashboardColumn);
dashboardLayout.appendChild(dashboardColumn);
dashboardColumnLayout.setWidth("100%");
currentColumnNo = columnNo;
}
Panel panel = new Panel();
panelList.add(panel);
panel.addEventListener(Events.ON_MAXIMIZE, this);
panel.setStyle("margin: 2px; position: relative;");
panel.setTitle(dp.get_Translation(MDashboardContent.COLUMNNAME_Name));
panel.setMaximizable(true);
String description = dp.get_Translation(MDashboardContent.COLUMNNAME_Description);
if(description != null)
panel.setTooltiptext(description);
panel.setCollapsible(dp.isCollapsible());
panel.setBorder("normal");
dashboardColumnLayout.appendChild(panel);
Panelchildren content = new Panelchildren();
panel.appendChild(content);
boolean panelEmpty = true;
// HTML content
String htmlContent = dp.getHTML();
if(htmlContent != null)
{
StringBuffer result = new StringBuffer("<html><head>");
URL url = getClass().getClassLoader().getResource("org/compiere/images/PAPanel.css");
InputStreamReader ins;
try {
ins = new InputStreamReader(url.openStream());
BufferedReader bufferedReader = new BufferedReader( ins );
String cssLine;
while ((cssLine = bufferedReader.readLine()) != null)
result.append(cssLine + "\n");
} catch (IOException e1) {
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
}
result.append("</head><body><div class=\"content\">\n");
// if(description != null)
// result.append("<h2>" + description + "</h2>\n");
result.append(stripHtml(htmlContent, false) + "<br>\n");
result.append("</div>\n</body>\n</html>\n</html>");
Html html = new Html();
html.setContent(result.toString());
content.appendChild(html);
panelEmpty = false;
}
// Window
int AD_Window_ID = dp.getAD_Window_ID();
if(AD_Window_ID > 0)
{
int AD_Menu_ID = dp.getAD_Menu_ID();
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
I_AD_Menu menu = dp.getAD_Menu();
btn.setLabel(menu.getName());
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
btn.addEventListener(Events.ON_CLICK, this);
content.appendChild(btn);
panelEmpty = false;
}
// Goal
int PA_Goal_ID = dp.getPA_Goal_ID();
if(PA_Goal_ID > 0)
{
//link to open performance detail
Toolbarbutton link = new Toolbarbutton();
link.setImage("/images/Zoom16.png");
link.setAttribute("PA_Goal_ID", PA_Goal_ID);
link.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
int PA_Goal_ID = (Integer)event.getTarget().getAttribute("PA_Goal_ID");
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
new WPerformanceDetail(goal);
}
});
content.appendChild(link);
String goalDisplay = dp.getGoalDisplay();
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
WGraph graph = new WGraph(goal, 55, false, true,
!(X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
content.appendChild(graph);
panelEmpty = false;
}
// ZUL file url
String url = dp.getZulFilePath();
if(url != null)
{
try {
Component component = Executions.createComponents(url, content, null);
if(component != null)
{
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
if (!dashboardPanel.getChildren().isEmpty()) {
content.appendChild(dashboardPanel);
dashboardRunnable.add(dashboardPanel);
panelEmpty = false;
}
}
else
{
content.appendChild(component);
panelEmpty = false;
}
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
}
}
if (panelEmpty)
panel.detach();
}
}
catch (Exception e)
{
logger.log(Level.WARNING, "Failed to create dashboard content", e);
}
//
if (!dashboardRunnable.isEmpty())
{
dashboardRunnable.refreshDashboard();
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
}
}
@Override
public void onEvent(MaximizeEvent event) throws Exception {
Panel panel = (Panel) event.getTarget();
if (event.isMaximized()) {
prevParent = panel.getParent();
prevNext = panel.getNextSibling();
panel.detach();
for (Anchorchildren anchorChildren : columnList) {
anchorChildren.detach();
}
dashboardLayout.appendChild(maximizedHolder);
maximizedHolder.appendChild(panel);
} else {
maximizedHolder.detach();
panel.detach();
prevParent.insertBefore(panel, prevNext);
for (Anchorchildren anchorChildren : columnList) {
dashboardLayout.appendChild(anchorChildren);
}
//following 2 line needed for restore to size the panel correctly
panel.setWidth(null);
panel.setHeight(null);
}
}
/**
*
* @param page
* @param desktop
* @param appDesktop
*/
public void onSetPage(Page page, Desktop desktop, IDesktop appDesktop) {
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
DashboardRunnable tmp = dashboardRunnable;
dashboardRunnable = new DashboardRunnable(tmp, desktop, appDesktop);
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
}
}
/**
* clean up for logout
*/
public void onLogOut() {
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
}
}
public void addDashboardPanel(DashboardPanel dashboardPanel) {
if (dashboardRunnable != null) {
dashboardRunnable.add(dashboardPanel);
}
}
private String stripHtml(String htmlString, boolean all) {
htmlString = htmlString
.replace("<html>", "")
.replace("</html>", "")
.replace("<body>", "")
.replace("</body>", "")
.replace("<head>", "")
.replace("</head>", "");
if (all)
htmlString = htmlString
.replace(">", "&gt;")
.replace("<", "&lt;");
return htmlString;
}
}

View File

@ -17,25 +17,14 @@
package org.adempiere.webui.desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.graph.WGraph;
import org.adempiere.webui.apps.graph.WPerformanceDetail;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DPActivities;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.dashboard.DashboardRunnable;
import org.adempiere.webui.event.MenuListener;
import org.adempiere.webui.panel.HeaderPanel;
import org.adempiere.webui.panel.SidePanel;
@ -44,36 +33,22 @@ import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.UserPreference;
import org.compiere.model.I_AD_Menu;
import org.compiere.model.MDashboardContent;
import org.compiere.model.MGoal;
import org.compiere.model.X_PA_DashboardContent;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
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.Events;
import org.zkoss.zk.ui.event.MaximizeEvent;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Anchorchildren;
import org.zkoss.zul.Anchorlayout;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.North;
import org.zkoss.zul.Style;
import org.zkoss.zul.Vlayout;
import org.zkoss.zul.West;
import org.zkoss.zul.Html;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Panelchildren;
import org.zkoss.zul.Toolbarbutton;
/**
*
@ -83,23 +58,20 @@ import org.zkoss.zul.Toolbarbutton;
* @date Mar 2, 2007
* @version $Revision: 0.10 $
*/
public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener, IServerPushCallback
public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback
{
/**
* generated serial version ID
*/
private static final long serialVersionUID = -8203958978173990301L;
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
private Center windowArea;
private Borderlayout layout;
private Thread dashboardThread;
private DashboardRunnable dashboardRunnable;
private int noOfNotice;
private int noOfRequest;
@ -108,14 +80,12 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
private Tabpanel homeTab;
private List<Panel> panelList = new ArrayList<Panel>();
private List<Vlayout> vlayoutList = new ArrayList<Vlayout>();
private Anchorlayout portalLayout;
private DashboardController dashboardController;
public DefaultDesktop()
{
super();
dashboardController = new DashboardController();
}
protected Component doCreatePart(Component parent)
@ -136,8 +106,6 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
else
layout.setPage(page);
dashboardRunnable = new DashboardRunnable(layout.getDesktop(), this);
North n = new North();
layout.appendChild(n);
n.setCollapsible(false);
@ -150,7 +118,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
w.setSplittable(true);
w.setTitle(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Menu")));
w.setFlex(true);
w.addEventListener(Events.ON_OPEN, new EventListener() {
w.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent oe = (OpenEvent) event;
@ -211,192 +179,13 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
private void renderHomeTab()
{
Style style = new Style();
//, .z-anchorchildren
style.setContent(".z-anchorlayout-body { overflow:auto } .z-anchorchildren { overflow:visible } ");
style.setPage(homeTab.getPage());
homeTab.getChildren().clear();
portalLayout = new Anchorlayout();
portalLayout.setWidth("99%");
portalLayout.setHeight("99%");
portalLayout.setStyle("position: absolute;");
portalLayout.setVflex("true");
homeTab.appendChild(portalLayout);
// Dashboard content
Vlayout portalchildren = null;
int currentColumnNo = 0;
int noOfCols = 0;
int width = 0;
try
{
noOfCols = MDashboardContent.getForSessionColumnCount();
width = noOfCols <= 0 ? 100 : 100 / noOfCols;
for (final MDashboardContent dp : MDashboardContent.getForSession())
{
int columnNo = dp.getColumnNo();
if(portalchildren == null || currentColumnNo != columnNo)
{
portalchildren = new Vlayout();
vlayoutList.add(portalchildren);
Anchorchildren anchorChildren = new Anchorchildren();
anchorChildren.setAnchor((width-2) + "%" + " 100%");
anchorChildren.appendChild(portalchildren);
portalLayout.appendChild(anchorChildren);
portalchildren.setWidth("100%");
currentColumnNo = columnNo;
}
Panel panel = new Panel();
panelList.add(panel);
panel.addEventListener(Events.ON_MAXIMIZE, this);
panel.setStyle("margin: 2px; position: relative;");
panel.setTitle(dp.get_Translation(MDashboardContent.COLUMNNAME_Name));
panel.setMaximizable(true);
String description = dp.get_Translation(MDashboardContent.COLUMNNAME_Description);
if(description != null)
panel.setTooltiptext(description);
panel.setCollapsible(dp.isCollapsible());
panel.setBorder("normal");
portalchildren.appendChild(panel);
Panelchildren content = new Panelchildren();
panel.appendChild(content);
boolean panelEmpty = true;
// HTML content
String htmlContent = dp.getHTML();
if(htmlContent != null)
{
StringBuffer result = new StringBuffer("<html><head>");
URL url = getClass().getClassLoader().getResource("org/compiere/images/PAPanel.css");
InputStreamReader ins;
try {
ins = new InputStreamReader(url.openStream());
BufferedReader bufferedReader = new BufferedReader( ins );
String cssLine;
while ((cssLine = bufferedReader.readLine()) != null)
result.append(cssLine + "\n");
} catch (IOException e1) {
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
}
result.append("</head><body><div class=\"content\">\n");
// if(description != null)
// result.append("<h2>" + description + "</h2>\n");
result.append(stripHtml(htmlContent, false) + "<br>\n");
result.append("</div>\n</body>\n</html>\n</html>");
Html html = new Html();
html.setContent(result.toString());
content.appendChild(html);
panelEmpty = false;
}
// Window
int AD_Window_ID = dp.getAD_Window_ID();
if(AD_Window_ID > 0)
{
int AD_Menu_ID = dp.getAD_Menu_ID();
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
I_AD_Menu menu = dp.getAD_Menu();
btn.setLabel(menu.getName());
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
btn.addEventListener(Events.ON_CLICK, this);
content.appendChild(btn);
panelEmpty = false;
}
// Goal
int PA_Goal_ID = dp.getPA_Goal_ID();
if(PA_Goal_ID > 0)
{
//link to open performance detail
Toolbarbutton link = new Toolbarbutton();
link.setImage("/images/Zoom16.png");
link.setAttribute("PA_Goal_ID", PA_Goal_ID);
link.addEventListener(Events.ON_CLICK, new EventListener() {
public void onEvent(Event event) throws Exception {
int PA_Goal_ID = (Integer)event.getTarget().getAttribute("PA_Goal_ID");
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
new WPerformanceDetail(goal);
}
});
content.appendChild(link);
String goalDisplay = dp.getGoalDisplay();
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
WGraph graph = new WGraph(goal, 55, false, true,
!(X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
content.appendChild(graph);
panelEmpty = false;
}
// ZUL file url
String url = dp.getZulFilePath();
if(url != null)
{
try {
Component component = Executions.createComponents(url, content, null);
if(component != null)
{
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
if (!dashboardPanel.getChildren().isEmpty()) {
content.appendChild(dashboardPanel);
dashboardRunnable.add(dashboardPanel);
panelEmpty = false;
}
}
else
{
content.appendChild(component);
panelEmpty = false;
}
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
}
}
if (panelEmpty)
panel.detach();
}
}
catch (Exception e)
{
logger.log(Level.WARNING, "Failed to create dashboard content", e);
}
//
//register as 0
//register as 0
registerWindow(homeTab);
if (!portalLayout.getDesktop().isServerPushEnabled())
portalLayout.getDesktop().enableServerPush(true);
if (!dashboardRunnable.isEmpty())
{
dashboardRunnable.refreshDashboard();
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
}
dashboardController.render(homeTab, this);
}
public void onEvent(Event event)
@ -417,51 +206,6 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
}
}
else if(event instanceof MaximizeEvent) {
MaximizeEvent me = (MaximizeEvent) event;
Panel panel = (Panel) event.getTarget();
if (((MaximizeEvent) event).isMaximized()) {
for (Panel p : panelList) {
if (p == panel) {
continue;
}
p.setVisible(false);
Anchorchildren layout = (Anchorchildren) p.getParent().getParent();
if (layout == panel.getParent().getParent()) {
if (!layout.getAnchor().equals("100% 100%")) {
layout.setAttribute("anchor.original", layout.getAnchor());
layout.setAnchor("100% 100%");
}
continue;
}
if (layout.isVisible()) {
layout.setVisible(false);
}
}
panel.getParent().getParent().getParent().invalidate();
} else {
for (Panel p : panelList) {
if (!p.isVisible()) {
p.setVisible(true);
}
Anchorchildren layout = (Anchorchildren) p.getParent().getParent();
if (!layout.isVisible()) {
layout.setVisible(true);
}
if (layout.getAnchor().equals("100% 100%")) {
layout.setAnchor((String) layout.getAttribute("anchor.original"));
}
}
}
// String uid = portalLayout.getUuid();
// String script = "zk.Widget.$('"+uid+"').rerender();";
// AuScript auScript = new AuScript(portalLayout, script);
// Clients.response("reRenderHomeTabLayout", auScript);
for (Panel p : panelList) {
Clients.resize(p);
}
// Clients.resize(portalLayout);
}
}
public void onServerPush(ServerPushTemplate template)
@ -481,15 +225,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
if (this.page != page) {
layout.setPage(page);
this.page = page;
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
DashboardRunnable tmp = dashboardRunnable;
dashboardRunnable = new DashboardRunnable(tmp, layout.getDesktop(), this);
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
if (dashboardController != null) {
dashboardController.onSetPage(page, layout.getDesktop(), this);
}
}
}
@ -503,9 +241,8 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
public void logout() {
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
if (dashboardController != null) {
dashboardController.onLogOut();
}
}

View File

@ -13,26 +13,17 @@
*****************************************************************************/
package org.adempiere.webui.desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.ProcessDialog;
import org.adempiere.webui.apps.graph.WGraph;
import org.adempiere.webui.component.Accordion;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DPActivities;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.dashboard.DashboardRunnable;
import org.adempiere.webui.event.MenuListener;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.panel.HeaderPanel;
@ -43,12 +34,7 @@ import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.UserPreference;
import org.adempiere.webui.window.ADWindow;
import org.compiere.model.MGoal;
import org.compiere.model.MMenu;
import org.compiere.model.X_AD_Menu;
import org.compiere.model.X_PA_DashboardContent;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
@ -63,19 +49,14 @@ import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.North;
import org.zkoss.zul.Vlayout;
import org.zkoss.zul.West;
import org.zkoss.zul.Div;
import org.zkoss.zul.Html;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Panelchildren;
/**
* @author hengsin
*/
public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Serializable, EventListener, IServerPushCallback
public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback
{
private static final long serialVersionUID = -7483133591812825441L;
@ -84,16 +65,13 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
private static final String ACTIVITIES_PATH = "/zul/activities.zul";
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
private Center windowArea;
private Borderlayout layout;
private Thread dashboardThread;
private DashboardRunnable dashboardRunnable;
private Accordion shortcutPanel;
private int noOfNotice;
@ -104,9 +82,12 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
private Tabpanel homeTab;
private DashboardController dashboardController;
public NavBar2Desktop()
{
super();
dashboardController = new DashboardController();
}
protected Component doCreatePart(Component parent)
@ -127,8 +108,6 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
else
layout.setPage(page);
dashboardRunnable = new DashboardRunnable(layout.getDesktop(), this);
North n = new North();
layout.appendChild(n);
n.setCollapsible(false);
@ -141,7 +120,7 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
w.setSplittable(true);
w.setTitle(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Menu")));
w.setFlex(true);
w.addEventListener(Events.ON_OPEN, new EventListener() {
w.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent oe = (OpenEvent) event;
@ -186,7 +165,7 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
dashboardRunnable.add(dashboardPanel);
dashboardController.addDashboardPanel(dashboardPanel);
}
shortcutPanel.add(div, "Activities");
@ -241,179 +220,10 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
{
homeTab.getChildren().clear();
Hlayout portalLayout = new Hlayout();
portalLayout.setWidth("100%");
portalLayout.setHeight("100%");
portalLayout.setStyle("position: absolute; overflow: auto");
homeTab.appendChild(portalLayout);
// Dashboard content
Vlayout portalchildren = null;
int currentColumnNo = 0;
String sql = "SELECT COUNT(DISTINCT COLUMNNO) "
+ "FROM PA_DASHBOARDCONTENT "
+ "WHERE (AD_CLIENT_ID=0 OR AD_CLIENT_ID=?) AND ISACTIVE='Y'";
int noOfCols = DB.getSQLValue(null, sql,
Env.getAD_Client_ID(Env.getCtx()));
int width = noOfCols <= 0 ? 100 : 100/noOfCols;
sql = "SELECT x.*, m.AD_MENU_ID "
+ "FROM PA_DASHBOARDCONTENT x "
+ "LEFT OUTER JOIN AD_MENU m ON x.AD_WINDOW_ID=m.AD_WINDOW_ID "
+ "WHERE (x.AD_CLIENT_ID=0 OR x.AD_CLIENT_ID=?) AND x.ISACTIVE='Y' "
+ "AND x.zulfilepath not in (?, ?) "
+ "ORDER BY x.COLUMNNO, x.AD_CLIENT_ID, x.LINE ";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, Env.getAD_Client_ID(Env.getCtx()));
pstmt.setString(2, ACTIVITIES_PATH);
pstmt.setString(3, FAVOURITES_PATH);
rs = pstmt.executeQuery();
while (rs.next())
{
int columnNo = rs.getInt(X_PA_DashboardContent.COLUMNNAME_ColumnNo);
if(portalchildren == null || currentColumnNo != columnNo)
{
portalchildren = new Vlayout();
portalLayout.appendChild(portalchildren);
portalchildren.setWidth(width + "%");
portalchildren.setStyle("padding: 5px");
currentColumnNo = columnNo;
}
Panel panel = new Panel();
panel.setStyle("margin-bottom:10px");
panel.setTitle(rs.getString(X_PA_DashboardContent.COLUMNNAME_Name));
String description = rs.getString(X_PA_DashboardContent.COLUMNNAME_Description);
if(description != null)
panel.setTooltiptext(description);
String collapsible = rs.getString(X_PA_DashboardContent.COLUMNNAME_IsCollapsible);
panel.setCollapsible(collapsible.equals("Y"));
panel.setBorder("normal");
portalchildren.appendChild(panel);
Panelchildren content = new Panelchildren();
panel.appendChild(content);
boolean panelEmpty = true;
// HTML content
String htmlContent = rs.getString(X_PA_DashboardContent.COLUMNNAME_HTML);
if(htmlContent != null)
{
StringBuffer result = new StringBuffer("<html><head>");
URL url = getClass().getClassLoader().
getResource("org/compiere/images/PAPanel.css");
InputStreamReader ins;
try {
ins = new InputStreamReader(url.openStream());
BufferedReader bufferedReader = new BufferedReader( ins );
String cssLine;
while ((cssLine = bufferedReader.readLine()) != null)
result.append(cssLine + "\n");
} catch (IOException e1) {
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
}
result.append("</head><body><div class=\"content\">\n");
// if(description != null)
// result.append("<h2>" + description + "</h2>\n");
result.append(stripHtml(htmlContent, false) + "<br>\n");
result.append("</div>\n</body>\n</html>\n</html>");
Html html = new Html();
html.setContent(result.toString());
content.appendChild(html);
panelEmpty = false;
}
// Window
int AD_Window_ID = rs.getInt(X_PA_DashboardContent.COLUMNNAME_AD_Window_ID);
if(AD_Window_ID > 0)
{
int AD_Menu_ID = rs.getInt(X_AD_Menu.COLUMNNAME_AD_Menu_ID);
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
MMenu menu = new MMenu(Env.getCtx(), AD_Menu_ID, null);
btn.setLabel(menu.getName());
btn.addEventListener(Events.ON_CLICK, this);
content.appendChild(btn);
panelEmpty = false;
}
// Goal
int PA_Goal_ID = rs.getInt(X_PA_DashboardContent.COLUMNNAME_PA_Goal_ID);
if(PA_Goal_ID > 0)
{
String goalDisplay = rs.getString(X_PA_DashboardContent.COLUMNNAME_GoalDisplay);
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
WGraph graph = new WGraph(goal, 55, false, true,
!(X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
content.appendChild(graph);
panelEmpty = false;
}
// ZUL file url
String url = rs.getString(X_PA_DashboardContent.COLUMNNAME_ZulFilePath);
if(url != null)
{
try {
Component component = Executions.createComponents(url, content, null);
if(component != null)
{
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
if (!dashboardPanel.getChildren().isEmpty()) {
content.appendChild(dashboardPanel);
dashboardRunnable.add(dashboardPanel);
panelEmpty = false;
}
}
else
{
content.appendChild(component);
panelEmpty = false;
}
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
}
}
if (panelEmpty)
panel.detach();
}
} catch(Exception e) {
logger.log(Level.WARNING, "Failed to create dashboard content", e);
} finally {
DB.close(rs, pstmt);
}
//
//register as 0
//register as 0
registerWindow(homeTab);
if (!portalLayout.getDesktop().isServerPushEnabled())
portalLayout.getDesktop().enableServerPush(true);
dashboardRunnable.refreshDashboard();
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
dashboardController.render(homeTab, this);
}
public void onEvent(Event event)
@ -459,15 +269,8 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
layout.setPage(page);
this.page = page;
}
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
DashboardRunnable tmp = dashboardRunnable;
dashboardRunnable = new DashboardRunnable(tmp, layout.getDesktop(), this);
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
if (dashboardController != null) {
dashboardController.onSetPage(page, layout.getDesktop(), this);
}
}
@ -480,9 +283,8 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria
}
public void logout() {
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
if (dashboardController != null) {
dashboardController.onLogOut();
}
}

View File

@ -13,28 +13,18 @@
*****************************************************************************/
package org.adempiere.webui.desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.ProcessDialog;
import org.adempiere.webui.apps.graph.WGraph;
import org.adempiere.webui.component.Accordion;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DPActivities;
import org.adempiere.webui.dashboard.DPFavourites;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.dashboard.DashboardRunnable;
import org.adempiere.webui.event.MenuListener;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.panel.HeaderPanel;
@ -45,12 +35,7 @@ import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.UserPreference;
import org.adempiere.webui.window.ADWindow;
import org.compiere.model.MGoal;
import org.compiere.model.MMenu;
import org.compiere.model.X_AD_Menu;
import org.compiere.model.X_PA_DashboardContent;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuScript;
@ -65,21 +50,16 @@ import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.North;
import org.zkoss.zul.Vlayout;
import org.zkoss.zul.West;
import org.zkoss.zul.Div;
import org.zkoss.zul.Html;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Panelchildren;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.Treerow;
/**
* @author hengsin
*/
public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener, IServerPushCallback
public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback
{
private static final long serialVersionUID = 4721048271543882164L;
@ -90,16 +70,13 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
private static final String VIEWS_PATH = "/zul/views.zul";
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
private Center windowArea;
private Borderlayout layout;
private Thread dashboardThread;
private DashboardRunnable dashboardRunnable;
private Accordion navigationPanel;
private West leftRegion;
@ -114,9 +91,12 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
private Tabpanel homeTab;
private DashboardController dashboardController;
public NavBarDesktop()
{
super();
dashboardController = new DashboardController();
}
protected Component doCreatePart(Component parent)
@ -137,8 +117,6 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
else
layout.setPage(page);
dashboardRunnable = new DashboardRunnable(layout.getDesktop(), this);
North n = new North();
layout.appendChild(n);
n.setCollapsible(false);
@ -151,7 +129,7 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
leftRegion.setSplittable(true);
leftRegion.setTitle("Navigation");
leftRegion.setFlex(true);
leftRegion.addEventListener(Events.ON_OPEN, new EventListener() {
leftRegion.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent oe = (OpenEvent) event;
@ -184,7 +162,7 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
dashboardRunnable.add(dashboardPanel);
dashboardController.addDashboardPanel(dashboardPanel);
}
navigationPanel.add(div, "Activities");
@ -243,180 +221,10 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
{
homeTab.getChildren().clear();
Hlayout portalLayout = new Hlayout();
portalLayout.setWidth("100%");
portalLayout.setHeight("100%");
portalLayout.setStyle("position: absolute; overflow: auto");
homeTab.appendChild(portalLayout);
// Dashboard content
Vlayout portalchildren = null;
int currentColumnNo = 0;
String sql = "SELECT COUNT(DISTINCT COLUMNNO) "
+ "FROM PA_DASHBOARDCONTENT "
+ "WHERE (AD_CLIENT_ID=0 OR AD_CLIENT_ID=?) AND ISACTIVE='Y'";
int noOfCols = DB.getSQLValue(null, sql,
Env.getAD_Client_ID(Env.getCtx()));
int width = noOfCols <= 0 ? 100 : 100/noOfCols;
sql = "SELECT x.*, m.AD_MENU_ID "
+ "FROM PA_DASHBOARDCONTENT x "
+ "LEFT OUTER JOIN AD_MENU m ON x.AD_WINDOW_ID=m.AD_WINDOW_ID "
+ "WHERE (x.AD_CLIENT_ID=0 OR x.AD_CLIENT_ID=?) AND x.ISACTIVE='Y' "
+ "AND x.zulfilepath not in (?, ?, ?) "
+ "ORDER BY x.COLUMNNO, x.AD_CLIENT_ID, x.LINE ";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, Env.getAD_Client_ID(Env.getCtx()));
pstmt.setString(2, ACTIVITIES_PATH);
pstmt.setString(3, FAVOURITES_PATH);
pstmt.setString(4, VIEWS_PATH);
rs = pstmt.executeQuery();
while (rs.next())
{
int columnNo = rs.getInt(X_PA_DashboardContent.COLUMNNAME_ColumnNo);
if(portalchildren == null || currentColumnNo != columnNo)
{
portalchildren = new Vlayout();
portalLayout.appendChild(portalchildren);
portalchildren.setWidth(width + "%");
portalchildren.setStyle("padding: 5px");
currentColumnNo = columnNo;
}
Panel panel = new Panel();
panel.setStyle("margin-bottom:10px");
panel.setTitle(rs.getString(X_PA_DashboardContent.COLUMNNAME_Name));
String description = rs.getString(X_PA_DashboardContent.COLUMNNAME_Description);
if(description != null)
panel.setTooltiptext(description);
String collapsible = rs.getString(X_PA_DashboardContent.COLUMNNAME_IsCollapsible);
panel.setCollapsible(collapsible.equals("Y"));
panel.setBorder("normal");
portalchildren.appendChild(panel);
Panelchildren content = new Panelchildren();
panel.appendChild(content);
boolean panelEmpty = true;
// HTML content
String htmlContent = rs.getString(X_PA_DashboardContent.COLUMNNAME_HTML);
if(htmlContent != null)
{
StringBuffer result = new StringBuffer("<html><head>");
URL url = getClass().getClassLoader().
getResource("org/compiere/images/PAPanel.css");
InputStreamReader ins;
try {
ins = new InputStreamReader(url.openStream());
BufferedReader bufferedReader = new BufferedReader( ins );
String cssLine;
while ((cssLine = bufferedReader.readLine()) != null)
result.append(cssLine + "\n");
} catch (IOException e1) {
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
}
result.append("</head><body><div class=\"content\">\n");
// if(description != null)
// result.append("<h2>" + description + "</h2>\n");
result.append(stripHtml(htmlContent, false) + "<br>\n");
result.append("</div>\n</body>\n</html>\n</html>");
Html html = new Html();
html.setContent(result.toString());
content.appendChild(html);
panelEmpty = false;
}
// Window
int AD_Window_ID = rs.getInt(X_PA_DashboardContent.COLUMNNAME_AD_Window_ID);
if(AD_Window_ID > 0)
{
int AD_Menu_ID = rs.getInt(X_AD_Menu.COLUMNNAME_AD_Menu_ID);
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
MMenu menu = new MMenu(Env.getCtx(), AD_Menu_ID, null);
btn.setLabel(menu.getName());
btn.addEventListener(Events.ON_CLICK, this);
content.appendChild(btn);
panelEmpty = false;
}
// Goal
int PA_Goal_ID = rs.getInt(X_PA_DashboardContent.COLUMNNAME_PA_Goal_ID);
if(PA_Goal_ID > 0)
{
String goalDisplay = rs.getString(X_PA_DashboardContent.COLUMNNAME_GoalDisplay);
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
WGraph graph = new WGraph(goal, 55, false, true,
!(X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
content.appendChild(graph);
panelEmpty = false;
}
// ZUL file url
String url = rs.getString(X_PA_DashboardContent.COLUMNNAME_ZulFilePath);
if(url != null)
{
try {
Component component = Executions.createComponents(url, content, null);
if(component != null)
{
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
if (!dashboardPanel.getChildren().isEmpty()) {
content.appendChild(dashboardPanel);
dashboardRunnable.add(dashboardPanel);
panelEmpty = false;
}
}
else
{
content.appendChild(component);
panelEmpty = false;
}
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
}
}
if (panelEmpty)
panel.detach();
}
} catch(Exception e) {
logger.log(Level.WARNING, "Failed to create dashboard content", e);
} finally {
DB.close(rs, pstmt);
}
//
//register as 0
//register as 0
registerWindow(homeTab);
if (!portalLayout.getDesktop().isServerPushEnabled())
portalLayout.getDesktop().enableServerPush(true);
dashboardRunnable.refreshDashboard();
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
dashboardController.render(homeTab, this);
}
public void onEvent(Event event)
@ -475,15 +283,9 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
layout.setPage(page);
this.page = page;
}
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
DashboardRunnable tmp = dashboardRunnable;
dashboardRunnable = new DashboardRunnable(tmp, layout.getDesktop(), this);
dashboardThread = new Thread(dashboardRunnable, "UpdateInfo");
dashboardThread.setDaemon(true);
dashboardThread.start();
if (dashboardController != null) {
dashboardController.onSetPage(page, layout.getDesktop(), this);
}
}
@ -496,9 +298,8 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial
}
public void logout() {
if (dashboardThread != null && dashboardThread.isAlive()) {
dashboardRunnable.stop();
dashboardThread.interrupt();
if (dashboardController != null) {
dashboardController.onLogOut();
}
}