diff --git a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
index eb25926ccf..01943e5c0e 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
+++ b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
@@ -57,6 +57,6 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
-
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WDocumentStatusIndicator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WDocumentStatusIndicator.java
index 87b2700515..c0d83a5b9f 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WDocumentStatusIndicator.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WDocumentStatusIndicator.java
@@ -57,6 +57,16 @@ public class WDocumentStatusIndicator extends Panel implements EventListener queue = EventQueues.lookup(IDesktop.ACTIVITIES_EVENT_QUEUE, true);
- Event event = new Event(IDesktop.ON_ACTIVITIES_CHANGED_EVENT, null, count);
- queue.publish(event);
+
}
- public void updateUI() {
+ public void updateUI() {
for (WDocumentStatusIndicator indicator : indicatorList) {
indicator.updateUI();
}
+ EventQueue queue = EventQueues.lookup(IDesktop.ACTIVITIES_EVENT_QUEUE, true);
+ Event event = new Event(IDesktop.ON_ACTIVITIES_CHANGED_EVENT, null, lastRefreshCount);
+ queue.publish(event);
}
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPActivities.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPActivities.java
index eb240118aa..4feed62654 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPActivities.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPActivities.java
@@ -178,4 +178,9 @@ public class DPActivities extends DashboardPanel implements EventListener
}
}
}
+
+ @Override
+ public boolean isLazy() {
+ return true;
+ }
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java
index 63d16f8ed3..6f34a9becc 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java
@@ -597,4 +597,9 @@ public class DPCalendar extends DashboardPanel implements EventListener,
trx.removeTrxEventListener(this);
}
}
+
+ @Override
+ public boolean isLazy() {
+ return true;
+ }
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPDocumentStatus.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPDocumentStatus.java
index c74e8cb71a..e17c078627 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPDocumentStatus.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPDocumentStatus.java
@@ -52,7 +52,7 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener 0){
- parentCtr.paPanel.setGoals(performanceData, (Options)null);
- if (parentCtr.getAttribute(ON_POST_RENDER_ATTR) == null) {
- parentCtr.setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
- Events.echoEvent("onPostRender", parentCtr, null);
- }
- }
- }
- });
-
- }
-
}
public void refresh(ServerPushTemplate template) {
- super.refresh(template);
+ performanceData = WPAPanel.loadGoal();
if (Executions.getCurrent() != null) {
+ updateUI();
if (this.getAttribute(ON_POST_RENDER_ATTR) == null && paPanel.getChildren().size() > 0) {
setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
Events.echoEvent("onPostRender", this, null);
}
+ } else {
+ template.executeAsync(this);
}
}
@@ -121,4 +93,15 @@ public class DPPerformance extends DashboardPanel {
this.getFirstChild().invalidate();
}
}
+
+ @Override
+ public void updateUI() {
+ paPanel.setGoals(performanceData, (Options)null);
+ performanceData = null;
+ }
+
+ @Override
+ public boolean isLazy() {
+ return true;
+ }
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java
index e041b878db..d280cd65b4 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java
@@ -93,7 +93,6 @@ public class DPRecentItems extends DashboardPanel implements EventListener {
@Override
public void onMessage(Integer message) {
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java
index 533445cff6..e2e6a9e56b 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java
@@ -82,7 +82,6 @@ public class DPRunningJobs extends DashboardPanel implements EventListener {
@Override
public void onMessage(Integer message) {
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DashboardPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DashboardPanel.java
index a6e702eef4..43c78643b6 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DashboardPanel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DashboardPanel.java
@@ -33,9 +33,11 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
super();
}
+ @Override
public void refresh(ServerPushTemplate template) {
}
+ @Override
public void updateUI() {
}
@@ -45,4 +47,12 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
public boolean isPooling() {
return false;
}
+
+ /**
+ * Override this together with refresh and updateUI to implement background loading of gadget
+ * @return true if panel created without loading of data
+ */
+ public boolean isLazy() {
+ return false;
+ }
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
index 832b325205..be1545a648 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
@@ -33,10 +33,12 @@ import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.ContextRunnable;
import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.graph.IChartRendererService;
import org.adempiere.webui.apps.graph.WGraph;
import org.adempiere.webui.apps.graph.WPAWidget;
@@ -49,8 +51,10 @@ import org.adempiere.webui.dashboard.DashboardRunnable;
import org.adempiere.webui.report.HTMLExtension;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
+import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.ZkReportViewerProvider;
+import org.compiere.Adempiere;
import org.compiere.model.I_AD_Menu;
import org.compiere.model.MChart;
import org.compiere.model.MDashboardContent;
@@ -200,7 +204,7 @@ public class DashboardController implements EventListener {
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
- MDashboardPreference[] dps = MDashboardPreference.getForSession(AD_User_ID, AD_Role_ID, true);
+ MDashboardPreference[] dps = MDashboardPreference.getForSession(AD_User_ID, AD_Role_ID, true);
MDashboardContent [] dcs = MDashboardContentAccess.get(Env.getCtx(), AD_Role_ID, AD_User_ID, null);
if(dps.length == 0){
@@ -245,9 +249,9 @@ public class DashboardController implements EventListener {
{
dashboardColumnLayout = new Vlayout();
dashboardColumnLayout.setSclass("dashboard-column");
- dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, columnNo);
- dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, false);
+ dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, columnNo);
+ dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, false);
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor(width + "%" + " 100%");
if (!ClientInfo.isMobile())
@@ -269,19 +273,48 @@ public class DashboardController implements EventListener {
} else {
panel = newGadgetPanel(dp, dc);
}
- if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null)
+ if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null)
dashboardColumnLayout.appendChild(panel);
if (!update) {
- renderGadgetPanel(dc, panel);
+ final Panel fp = panel;
+ ServerPushTemplate spt = new ServerPushTemplate(dashboardLayout.getDesktop());
+ IDesktop appDesktop = SessionManager.getAppDesktop();
+ String contextPath = Executions.getCurrent().getContextPath();
+ Panelchildren panelChildren = new Panelchildren();
+ fp.appendChild(panelChildren);
+ BusyDialog busyDialog = new BusyDialog();
+ busyDialog.setShadow(false);
+ panelChildren.appendChild(busyDialog);
+ //must create zulfile component in foreground UI thread
+ Component zComponent = null;
+ if (!Util.isEmpty(dc.getZulFilePath(), true)) {
+ try {
+ zComponent = Extensions.getDashboardGadget(dc.getZulFilePath(), panelChildren, dc);
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+ final Component zulComponent = zComponent;
+ ContextRunnable cr = new ContextRunnable() {
+ @Override
+ protected void doRun() {
+ try {
+ asyncRenderGadgetPanel(spt, dc, fp, appDesktop, contextPath, panelChildren, zulComponent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ Adempiere.getThreadPoolExecutor().submit(cr);
}
}
if (dps.length == 0)
{
dashboardColumnLayout = new Vlayout();
- dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, "0");
- dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
+ dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, "0");
+ dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor((width-5) + "%" + " 100%");
if (!ClientInfo.isMobile())
@@ -299,9 +332,9 @@ public class DashboardController implements EventListener {
// additional column
dashboardColumnLayout = new Vlayout();
ZKUpdateUtil.setWidth(dashboardColumnLayout, "100%");
- dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, currentColumnNo + 1);
- dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
+ dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, currentColumnNo + 1);
+ dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor(extraWidth + "% 100%");
if (!ClientInfo.isMobile())
@@ -321,9 +354,9 @@ public class DashboardController implements EventListener {
}
//
- if (!update && !dashboardRunnable.isEmpty())
+ if (!update)
{
- startDashboardRunnable(parent);
+ startDashboardRunnable(parent);
}
}
@@ -387,19 +420,50 @@ public class DashboardController implements EventListener {
});
}
- private void renderGadgetPanel(MDashboardContent dc, Panel panel) throws Exception {
- Panelchildren content = new Panelchildren();
- panel.appendChild(content);
- boolean panelEmpty = true;
- panelEmpty = !render(content, dc, dashboardRunnable);
- if (panelEmpty) {
- panel.detach();
- panel.setAttribute(PANEL_EMPTY_ATTRIBUTE, Boolean.TRUE);
- }
+ /**
+ * Render gadget panel in background thread
+ * @param spt
+ * @param dashboardContent
+ * @param panel
+ * @param appDesktop
+ * @param contextPath
+ * @param panelChildren
+ * @param zulComponent
+ * @throws Exception
+ */
+ private void asyncRenderGadgetPanel(ServerPushTemplate spt, MDashboardContent dashboardContent, Panel panel, IDesktop appDesktop, String contextPath,
+ Panelchildren panelChildren, Component zulComponent) throws Exception {
+ List components = new ArrayList<>();
+ asyncRenderComponents(dashboardContent, dashboardRunnable, appDesktop, contextPath, panelChildren, components, zulComponent);
+ if (components.size() > 0) {
+ for(Component c : components) {
+ if (c.getParent() != panelChildren) {
+ spt.executeAsync(() -> panelChildren.appendChild(c));
+ }
+ if (c instanceof DashboardPanel) {
+ DashboardPanel dpanel = (DashboardPanel) c;
+ if (dpanel.isLazy()) {
+ try {
+ dpanel.refresh(spt);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, e.getMessage(), e);
+ }
+ }
+ }
+ }
+ spt.executeAsync(() -> {
+ if (panelChildren.getFirstChild() != null && panelChildren.getFirstChild() instanceof BusyDialog)
+ panelChildren.getFirstChild().detach();
+ });
+ } else {
+ spt.executeAsync(() -> {
+ panel.detach();
+ panel.setAttribute(PANEL_EMPTY_ATTRIBUTE, Boolean.TRUE);
+ });
+ }
}
-
+
private void startDashboardRunnable(Component parent) {
- dashboardRunnable.refreshDashboard(false);
// default Update every one minutes
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
dashboardTimer = new Timer();
@@ -442,7 +506,7 @@ public class DashboardController implements EventListener {
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
- MDashboardPreference[] dps = MDashboardPreference.getForSession(AD_User_ID, AD_Role_ID, false);
+ MDashboardPreference[] dps = MDashboardPreference.getForSession(AD_User_ID, AD_Role_ID, false);
MDashboardContent [] dcs = MDashboardContentAccess.get(Env.getCtx(), AD_Role_ID, AD_User_ID, null);
if(dps.length == 0){
@@ -478,12 +542,12 @@ public class DashboardController implements EventListener {
int lineNo = dp.getLine().intValue();
int flexGrow = (flexGrow = dp.getFlexGrow()) > 0 ? flexGrow : DEFAULT_FLEX_GROW;
- if(dashboardLineLayout == null || currentLineNo != lineNo)
+ if(dashboardLineLayout == null || currentLineNo != lineNo)
{
dashboardLineLayout = new Hlayout();
- dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, lineNo);
- dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, false);
+ dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, lineNo);
+ dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, false);
dashboardLineLayout.setSclass("dashboard-row");
Anchorchildren dashboardLine = new Anchorchildren();
dashboardLine.setAnchor(width + "%");
@@ -503,24 +567,53 @@ public class DashboardController implements EventListener {
if (update) {
panel = findPanel(dp.getPA_DashboardContent_ID(), dp.getPA_DashboardPreference_ID());
} else {
- panel = newGadgetPanel(dp, dc);
- panel.setAttribute(FLEX_GROW_ATTRIBUTE, String.valueOf(flexGrow));
+ panel = newGadgetPanel(dp, dc);
+ panel.setAttribute(FLEX_GROW_ATTRIBUTE, String.valueOf(flexGrow));
ZKUpdateUtil.setHflex(panel, String.valueOf(flexGrow));
}
- if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null) {
+ if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null) {
dashboardLineLayout.appendChild(panel);
}
if (!update) {
- renderGadgetPanel(dc, panel);
+ final Panel fp = panel;
+ ServerPushTemplate spt = new ServerPushTemplate(dashboardLayout.getDesktop());
+ IDesktop appDesktop = SessionManager.getAppDesktop();
+ String contextPath = Executions.getCurrent().getContextPath();
+ Panelchildren panelChildren = new Panelchildren();
+ fp.appendChild(panelChildren);
+ BusyDialog busyDialog = new BusyDialog();
+ busyDialog.setShadow(false);
+ panelChildren.appendChild(busyDialog);
+ //must create zulfile component in foreground UI thread
+ Component zComponent = null;
+ if (!Util.isEmpty(dc.getZulFilePath(), true)) {
+ try {
+ zComponent = Extensions.getDashboardGadget(dc.getZulFilePath(), panelChildren, dc);
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+ final Component zulComponent = zComponent;
+ ContextRunnable cr = new ContextRunnable() {
+ @Override
+ protected void doRun() {
+ try {
+ asyncRenderGadgetPanel(spt, dc, fp, appDesktop, contextPath, panelChildren, zulComponent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ Adempiere.getThreadPoolExecutor().submit(cr);
}
}
if (dps.length == 0)
{
dashboardLineLayout = new Hlayout();
- dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, "0");
- dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
+ dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, "0");
+ dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
dashboardLineLayout.setSclass("dashboard-row");
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor((width-5) + "%" + " 100%");
@@ -539,9 +632,9 @@ public class DashboardController implements EventListener {
// additional row
dashboardLineLayout = new Hlayout();
ZKUpdateUtil.setWidth(dashboardLineLayout, "100%");
- dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, currentLineNo + 1);
- dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
+ dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, currentLineNo + 1);
+ dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
dashboardLineLayout.setSclass("dashboard-row");
Anchorchildren dashboardLine = new Anchorchildren();
dashboardLine.setAnchor(width + "% 1%");
@@ -564,9 +657,9 @@ public class DashboardController implements EventListener {
}
//
- if (!update && !dashboardRunnable.isEmpty())
+ if (!update)
{
- startDashboardRunnable(parent);
+ startDashboardRunnable(parent);
}
}
@@ -585,18 +678,20 @@ public class DashboardController implements EventListener {
}
/**
- *
- * @param content
- * @param dc
+ * Create gadget components in background thread
+ * @param dashboardContent
* @param dashboardRunnable
- * @return
+ * @param appDesktop
+ * @param contextPath
+ * @param parentComponent
+ * @param components
+ * @param zulComponent
* @throws Exception
*/
- public boolean render(Component content, MDashboardContent dc, DashboardRunnable dashboardRunnable) throws Exception {
- boolean empty = true;
-
+ private void asyncRenderComponents(MDashboardContent dashboardContent, DashboardRunnable dashboardRunnable, IDesktop appDesktop, String contextPath,
+ HtmlBasedComponent parentComponent, List components, Component zulComponent) throws Exception {
// HTML content
- String htmlContent = dc.get_ID() > 0 ? dc.get_Translation(MDashboardContent.COLUMNNAME_HTML) : null;
+ String htmlContent = dashboardContent.get_ID() > 0 ? dashboardContent.get_Translation(MDashboardContent.COLUMNNAME_HTML) : null;
if(htmlContent != null)
{
StringBuilder result = new StringBuilder("");
@@ -614,8 +709,7 @@ public class DashboardController implements EventListener {
result.append("");
} catch (Exception e1) {
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
- }
- finally{
+ } finally{
if (bufferedReader != null) {
try {
bufferedReader.close();
@@ -629,56 +723,58 @@ public class DashboardController implements EventListener {
Html html = new Html();
html.setContent(result.toString());
- content.appendChild(html);
- empty = false;
+ components.add(html);
}
// Window
- int AD_Window_ID = dc.getAD_Window_ID();
+ int AD_Window_ID = dashboardContent.getAD_Window_ID();
if(AD_Window_ID > 0)
{
- int AD_Menu_ID = dc.getAD_Menu_ID();
+ int AD_Menu_ID = dashboardContent.getAD_Menu_ID();
Div div = new Div();
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
- I_AD_Menu menu = dc.getAD_Menu();
+ I_AD_Menu menu = dashboardContent.getAD_Menu();
btn.setLabel(menu.getName());
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
btn.addEventListener(Events.ON_CLICK, this);
div.appendChild(btn);
- content.appendChild(div);
- empty = false;
+ components.add(div);
}
//Report & Process
- int AD_Process_ID = dc.getAD_Process_ID();
+ int AD_Process_ID = dashboardContent.getAD_Process_ID();
if(AD_Process_ID > 0)
{
String sql = "SELECT AD_MENU_ID FROM AD_MENU WHERE AD_Process_ID=?";
- int AD_Menu_ID = DB.getSQLValue(null, sql, AD_Process_ID);
+ int AD_Menu_ID = DB.getSQLValueEx(null, sql, AD_Process_ID);
ToolBarButton btn = new ToolBarButton();
MMenu menu = new MMenu(Env.getCtx(), AD_Menu_ID, null);
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
btn.addEventListener(Events.ON_CLICK, this);
- empty = false;
- if (dc.isEmbedReportContent())
+ if (dashboardContent.isEmbedReportContent())
{
- String processParameters = dc.getProcessParameters();
+ String processParameters = dashboardContent.getProcessParameters();
+ Div layout = new Div();
+ layout.setHeight("100%");
+ layout.setStyle("display: flex;flex-direction: column;");
+ components.add(layout);
Iframe iframe = new Iframe();
iframe.setSclass("dashboard-report-iframe");
- content.appendChild(iframe);
- iframe.setContent(generateReport(AD_Process_ID, dc.getAD_PrintFormat_ID(), processParameters));
+ iframe.setStyle("flex-grow: 1;");
+ layout.appendChild(iframe);
+ iframe.setContent(generateReport(AD_Process_ID, dashboardContent.getAD_PrintFormat_ID(), processParameters, appDesktop, contextPath));
Toolbar toolbar = new Toolbar();
- content.appendChild(toolbar);
+ layout.appendChild(toolbar);
btn.setLabel(Msg.getMsg(Env.getCtx(), "OpenRunDialog"));
toolbar.appendChild(btn);
btn = new ToolBarButton();
btn.setAttribute("AD_Process_ID", AD_Process_ID);
btn.setAttribute("ProcessParameters", processParameters);
- btn.setAttribute("AD_PrintFormat_ID", dc.getAD_PrintFormat_ID());
+ btn.setAttribute("AD_PrintFormat_ID", dashboardContent.getAD_PrintFormat_ID());
btn.addEventListener(Events.ON_CLICK, this);
btn.setLabel(Msg.getMsg(Env.getCtx(), "ViewReportInNewTab"));
toolbar.appendChild(new Separator("vertical"));
@@ -692,32 +788,30 @@ public class DashboardController implements EventListener {
else
btn.setImage(ThemeManager.getThemeResource("images/Refresh16.png"));
- btn.addEventListener(Events.ON_CLICK, e -> iframe.setContent(generateReport(AD_Process_ID, dc.getAD_PrintFormat_ID(), processParameters)));
- toolbar.appendChild(btn);
+ btn.addEventListener(Events.ON_CLICK, e -> iframe.setContent(generateReport(AD_Process_ID, dashboardContent.getAD_PrintFormat_ID(), processParameters, appDesktop, contextPath)));
+ toolbar.appendChild(btn);
}
else
{
btn.setLabel(menu.getName());
- content.appendChild(btn);
+ components.add(btn);
}
}
// Goal
- int PA_Goal_ID = dc.getPA_Goal_ID();
+ int PA_Goal_ID = dashboardContent.getPA_Goal_ID();
if(PA_Goal_ID > 0)
{
-
- String goalDisplay = dc.getGoalDisplay();
+ String goalDisplay = dashboardContent.getGoalDisplay();
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
if(MDashboardContent.GOALDISPLAY_GaugeIndicator.equals(goalDisplay)) {
WPerformanceIndicator.Options options = new WPerformanceIndicator.Options();
options.colorMap = new HashMap();
options.colorMap.put(WPerformanceIndicator.DIAL_BACKGROUND, new Color(224, 224, 224, 1));
- WPAWidget paWidget = new WPAWidget(goal, options, dc.isShowTitle());
- ((HtmlBasedComponent)content).setSclass("performance-gadget");
- content.appendChild(paWidget);
- }
- else {
+ WPAWidget paWidget = new WPAWidget(goal, options, dashboardContent.isShowTitle());
+ components.add(paWidget);
+ LayoutUtils.addSclass("performance-gadget", parentComponent);
+ } else {
//link to open performance detail
Div div = new Div();
Toolbarbutton link = new Toolbarbutton();
@@ -734,57 +828,46 @@ public class DashboardController implements EventListener {
}
});
div.appendChild(link);
- content.appendChild(div);
+ components.add(div);
WGraph graph = new WGraph(goal, 55, false, true,
!(MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
- content.appendChild(graph);
+ components.add(graph);
}
- empty = false;
}
- // ZUL file url
- String url = dc.getZulFilePath();
- if(url != null)
+ // Component created from ZUL file url
+ if(zulComponent != null)
{
try {
-
- Component component = Extensions.getDashboardGadget(url, content, dc);
- if(component != null)
- {
- if (component instanceof Include)
- component = component.getFirstChild();
-
- if (component instanceof DashboardPanel)
- {
- DashboardPanel dashboardPanel = (DashboardPanel) component;
- if (!dashboardPanel.getChildren().isEmpty()) {
- content.appendChild(dashboardPanel);
- addDashboardPanel(dashboardPanel);
- empty = false;
- }
+ if (zulComponent instanceof Include)
+ zulComponent = zulComponent.getFirstChild();
+
+ if (zulComponent instanceof DashboardPanel)
+ {
+ DashboardPanel dashboardPanel = (DashboardPanel) zulComponent;
+ if (!dashboardPanel.getChildren().isEmpty()) {
+ components.add(dashboardPanel);
+ addDashboardPanel(dashboardPanel);
}
- else
- {
- content.appendChild(component);
- empty = false;
- }
- }
+ }
+ else
+ {
+ components.add(zulComponent);
+ }
} catch (Exception e) {
- logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
throw new AdempiereException(e);
}
}
-
+
//chart
- final int AD_Chart_ID = dc.getAD_Chart_ID();
+ final int AD_Chart_ID = dashboardContent.getAD_Chart_ID();
if (AD_Chart_ID > 0) {
final Div chartPanel = new Div();
chartPanel.setSclass("chart-gadget");
final MChart chartModel = new MChart(Env.getCtx(), AD_Chart_ID, null);
- content.appendChild(chartPanel);
- empty = false;
+ components.add(chartPanel);
chartPanel.addEventListener(Events.ON_AFTER_SIZE, new EventListener() {
@Override
public void onEvent(AfterSizeEvent event) throws Exception {
@@ -798,13 +881,13 @@ public class DashboardController implements EventListener {
chartPanel.getChildren().clear();
ChartModel model = new ChartModel();
model.chart = chartModel;
- renderChart(chartPanel, width, height, model, dc.isShowTitle());
+ renderChart(chartPanel, width, height, model, dashboardContent.isShowTitle());
}
});
}
// Status Line
- final int AD_StatusLine_ID = dc.getAD_StatusLine_ID();
+ final int AD_StatusLine_ID = dashboardContent.getAD_StatusLine_ID();
if(AD_StatusLine_ID > 0) {
MStatusLine sl = new MStatusLine(Env.getCtx(), AD_StatusLine_ID, null);
final Html statusLineHtml = new Html();
@@ -812,11 +895,49 @@ public class DashboardController implements EventListener {
Div div = new Div();
div.appendChild(statusLineHtml);
div.setSclass("statusline-gadget");
- ((HtmlBasedComponent) content.getParent()).setSclass("statusline-wrapper");
- content.appendChild(div);
- empty = false;
+ components.add(div);
+ LayoutUtils.addSclass("statusline-wrapper", ((HtmlBasedComponent) parentComponent.getParent()));
}
-
+ }
+
+ /**
+ * Synchronous render of gadget content in foreground ui thread
+ * @param content must be an instanceof {@link HtmlBasedComponent}
+ * @param dashboardContent
+ * @param dashboardRunnable
+ * @return true if gadget dashboard is not empty
+ * @throws Exception
+ */
+ public boolean render(Component content, MDashboardContent dashboardContent, DashboardRunnable dashboardRunnable) throws Exception {
+ List components = new ArrayList<>();
+ Component zulComponent = null;
+ if (!Util.isEmpty(dashboardContent.getZulFilePath(), true)) {
+ try {
+ zulComponent = Extensions.getDashboardGadget(dashboardContent.getZulFilePath(), content, dashboardContent);
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+ HtmlBasedComponent parentComponent = (HtmlBasedComponent) content;
+ asyncRenderComponents(dashboardContent, dashboardRunnable, SessionManager.getAppDesktop(), Executions.getCurrent().getContextPath(), parentComponent, components, zulComponent);
+ boolean empty = components.isEmpty();
+ ServerPushTemplate spt = new ServerPushTemplate(content.getDesktop());
+ for(Component c : components) {
+ if (c.getParent() != parentComponent) {
+ parentComponent.appendChild(c);
+ }
+ if (c instanceof DashboardPanel) {
+ DashboardPanel dpanel = (DashboardPanel) c;
+ if (dpanel.isLazy()) {
+ try {
+ dpanel.refresh(spt);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, e.getMessage(), e);
+ }
+ }
+ }
+ }
+
return !empty;
}
@@ -866,8 +987,8 @@ public class DashboardController implements EventListener {
}
panel.setSclass("dashboard-widget");
//following 2 line needed for restore to size the panel correctly
- ZKUpdateUtil.setHflex(panel, (String)panel.getAttribute(FLEX_GROW_ATTRIBUTE));
- ZKUpdateUtil.setHeight(panel, "100%");
+ ZKUpdateUtil.setHflex(panel, (String)panel.getAttribute(FLEX_GROW_ATTRIBUTE));
+ ZKUpdateUtil.setHeight(panel, "100%");
}
}
else if(eventName.equals(Events.ON_CLICK))
@@ -964,7 +1085,7 @@ public class DashboardController implements EventListener {
if(comp instanceof Panel)
{
Panel panel = (Panel) comp;
- Object value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
+ Object value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
if (value != null)
{
int PA_DashboardPreference_ID = Integer.parseInt(value.toString());
@@ -1064,7 +1185,7 @@ public class DashboardController implements EventListener {
if (child instanceof Panel)
{
Panel panel = (Panel) child;
- value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
+ value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
if (value != null)
{
++counter;
@@ -1100,9 +1221,9 @@ public class DashboardController implements EventListener {
// additional column
Vlayout dashboardColumnLayout = new Vlayout();
- dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, columnNo + 1);
- dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
+ dashboardColumnLayout.setAttribute(COLUMN_NO_ATTRIBUTE, columnNo + 1);
+ dashboardColumnLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardColumnLayout.setAttribute(IS_ADDITIONAL_COLUMN_ATTRIBUTE, true);
Anchorchildren dashboardColumn = new Anchorchildren();
dashboardColumn.setAnchor(extraWidth + "% 100%");
if (!ClientInfo.isMobile()) {
@@ -1149,7 +1270,7 @@ public class DashboardController implements EventListener {
if (child instanceof Panel)
{
Panel panel = (Panel) child;
- value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
+ value = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardPreference_ID);
if (value != null)
{
int PA_DashboardPreference_ID = Integer.parseInt(value.toString());
@@ -1197,9 +1318,9 @@ public class DashboardController implements EventListener {
// additional row
Hlayout dashboardLineLayout = new Hlayout();
ZKUpdateUtil.setWidth(dashboardLineLayout, "100%");
- dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, lineNo + 1);
- dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
- dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
+ dashboardLineLayout.setAttribute(LINE_ATTRIBUTE, lineNo + 1);
+ dashboardLineLayout.setAttribute(IS_SHOW_IN_DASHBOARD_ATTRIBUTE, isShowInDashboard);
+ dashboardLineLayout.setAttribute(IS_ADDITIONAL_ROW_ATTRIBUTE, true);
dashboardLineLayout.setSclass("dashboard-row");
Anchorchildren dashboardLine = new Anchorchildren();
dashboardLine.setAnchor(width + "% 1%");
@@ -1315,12 +1436,12 @@ public class DashboardController implements EventListener {
}
- private AMedia generateReport(int AD_Process_ID, int AD_PrintFormat_ID, String parameters) throws Exception {
+ private AMedia generateReport(int AD_Process_ID, int AD_PrintFormat_ID, String parameters, IDesktop appDesktop, String contextPath) throws Exception {
ReportEngine re = runReport(AD_Process_ID, AD_PrintFormat_ID, parameters);
File file = FileUtil.createTempFile(re.getName(), ".html");
- re.createHTML(file, false, AEnv.getLanguage(Env.getCtx()), new HTMLExtension(Executions.getCurrent().getContextPath(), "rp",
- SessionManager.getAppDesktop().getComponent().getUuid()));
+ re.createHTML(file, false, AEnv.getLanguage(Env.getCtx()), new HTMLExtension(contextPath, "rp",
+ appDesktop.getComponent().getUuid()));
return new AMedia(re.getName(), "html", "text/html", file, false);
}
@@ -1448,8 +1569,8 @@ public class DashboardController implements EventListener {
ts = (Timestamp)value;
else
ts = Timestamp.valueOf(value.toString());
- SimpleDateFormat dateFormat = DisplayType.getDateFormat(iPara.getDisplayType());
- String info = dateFormat.format(ts);
+ SimpleDateFormat dateFormat = DisplayType.getDateFormat(iPara.getDisplayType());
+ String info = dateFormat.format(ts);
if (isTo) {
iPara.setP_Date_To(ts);
iPara.setInfo_To(info);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WDashboardContentEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WDashboardContentEditor.java
index ba87797d53..2dc29c4007 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WDashboardContentEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WDashboardContentEditor.java
@@ -1,6 +1,27 @@
-/**
- *
- */
+/***********************************************************************
+ * This file is part of iDempiere ERP Open Source *
+ * http://www.idempiere.org *
+ * *
+ * Copyright (C) Contributors *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301, USA. *
+ * *
+ * Contributors: *
+ * - hengsin *
+ **********************************************************************/
package org.adempiere.webui.editor;
import java.util.logging.Level;
@@ -139,8 +160,6 @@ public class WDashboardContentEditor extends WEditor {
DashboardRunnable dashboardRunnable = new DashboardRunnable(panel.getDesktop());
dashboardController.render(div, content, dashboardRunnable);
- if (!dashboardRunnable.isEmpty())
- dashboardRunnable.refreshDashboard(false);
pc.appendChild(div);
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/gadget.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/gadget.css.dsp
index 93a40775f6..d56afddb92 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/gadget.css.dsp
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/gadget.css.dsp
@@ -17,8 +17,13 @@
width: calc(100% - 10px);
}
+.dashboard-widget.z-panel {
+ display: flex;
+ flex-direction: column;
+ justify-content: stretch;
+}
.dashboard-widget > .z-panel-body {
- height: 100%;
+ flex-grow: 1;
}
.statusline-wrapper {
@@ -95,7 +100,6 @@
border: 1px solid lightgray;
margin:auto;
width: 99%;
- height: 90%;
}
.favourites-box {