From 95b51fefea72b6b2992c242560c81e306a64f407 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Tue, 21 Jan 2014 09:21:46 +0000 Subject: [PATCH] Some UI for client error log, log egw.open() calls --- phpgwapi/js/jsapi/egw_debug.js | 89 ++++++++++++++++++-- phpgwapi/js/jsapi/egw_open.js | 14 +++ phpgwapi/js/jsapi/jsapi.js | 6 ++ phpgwapi/templates/idots/css/traditional.css | 28 ++++++ 4 files changed, 128 insertions(+), 9 deletions(-) diff --git a/phpgwapi/js/jsapi/egw_debug.js b/phpgwapi/js/jsapi/egw_debug.js index 2ea31cda70..a0b6000bf4 100644 --- a/phpgwapi/js/jsapi/egw_debug.js +++ b/phpgwapi/js/jsapi/egw_debug.js @@ -30,14 +30,14 @@ egw.extend('debug', egw.MODULE_GLOBAL, function(_app, _wnd) { * 4 = -- " -- plus "log" * 5 = -- " -- plus a stacktrace */ - var DEBUGLEVEL = 2; + var DEBUGLEVEL = 3; /** * Log-level for local storage * * @type Number */ - var LOCAL_LOG_LEVEL = 1; + var LOCAL_LOG_LEVEL = 2; /** * Number of log-entries stored on client, new errors overwrite old ones * @@ -127,6 +127,9 @@ egw.extend('debug', egw.MODULE_GLOBAL, function(_app, _wnd) { */ function clear_client_log() { + // Remove indicator icon + jQuery('#topmenu_info_error').remove(); + if (!window.localStorage) return false; for(var i=0; i < MAX_LOGS; ++i) @@ -141,6 +144,43 @@ egw.extend('debug', egw.MODULE_GLOBAL, function(_app, _wnd) { return true; } + /** + * Format one log message for display + * + * @param {{level: string, time: number, stack: string, args: array[]}} Log information + * Actual message is in args[0] + * @returns {DOMNode} + */ + function format_message(log) + { + var row = document.createElement('tr'); + row.setAttribute('class', log.level); + var timestamp = row.insertCell(-1); + timestamp.appendChild(document.createTextNode(new Date(log.time))); + timestamp.setAttribute('class', 'timestamp'); + + var level = row.insertCell(-1); + level.appendChild(document.createTextNode(log.level)); + level.setAttribute('class', 'level'); + + var message = row.insertCell(-1); + for(var i = 0; i < log.args.length; i++) + { + + var arg = document.createElement('p'); + arg.appendChild( + document.createTextNode(typeof log.args[i] == 'string' ? log.args[i] : JSON.stringify( log.args[i])) + ); + message.appendChild(arg); + } + + var stack = row.insertCell(-1); + stack.appendChild(document.createTextNode(log.stack||'')); + stack.setAttribute('class','stack'); + + return row; + } + /** * Show user an error happend by displaying a clickable icon with tooltip of current error */ @@ -166,12 +206,6 @@ egw.extend('debug', egw.MODULE_GLOBAL, function(_app, _wnd) { throw e; }); - /* show error icon / show_log trigger */ - window.setTimeout(function(){ - raise_error(); - }, 10000); - - /** * The debug function can be used to send a debug message to the * java script console. The first parameter specifies the debug @@ -236,7 +270,44 @@ egw.extend('debug', egw.MODULE_GLOBAL, function(_app, _wnd) { */ show_log: function() { - alert('show_log clicked :-)'); + var table = document.createElement('table'); + var body = document.createElement('tbody'); + var client_log = get_client_log(); + for(var i = 0; i < client_log.length; i++) + { + body.appendChild(format_message(client_log[i])); + } + table.appendChild(body); + + // Use a wrapper div for ease of styling + var wrapper = document.createElement('div') + wrapper.setAttribute('class', 'client_error_log'); + wrapper.appendChild(table); + + if(window.jQuery && window.jQuery.ui.dialog) + { + var $wrapper = $j(wrapper); + // Start hidden + $j('tr',$wrapper).addClass('hidden') + .on('click', function() { + $j(this).toggleClass('hidden',{}); + $j(this).find('.stack').children().toggleClass('ui-icon ui-icon-circle-plus'); + }) + // Wrap in div so we can control height + $j('td',$wrapper).wrapInner('
') + .filter('.stack').children().addClass('ui-icon ui-icon-circle-plus'); + + $wrapper.dialog({ + title: egw.lang('Error log'), + buttons: [ + {text: egw.lang('OK'), click: function() {$j(this).dialog( "close" ); }}, + {text: egw.lang('clear'), click: function() {clear_client_log(); $j(this).empty();}} + ], + width: 800, + height: 400 + }) + $wrapper[0].scrollTop = $wrapper[0].scrollHeight; + } if (_wnd.console) _wnd.console.log(get_client_log()); } }; diff --git a/phpgwapi/js/jsapi/egw_open.js b/phpgwapi/js/jsapi/egw_open.js index 8fd716271d..bdd9915130 100644 --- a/phpgwapi/js/jsapi/egw_open.js +++ b/phpgwapi/js/jsapi/egw_open.js @@ -131,6 +131,13 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) { */ open: function(id_data, app, type, extra, target, target_app) { + // Log for debugging purposes - special log tag 'navigation' always + // goes in user log, if user log is enabled + egw.debug("navigation", + "egw.open(id_data=%o, app=%s, type=%s, extra=%o, target=%s, target_app=%s)", + id_data,app,type,extra,target,target_app + ); + var id; if(typeof target === 'undefined') { @@ -234,6 +241,13 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) { */ open_link: function(_link, _target, _popup, _target_app) { + // Log for debugging purposes - don't use navigation here to avoid + // flooding log with details already captured by egw.open() + egw.debug("log", + "egw.open_link(_link=%s, _target=%s, _popup=%s, _target_app=%s)", + _link,_target,_popup,_target_app + ); + var url = _link; if (url.indexOf('javascript:') == 0) { diff --git a/phpgwapi/js/jsapi/jsapi.js b/phpgwapi/js/jsapi/jsapi.js index 1c3d1b834a..1b7fbe3b3b 100644 --- a/phpgwapi/js/jsapi/jsapi.js +++ b/phpgwapi/js/jsapi/jsapi.js @@ -227,6 +227,9 @@ function egw_getAppName() */ function egw_refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type) { + // Log for debugging purposes + egw.debug("log", "egw_refresh(%s, %s, %s, %o, %s, %s)",_msg,_app,_id,_type,_target_app,_replace,_with,_msg_type); + //alert("egw_refresh(\'"+_msg+"\',\'"+_app+"\',\'"+_id+"\',\'"+_type+"\')"); var win = typeof _targetapp != 'undefined' ? egw_appWindow(_targetapp) : window; @@ -456,6 +459,9 @@ function egw_set_checkbox_multiselect_enabled(_id, _enabled) // works only correctly in Mozilla/FF and Konqueror function egw_openWindowCentered2(_url, _windowName, _width, _height, _status, _app, _returnID) { + // Log for debugging purposes + egw.debug("navigation", "egw_openWindowCentered2(%s, %s, %s, %o, %s, %s)",_url,_windowName,_width,_height,_status,_app); + if (typeof(_app) == 'undefined') _app = false; if (typeof(_returnID) == 'undefined') _returnID = false; windowWidth = egw_getWindowOuterWidth(); diff --git a/phpgwapi/templates/idots/css/traditional.css b/phpgwapi/templates/idots/css/traditional.css index 08f350370a..74733f20ff 100755 --- a/phpgwapi/templates/idots/css/traditional.css +++ b/phpgwapi/templates/idots/css/traditional.css @@ -918,3 +918,31 @@ td.lettersearch { width: 16px; cursor: pointer; } + +/** + * Error log + */ +div.client_error_log { + max-height: 50ex; +} +div.client_error_log tbody { + vertical-align: top; +} +div.client_error_log tr.hidden td > div { + max-height: 2ex; + max-width: 40ex; + overflow: hidden; + text-overflow: ellipsis; + white-space:nowrap; +} +div.client_error_log tr td.timestamp > div { + text-wrap: none; + white-space: normal; + width: 27ex; +} +div.client_error_log tr.hidden td.stack > div { + text-indent: 100% +} +div.client_error_log tr td.stack > div { + white-space: pre; +} \ No newline at end of file