IDEMPIERE-669 Zk: User Feedback Service. Added shortcut key ( ctrl+u for request, alt+u for email ) support. Added auto screen capture support ( tested on firefox and chrome, doesn't work for report and iframe ).
This commit is contained in:
parent
ac93bd4473
commit
e0279e57d4
|
@ -41,6 +41,7 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
|
||||||
<javascript src="/js/jquery-patch.js" charset="UTF-8"/>
|
<javascript src="/js/jquery-patch.js" charset="UTF-8"/>
|
||||||
<javascript src="/js/jquery.slimscroll.min.js" charset="UTF-8"/>
|
<javascript src="/js/jquery.slimscroll.min.js" charset="UTF-8"/>
|
||||||
<javascript src="/js/jquery-ui-1.10.1.min.js" charset="UTF-8"/>
|
<javascript src="/js/jquery-ui-1.10.1.min.js" charset="UTF-8"/>
|
||||||
|
<javascript src="/js/html2canvas.js" charset="UTF-8"/>
|
||||||
|
|
||||||
<javascript package="jawwa.atmosphere" merge="false" />
|
<javascript package="jawwa.atmosphere" merge="false" />
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
|
|
||||||
keyListener = new Keylistener();
|
keyListener = new Keylistener();
|
||||||
keyListener.setPage(this.getPage());
|
keyListener.setPage(this.getPage());
|
||||||
keyListener.setCtrlKeys("@a@c@d@e@f@h@n@o@p@r@s@t@z@x@#left@#right@#up@#down@#home@#end#enter");
|
keyListener.setCtrlKeys("@a@c@d@e@f@h@n@o@p@r@s@t@z@x@#left@#right@#up@#down@#home@#end#enter^u@u");
|
||||||
keyListener.setAutoBlur(false);
|
keyListener.setAutoBlur(false);
|
||||||
|
|
||||||
IDesktop d = (IDesktop) currSess.getAttribute(APPLICATION_DESKTOP_KEY);
|
IDesktop d = (IDesktop) currSess.getAttribute(APPLICATION_DESKTOP_KEY);
|
||||||
|
|
|
@ -284,15 +284,15 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
ByteArrayDataSource dataSource = new ByteArrayDataSource(data, media.getContentType());
|
ByteArrayDataSource dataSource = new ByteArrayDataSource(data, media.getContentType());
|
||||||
dataSource.setName(media.getName());
|
dataSource.setName(media.getName());
|
||||||
addAttachment(dataSource, true);
|
addAttachment(dataSource, true);
|
||||||
getFirstChild().invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAttachment(DataSource dataSource, boolean removable) {
|
public void addAttachment(DataSource dataSource, boolean removable) {
|
||||||
attachments.add(dataSource);
|
attachments.add(dataSource);
|
||||||
AttachmentItem item = new AttachmentItem(dataSource, attachments, removable);
|
AttachmentItem item = new AttachmentItem(dataSource, attachments, removable);
|
||||||
attachmentBox.appendChild(item);
|
attachmentBox.appendChild(item);
|
||||||
|
getFirstChild().invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getMediaData(Media media) {
|
private byte[] getMediaData(Media media) {
|
||||||
|
|
|
@ -14,17 +14,24 @@
|
||||||
package org.adempiere.webui.factory;
|
package org.adempiere.webui.factory;
|
||||||
|
|
||||||
import javax.activation.DataSource;
|
import javax.activation.DataSource;
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
import org.adempiere.webui.apps.AEnv;
|
import org.adempiere.webui.apps.AEnv;
|
||||||
import org.adempiere.webui.apps.FeedbackRequestWindow;
|
import org.adempiere.webui.apps.FeedbackRequestWindow;
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.util.FeedbackManager;
|
import org.adempiere.webui.util.FeedbackManager;
|
||||||
import org.adempiere.webui.window.WEMailDialog;
|
import org.adempiere.webui.window.WEMailDialog;
|
||||||
import org.compiere.model.MSystem;
|
import org.compiere.model.MSystem;
|
||||||
import org.compiere.model.MUser;
|
import org.compiere.model.MUser;
|
||||||
|
import org.compiere.util.ByteArrayDataSource;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
|
import org.zkoss.zk.au.out.AuScript;
|
||||||
|
import org.zkoss.zk.ui.event.Event;
|
||||||
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
|
import org.zkoss.zk.ui.util.Clients;
|
||||||
import org.zkoss.zul.Window.Mode;
|
import org.zkoss.zul.Window.Mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +51,52 @@ public class DefaultFeedbackService implements IFeedbackService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void emailSupport(boolean errorOnly) {
|
public void emailSupport(boolean errorOnly) {
|
||||||
|
new EmailSupportAction(errorOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.adempiere.webui.factory.IFeedbackService#createNewRequest()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void createNewRequest() {
|
||||||
|
new CreateNewRequestAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EmailSupportAction implements EventListener<Event>{
|
||||||
|
|
||||||
|
private boolean errorOnly;
|
||||||
|
|
||||||
|
protected EmailSupportAction(boolean errorOnly) {
|
||||||
|
this.errorOnly = errorOnly;
|
||||||
|
SessionManager.getAppDesktop().getComponent().addEventListener("onEmailSupport", this);
|
||||||
|
|
||||||
|
String script = "html2canvas(document.body, { onrendered: function(canvas) " +
|
||||||
|
"{ var dataUrl = canvas.toDataURL();" +
|
||||||
|
" var widget = zk.Widget.$('#" + SessionManager.getAppDesktop().getComponent().getUuid()+"');"+
|
||||||
|
" var event = new zk.Event(widget, 'onEmailSupport', dataUrl, {toServer: true});" +
|
||||||
|
" zAu.send(event); } " +
|
||||||
|
"});";
|
||||||
|
Clients.response(new AuScript(script));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(Event event) throws Exception {
|
||||||
|
SessionManager.getAppDesktop().getComponent().removeEventListener("onEmailSupport", this);
|
||||||
|
String dataUrl = (String) event.getData();
|
||||||
|
byte[] imageBytes = null;
|
||||||
|
if (dataUrl != null && dataUrl.startsWith("data:image/png;base64,"))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// remove data:image/png;base64, and then take rest sting
|
||||||
|
String img64 = dataUrl.substring("data:image/png;base64,".length()).trim();
|
||||||
|
imageBytes = DatatypeConverter.parseBase64Binary(img64 );
|
||||||
|
} catch(Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showEmailDialog(imageBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showEmailDialog(byte[] imageBytes) {
|
||||||
DataSource ds = FeedbackManager.getLogAttachment(errorOnly);
|
DataSource ds = FeedbackManager.getLogAttachment(errorOnly);
|
||||||
|
|
||||||
WEMailDialog dialog = new WEMailDialog(
|
WEMailDialog dialog = new WEMailDialog(
|
||||||
|
@ -60,18 +113,55 @@ public class DefaultFeedbackService implements IFeedbackService {
|
||||||
dialog.addTo(system.getSupportEMail(), true);
|
dialog.addTo(system.getSupportEMail(), true);
|
||||||
}
|
}
|
||||||
AEnv.showWindow(dialog);
|
AEnv.showWindow(dialog);
|
||||||
|
if (imageBytes != null && imageBytes.length > 0) {
|
||||||
|
ByteArrayDataSource screenShot = new ByteArrayDataSource(imageBytes, "image/png");
|
||||||
|
screenShot.setName("screenshot.png");
|
||||||
|
dialog.addAttachment(screenShot, true);
|
||||||
|
}
|
||||||
dialog.focus();
|
dialog.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CreateNewRequestAction implements EventListener<Event>{
|
||||||
|
protected CreateNewRequestAction() {
|
||||||
|
SessionManager.getAppDesktop().getComponent().addEventListener("onCreateFeedbackRequest", this);
|
||||||
|
|
||||||
|
String script = "html2canvas(document.body, { onrendered: function(canvas) " +
|
||||||
|
"{ var dataUrl = canvas.toDataURL();" +
|
||||||
|
" var widget = zk.Widget.$('#" + SessionManager.getAppDesktop().getComponent().getUuid()+"');"+
|
||||||
|
" var event = new zk.Event(widget, 'onCreateFeedbackRequest', dataUrl, {toServer: true});" +
|
||||||
|
" zAu.send(event); } " +
|
||||||
|
"});";
|
||||||
|
Clients.response(new AuScript(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.adempiere.webui.factory.IFeedbackService#createNewRequest()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void createNewRequest() {
|
public void onEvent(Event event) throws Exception {
|
||||||
|
SessionManager.getAppDesktop().getComponent().removeEventListener("onCreateFeedbackRequest", this);
|
||||||
|
String dataUrl = (String) event.getData();
|
||||||
|
byte[] imageBytes = null;
|
||||||
|
if (dataUrl != null && dataUrl.startsWith("data:image/png;base64,"))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// remove data:image/png;base64, and then take rest sting
|
||||||
|
String img64 = dataUrl.substring("data:image/png;base64,".length()).trim();
|
||||||
|
imageBytes = DatatypeConverter.parseBase64Binary(img64 );
|
||||||
|
} catch(Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showRequestDialog(imageBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showRequestDialog(byte[] imageBytes) {
|
||||||
FeedbackRequestWindow window = new FeedbackRequestWindow();
|
FeedbackRequestWindow window = new FeedbackRequestWindow();
|
||||||
AEnv.showWindow(window);
|
AEnv.showWindow(window);
|
||||||
|
|
||||||
|
if (imageBytes != null && imageBytes.length > 0) {
|
||||||
|
ByteArrayDataSource screenShot = new ByteArrayDataSource(imageBytes, "image/png");
|
||||||
|
screenShot.setName("screenshot.png");
|
||||||
|
window.addAttachment(screenShot, true);
|
||||||
|
}
|
||||||
window.focus();
|
window.focus();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.compiere.util.Msg;
|
||||||
import org.zkoss.zk.ui.event.Event;
|
import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
import org.zkoss.zk.ui.event.Events;
|
import org.zkoss.zk.ui.event.Events;
|
||||||
|
import org.zkoss.zk.ui.event.KeyEvent;
|
||||||
import org.zkoss.zul.Hbox;
|
import org.zkoss.zul.Hbox;
|
||||||
import org.zkoss.zul.Menuitem;
|
import org.zkoss.zul.Menuitem;
|
||||||
import org.zkoss.zul.Separator;
|
import org.zkoss.zul.Separator;
|
||||||
|
@ -145,6 +146,9 @@ public class UserPanel extends Vbox implements EventListener<Event>
|
||||||
mi.setId("EmailSupport");
|
mi.setId("EmailSupport");
|
||||||
mi.addEventListener(Events.ON_CLICK, this);
|
mi.addEventListener(Events.ON_CLICK, this);
|
||||||
feedbackMenu.appendChild(mi);
|
feedbackMenu.appendChild(mi);
|
||||||
|
|
||||||
|
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
|
||||||
|
addEventListener("onEmailSupport", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUserName()
|
private String getUserName()
|
||||||
|
@ -228,6 +232,22 @@ public class UserPanel extends Vbox implements EventListener<Event>
|
||||||
FeedbackManager.emailSupport(false);
|
FeedbackManager.emailSupport(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event instanceof KeyEvent)
|
||||||
|
{
|
||||||
|
//alt+u for email, ctrl+u for request
|
||||||
|
KeyEvent ke = (KeyEvent) event;
|
||||||
|
if (ke.getKeyCode() == 0x55)
|
||||||
|
{
|
||||||
|
if (ke.isAltKey())
|
||||||
|
{
|
||||||
|
FeedbackManager.emailSupport(false);
|
||||||
|
}
|
||||||
|
else if (ke.isCtrlKey())
|
||||||
|
{
|
||||||
|
FeedbackManager.createNewRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,13 +514,21 @@ public class WEMailDialog extends Window implements EventListener<Event>, ValueC
|
||||||
byte[] data = getMediaData(media);
|
byte[] data = getMediaData(media);
|
||||||
ByteArrayDataSource dataSource = new ByteArrayDataSource(data, media.getContentType());
|
ByteArrayDataSource dataSource = new ByteArrayDataSource(data, media.getContentType());
|
||||||
dataSource.setName(media.getName());
|
dataSource.setName(media.getName());
|
||||||
|
addAttachment(dataSource, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dataSource
|
||||||
|
* @param removeable
|
||||||
|
*/
|
||||||
|
public void addAttachment(DataSource dataSource, boolean removeable) {
|
||||||
attachments.add(dataSource);
|
attachments.add(dataSource);
|
||||||
AttachmentItem item = new AttachmentItem(dataSource, attachments, true);
|
AttachmentItem item = new AttachmentItem(dataSource, attachments, removeable);
|
||||||
attachmentBox.appendChild(item);
|
attachmentBox.appendChild(item);
|
||||||
getFirstChild().invalidate();
|
getFirstChild().invalidate();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] getMediaData(Media media) {
|
private byte[] getMediaData(Media media) {
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue