]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - panel/LogView.js
add log viewer class
[proxmox-widget-toolkit.git] / panel / LogView.js
1 /*
2 * Display log entries in a panel with scrollbar
3 * The log entries are automatically refreshed via a background task,
4 * with newest entries comming at the bottom
5 */
6 Ext.define('Proxmox.panel.LogView', {
7 extend: 'Ext.panel.Panel',
8
9 alias: ['widget.proxmoxLogView'],
10
11 pageSize: 500,
12
13 lineHeight: 16,
14
15 viewInfo: undefined,
16
17 scrollToEnd: true,
18
19 autoScroll: true,
20
21 layout: 'auto',
22
23 bodyPadding: 5,
24
25 getMaxDown: function(scrollToEnd) {
26 var me = this;
27
28 var target = me.getTargetEl();
29 var dom = target.dom;
30 if (scrollToEnd) {
31 dom.scrollTop = dom.scrollHeight - dom.clientHeight;
32 }
33
34 var maxDown = dom.scrollHeight - dom.clientHeight -
35 dom.scrollTop;
36
37 return maxDown;
38 },
39
40 updateView: function(start, end, total, text) {
41 var me = this;
42 var el = me.dataCmp.el;
43
44 if (me.destroyed) { // return if element is not there anymore
45 return;
46 }
47
48 if (me.viewInfo && me.viewInfo.start === start &&
49 me.viewInfo.end === end && me.viewInfo.total === total &&
50 me.viewInfo.textLength === text.length) {
51 return; // same content
52 }
53
54 var maxDown = me.getMaxDown();
55 var scrollToEnd = (maxDown <= 0) && me.scrollToEnd;
56
57 el.setStyle('padding-top', (start*me.lineHeight).toString() + 'px');
58 el.update(text);
59 me.dataCmp.setHeight(total*me.lineHeight);
60
61 if (scrollToEnd) {
62 me.getMaxDown(true);
63 }
64
65 me.viewInfo = {
66 start: start,
67 end: end,
68 total: total,
69 textLength: text.length
70 };
71 },
72
73 doAttemptLoad: function(start) {
74 var me = this;
75
76 var req_params = {
77 start: start,
78 limit: me.pageSize
79 };
80
81 if (me.log_select_timespan) {
82 // always show log until the end of the selected day
83 req_params.until = Ext.Date.format(me.until_date, 'Y-m-d') + ' 23:59:59';
84 req_params.since = Ext.Date.format(me.since_date, 'Y-m-d');
85 }
86
87 Proxmox.Utils.API2Request({
88 url: me.url,
89 params: req_params,
90 method: 'GET',
91 success: function(response) {
92 Proxmox.Utils.setErrorMask(me, false);
93 var list = response.result.data;
94 var total = response.result.total;
95 var first = 0, last = 0;
96 var text = '';
97 Ext.Array.each(list, function(item) {
98 if (!first|| item.n < first) {
99 first = item.n;
100 }
101 if (!last || item.n > last) {
102 last = item.n;
103 }
104 text = text + Ext.htmlEncode(item.t) + "<br>";
105 });
106
107 if (first && last && total) {
108 me.updateView(first -1 , last -1, total, text);
109 } else {
110 me.updateView(0, 0, 0, '');
111 }
112 },
113 failure: function(response) {
114 var msg = response.htmlStatus;
115 Proxmox.Utils.setErrorMask(me, msg);
116 }
117 });
118 },
119
120 attemptLoad: function(start) {
121 var me = this;
122 if (!me.loadTask) {
123 me.loadTask = Ext.create('Ext.util.DelayedTask', me.doAttemptLoad, me, []);
124 }
125 me.loadTask.delay(200, me.doAttemptLoad, me, [start]);
126 },
127
128 requestUpdate: function(top, force) {
129 var me = this;
130
131 if (top === undefined) {
132 var target = me.getTargetEl();
133 top = target.dom.scrollTop;
134 }
135
136 var viewStart = parseInt((top / me.lineHeight) - 1, 10);
137 if (viewStart < 0) {
138 viewStart = 0;
139 }
140 var viewEnd = parseInt(((top + me.getHeight())/ me.lineHeight) + 1, 10);
141 var info = me.viewInfo;
142
143 if (info && !force) {
144 if (viewStart >= info.start && viewEnd <= info.end) {
145 return;
146 }
147 }
148
149 var line = parseInt((top / me.lineHeight) - (me.pageSize / 2) + 10, 10);
150 if (line < 0) {
151 line = 0;
152 }
153
154 me.attemptLoad(line);
155 },
156
157 afterRender: function() {
158 var me = this;
159
160 me.callParent(arguments);
161
162 Ext.Function.defer(function() {
163 var target = me.getTargetEl();
164 target.on('scroll', function(e) {
165 me.requestUpdate();
166 });
167 me.requestUpdate(0);
168 }, 20);
169 },
170
171 initComponent : function() {
172 /*jslint confusion: true */
173
174 var me = this;
175
176 if (!me.url) {
177 throw "no url specified";
178 }
179
180 // show logs from today back to 3 days ago per default
181 me.until_date = new Date();
182 me.since_date = new Date();
183 me.since_date.setDate(me.until_date.getDate() - 3);
184
185 me.dataCmp = Ext.create('Ext.Component', {
186 style: 'font:normal 11px tahoma, arial, verdana, sans-serif;' +
187 'line-height: ' + me.lineHeight.toString() + 'px; white-space: pre;'
188 });
189
190 me.task = Ext.TaskManager.start({
191 run: function() {
192 if (!me.isVisible() || !me.scrollToEnd || !me.viewInfo) {
193 return;
194 }
195
196 var maxDown = me.getMaxDown();
197 if (maxDown > 0) {
198 return;
199 }
200
201 me.requestUpdate(undefined, true);
202 },
203 interval: 1000
204 });
205
206 Ext.apply(me, {
207 items: me.dataCmp,
208 listeners: {
209 destroy: function() {
210 Ext.TaskManager.stop(me.task);
211 }
212 }
213 });
214
215 if (me.log_select_timespan) {
216 me.tbar = ['->','Since: ',
217 {
218 xtype: 'datefield',
219 maxValue: me.until_date,
220 value: me.since_date,
221 name: 'since_date',
222 format: 'Y-m-d',
223 listeners: {
224 select: function(field, date) {
225 me.since_date_selected = date;
226 var until_field = field.up().down('field[name=until_date]');
227 if (date > until_field.getValue()) {
228 until_field.setValue(date);
229 }
230 }
231 }
232 },
233 'Until: ',
234 {
235 xtype: 'datefield',
236 maxValue: me.until_date,
237 value: me.until_date,
238 name: 'until_date',
239 format: 'Y-m-d',
240 listeners: {
241 select: function(field, date) {
242 var since_field = field.up().down('field[name=since_date]');
243 if (date < since_field.getValue()) {
244 since_field.setValue(date);
245 }
246 }
247 }
248 },
249 {
250 xtype: 'button',
251 text: 'Update',
252 handler: function() {
253 var until_field = me.down('field[name=until_date]');
254 var since_field = me.down('field[name=since_date]');
255 if (until_field.getValue() < since_field.getValue()) {
256 Ext.Msg.alert('Error',
257 'Since date must be less equal than Until date.');
258 until_field.setValue(me.until_date);
259 since_field.setValue(me.since_date);
260 } else {
261 me.until_date = until_field.getValue();
262 me.since_date = since_field.getValue();
263 me.requestUpdate();
264 }
265 }
266 }
267 ];
268 }
269
270
271 me.callParent();
272 }
273 });