]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - panel/LogView.js
use eslint and execute as check target
[proxmox-widget-toolkit.git] / panel / LogView.js
CommitLineData
de2e10b5
DM
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 */
6Ext.define('Proxmox.panel.LogView', {
7 extend: 'Ext.panel.Panel',
65bb3b67 8 xtype: 'proxmoxLogView',
de2e10b5
DM
9
10 pageSize: 500,
65bb3b67 11 viewBuffer: 50,
de2e10b5
DM
12 lineHeight: 16,
13
de2e10b5
DM
14 scrollToEnd: true,
15
65bb3b67
DC
16 // callback for load failure, used for ceph
17 failCallback: undefined,
de2e10b5 18
65bb3b67
DC
19 controller: {
20 xclass: 'Ext.app.ViewController',
de2e10b5 21
65bb3b67 22 updateParams: function() {
05a977a2
TL
23 let me = this;
24 let viewModel = me.getViewModel();
25 let since = viewModel.get('since');
26 let until = viewModel.get('until');
65bb3b67
DC
27 if (viewModel.get('hide_timespan')) {
28 return;
29 }
de2e10b5 30
65bb3b67
DC
31 if (since > until) {
32 Ext.Msg.alert('Error', 'Since date must be less equal than Until date.');
33 return;
34 }
de2e10b5 35
65bb3b67
DC
36 viewModel.set('params.since', Ext.Date.format(since, 'Y-m-d'));
37 viewModel.set('params.until', Ext.Date.format(until, 'Y-m-d') + ' 23:59:59');
38 me.getView().loadTask.delay(200);
39 },
40
41 scrollPosBottom: function() {
05a977a2
TL
42 let view = this.getView();
43 let pos = view.getScrollY();
44 let maxPos = view.getScrollable().getMaxPosition().y;
65bb3b67
DC
45 return maxPos - pos;
46 },
47
48 updateView: function(text, first, total) {
05a977a2
TL
49 let me = this;
50 let view = me.getView();
51 let viewModel = me.getViewModel();
52 let content = me.lookup('content');
53 let data = viewModel.get('data');
65bb3b67
DC
54
55 if (first === data.first && total === data.total && text.length === data.textlen) {
56 return; // same content, skip setting and scrolling
57 }
58 viewModel.set('data', {
59 first: first,
60 total: total,
01031528 61 textlen: text.length,
65bb3b67 62 });
de2e10b5 63
05a977a2 64 let scrollPos = me.scrollPosBottom();
de2e10b5 65
65bb3b67 66 content.update(text);
de2e10b5 67
65bb3b67
DC
68 if (view.scrollToEnd && scrollPos <= 0) {
69 // we use setTimeout to work around scroll handling on touchscreens
70 setTimeout(function() { view.scrollTo(0, Infinity); }, 10);
71 }
72 },
73
74 doLoad: function() {
05a977a2 75 let me = this;
72be386c
TL
76 if (me.running) {
77 me.requested = true;
78 return;
79 }
7f9a6567 80 me.running = true;
05a977a2
TL
81 let view = me.getView();
82 let viewModel = me.getViewModel();
65bb3b67
DC
83 Proxmox.Utils.API2Request({
84 url: me.getView().url,
85 params: viewModel.get('params'),
86 method: 'GET',
87 success: function(response) {
88 Proxmox.Utils.setErrorMask(me, false);
05a977a2
TL
89 let total = response.result.total;
90 let lines = [];
91 let first = Infinity;
65bb3b67
DC
92
93 Ext.Array.each(response.result.data, function(line) {
94 if (first > line.n) {
95 first = line.n;
96 }
97 lines[line.n - 1] = Ext.htmlEncode(line.t);
98 });
99
100 lines.length = total;
101 me.updateView(lines.join('<br>'), first - 1, total);
7f9a6567 102 me.running = false;
72be386c
TL
103 if (me.requested) {
104 me.requested = false;
105 view.loadTask.delay(200);
106 }
65bb3b67
DC
107 },
108 failure: function(response) {
109 if (view.failCallback) {
110 view.failCallback(response);
111 } else {
05a977a2 112 let msg = response.htmlStatus;
65bb3b67 113 Proxmox.Utils.setErrorMask(me, msg);
de2e10b5 114 }
7f9a6567 115 me.running = false;
72be386c
TL
116 if (me.requested) {
117 me.requested = false;
118 view.loadTask.delay(200);
119 }
01031528 120 },
65bb3b67
DC
121 });
122 },
123
124 onScroll: function(x, y) {
05a977a2
TL
125 let me = this;
126 let view = me.getView();
127 let viewModel = me.getViewModel();
65bb3b67 128
05a977a2
TL
129 let lineHeight = view.lineHeight;
130 let line = view.getScrollY()/lineHeight;
131 let start = viewModel.get('params.start');
132 let limit = viewModel.get('params.limit');
133 let viewLines = view.getHeight()/lineHeight;
65bb3b67 134
05a977a2
TL
135 let viewStart = Math.max(parseInt(line - 1 - view.viewBuffer, 10), 0);
136 let viewEnd = parseInt(line + viewLines + 1 + view.viewBuffer, 10);
65bb3b67 137
01031528 138 if (viewStart < start || viewEnd > start+limit) {
65bb3b67 139 viewModel.set('params.start',
05a977a2 140 Math.max(parseInt(line - (limit / 2) + 10, 10), 0));
65bb3b67 141 view.loadTask.delay(200);
de2e10b5 142 }
65bb3b67 143 },
de2e10b5 144
65bb3b67 145 init: function(view) {
05a977a2 146 let me = this;
de2e10b5 147
65bb3b67
DC
148 if (!view.url) {
149 throw "no url specified";
de2e10b5 150 }
de2e10b5 151
05a977a2
TL
152 let viewModel = this.getViewModel();
153 let since = new Date();
65bb3b67
DC
154 since.setDate(since.getDate() - 3);
155 viewModel.set('until', new Date());
156 viewModel.set('since', since);
157 viewModel.set('params.limit', view.pageSize);
158 viewModel.set('hide_timespan', !view.log_select_timespan);
159 me.lookup('content').setStyle('line-height', view.lineHeight + 'px');
160
161 view.loadTask = new Ext.util.DelayedTask(me.doLoad, me);
162
163 me.updateParams();
164 view.task = Ext.TaskManager.start({
165 run: function() {
166 if (!view.isVisible() || !view.scrollToEnd) {
167 return;
168 }
de2e10b5 169
65bb3b67 170 if (me.scrollPosBottom() <= 1) {
72be386c 171 view.loadTask.delay(200);
65bb3b67
DC
172 }
173 },
01031528 174 interval: 1000,
65bb3b67 175 });
01031528 176 },
de2e10b5
DM
177 },
178
65bb3b67 179 onDestroy: function() {
05a977a2 180 let me = this;
65bb3b67
DC
181 me.loadTask.cancel();
182 Ext.TaskManager.stop(me.task);
de2e10b5
DM
183 },
184
65bb3b67
DC
185 // for user to initiate a load from outside
186 requestUpdate: function() {
05a977a2 187 let me = this;
65bb3b67
DC
188 me.loadTask.delay(200);
189 },
de2e10b5 190
65bb3b67
DC
191 viewModel: {
192 data: {
193 until: null,
194 since: null,
195 hide_timespan: false,
196 data: {
197 start: 0,
198 total: 0,
01031528 199 textlen: 0,
65bb3b67
DC
200 },
201 params: {
202 start: 0,
203 limit: 500,
01031528
TL
204 },
205 },
65bb3b67 206 },
de2e10b5 207
65bb3b67
DC
208 layout: 'auto',
209 bodyPadding: 5,
210 scrollable: {
211 x: 'auto',
212 y: 'auto',
213 listeners: {
214 // we have to have this here, since we cannot listen to events
215 // of the scroller in the viewcontroller (extjs bug?), nor does
216 // the panel have a 'scroll' event'
217 scroll: {
218 fn: function(scroller, x, y) {
05a977a2 219 let controller = this.component.getController();
65bb3b67 220 if (controller) { // on destroy, controller can be gone
01031528 221 controller.onScroll(x, y);
65bb3b67
DC
222 }
223 },
01031528 224 buffer: 200,
65bb3b67 225 },
01031528 226 },
65bb3b67 227 },
de2e10b5 228
65bb3b67
DC
229 tbar: {
230 bind: {
01031528 231 hidden: '{hide_timespan}',
65bb3b67
DC
232 },
233 items: [
234 '->',
235 'Since: ',
236 {
237 xtype: 'datefield',
238 name: 'since_date',
239 reference: 'since',
240 format: 'Y-m-d',
241 bind: {
242 value: '{since}',
01031528
TL
243 maxValue: '{until}',
244 },
de2e10b5 245 },
65bb3b67
DC
246 'Until: ',
247 {
248 xtype: 'datefield',
249 name: 'until_date',
250 reference: 'until',
251 format: 'Y-m-d',
252 bind: {
253 value: '{until}',
01031528
TL
254 minValue: '{since}',
255 },
65bb3b67
DC
256 },
257 {
258 xtype: 'button',
259 text: 'Update',
01031528
TL
260 handler: 'updateParams',
261 },
65bb3b67
DC
262 ],
263 },
de2e10b5 264
65bb3b67
DC
265 items: [
266 {
267 xtype: 'box',
268 reference: 'content',
269 style: {
270 font: 'normal 11px tahoma, arial, verdana, sans-serif',
01031528 271 'white-space': 'pre',
65bb3b67 272 },
01031528
TL
273 },
274 ],
de2e10b5 275});