@openremote/or-log-viewer 1.8.0-snapshot.20250725120001 → 1.8.0-snapshot.20250725123024

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,583 +1,181 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
- return new (P || (P = Promise))(function (resolve, reject) {
10
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
- step((generator = generator.apply(thisArg, _arguments || [])).next());
14
- });
15
- };
16
- var OrLogViewer_1;
17
- import { css, html, LitElement, unsafeCSS } from "lit";
18
- import { customElement, property, query } from "lit/decorators.js";
19
- import i18next from "i18next";
20
- import { translate } from "@openremote/or-translate";
21
- import * as Model from "@openremote/model";
22
- import manager, { DefaultColor2, DefaultColor3, DefaultColor4, DefaultColor5, Util } from "@openremote/core";
23
- import "@openremote/or-mwc-components/or-mwc-input";
24
- import "@openremote/or-components/or-panel";
25
- import "@openremote/or-translate";
26
- import { InputType } from "@openremote/or-mwc-components/or-mwc-input";
27
- import moment from "moment";
28
- import "@openremote/or-mwc-components/or-mwc-menu";
29
- import { getContentWithMenuTemplate } from "@openremote/or-mwc-components/or-mwc-menu";
30
- import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar";
31
- import { when } from "lit/directives/when.js";
32
- // TODO: Add webpack/rollup to build so consumers aren't forced to use the same tooling
33
- const linkParser = require("http-link-header");
34
- const tableStyle = require("@material/data-table/dist/mdc.data-table.css");
35
- // language=CSS
36
- const style = css `
37
- :host {
38
- --internal-or-log-viewer-background-color: var(--or-log-viewer-background-color, var(--or-app-color2, ${unsafeCSS(DefaultColor2)}));
39
- --internal-or-log-viewer-text-color: var(--or-log-viewer-text-color, var(--or-app-color3, ${unsafeCSS(DefaultColor3)}));
40
- --internal-or-log-viewer-controls-margin: var(--or-log-viewer-controls-margin, 0);
41
-
42
- display: block;
43
- }
44
-
45
- :host([hidden]) {
46
- display: none;
47
- }
48
-
49
- #container {
50
- display: flex;
51
- min-width: 0;
52
- width: 100%;
53
- height: 100%;
54
- flex-direction: column;
55
- }
56
-
57
- #msg {
58
- height: 100%;
59
- width: 100%;
60
- justify-content: center;
61
- align-items: center;
62
- text-align: center;
63
- }
64
-
65
- #msg:not([hidden]) {
66
- display: flex;
67
- }
68
-
69
- #controls {
70
- flex: 0;
71
- display: flex;
72
- flex-wrap: wrap;
73
- justify-content: space-between;
74
- margin: var(--internal-or-log-viewer-controls-margin);
75
- padding: 0 20px 20px 20px;
76
- }
77
-
78
- #controls > * {
79
- margin-top: 20px;
80
- }
81
-
82
- #time-controls {
83
- display: flex;
84
- align-items: center;
85
- }
86
-
87
- #live-button {
88
- margin-right: 40px;
89
- }
90
-
91
- /* min-width of selects is 200px somehow
92
- #period-select {
93
- width: 90px;
94
- }
95
-
96
- #level-select {
97
- width: 120px;
98
- }
99
-
100
- #limit-select {
101
- width: 80px;
102
- }
103
- */
104
-
105
- #log-controls, #ending-controls, #page-controls {
106
- display: flex;
107
- max-width: 100%;
108
- align-items: center;
109
- }
110
-
111
- #ending-controls {
112
- float: right;
113
- margin: 0 10px;
114
- }
115
-
116
- #log-controls > *, #ending-controls > *, #page-controls > * {
117
- padding: 0 5px;
118
- }
119
-
120
- #page-controls[hidden] {
121
- visibility: hidden;
122
- }
123
-
124
- #ending-date {
125
- min-width: 0;
126
- }
127
-
128
- #table-container {
129
- height: 100%;
130
- overflow: auto;
131
- }
132
-
133
- #table {
134
- width: 100%;
135
- margin-bottom: 10px;
136
- }
137
-
138
- #table > table {
139
- width: 100%;
140
- table-layout: fixed;
141
- }
142
-
143
- #table th:not(.icon-cell), #table td:not(.icon-cell) {
144
- word-wrap: break-word;
145
- white-space: pre-wrap;
146
- }
147
-
148
- .copy-button {
149
- --or-mwc-input-color: var(--or-app-color5, ${unsafeCSS(DefaultColor5)});
150
- }
151
-
152
- .copy-button:hover {
153
- --or-mwc-input-color: var(--or-app-color4, ${unsafeCSS(DefaultColor4)});
154
- }
155
- `;
156
- let OrLogViewer = OrLogViewer_1 = class OrLogViewer extends translate(i18next)(LitElement) {
157
- constructor() {
158
- super(...arguments);
159
- this.live = false;
160
- this._loading = false;
161
- this._currentPage = 1;
162
- }
163
- static get styles() {
164
- return [
165
- css `${unsafeCSS(tableStyle)}`,
166
- style
167
- ];
168
- }
169
- connectedCallback() {
170
- super.connectedCallback();
171
- }
172
- disconnectedCallback() {
173
- super.disconnectedCallback();
174
- this._cleanup();
175
- this._unsubscribeEvents();
176
- }
177
- shouldUpdate(_changedProperties) {
178
- if (_changedProperties.has("level")
179
- || _changedProperties.has("interval")
180
- || _changedProperties.has("timestamp")
181
- || _changedProperties.has("limit")
182
- || _changedProperties.has("categories")
183
- || _changedProperties.has("filter")
184
- || _changedProperties.has("live")) {
185
- if (!this.live) {
186
- this._pageCount = undefined;
187
- this._currentPage = 1;
188
- this._data = undefined;
189
- }
190
- }
191
- if (!this.interval) {
192
- this.interval = OrLogViewer_1.DEFAULT_INTERVAL;
193
- }
194
- if (!this.categories) {
195
- if (this.config && this.config.initialCategories) {
196
- this.categories = [...this.config.initialCategories];
197
- }
198
- }
199
- if (this.filter === undefined && this.config && this.config.initialFilter) {
200
- this.filter = this.config.initialFilter;
201
- }
202
- if (!this.level) {
203
- if (this.config && this.config.initialLevel) {
204
- this.level = this.config.initialLevel;
205
- }
206
- else {
207
- this.level = OrLogViewer_1.DEFAULT_LEVEL;
208
- }
209
- }
210
- if (!this.live && !this.timestamp) {
211
- this.timestamp = new Date();
212
- }
213
- if (!this._data && !this.live) {
214
- this._loadData();
215
- }
216
- if (_changedProperties.has("live")) {
217
- if (this.live) {
218
- this._subscribeEvents();
219
- }
220
- else {
221
- this._unsubscribeEvents();
222
- }
223
- }
224
- return super.shouldUpdate(_changedProperties);
225
- }
226
- render() {
227
- const disabled = this._loading;
228
- const isLive = this.live;
229
- const hideCategories = this.config && this.config.hideCategories;
230
- const hideFilter = this.config && this.config.hideFilter;
231
- const hideLevel = this.config && this.config.hideLevel;
232
- return html `
233
- <div id="container">
234
- <div id="controls">
235
- <div id="log-controls">
236
- ${hideCategories ? `` : getContentWithMenuTemplate(html `<or-mwc-input .type=${InputType.BUTTON} raised ?disabled="${disabled}" .label="${i18next.t("categories")}" icontrailing="chevron-down"></or-mwc-input>`, this._getCategoryMenuItems(), this.categories, (v) => this._onCategoriesChanged(v), () => this._onCategoriesClosed(), true)}
237
- <or-mwc-input ?hidden="${hideFilter}" .type="${InputType.TEXT}" outlined ?disabled="${disabled}" icontrailing="magnify" .label="${i18next.t("subCategoryFilters")}" .value="${this.filter}" @or-mwc-input-changed="${(evt) => this._onFilterChanged(evt.detail.value)}"></or-mwc-input>
238
- <or-mwc-input ?hidden="${hideLevel}" .type="${InputType.SELECT}" id="level-select" ?disabled="${disabled}" .label="${i18next.t("level")}" @or-mwc-input-changed="${(evt) => this._onLevelChanged(evt.detail.value)}" .value="${this.level}" .options="${this._getLevelOptions()}"></or-mwc-input>
239
- <or-mwc-input .type="${InputType.SELECT}" id="limit-select" ?disabled="${disabled}" .label="${i18next.t("limit")}" @or-mwc-input-changed="${(evt) => this._onLimitChanged(evt.detail.value)}" .value="${"" + this.getLimit()}" .options="${this._getLimitOptions()}"></or-mwc-input>
240
- </div>
241
- <div id="page-controls" ?hidden="${isLive || !this._pageCount || !this._data || this._data.length === 0}">
242
- <or-mwc-input class="button" .type="${InputType.BUTTON}" ?disabled="${disabled || isLive || this._currentPage === 1}" icon="chevron-left" @or-mwc-input-changed="${() => this._updatePage(false)}"></or-mwc-input>
243
- <span>${this._currentPage}</span><or-translate value="of"></or-translate><span>${this._pageCount}</span>
244
- <or-mwc-input class="button" .type="${InputType.BUTTON}" ?disabled="${disabled || isLive || this._currentPage === this._pageCount || (this._data && this._data.length < this.getLimit())}" icon="chevron-right" @or-mwc-input-changed="${() => this._updatePage(true)}"></or-mwc-input>
245
- </div>
246
- <div id="time-controls">
247
- <or-mwc-input id="live-button" .type="${InputType.CHECKBOX}" ?disabled="${disabled}" .label="${i18next.t("live")}" @or-mwc-input-changed="${(evt) => this._onLiveChanged(evt.detail.value)}" .value="${this.live}"></or-mwc-input>
248
- <or-mwc-input .type="${InputType.SELECT}" id="period-select" ?disabled="${disabled || isLive}" .label="${i18next.t("period")}" @or-mwc-input-changed="${(evt) => this.interval = evt.detail.value}" .value="${this.interval}" .options="${this._getIntervalOptions()}"></or-mwc-input>
249
- <div id="ending-controls">
250
- <or-mwc-input class="button" .type="${InputType.BUTTON}" ?disabled="${disabled || isLive}" icon="chevron-left" @or-mwc-input-changed="${() => this.timestamp = this._calculateTimestamp(this.timestamp, false)}"></or-mwc-input>
251
- <or-mwc-input id="ending-date" .type="${InputType.DATETIME}" ?disabled="${disabled || isLive}" label="${i18next.t("ending")}" .value="${this.timestamp}" @or-mwc-input-changed="${(evt) => this.timestamp = this._calculateTimestamp(moment(evt.detail.value).toDate())}"></or-mwc-input>
252
- <or-mwc-input class="button" .type="${InputType.BUTTON}" ?disabled="${disabled || isLive}" icon="chevron-right" @or-mwc-input-changed="${() => this.timestamp = this._calculateTimestamp(this.timestamp, true)}"></or-mwc-input>
253
- <or-mwc-input class="button" .type="${InputType.BUTTON}" ?disabled="${disabled || isLive}" icon="chevron-double-right" @or-mwc-input-changed="${() => this.timestamp = this._calculateTimestamp(new Date())}"></or-mwc-input>
254
- </div>
255
- </div>
256
- </div>
257
-
258
- ${disabled ? html `<div id="msg">${i18next.t("loading")}</div>` :
259
- html `<div id="table-container">
260
- ${this._data ? this._getTable() : ``}
261
- </div>`}
262
- </div>
263
- `;
264
- }
265
- _getLimitOptions() {
266
- return ["25", "50", "100", "200"];
267
- }
268
- _getLevelOptions() {
269
- return Object.keys(Model["SyslogLevel"]).map((key) => [key, i18next.t(key.toLocaleLowerCase())]);
270
- }
271
- _getCategoryMenuItems() {
272
- const categories = this.config && this.config.allowedCategories ? this.config.allowedCategories : Object.keys(Model["SyslogCategory"]);
273
- return categories.map((cat) => {
274
- return {
275
- text: i18next.t("logCategory." + cat, { defaultValue: Util.capitaliseFirstLetter(cat.toLowerCase().replace(/_/g, " ")) }),
276
- value: cat
277
- };
278
- });
279
- }
280
- getLimit() {
281
- return this.limit || OrLogViewer_1.DEFAULT_LIMIT;
282
- }
283
- _onCategoriesChanged(values) {
284
- this._pendingCategories = values;
285
- }
286
- _onCategoriesClosed() {
287
- if (!this._pendingCategories) {
288
- return;
289
- }
290
- this.categories = [...this._pendingCategories];
291
- if (this.categories && this.live) {
292
- this._data = this._data.filter((e) => this.categories.find((c) => c === e.category));
293
- }
294
- this._pendingCategories = undefined;
295
- }
296
- _onLiveChanged(live) {
297
- this.live = live;
298
- if (live) {
299
- this._data = [];
300
- this._pageCount = undefined;
301
- this._currentPage = 1;
302
- }
303
- }
304
- _onLimitChanged(limit) {
305
- if (!limit) {
306
- this.limit = undefined;
307
- return;
308
- }
309
- this.limit = parseInt(limit);
310
- const newLimit = this.getLimit();
311
- if (this.live && this._data.length > newLimit) {
312
- this._data.splice(newLimit - 1);
313
- }
314
- }
315
- _onFilterChanged(filter) {
316
- this.filter = filter;
317
- if (!this.filter) {
318
- return;
319
- }
320
- if (this.live) {
321
- const filters = this.filter.split(";");
322
- this._data = this._data.filter((e) => filters.find((f) => f === e.subCategory));
323
- }
324
- }
325
- _onLevelChanged(level) {
326
- this.level = level;
327
- if (!this.level) {
328
- return;
329
- }
330
- if (this.live) {
331
- this._data = this._data.filter((e) => this._eventMatchesLevel(e));
332
- }
333
- }
334
- _getTable() {
335
- return html `
336
- <div id="table" class="mdc-data-table">
337
- <table class="mdc-data-table__table" aria-label="logs list">
338
- <thead>
339
- <tr class="mdc-data-table__header-row">
340
- <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${i18next.t("timestamp")}</th>
341
- <th style="width: 80px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${i18next.t("level")}</th>
342
- <th style="width: 130px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${i18next.t("category")}</th>
343
- <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${i18next.t("subCategory")}</th>
344
- <th style="width: 100%; min-width: 300px;" class="mdc-data-table__header-cell" role="columnheader" scope="col">${i18next.t("message")}</th>
345
- <th style="width: 80px;" class="mdc-data-table__header-cell" role="columnheader" scope="col"></th>
346
- </tr>
347
- </thead>
348
- <tbody class="mdc-data-table__content">
349
- ${this._data.map((ev) => {
350
- return html `
351
- <tr class="mdc-data-table__row">
352
- <td class="mdc-data-table__cell">${moment(ev.timestamp).format(OrLogViewer_1.DEFAULT_TIMESTAMP_FORMAT)}</td>
353
- <td class="mdc-data-table__cell">${i18next.t(ev.level)}</td>
354
- <td class="mdc-data-table__cell">${i18next.t(ev.category)}</td>
355
- <td class="mdc-data-table__cell">${i18next.t(ev.subCategory)}</td>
356
- <td class="mdc-data-table__cell">${ev.message}</td>
357
- <td class="mdc-data-table__cell icon-cell">
358
- ${when(window.isSecureContext, () => html `
359
- <or-mwc-input type="${InputType.BUTTON}" class="copy-button" icon="content-copy" @or-mwc-input-changed=${() => this._copyRow(ev)}></or-mwc-input>
360
- `)}
361
- </td>
362
- </tr>
363
- `;
364
- })}
365
- </tbody>
366
- </table>
367
- </div>
368
- `;
369
- }
370
- /** Copy a single log event to the clipboard as JSON */
371
- _copyRow(row) {
372
- return __awaiter(this, void 0, void 0, function* () {
373
- try {
374
- const text = row.message || "";
375
- yield navigator.clipboard.writeText(text);
376
- showSnackbar(undefined, i18next.t("copiedToClipboard"));
377
- }
378
- catch (err) {
379
- console.error("Failed to copy:", err);
380
- }
381
- });
382
- }
383
- _getIntervalOptions() {
384
- return [
385
- "HOUR" /* Model.DatapointInterval.HOUR */,
386
- "DAY" /* Model.DatapointInterval.DAY */,
387
- "WEEK" /* Model.DatapointInterval.WEEK */,
388
- "MONTH" /* Model.DatapointInterval.MONTH */,
389
- "YEAR" /* Model.DatapointInterval.YEAR */
390
- ].map((interval) => {
391
- return [interval, i18next.t(interval.toLowerCase())];
392
- });
393
- }
394
- _loadData() {
395
- return __awaiter(this, void 0, void 0, function* () {
396
- if (this._loading) {
397
- return;
398
- }
399
- this._loading = true;
400
- const response = yield manager.rest.api.SyslogResource.getEvents({
401
- level: this.level,
402
- per_page: this.getLimit(),
403
- page: this._currentPage,
404
- from: this._getFrom(),
405
- to: this.timestamp ? this.timestamp.getTime() : undefined,
406
- category: this.categories,
407
- subCategory: this.filter ? this.filter.split(";") : undefined
408
- });
409
- this._loading = false;
410
- if (response.status === 200) {
411
- this._data = response.data;
412
- // Get page count
413
- this._pageCount = this._getPageCount(response);
414
- }
415
- });
416
- }
417
- _getPageCount(response) {
418
- const linkHeaders = response.headers["link"];
419
- if (linkHeaders) {
420
- const links = linkParser.parse(linkHeaders);
421
- let lastLink = links.rel("last");
422
- if (Array.isArray(lastLink) && lastLink.length > 0) {
423
- lastLink = lastLink[0];
424
- }
425
- if (lastLink && lastLink.uri) {
426
- const url = new URL(lastLink.uri);
427
- return parseInt(Util.getQueryParameters(url.search)['page']);
428
- }
429
- }
430
- }
431
- _updatePage(forward) {
432
- if (!this._pageCount) {
433
- return;
434
- }
435
- if (forward) {
436
- if (this._currentPage < this._pageCount) {
437
- this._data = undefined;
438
- this._currentPage++;
439
- }
440
- }
441
- else {
442
- if (this._currentPage > 1) {
443
- this._data = undefined;
444
- this._currentPage--;
445
- }
446
- }
447
- }
448
- _subscribeEvents() {
449
- return __awaiter(this, void 0, void 0, function* () {
450
- if (manager.events) {
451
- this._eventSubscriptionId = yield manager.events.subscribe({
452
- eventType: "syslog"
453
- }, (ev) => this._onEvent(ev));
454
- }
455
- });
456
- }
457
- _unsubscribeEvents() {
458
- if (this._eventSubscriptionId) {
459
- manager.events.unsubscribe(this._eventSubscriptionId);
460
- this._eventSubscriptionId = undefined;
461
- }
462
- }
463
- _getFrom() {
464
- if (!this.timestamp || !this.interval) {
465
- return;
466
- }
467
- return this._calculateTimestamp(this.timestamp, false).getTime();
468
- }
469
- _calculateTimestamp(timestamp, forward) {
470
- if (!this.interval) {
471
- return;
472
- }
473
- const newMoment = moment(timestamp);
474
- if (forward !== undefined) {
475
- switch (this.interval) {
476
- case "HOUR" /* Model.DatapointInterval.HOUR */:
477
- newMoment.add(forward ? 1 : -1, "hour");
478
- break;
479
- case "DAY" /* Model.DatapointInterval.DAY */:
480
- newMoment.add(forward ? 1 : -1, "day");
481
- break;
482
- case "WEEK" /* Model.DatapointInterval.WEEK */:
483
- newMoment.add(forward ? 1 : -1, "week");
484
- break;
485
- case "MONTH" /* Model.DatapointInterval.MONTH */:
486
- newMoment.add(forward ? 1 : -1, "month");
487
- break;
488
- case "YEAR" /* Model.DatapointInterval.YEAR */:
489
- newMoment.add(forward ? 1 : -1, "year");
490
- break;
491
- }
492
- }
493
- return newMoment.toDate();
494
- }
495
- _onEvent(event) {
496
- // TODO: Move filtering to server side
497
- if (this.categories && !this.categories.find((c) => c === event.category)) {
498
- return;
499
- }
500
- if (this.filter) {
501
- const filters = this.filter.split(";");
502
- if (!filters.find((f) => f === event.subCategory)) {
503
- return;
504
- }
505
- }
506
- if (!this._eventMatchesLevel(event)) {
507
- return;
508
- }
509
- const limit = this.getLimit();
510
- if (this._data.length === limit - 1) {
511
- this._data.pop();
512
- }
513
- this._data.splice(0, 0, event);
514
- if (this._refresh) {
515
- window.clearTimeout(this._refresh);
516
- }
517
- // Buffer updates to prevent excessive re-renders
518
- this._refresh = window.setTimeout(() => this.requestUpdate("_data"), 2000);
519
- }
520
- _eventMatchesLevel(event) {
521
- if (!this.level || this.level === "INFO" /* Model.SyslogLevel.INFO */) {
522
- return true;
523
- }
524
- if (this.level === "WARN" /* Model.SyslogLevel.WARN */ && (event.level === "WARN" /* Model.SyslogLevel.WARN */ || event.level === "ERROR" /* Model.SyslogLevel.ERROR */)) {
525
- return true;
526
- }
527
- if (this.level === "ERROR" /* Model.SyslogLevel.ERROR */ && event.level === "ERROR" /* Model.SyslogLevel.ERROR */) {
528
- return true;
529
- }
530
- return false;
531
- }
532
- _cleanup() {
533
- if (this._table) {
534
- this._table.destroy();
535
- this._table = undefined;
536
- }
537
- if (this._refresh) {
538
- window.clearTimeout(this._refresh);
539
- }
540
- }
541
- };
542
- OrLogViewer.DEFAULT_TIMESTAMP_FORMAT = "L HH:mm:ss";
543
- OrLogViewer.DEFAULT_LIMIT = 50;
544
- OrLogViewer.DEFAULT_LEVEL = "INFO" /* Model.SyslogLevel.INFO */;
545
- OrLogViewer.DEFAULT_INTERVAL = "HOUR" /* Model.DatapointInterval.HOUR */;
546
- __decorate([
547
- property({ type: String })
548
- ], OrLogViewer.prototype, "interval", void 0);
549
- __decorate([
550
- property({ type: Number })
551
- ], OrLogViewer.prototype, "timestamp", void 0);
552
- __decorate([
553
- property({ type: Number })
554
- ], OrLogViewer.prototype, "limit", void 0);
555
- __decorate([
556
- property({ type: Array })
557
- ], OrLogViewer.prototype, "categories", void 0);
558
- __decorate([
559
- property({ type: String })
560
- ], OrLogViewer.prototype, "filter", void 0);
561
- __decorate([
562
- property({ type: String })
563
- ], OrLogViewer.prototype, "level", void 0);
564
- __decorate([
565
- property({ type: Boolean })
566
- ], OrLogViewer.prototype, "live", void 0);
567
- __decorate([
568
- property({ type: Object })
569
- ], OrLogViewer.prototype, "config", void 0);
570
- __decorate([
571
- property()
572
- ], OrLogViewer.prototype, "_loading", void 0);
573
- __decorate([
574
- property()
575
- ], OrLogViewer.prototype, "_data", void 0);
576
- __decorate([
577
- query("#table")
578
- ], OrLogViewer.prototype, "_tableElem", void 0);
579
- OrLogViewer = OrLogViewer_1 = __decorate([
580
- customElement("or-log-viewer")
581
- ], OrLogViewer);
582
- export { OrLogViewer };
583
- //# sourceMappingURL=index.js.map
1
+ var OrLogViewer_1,__decorate=this&&this.__decorate||function(e,t,i,o){var a,r=arguments.length,s=r<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(s=(r<3?a(s):r>3?a(t,i,s):a(t,i))||s);return r>3&&s&&Object.defineProperty(t,i,s),s},__awaiter=this&&this.__awaiter||function(e,t,i,o){return new(i||(i=Promise))(function(a,r){function s(e){try{n(o.next(e))}catch(e){r(e)}}function l(e){try{n(o.throw(e))}catch(e){r(e)}}function n(e){var t;e.done?a(e.value):((t=e.value)instanceof i?t:new i(function(e){e(t)})).then(s,l)}n((o=o.apply(e,t||[])).next())})};import{css as e,html as t,LitElement as i,unsafeCSS as o}from"lit";import{customElement as a,property as r,query as s}from"lit/decorators.js";import l from"i18next";import{translate as n}from"@openremote/or-translate";import*as c from"@openremote/model";import d,{DefaultColor2 as h,DefaultColor3 as p,DefaultColor4 as g,DefaultColor5 as m,Util as _}from"@openremote/core";import"@openremote/or-mwc-components/or-mwc-input";import"@openremote/or-components/or-panel";import"@openremote/or-translate";import{InputType as u}from"@openremote/or-mwc-components/or-mwc-input";import v from"moment";import"@openremote/or-mwc-components/or-mwc-menu";import{getContentWithMenuTemplate as w}from"@openremote/or-mwc-components/or-mwc-menu";import{showSnackbar as b}from"@openremote/or-mwc-components/or-mwc-snackbar";import{when as f}from"lit/directives/when.js";let linkParser=require("http-link-header"),tableStyle=require("@material/data-table/dist/mdc.data-table.css"),style=e`
2
+ :host {
3
+ --internal-or-log-viewer-background-color: var(--or-log-viewer-background-color, var(--or-app-color2, ${o(h)}));
4
+ --internal-or-log-viewer-text-color: var(--or-log-viewer-text-color, var(--or-app-color3, ${o(p)}));
5
+ --internal-or-log-viewer-controls-margin: var(--or-log-viewer-controls-margin, 0);
6
+
7
+ display: block;
8
+ }
9
+
10
+ :host([hidden]) {
11
+ display: none;
12
+ }
13
+
14
+ #container {
15
+ display: flex;
16
+ min-width: 0;
17
+ width: 100%;
18
+ height: 100%;
19
+ flex-direction: column;
20
+ }
21
+
22
+ #msg {
23
+ height: 100%;
24
+ width: 100%;
25
+ justify-content: center;
26
+ align-items: center;
27
+ text-align: center;
28
+ }
29
+
30
+ #msg:not([hidden]) {
31
+ display: flex;
32
+ }
33
+
34
+ #controls {
35
+ flex: 0;
36
+ display: flex;
37
+ flex-wrap: wrap;
38
+ justify-content: space-between;
39
+ margin: var(--internal-or-log-viewer-controls-margin);
40
+ padding: 0 20px 20px 20px;
41
+ }
42
+
43
+ #controls > * {
44
+ margin-top: 20px;
45
+ }
46
+
47
+ #time-controls {
48
+ display: flex;
49
+ align-items: center;
50
+ }
51
+
52
+ #live-button {
53
+ margin-right: 40px;
54
+ }
55
+
56
+ /* min-width of selects is 200px somehow
57
+ #period-select {
58
+ width: 90px;
59
+ }
60
+
61
+ #level-select {
62
+ width: 120px;
63
+ }
64
+
65
+ #limit-select {
66
+ width: 80px;
67
+ }
68
+ */
69
+
70
+ #log-controls, #ending-controls, #page-controls {
71
+ display: flex;
72
+ max-width: 100%;
73
+ align-items: center;
74
+ }
75
+
76
+ #ending-controls {
77
+ float: right;
78
+ margin: 0 10px;
79
+ }
80
+
81
+ #log-controls > *, #ending-controls > *, #page-controls > * {
82
+ padding: 0 5px;
83
+ }
84
+
85
+ #page-controls[hidden] {
86
+ visibility: hidden;
87
+ }
88
+
89
+ #ending-date {
90
+ min-width: 0;
91
+ }
92
+
93
+ #table-container {
94
+ height: 100%;
95
+ overflow: auto;
96
+ }
97
+
98
+ #table {
99
+ width: 100%;
100
+ margin-bottom: 10px;
101
+ }
102
+
103
+ #table > table {
104
+ width: 100%;
105
+ table-layout: fixed;
106
+ }
107
+
108
+ #table th:not(.icon-cell), #table td:not(.icon-cell) {
109
+ word-wrap: break-word;
110
+ white-space: pre-wrap;
111
+ }
112
+
113
+ .copy-button {
114
+ --or-mwc-input-color: var(--or-app-color5, ${o(m)});
115
+ }
116
+
117
+ .copy-button:hover {
118
+ --or-mwc-input-color: var(--or-app-color4, ${o(g)});
119
+ }
120
+ `,OrLogViewer=OrLogViewer_1=class extends n(l)(i){constructor(){super(...arguments),this.live=!1,this._loading=!1,this._currentPage=1}static get styles(){return[e`${o(tableStyle)}`,style]}connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this._cleanup(),this._unsubscribeEvents()}shouldUpdate(e){return(e.has("level")||e.has("interval")||e.has("timestamp")||e.has("limit")||e.has("categories")||e.has("filter")||e.has("live"))&&!this.live&&(this._pageCount=void 0,this._currentPage=1,this._data=void 0),this.interval||(this.interval=OrLogViewer_1.DEFAULT_INTERVAL),!this.categories&&this.config&&this.config.initialCategories&&(this.categories=[...this.config.initialCategories]),void 0===this.filter&&this.config&&this.config.initialFilter&&(this.filter=this.config.initialFilter),this.level||(this.config&&this.config.initialLevel?this.level=this.config.initialLevel:this.level=OrLogViewer_1.DEFAULT_LEVEL),this.live||this.timestamp||(this.timestamp=new Date),this._data||this.live||this._loadData(),e.has("live")&&(this.live?this._subscribeEvents():this._unsubscribeEvents()),super.shouldUpdate(e)}render(){let e=this._loading,i=this.live,o=this.config&&this.config.hideCategories,a=this.config&&this.config.hideFilter,r=this.config&&this.config.hideLevel;return t`
121
+ <div id="container">
122
+ <div id="controls">
123
+ <div id="log-controls">
124
+ ${o?"":w(t`<or-mwc-input .type=${u.BUTTON} raised ?disabled="${e}" .label="${l.t("categories")}" icontrailing="chevron-down"></or-mwc-input>`,this._getCategoryMenuItems(),this.categories,e=>this._onCategoriesChanged(e),()=>this._onCategoriesClosed(),!0)}
125
+ <or-mwc-input ?hidden="${a}" .type="${u.TEXT}" outlined ?disabled="${e}" icontrailing="magnify" .label="${l.t("subCategoryFilters")}" .value="${this.filter}" @or-mwc-input-changed="${e=>this._onFilterChanged(e.detail.value)}"></or-mwc-input>
126
+ <or-mwc-input ?hidden="${r}" .type="${u.SELECT}" id="level-select" ?disabled="${e}" .label="${l.t("level")}" @or-mwc-input-changed="${e=>this._onLevelChanged(e.detail.value)}" .value="${this.level}" .options="${this._getLevelOptions()}"></or-mwc-input>
127
+ <or-mwc-input .type="${u.SELECT}" id="limit-select" ?disabled="${e}" .label="${l.t("limit")}" @or-mwc-input-changed="${e=>this._onLimitChanged(e.detail.value)}" .value="${""+this.getLimit()}" .options="${this._getLimitOptions()}"></or-mwc-input>
128
+ </div>
129
+ <div id="page-controls" ?hidden="${i||!this._pageCount||!this._data||0===this._data.length}">
130
+ <or-mwc-input class="button" .type="${u.BUTTON}" ?disabled="${e||i||1===this._currentPage}" icon="chevron-left" @or-mwc-input-changed="${()=>this._updatePage(!1)}"></or-mwc-input>
131
+ <span>${this._currentPage}</span><or-translate value="of"></or-translate><span>${this._pageCount}</span>
132
+ <or-mwc-input class="button" .type="${u.BUTTON}" ?disabled="${e||i||this._currentPage===this._pageCount||this._data&&this._data.length<this.getLimit()}" icon="chevron-right" @or-mwc-input-changed="${()=>this._updatePage(!0)}"></or-mwc-input>
133
+ </div>
134
+ <div id="time-controls">
135
+ <or-mwc-input id="live-button" .type="${u.CHECKBOX}" ?disabled="${e}" .label="${l.t("live")}" @or-mwc-input-changed="${e=>this._onLiveChanged(e.detail.value)}" .value="${this.live}"></or-mwc-input>
136
+ <or-mwc-input .type="${u.SELECT}" id="period-select" ?disabled="${e||i}" .label="${l.t("period")}" @or-mwc-input-changed="${e=>this.interval=e.detail.value}" .value="${this.interval}" .options="${this._getIntervalOptions()}"></or-mwc-input>
137
+ <div id="ending-controls">
138
+ <or-mwc-input class="button" .type="${u.BUTTON}" ?disabled="${e||i}" icon="chevron-left" @or-mwc-input-changed="${()=>this.timestamp=this._calculateTimestamp(this.timestamp,!1)}"></or-mwc-input>
139
+ <or-mwc-input id="ending-date" .type="${u.DATETIME}" ?disabled="${e||i}" label="${l.t("ending")}" .value="${this.timestamp}" @or-mwc-input-changed="${e=>this.timestamp=this._calculateTimestamp(v(e.detail.value).toDate())}"></or-mwc-input>
140
+ <or-mwc-input class="button" .type="${u.BUTTON}" ?disabled="${e||i}" icon="chevron-right" @or-mwc-input-changed="${()=>this.timestamp=this._calculateTimestamp(this.timestamp,!0)}"></or-mwc-input>
141
+ <or-mwc-input class="button" .type="${u.BUTTON}" ?disabled="${e||i}" icon="chevron-double-right" @or-mwc-input-changed="${()=>this.timestamp=this._calculateTimestamp(new Date)}"></or-mwc-input>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ ${e?t`<div id="msg">${l.t("loading")}</div>`:t`<div id="table-container">
147
+ ${this._data?this._getTable():""}
148
+ </div>`}
149
+ </div>
150
+ `}_getLimitOptions(){return["25","50","100","200"]}_getLevelOptions(){return Object.keys(c.SyslogLevel).map(e=>[e,l.t(e.toLocaleLowerCase())])}_getCategoryMenuItems(){return(this.config&&this.config.allowedCategories?this.config.allowedCategories:Object.keys(c.SyslogCategory)).map(e=>({text:l.t("logCategory."+e,{defaultValue:_.capitaliseFirstLetter(e.toLowerCase().replace(/_/g," "))}),value:e}))}getLimit(){return this.limit||OrLogViewer_1.DEFAULT_LIMIT}_onCategoriesChanged(e){this._pendingCategories=e}_onCategoriesClosed(){this._pendingCategories&&(this.categories=[...this._pendingCategories],this.categories&&this.live&&(this._data=this._data.filter(e=>this.categories.find(t=>t===e.category))),this._pendingCategories=void 0)}_onLiveChanged(e){this.live=e,e&&(this._data=[],this._pageCount=void 0,this._currentPage=1)}_onLimitChanged(e){if(!e){this.limit=void 0;return}this.limit=parseInt(e);let t=this.getLimit();this.live&&this._data.length>t&&this._data.splice(t-1)}_onFilterChanged(e){if(this.filter=e,this.filter&&this.live){let e=this.filter.split(";");this._data=this._data.filter(t=>e.find(e=>e===t.subCategory))}}_onLevelChanged(e){this.level=e,this.level&&this.live&&(this._data=this._data.filter(e=>this._eventMatchesLevel(e)))}_getTable(){return t`
151
+ <div id="table" class="mdc-data-table">
152
+ <table class="mdc-data-table__table" aria-label="logs list">
153
+ <thead>
154
+ <tr class="mdc-data-table__header-row">
155
+ <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${l.t("timestamp")}</th>
156
+ <th style="width: 80px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${l.t("level")}</th>
157
+ <th style="width: 130px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${l.t("category")}</th>
158
+ <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${l.t("subCategory")}</th>
159
+ <th style="width: 100%; min-width: 300px;" class="mdc-data-table__header-cell" role="columnheader" scope="col">${l.t("message")}</th>
160
+ <th style="width: 80px;" class="mdc-data-table__header-cell" role="columnheader" scope="col"></th>
161
+ </tr>
162
+ </thead>
163
+ <tbody class="mdc-data-table__content">
164
+ ${this._data.map(e=>t`
165
+ <tr class="mdc-data-table__row">
166
+ <td class="mdc-data-table__cell">${v(e.timestamp).format(OrLogViewer_1.DEFAULT_TIMESTAMP_FORMAT)}</td>
167
+ <td class="mdc-data-table__cell">${l.t(e.level)}</td>
168
+ <td class="mdc-data-table__cell">${l.t(e.category)}</td>
169
+ <td class="mdc-data-table__cell">${l.t(e.subCategory)}</td>
170
+ <td class="mdc-data-table__cell">${e.message}</td>
171
+ <td class="mdc-data-table__cell icon-cell">
172
+ ${f(window.isSecureContext,()=>t`
173
+ <or-mwc-input type="${u.BUTTON}" class="copy-button" icon="content-copy" @or-mwc-input-changed=${()=>this._copyRow(e)}></or-mwc-input>
174
+ `)}
175
+ </td>
176
+ </tr>
177
+ `)}
178
+ </tbody>
179
+ </table>
180
+ </div>
181
+ `}_copyRow(e){return __awaiter(this,void 0,void 0,function*(){try{let t=e.message||"";yield navigator.clipboard.writeText(t),b(void 0,l.t("copiedToClipboard"))}catch(e){console.error("Failed to copy:",e)}})}_getIntervalOptions(){return["HOUR","DAY","WEEK","MONTH","YEAR"].map(e=>[e,l.t(e.toLowerCase())])}_loadData(){return __awaiter(this,void 0,void 0,function*(){if(this._loading)return;this._loading=!0;let e=yield d.rest.api.SyslogResource.getEvents({level:this.level,per_page:this.getLimit(),page:this._currentPage,from:this._getFrom(),to:this.timestamp?this.timestamp.getTime():void 0,category:this.categories,subCategory:this.filter?this.filter.split(";"):void 0});this._loading=!1,200===e.status&&(this._data=e.data,this._pageCount=this._getPageCount(e))})}_getPageCount(e){let t=e.headers.link;if(t){let e=linkParser.parse(t).rel("last");if(Array.isArray(e)&&e.length>0&&(e=e[0]),e&&e.uri){let t=new URL(e.uri);return parseInt(_.getQueryParameters(t.search).page)}}}_updatePage(e){this._pageCount&&(e?this._currentPage<this._pageCount&&(this._data=void 0,this._currentPage++):this._currentPage>1&&(this._data=void 0,this._currentPage--))}_subscribeEvents(){return __awaiter(this,void 0,void 0,function*(){d.events&&(this._eventSubscriptionId=yield d.events.subscribe({eventType:"syslog"},e=>this._onEvent(e)))})}_unsubscribeEvents(){this._eventSubscriptionId&&(d.events.unsubscribe(this._eventSubscriptionId),this._eventSubscriptionId=void 0)}_getFrom(){if(this.timestamp&&this.interval)return this._calculateTimestamp(this.timestamp,!1).getTime()}_calculateTimestamp(e,t){if(!this.interval)return;let i=v(e);if(void 0!==t)switch(this.interval){case"HOUR":i.add(t?1:-1,"hour");break;case"DAY":i.add(t?1:-1,"day");break;case"WEEK":i.add(t?1:-1,"week");break;case"MONTH":i.add(t?1:-1,"month");break;case"YEAR":i.add(t?1:-1,"year")}return i.toDate()}_onEvent(e){if(this.categories&&!this.categories.find(t=>t===e.category)||this.filter&&!this.filter.split(";").find(t=>t===e.subCategory)||!this._eventMatchesLevel(e))return;let t=this.getLimit();this._data.length===t-1&&this._data.pop(),this._data.splice(0,0,e),this._refresh&&window.clearTimeout(this._refresh),this._refresh=window.setTimeout(()=>this.requestUpdate("_data"),2e3)}_eventMatchesLevel(e){return!this.level||"INFO"===this.level||"WARN"===this.level&&("WARN"===e.level||"ERROR"===e.level)||"ERROR"===this.level&&"ERROR"===e.level}_cleanup(){this._table&&(this._table.destroy(),this._table=void 0),this._refresh&&window.clearTimeout(this._refresh)}};OrLogViewer.DEFAULT_TIMESTAMP_FORMAT="L HH:mm:ss",OrLogViewer.DEFAULT_LIMIT=50,OrLogViewer.DEFAULT_LEVEL="INFO",OrLogViewer.DEFAULT_INTERVAL="HOUR",__decorate([r({type:String})],OrLogViewer.prototype,"interval",void 0),__decorate([r({type:Number})],OrLogViewer.prototype,"timestamp",void 0),__decorate([r({type:Number})],OrLogViewer.prototype,"limit",void 0),__decorate([r({type:Array})],OrLogViewer.prototype,"categories",void 0),__decorate([r({type:String})],OrLogViewer.prototype,"filter",void 0),__decorate([r({type:String})],OrLogViewer.prototype,"level",void 0),__decorate([r({type:Boolean})],OrLogViewer.prototype,"live",void 0),__decorate([r({type:Object})],OrLogViewer.prototype,"config",void 0),__decorate([r()],OrLogViewer.prototype,"_loading",void 0),__decorate([r()],OrLogViewer.prototype,"_data",void 0),__decorate([s("#table")],OrLogViewer.prototype,"_tableElem",void 0),OrLogViewer=OrLogViewer_1=__decorate([a("or-log-viewer")],OrLogViewer);export{OrLogViewer};