IDEMPIERE-5527 Implement asynchronous rendering of dashboard gadget p… (#1621)
* IDEMPIERE-5527 Implement asynchronous rendering of dashboard gadget panel * IDEMPIERE-5527 Implement asynchronous rendering of dashboard gadget panel - add DashboardPanel.isLazy - use background thread * IDEMPIERE-5527 Implement asynchronous rendering of dashboard gadget panel - Fix aynsc rendering of dashboard gadget
This commit is contained in:
parent
c047592862
commit
a24de47473
|
@ -57,6 +57,6 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
|
||||||
|
|
||||||
<!-- this js module doesn't actually exists and it is here for default theme version -->
|
<!-- this js module doesn't actually exists and it is here for default theme version -->
|
||||||
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
|
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
|
||||||
<javascript-module name="idempiere.theme.default" version="202211301708" />
|
<javascript-module name="idempiere.theme.default" version="202301160600" />
|
||||||
|
|
||||||
</language>
|
</language>
|
||||||
|
|
|
@ -57,6 +57,16 @@ public class WDocumentStatusIndicator extends Panel implements EventListener<Eve
|
||||||
* @param documentStatus
|
* @param documentStatus
|
||||||
*/
|
*/
|
||||||
public WDocumentStatusIndicator(MDocumentStatus documentStatus)
|
public WDocumentStatusIndicator(MDocumentStatus documentStatus)
|
||||||
|
{
|
||||||
|
this(documentStatus, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param documentStatus
|
||||||
|
* @param lazy
|
||||||
|
*/
|
||||||
|
public WDocumentStatusIndicator(MDocumentStatus documentStatus, boolean lazy)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -65,8 +75,11 @@ public class WDocumentStatusIndicator extends Panel implements EventListener<Eve
|
||||||
init();
|
init();
|
||||||
this.setSclass("activities-box");
|
this.setSclass("activities-box");
|
||||||
|
|
||||||
|
if (!lazy)
|
||||||
|
{
|
||||||
refresh();
|
refresh();
|
||||||
updateUI();
|
updateUI();
|
||||||
|
}
|
||||||
} // WDocumentStatusIndicator
|
} // WDocumentStatusIndicator
|
||||||
|
|
||||||
private MDocumentStatus m_documentStatus = null;
|
private MDocumentStatus m_documentStatus = null;
|
||||||
|
|
|
@ -55,6 +55,8 @@ public class WDocumentStatusPanel extends Panel {
|
||||||
/** Document Status Indicators */
|
/** Document Status Indicators */
|
||||||
private MDocumentStatus[] m_indicators = null;
|
private MDocumentStatus[] m_indicators = null;
|
||||||
|
|
||||||
|
private int lastRefreshCount;
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger (WDocumentStatusPanel.class);
|
private static final CLogger log = CLogger.getCLogger (WDocumentStatusPanel.class);
|
||||||
|
|
||||||
|
@ -102,27 +104,28 @@ public class WDocumentStatusPanel extends Panel {
|
||||||
Row row = new Row();
|
Row row = new Row();
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
|
|
||||||
WDocumentStatusIndicator pi = new WDocumentStatusIndicator(m_indicators[i]);
|
WDocumentStatusIndicator pi = new WDocumentStatusIndicator(m_indicators[i], true);
|
||||||
row.appendChild(pi);
|
row.appendChild(pi);
|
||||||
indicatorList.add(pi);
|
indicatorList.add(pi);
|
||||||
}
|
}
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
int count = 0;
|
lastRefreshCount = 0;
|
||||||
for (WDocumentStatusIndicator indicator : indicatorList) {
|
for (WDocumentStatusIndicator indicator : indicatorList) {
|
||||||
indicator.refresh();
|
indicator.refresh();
|
||||||
if (indicator.getDocumentStatus().getAD_Client_ID() == 0)
|
if (indicator.getDocumentStatus().getAD_Client_ID() == 0)
|
||||||
count += indicator.getStatusCount();
|
lastRefreshCount += indicator.getStatusCount();
|
||||||
}
|
}
|
||||||
EventQueue<Event> 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) {
|
for (WDocumentStatusIndicator indicator : indicatorList) {
|
||||||
indicator.updateUI();
|
indicator.updateUI();
|
||||||
}
|
}
|
||||||
|
EventQueue<Event> queue = EventQueues.lookup(IDesktop.ACTIVITIES_EVENT_QUEUE, true);
|
||||||
|
Event event = new Event(IDesktop.ON_ACTIVITIES_CHANGED_EVENT, null, lastRefreshCount);
|
||||||
|
queue.publish(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,4 +178,9 @@ public class DPActivities extends DashboardPanel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,4 +597,9 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
|
||||||
trx.removeTrxEventListener(this);
|
trx.removeTrxEventListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener<Ev
|
||||||
@Override
|
@Override
|
||||||
public void refresh(ServerPushTemplate template) {
|
public void refresh(ServerPushTemplate template) {
|
||||||
statusPanel.refresh();
|
statusPanel.refresh();
|
||||||
template.execute(this);
|
template.executeAsync(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -104,4 +104,9 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener<Ev
|
||||||
public boolean isPooling() {
|
public boolean isPooling() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,9 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.adempiere.webui.dashboard;
|
package org.adempiere.webui.dashboard;
|
||||||
|
|
||||||
import org.adempiere.util.ContextRunnable;
|
|
||||||
import org.adempiere.webui.apps.AEnv;
|
|
||||||
import org.adempiere.webui.apps.DesktopRunnable;
|
|
||||||
import org.adempiere.webui.apps.graph.WPAPanel;
|
import org.adempiere.webui.apps.graph.WPAPanel;
|
||||||
import org.adempiere.webui.apps.graph.WPerformanceIndicator.Options;
|
import org.adempiere.webui.apps.graph.WPerformanceIndicator.Options;
|
||||||
import org.adempiere.webui.util.ServerPushTemplate;
|
import org.adempiere.webui.util.ServerPushTemplate;
|
||||||
import org.compiere.Adempiere;
|
|
||||||
import org.compiere.model.MGoal;
|
import org.compiere.model.MGoal;
|
||||||
import org.compiere.model.MSysConfig;
|
import org.compiere.model.MSysConfig;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
@ -44,6 +40,7 @@ public class DPPerformance extends DashboardPanel {
|
||||||
private static final long serialVersionUID = -8878665031716441912L;
|
private static final long serialVersionUID = -8878665031716441912L;
|
||||||
|
|
||||||
private WPAPanel paPanel;
|
private WPAPanel paPanel;
|
||||||
|
private MGoal[] performanceData;
|
||||||
|
|
||||||
public DPPerformance()
|
public DPPerformance()
|
||||||
{
|
{
|
||||||
|
@ -53,43 +50,18 @@ public class DPPerformance extends DashboardPanel {
|
||||||
// and can't update when finish load data
|
// and can't update when finish load data
|
||||||
paPanel = new WPAPanel();
|
paPanel = new WPAPanel();
|
||||||
appendChild(paPanel);
|
appendChild(paPanel);
|
||||||
Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new LoadPerfomanceData(this), Executions.getCurrent().getDesktop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static class LoadPerfomanceData extends ContextRunnable{
|
|
||||||
private DPPerformance parentCtr;
|
|
||||||
public LoadPerfomanceData (DPPerformance parentCtr){
|
|
||||||
this.parentCtr = parentCtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doRun() {
|
|
||||||
MGoal [] performanceData = WPAPanel.loadGoal();
|
|
||||||
|
|
||||||
AEnv.executeAsyncDesktopTask(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (performanceData != null && performanceData.length > 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) {
|
public void refresh(ServerPushTemplate template) {
|
||||||
super.refresh(template);
|
performanceData = WPAPanel.loadGoal();
|
||||||
if (Executions.getCurrent() != null) {
|
if (Executions.getCurrent() != null) {
|
||||||
|
updateUI();
|
||||||
if (this.getAttribute(ON_POST_RENDER_ATTR) == null && paPanel.getChildren().size() > 0) {
|
if (this.getAttribute(ON_POST_RENDER_ATTR) == null && paPanel.getChildren().size() > 0) {
|
||||||
setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
|
setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
|
||||||
Events.echoEvent("onPostRender", this, null);
|
Events.echoEvent("onPostRender", this, null);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
template.executeAsync(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,4 +93,15 @@ public class DPPerformance extends DashboardPanel {
|
||||||
this.getFirstChild().invalidate();
|
this.getFirstChild().invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
paPanel.setGoals(performanceData, (Options)null);
|
||||||
|
performanceData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,6 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
||||||
ZKUpdateUtil.setHflex(bxRecentItems, "1");
|
ZKUpdateUtil.setHflex(bxRecentItems, "1");
|
||||||
this.setSclass("recentitems-box");
|
this.setSclass("recentitems-box");
|
||||||
recentItemsContent.appendChild(bxRecentItems);
|
recentItemsContent.appendChild(bxRecentItems);
|
||||||
createRecentItemsPanel();
|
|
||||||
|
|
||||||
Toolbar recentItemsToolbar = new Toolbar();
|
Toolbar recentItemsToolbar = new Toolbar();
|
||||||
this.appendChild(recentItemsToolbar);
|
this.appendChild(recentItemsToolbar);
|
||||||
|
@ -162,11 +161,6 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRecentItemsPanel()
|
|
||||||
{
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make Recent Item remove persistent
|
* Make Recent Item remove persistent
|
||||||
* @param AD_RecentItem_ID Recent Item ID
|
* @param AD_RecentItem_ID Recent Item ID
|
||||||
|
@ -365,6 +359,11 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static class TopicSubscriber implements ITopicSubscriber<Integer> {
|
static class TopicSubscriber implements ITopicSubscriber<Integer> {
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(Integer message) {
|
public void onMessage(Integer message) {
|
||||||
|
|
|
@ -82,7 +82,6 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
|
||||||
ZKUpdateUtil.setHflex(bxJobs, "1");
|
ZKUpdateUtil.setHflex(bxJobs, "1");
|
||||||
this.setSclass("recentitems-box");
|
this.setSclass("recentitems-box");
|
||||||
jobsContent.appendChild(bxJobs);
|
jobsContent.appendChild(bxJobs);
|
||||||
createJobsPanel();
|
|
||||||
|
|
||||||
Toolbar jobsToolbar = new Toolbar();
|
Toolbar jobsToolbar = new Toolbar();
|
||||||
this.appendChild(jobsToolbar);
|
this.appendChild(jobsToolbar);
|
||||||
|
@ -133,11 +132,6 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createJobsPanel()
|
|
||||||
{
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception
|
public void onEvent(Event event) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -281,6 +275,11 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLazy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static class TopicSubscriber implements ITopicSubscriber<Integer> {
|
static class TopicSubscriber implements ITopicSubscriber<Integer> {
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(Integer message) {
|
public void onMessage(Integer message) {
|
||||||
|
|
|
@ -33,9 +33,11 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void refresh(ServerPushTemplate template) {
|
public void refresh(ServerPushTemplate template) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateUI() {
|
public void updateUI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,4 +47,12 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
|
||||||
public boolean isPooling() {
|
public boolean isPooling() {
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,12 @@ import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.adempiere.exceptions.AdempiereException;
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
|
import org.adempiere.util.ContextRunnable;
|
||||||
import org.adempiere.webui.ClientInfo;
|
import org.adempiere.webui.ClientInfo;
|
||||||
import org.adempiere.webui.Extensions;
|
import org.adempiere.webui.Extensions;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
import org.adempiere.webui.apps.AEnv;
|
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.IChartRendererService;
|
||||||
import org.adempiere.webui.apps.graph.WGraph;
|
import org.adempiere.webui.apps.graph.WGraph;
|
||||||
import org.adempiere.webui.apps.graph.WPAWidget;
|
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.report.HTMLExtension;
|
||||||
import org.adempiere.webui.session.SessionManager;
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.theme.ThemeManager;
|
import org.adempiere.webui.theme.ThemeManager;
|
||||||
|
import org.adempiere.webui.util.ServerPushTemplate;
|
||||||
import org.adempiere.webui.util.ZKUpdateUtil;
|
import org.adempiere.webui.util.ZKUpdateUtil;
|
||||||
import org.adempiere.webui.window.ZkReportViewerProvider;
|
import org.adempiere.webui.window.ZkReportViewerProvider;
|
||||||
|
import org.compiere.Adempiere;
|
||||||
import org.compiere.model.I_AD_Menu;
|
import org.compiere.model.I_AD_Menu;
|
||||||
import org.compiere.model.MChart;
|
import org.compiere.model.MChart;
|
||||||
import org.compiere.model.MDashboardContent;
|
import org.compiere.model.MDashboardContent;
|
||||||
|
@ -272,7 +276,36 @@ public class DashboardController implements EventListener<Event> {
|
||||||
if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null)
|
if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTRIBUTE) == null)
|
||||||
dashboardColumnLayout.appendChild(panel);
|
dashboardColumnLayout.appendChild(panel);
|
||||||
if (!update) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +354,7 @@ public class DashboardController implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!update && !dashboardRunnable.isEmpty())
|
if (!update)
|
||||||
{
|
{
|
||||||
startDashboardRunnable(parent);
|
startDashboardRunnable(parent);
|
||||||
}
|
}
|
||||||
|
@ -387,19 +420,50 @@ public class DashboardController implements EventListener<Event> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderGadgetPanel(MDashboardContent dc, Panel panel) throws Exception {
|
/**
|
||||||
Panelchildren content = new Panelchildren();
|
* Render gadget panel in background thread
|
||||||
panel.appendChild(content);
|
* @param spt
|
||||||
boolean panelEmpty = true;
|
* @param dashboardContent
|
||||||
panelEmpty = !render(content, dc, dashboardRunnable);
|
* @param panel
|
||||||
if (panelEmpty) {
|
* @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<Component> 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.detach();
|
||||||
panel.setAttribute(PANEL_EMPTY_ATTRIBUTE, Boolean.TRUE);
|
panel.setAttribute(PANEL_EMPTY_ATTRIBUTE, Boolean.TRUE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDashboardRunnable(Component parent) {
|
private void startDashboardRunnable(Component parent) {
|
||||||
dashboardRunnable.refreshDashboard(false);
|
|
||||||
// default Update every one minutes
|
// default Update every one minutes
|
||||||
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
|
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
|
||||||
dashboardTimer = new Timer();
|
dashboardTimer = new Timer();
|
||||||
|
@ -511,7 +575,36 @@ public class DashboardController implements EventListener<Event> {
|
||||||
dashboardLineLayout.appendChild(panel);
|
dashboardLineLayout.appendChild(panel);
|
||||||
}
|
}
|
||||||
if (!update) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +657,7 @@ public class DashboardController implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!update && !dashboardRunnable.isEmpty())
|
if (!update)
|
||||||
{
|
{
|
||||||
startDashboardRunnable(parent);
|
startDashboardRunnable(parent);
|
||||||
}
|
}
|
||||||
|
@ -585,18 +678,20 @@ public class DashboardController implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Create gadget components in background thread
|
||||||
* @param content
|
* @param dashboardContent
|
||||||
* @param dc
|
|
||||||
* @param dashboardRunnable
|
* @param dashboardRunnable
|
||||||
* @return
|
* @param appDesktop
|
||||||
|
* @param contextPath
|
||||||
|
* @param parentComponent
|
||||||
|
* @param components
|
||||||
|
* @param zulComponent
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public boolean render(Component content, MDashboardContent dc, DashboardRunnable dashboardRunnable) throws Exception {
|
private void asyncRenderComponents(MDashboardContent dashboardContent, DashboardRunnable dashboardRunnable, IDesktop appDesktop, String contextPath,
|
||||||
boolean empty = true;
|
HtmlBasedComponent parentComponent, List<Component> components, Component zulComponent) throws Exception {
|
||||||
|
|
||||||
// HTML content
|
// 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)
|
if(htmlContent != null)
|
||||||
{
|
{
|
||||||
StringBuilder result = new StringBuilder("<html><head>");
|
StringBuilder result = new StringBuilder("<html><head>");
|
||||||
|
@ -614,8 +709,7 @@ public class DashboardController implements EventListener<Event> {
|
||||||
result.append("</style>");
|
result.append("</style>");
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
|
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
|
||||||
}
|
} finally{
|
||||||
finally{
|
|
||||||
if (bufferedReader != null) {
|
if (bufferedReader != null) {
|
||||||
try {
|
try {
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
|
@ -629,56 +723,58 @@ public class DashboardController implements EventListener<Event> {
|
||||||
|
|
||||||
Html html = new Html();
|
Html html = new Html();
|
||||||
html.setContent(result.toString());
|
html.setContent(result.toString());
|
||||||
content.appendChild(html);
|
components.add(html);
|
||||||
empty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window
|
// Window
|
||||||
int AD_Window_ID = dc.getAD_Window_ID();
|
int AD_Window_ID = dashboardContent.getAD_Window_ID();
|
||||||
if(AD_Window_ID > 0)
|
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();
|
Div div = new Div();
|
||||||
ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID));
|
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.setLabel(menu.getName());
|
||||||
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
|
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
|
||||||
btn.addEventListener(Events.ON_CLICK, this);
|
btn.addEventListener(Events.ON_CLICK, this);
|
||||||
div.appendChild(btn);
|
div.appendChild(btn);
|
||||||
content.appendChild(div);
|
components.add(div);
|
||||||
empty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Report & Process
|
//Report & Process
|
||||||
int AD_Process_ID = dc.getAD_Process_ID();
|
int AD_Process_ID = dashboardContent.getAD_Process_ID();
|
||||||
if(AD_Process_ID > 0)
|
if(AD_Process_ID > 0)
|
||||||
{
|
{
|
||||||
String sql = "SELECT AD_MENU_ID FROM AD_MENU WHERE AD_Process_ID=?";
|
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();
|
ToolBarButton btn = new ToolBarButton();
|
||||||
MMenu menu = new MMenu(Env.getCtx(), AD_Menu_ID, null);
|
MMenu menu = new MMenu(Env.getCtx(), AD_Menu_ID, null);
|
||||||
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
|
btn.setAttribute("AD_Menu_ID", AD_Menu_ID);
|
||||||
btn.addEventListener(Events.ON_CLICK, this);
|
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 iframe = new Iframe();
|
||||||
iframe.setSclass("dashboard-report-iframe");
|
iframe.setSclass("dashboard-report-iframe");
|
||||||
content.appendChild(iframe);
|
iframe.setStyle("flex-grow: 1;");
|
||||||
iframe.setContent(generateReport(AD_Process_ID, dc.getAD_PrintFormat_ID(), processParameters));
|
layout.appendChild(iframe);
|
||||||
|
iframe.setContent(generateReport(AD_Process_ID, dashboardContent.getAD_PrintFormat_ID(), processParameters, appDesktop, contextPath));
|
||||||
|
|
||||||
Toolbar toolbar = new Toolbar();
|
Toolbar toolbar = new Toolbar();
|
||||||
content.appendChild(toolbar);
|
layout.appendChild(toolbar);
|
||||||
btn.setLabel(Msg.getMsg(Env.getCtx(), "OpenRunDialog"));
|
btn.setLabel(Msg.getMsg(Env.getCtx(), "OpenRunDialog"));
|
||||||
toolbar.appendChild(btn);
|
toolbar.appendChild(btn);
|
||||||
|
|
||||||
btn = new ToolBarButton();
|
btn = new ToolBarButton();
|
||||||
btn.setAttribute("AD_Process_ID", AD_Process_ID);
|
btn.setAttribute("AD_Process_ID", AD_Process_ID);
|
||||||
btn.setAttribute("ProcessParameters", processParameters);
|
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.addEventListener(Events.ON_CLICK, this);
|
||||||
btn.setLabel(Msg.getMsg(Env.getCtx(), "ViewReportInNewTab"));
|
btn.setLabel(Msg.getMsg(Env.getCtx(), "ViewReportInNewTab"));
|
||||||
toolbar.appendChild(new Separator("vertical"));
|
toolbar.appendChild(new Separator("vertical"));
|
||||||
|
@ -692,32 +788,30 @@ public class DashboardController implements EventListener<Event> {
|
||||||
else
|
else
|
||||||
btn.setImage(ThemeManager.getThemeResource("images/Refresh16.png"));
|
btn.setImage(ThemeManager.getThemeResource("images/Refresh16.png"));
|
||||||
|
|
||||||
btn.addEventListener(Events.ON_CLICK, e -> iframe.setContent(generateReport(AD_Process_ID, dc.getAD_PrintFormat_ID(), processParameters)));
|
btn.addEventListener(Events.ON_CLICK, e -> iframe.setContent(generateReport(AD_Process_ID, dashboardContent.getAD_PrintFormat_ID(), processParameters, appDesktop, contextPath)));
|
||||||
toolbar.appendChild(btn);
|
toolbar.appendChild(btn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
btn.setLabel(menu.getName());
|
btn.setLabel(menu.getName());
|
||||||
content.appendChild(btn);
|
components.add(btn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Goal
|
// Goal
|
||||||
int PA_Goal_ID = dc.getPA_Goal_ID();
|
int PA_Goal_ID = dashboardContent.getPA_Goal_ID();
|
||||||
if(PA_Goal_ID > 0)
|
if(PA_Goal_ID > 0)
|
||||||
{
|
{
|
||||||
|
String goalDisplay = dashboardContent.getGoalDisplay();
|
||||||
String goalDisplay = dc.getGoalDisplay();
|
|
||||||
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
|
MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null);
|
||||||
if(MDashboardContent.GOALDISPLAY_GaugeIndicator.equals(goalDisplay)) {
|
if(MDashboardContent.GOALDISPLAY_GaugeIndicator.equals(goalDisplay)) {
|
||||||
WPerformanceIndicator.Options options = new WPerformanceIndicator.Options();
|
WPerformanceIndicator.Options options = new WPerformanceIndicator.Options();
|
||||||
options.colorMap = new HashMap<String, Color>();
|
options.colorMap = new HashMap<String, Color>();
|
||||||
options.colorMap.put(WPerformanceIndicator.DIAL_BACKGROUND, new Color(224, 224, 224, 1));
|
options.colorMap.put(WPerformanceIndicator.DIAL_BACKGROUND, new Color(224, 224, 224, 1));
|
||||||
WPAWidget paWidget = new WPAWidget(goal, options, dc.isShowTitle());
|
WPAWidget paWidget = new WPAWidget(goal, options, dashboardContent.isShowTitle());
|
||||||
((HtmlBasedComponent)content).setSclass("performance-gadget");
|
components.add(paWidget);
|
||||||
content.appendChild(paWidget);
|
LayoutUtils.addSclass("performance-gadget", parentComponent);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//link to open performance detail
|
//link to open performance detail
|
||||||
Div div = new Div();
|
Div div = new Div();
|
||||||
Toolbarbutton link = new Toolbarbutton();
|
Toolbarbutton link = new Toolbarbutton();
|
||||||
|
@ -734,57 +828,46 @@ public class DashboardController implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
div.appendChild(link);
|
div.appendChild(link);
|
||||||
content.appendChild(div);
|
components.add(div);
|
||||||
|
|
||||||
WGraph graph = new WGraph(goal, 55, false, true,
|
WGraph graph = new WGraph(goal, 55, false, true,
|
||||||
!(MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
|
!(MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)),
|
||||||
MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
|
MDashboardContent.GOALDISPLAY_Chart.equals(goalDisplay));
|
||||||
content.appendChild(graph);
|
components.add(graph);
|
||||||
}
|
}
|
||||||
empty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZUL file url
|
// Component created from ZUL file url
|
||||||
String url = dc.getZulFilePath();
|
if(zulComponent != null)
|
||||||
if(url != null)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
if (zulComponent instanceof Include)
|
||||||
|
zulComponent = zulComponent.getFirstChild();
|
||||||
|
|
||||||
Component component = Extensions.getDashboardGadget(url, content, dc);
|
if (zulComponent instanceof DashboardPanel)
|
||||||
if(component != null)
|
|
||||||
{
|
{
|
||||||
if (component instanceof Include)
|
DashboardPanel dashboardPanel = (DashboardPanel) zulComponent;
|
||||||
component = component.getFirstChild();
|
|
||||||
|
|
||||||
if (component instanceof DashboardPanel)
|
|
||||||
{
|
|
||||||
DashboardPanel dashboardPanel = (DashboardPanel) component;
|
|
||||||
if (!dashboardPanel.getChildren().isEmpty()) {
|
if (!dashboardPanel.getChildren().isEmpty()) {
|
||||||
content.appendChild(dashboardPanel);
|
components.add(dashboardPanel);
|
||||||
addDashboardPanel(dashboardPanel);
|
addDashboardPanel(dashboardPanel);
|
||||||
empty = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
content.appendChild(component);
|
components.add(zulComponent);
|
||||||
empty = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.WARNING, "Failed to create components. zul="+url, e);
|
|
||||||
throw new AdempiereException(e);
|
throw new AdempiereException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//chart
|
//chart
|
||||||
final int AD_Chart_ID = dc.getAD_Chart_ID();
|
final int AD_Chart_ID = dashboardContent.getAD_Chart_ID();
|
||||||
if (AD_Chart_ID > 0) {
|
if (AD_Chart_ID > 0) {
|
||||||
final Div chartPanel = new Div();
|
final Div chartPanel = new Div();
|
||||||
chartPanel.setSclass("chart-gadget");
|
chartPanel.setSclass("chart-gadget");
|
||||||
final MChart chartModel = new MChart(Env.getCtx(), AD_Chart_ID, null);
|
final MChart chartModel = new MChart(Env.getCtx(), AD_Chart_ID, null);
|
||||||
content.appendChild(chartPanel);
|
components.add(chartPanel);
|
||||||
empty = false;
|
|
||||||
chartPanel.addEventListener(Events.ON_AFTER_SIZE, new EventListener<AfterSizeEvent>() {
|
chartPanel.addEventListener(Events.ON_AFTER_SIZE, new EventListener<AfterSizeEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(AfterSizeEvent event) throws Exception {
|
public void onEvent(AfterSizeEvent event) throws Exception {
|
||||||
|
@ -798,13 +881,13 @@ public class DashboardController implements EventListener<Event> {
|
||||||
chartPanel.getChildren().clear();
|
chartPanel.getChildren().clear();
|
||||||
ChartModel model = new ChartModel();
|
ChartModel model = new ChartModel();
|
||||||
model.chart = chartModel;
|
model.chart = chartModel;
|
||||||
renderChart(chartPanel, width, height, model, dc.isShowTitle());
|
renderChart(chartPanel, width, height, model, dashboardContent.isShowTitle());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status Line
|
// 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) {
|
if(AD_StatusLine_ID > 0) {
|
||||||
MStatusLine sl = new MStatusLine(Env.getCtx(), AD_StatusLine_ID, null);
|
MStatusLine sl = new MStatusLine(Env.getCtx(), AD_StatusLine_ID, null);
|
||||||
final Html statusLineHtml = new Html();
|
final Html statusLineHtml = new Html();
|
||||||
|
@ -812,9 +895,47 @@ public class DashboardController implements EventListener<Event> {
|
||||||
Div div = new Div();
|
Div div = new Div();
|
||||||
div.appendChild(statusLineHtml);
|
div.appendChild(statusLineHtml);
|
||||||
div.setSclass("statusline-gadget");
|
div.setSclass("statusline-gadget");
|
||||||
((HtmlBasedComponent) content.getParent()).setSclass("statusline-wrapper");
|
components.add(div);
|
||||||
content.appendChild(div);
|
LayoutUtils.addSclass("statusline-wrapper", ((HtmlBasedComponent) parentComponent.getParent()));
|
||||||
empty = false;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<Component> 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;
|
return !empty;
|
||||||
|
@ -1315,12 +1436,12 @@ public class DashboardController implements EventListener<Event> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
ReportEngine re = runReport(AD_Process_ID, AD_PrintFormat_ID, parameters);
|
||||||
|
|
||||||
File file = FileUtil.createTempFile(re.getName(), ".html");
|
File file = FileUtil.createTempFile(re.getName(), ".html");
|
||||||
re.createHTML(file, false, AEnv.getLanguage(Env.getCtx()), new HTMLExtension(Executions.getCurrent().getContextPath(), "rp",
|
re.createHTML(file, false, AEnv.getLanguage(Env.getCtx()), new HTMLExtension(contextPath, "rp",
|
||||||
SessionManager.getAppDesktop().getComponent().getUuid()));
|
appDesktop.getComponent().getUuid()));
|
||||||
return new AMedia(re.getName(), "html", "text/html", file, false);
|
return new AMedia(re.getName(), "html", "text/html", file, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
package org.adempiere.webui.editor;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -139,8 +160,6 @@ public class WDashboardContentEditor extends WEditor {
|
||||||
|
|
||||||
DashboardRunnable dashboardRunnable = new DashboardRunnable(panel.getDesktop());
|
DashboardRunnable dashboardRunnable = new DashboardRunnable(panel.getDesktop());
|
||||||
dashboardController.render(div, content, dashboardRunnable);
|
dashboardController.render(div, content, dashboardRunnable);
|
||||||
if (!dashboardRunnable.isEmpty())
|
|
||||||
dashboardRunnable.refreshDashboard(false);
|
|
||||||
|
|
||||||
pc.appendChild(div);
|
pc.appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,13 @@
|
||||||
width: calc(100% - 10px);
|
width: calc(100% - 10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard-widget.z-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: stretch;
|
||||||
|
}
|
||||||
.dashboard-widget > .z-panel-body {
|
.dashboard-widget > .z-panel-body {
|
||||||
height: 100%;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statusline-wrapper {
|
.statusline-wrapper {
|
||||||
|
@ -95,7 +100,6 @@
|
||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
margin:auto;
|
margin:auto;
|
||||||
width: 99%;
|
width: 99%;
|
||||||
height: 90%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.favourites-box {
|
.favourites-box {
|
||||||
|
|
Loading…
Reference in New Issue