From 8815805e314065601b8c6f12c73f77b95f1d02bc Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 16 Nov 2011 11:52:46 +0100 Subject: [PATCH] improve LogViewer --- www/manager/Makefile | 2 +- www/manager/grid/LogView.js | 133 ----------------------- www/manager/node/Config.js | 2 +- www/manager/openvz/Config.js | 2 +- www/manager/panel/LogView.js | 197 +++++++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 136 deletions(-) delete mode 100644 www/manager/grid/LogView.js create mode 100644 www/manager/panel/LogView.js diff --git a/www/manager/Makefile b/www/manager/Makefile index 671cd31c..beb44d15 100644 --- a/www/manager/Makefile +++ b/www/manager/Makefile @@ -62,7 +62,7 @@ JSSRC= \ tree/ResourceTree.js \ panel/ConfigPanel.js \ grid/BackupView.js \ - grid/LogView.js \ + panel/LogView.js \ node/DNSEdit.js \ node/DNSView.js \ node/TimeView.js \ diff --git a/www/manager/grid/LogView.js b/www/manager/grid/LogView.js deleted file mode 100644 index 013072b1..00000000 --- a/www/manager/grid/LogView.js +++ /dev/null @@ -1,133 +0,0 @@ -Ext.define('PVE.grig.LogView', { - extend: 'Ext.grid.GridPanel', - - alias: ['widget.pveLogView'], - - scrollToEnd: true, - - initComponent : function() { - var me = this; - - if (!me.url) { - throw "no url specified"; - } - - var store = Ext.create('Ext.data.Store', { - pageSize: 500, - buffered: true, - model: 'pve-string-list', - proxy: { - type: 'pve', - startParam: 'start', - limitParam: 'limit', - url: me.url - } - }); - - var scrollEndMarker = false; - var autoscroll = true; - - var scrollToEndFn = function() { - var vertScroller = me.getVerticalScroller(); - if (!(vertScroller && vertScroller.scrollEl)) { - return; - } - - var vertScrollerEl = vertScroller.scrollEl; - var vertScrollerElDom = vertScrollerEl.dom; - var maxDown = vertScrollerElDom.scrollHeight - - vertScrollerElDom.clientHeight - - vertScrollerElDom.scrollTop; - - scrollEndMarker = (maxDown <= 0); - - if (me.scrollToEnd && scrollEndMarker) { - autoscroll = true; - } - - if (!autoscroll) { - return; - } - - vertScroller.scrollByDeltaY(maxDown); - - // invalidate last page by removing last entry from cache - store.prefetchData.removeAtKey(store.totalCount - 1); - var start = store.totalCount - store.pageSize; - if (start < 0) { - start = 0; - } - store.guaranteeRange(start, start + store.pageSize - 1); - }; - - var onScroll = function() { - var scroller = this; - if (me.scrollToEnd && scrollEndMarker) { - autoscroll = false; - } - }; - - Ext.apply(me, { - store: store, - features: [ {ftype: 'selectable'}], - stateful: false, - verticalScrollerType: 'paginggridscroller', - invalidateScrollerOnRefresh: false, - viewConfig: { - loadMask: false, - trackOver: false, - stripeRows: false - }, - hideHeaders: true, - columns: [ - { header: "Text", dataIndex: 't', flex: 1 } - ], - listeners: { - 'scrollershow': function(scroller, orientation) { - if (orientation !== 'vertical') { - return; - } - scroller.on('afterrender', function() { - me.mon(scroller.scrollEl, 'scroll', onScroll, scroller); - }); - }, - 'scrollerhide': function(scroller, orientation) { - if (orientation !== 'vertical') { - return; - } - autoscroll = false; - } - } - }); - - me.callParent(); - - var load_task = new Ext.util.DelayedTask(); - - var run_load_task = function() { - if (!store.totalCount) { - store.guaranteeRange(0, store.pageSize - 1); - } else { - scrollToEndFn(); - } - load_task.delay(1000, run_load_task); - }; - - me.on('show', function() { - if (me.scrollToEnd) { - run_load_task(); - } else { - store.guaranteeRange(0, store.pageSize - 1); - } - }); - - me.on('hide', function() { - load_task.cancel(); - }); - - me.on('destroy', function() { - load_task.cancel(); - }); - } -}); - diff --git a/www/manager/node/Config.js b/www/manager/node/Config.js index e396f6bb..ab4f2f6a 100644 --- a/www/manager/node/Config.js +++ b/www/manager/node/Config.js @@ -91,7 +91,7 @@ Ext.define('PVE.node.Config', { title: 'Syslog', itemId: 'syslog', xtype: 'pveLogView', - url: "/api2/json/nodes/" + nodename + "/syslog" + url: "/api2/extjs/nodes/" + nodename + "/syslog" }, { title: 'Task History', diff --git a/www/manager/openvz/Config.js b/www/manager/openvz/Config.js index 7e27f889..1e164de7 100644 --- a/www/manager/openvz/Config.js +++ b/www/manager/openvz/Config.js @@ -122,7 +122,7 @@ Ext.define('PVE.openvz.Config', { title: "InitLog", itemId: 'initlog', xtype: 'pveLogView', - url: '/api2/json/nodes/' + nodename + '/openvz/' + vmid + '/initlog' + url: '/api2/extjs/nodes/' + nodename + '/openvz/' + vmid + '/initlog' }, { xtype: 'pveBackupView', diff --git a/www/manager/panel/LogView.js b/www/manager/panel/LogView.js new file mode 100644 index 00000000..63f80168 --- /dev/null +++ b/www/manager/panel/LogView.js @@ -0,0 +1,197 @@ +Ext.define('PVE.LogView', { + extend: 'Ext.panel.Panel', + + alias: ['widget.pveLogView'], + + pageSize: 500, + + lineHeight: 16, + + viewInfo: undefined, + + scrollToEnd: true, + + getMaxDown: function(scrollToEnd) { + var me = this; + + var target = me.getTargetEl(); + var dom = target.dom; + if (scrollToEnd) { + dom.scrollTop = dom.scrollHeight - dom.clientHeight; + } + + var maxDown = dom.scrollHeight - dom.clientHeight - + dom.scrollTop; + + return maxDown; + }, + + updateView: function(start, end, total, text) { + var me = this; + var el = me.dataCmp.el; + + if (me.viewInfo && me.viewInfo.start === start && + me.viewInfo.end === end && me.viewInfo.total === total && + me.viewInfo.textLength === text.length) { + return; // same content + } + + var maxDown = me.getMaxDown(); + var scrollToEnd = (maxDown <= 0) && me.scrollToEnd; + + el.setStyle('padding-top', start*me.lineHeight); + el.update(text); + me.dataCmp.setHeight(total*me.lineHeight); + + if (scrollToEnd) { + me.getMaxDown(true); + } + + me.viewInfo = { + start: start, + end: end, + total: total, + textLength: text.length + }; + }, + + doAttemptLoad: function(start) { + var me = this; + + PVE.Utils.API2Request({ + url: me.url, + params: { + start: start, + limit: me.pageSize + }, + method: 'GET', + success: function(response) { + me.setLoading(false); + var list = response.result.data; + var total = response.result.total; + var first = 0, last = 0; + var text = ''; + Ext.Array.each(list, function(item) { + if (!first|| item.n < first) { + first = item.n; + } + if (!last || item.n > last) { + last = item.n; + } + text = text + Ext.htmlEncode(item.t) + "
"; + }); + + if (first && last && total) { + me.updateView(first -1 , last -1, total, text); + } else { + me.updateView(0, 0, 0, ''); + } + }, + failure: function(response) { + var msg = response.htmlStatus; + me.setLoading(msg); + } + }); + }, + + attemptLoad: function(start) { + var me = this; + if (!me.loadTask) { + me.loadTask = Ext.create('Ext.util.DelayedTask', me.doAttemptLoad, me, []); + } + me.loadTask.delay(200, me.doAttemptLoad, me, [start]); + }, + + + initComponent : function() { + var me = this; + + if (!me.url) { + throw "no url specified"; + } + + me.dataCmp = Ext.create('Ext.Component', { + style: 'font:normal 11px tahoma, arial, verdana, sans-serif;' + + 'line-height: ' + me.lineHeight + 'px; white-space: pre;' + }); + + var requestUpdate = function(top, force) { + var viewStart = parseInt((top / me.lineHeight) - 1); + if (viewStart < 0) { + viewStart = 0; + } + var viewEnd = parseInt(((top + me.getHeight())/ me.lineHeight) + 1); + var info = me.viewInfo; + if (info && !force) { + if (viewStart >= info.start && viewEnd <= info.end) { + return; + } + } + var line = parseInt((top / me.lineHeight) - (me.pageSize / 2) + 10); + if (line < 0) { + line = 0; + } + + me.attemptLoad(line); + }; + + var autoScrollTask = { + run: function() { + if (!me.scrollToEnd || !me.viewInfo) { + return; + } + + var target = me.getTargetEl(); + var dom = target.dom; + var maxDown = dom.scrollHeight - dom.clientHeight - + dom.scrollTop; + + if (maxDown > 0) { + return; + } + + requestUpdate(dom.scrollTop, true); + }, + interval: 1000 + }; + + var task; + var savedScrollTop = 0; + + Ext.apply(me, { + autoScroll: true, + layout: 'auto', + items: me.dataCmp, + bodyStyle: 'padding: 5px;', + listeners: { + afterrender: Ext.Function.createDelayed(function() { + var target = me.getTargetEl(); + target.on('scroll', function(e) { + requestUpdate(target.dom.scrollTop); + }); + requestUpdate(0); + }, 20), + show: function() { + var target = me.getTargetEl(); + target.dom.scrollTop = savedScrollTop; + task = Ext.TaskManager.start(autoScrollTask); + }, + beforehide: function() { + var target = me.getTargetEl(); + // Hack: chrome reset scrollTop to 0, so we save/restore + savedScrollTop = target.dom.scrollTop; + if (task) { + Ext.TaskManager.stop(task); + } + }, + destroy: function() { + if (task) { + Ext.TaskManager.stop(task); + } + } + } + }); + + me.callParent(); + } +});