@viplance/nestjs-logger 0.4.5 → 0.4.8
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/dist/log.module.js +9 -5
- package/dist/log.module.js.map +1 -1
- package/dist/services/log.service.d.ts +1 -1
- package/dist/services/log.service.js +49 -7
- package/dist/services/log.service.js.map +1 -1
- package/dist/services/memory-db.service.d.ts +6 -0
- package/dist/services/memory-db.service.js +85 -1
- package/dist/services/memory-db.service.js.map +1 -1
- package/dist/services/ws.service.d.ts +2 -4
- package/dist/services/ws.service.js +61 -32
- package/dist/services/ws.service.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +3 -1
- package/public/scripts/common.js +143 -33
- package/public/scripts/details-popup.js +17 -2
- package/public/scripts/local-storage.js +6 -6
- package/public/scripts/ws.js +36 -7
- package/public/styles/index.css +177 -2
- package/src/log.module.ts +10 -6
- package/src/services/log.service.ts +64 -8
- package/src/services/memory-db.service.ts +90 -3
- package/src/services/ws.service.ts +33 -36
- package/dist/db.service.d.ts +0 -8
- package/dist/db.service.js +0 -51
- package/dist/db.service.js.map +0 -1
- package/dist/exception.filter.d.ts +0 -4
- package/dist/exception.filter.js +0 -34
- package/dist/exception.filter.js.map +0 -1
- package/dist/log.interceptor.d.ts +0 -9
- package/dist/log.interceptor.js +0 -43
- package/dist/log.interceptor.js.map +0 -1
- package/dist/log.service.d.ts +0 -12
- package/dist/log.service.js +0 -66
- package/dist/log.service.js.map +0 -1
- package/dist/logger.module.d.ts +0 -7
- package/dist/logger.module.js +0 -47
- package/dist/logger.module.js.map +0 -1
- package/dist/logger.service.d.ts +0 -8
- package/dist/logger.service.js +0 -35
- package/dist/logger.service.js.map +0 -1
- package/dist/services/db.service.d.ts +0 -9
- package/dist/services/db.service.js +0 -65
- package/dist/services/db.service.js.map +0 -1
- package/dist/types/db.type.d.ts +0 -1
- package/dist/types/db.type.js +0 -3
- package/dist/types/db.type.js.map +0 -1
- package/dist/types.d.ts +0 -7
- package/dist/types.js +0 -12
- package/dist/types.js.map +0 -1
package/public/scripts/common.js
CHANGED
|
@@ -11,6 +11,10 @@ const logTypes = Object.keys(selectedLogTypes).filter((key) => key !== `all`);
|
|
|
11
11
|
|
|
12
12
|
let logs = [];
|
|
13
13
|
let text = '';
|
|
14
|
+
let currentPage = 1;
|
|
15
|
+
let isLoading = false;
|
|
16
|
+
let hasMore = true;
|
|
17
|
+
const limit = 10;
|
|
14
18
|
|
|
15
19
|
connectWebSocket();
|
|
16
20
|
|
|
@@ -36,7 +40,9 @@ document.addEventListener(`click`, (e) => {
|
|
|
36
40
|
});
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
currentPage = 1;
|
|
44
|
+
hasMore = true;
|
|
45
|
+
getLogs(1);
|
|
40
46
|
|
|
41
47
|
return;
|
|
42
48
|
}
|
|
@@ -53,7 +59,9 @@ document.addEventListener(`click`, (e) => {
|
|
|
53
59
|
selectedLogTypes[`all`] = false;
|
|
54
60
|
unsetSelectorActive(document.querySelector(`li.all`));
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
currentPage = 1;
|
|
63
|
+
hasMore = true;
|
|
64
|
+
getLogs(1);
|
|
57
65
|
|
|
58
66
|
return;
|
|
59
67
|
}
|
|
@@ -141,24 +149,9 @@ function getLogHtmlElement(log) {
|
|
|
141
149
|
function renderLogs(logList = logs) {
|
|
142
150
|
let html = '';
|
|
143
151
|
|
|
144
|
-
logList
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
})
|
|
148
|
-
.filter((log) => {
|
|
149
|
-
if (text === '') return true;
|
|
150
|
-
|
|
151
|
-
return (
|
|
152
|
-
log.message.toLowerCase().includes(text) ||
|
|
153
|
-
log.trace?.toLowerCase().includes(text) ||
|
|
154
|
-
JSON.stringify(log.context || {})
|
|
155
|
-
.toLowerCase()
|
|
156
|
-
.includes(text)
|
|
157
|
-
);
|
|
158
|
-
})
|
|
159
|
-
.forEach((log) => {
|
|
160
|
-
html += getLogHtmlElement(log);
|
|
161
|
-
});
|
|
152
|
+
logList.forEach((log) => {
|
|
153
|
+
html += getLogHtmlElement(log);
|
|
154
|
+
});
|
|
162
155
|
|
|
163
156
|
document.getElementById('logs').innerHTML = html;
|
|
164
157
|
}
|
|
@@ -166,39 +159,79 @@ function renderLogs(logList = logs) {
|
|
|
166
159
|
async function checkElementsVisibility(logList = logs) {
|
|
167
160
|
if (logList.length === 0) {
|
|
168
161
|
document.getElementById('no-logs').style.display = 'block';
|
|
169
|
-
document.getElementById('search').style.display = 'none';
|
|
170
162
|
document.querySelector('.table-header').style.display = 'none';
|
|
171
|
-
document.querySelector('nav').style.display = '
|
|
163
|
+
document.querySelector('nav').style.display = 'flex';
|
|
172
164
|
} else {
|
|
173
165
|
document.getElementById('no-logs').style.display = 'none';
|
|
174
|
-
document.getElementById('search').style.display = 'inline-block';
|
|
175
166
|
document.querySelector('.table-header').style.display = 'flex';
|
|
176
167
|
document.querySelector('nav').style.display = 'flex';
|
|
177
168
|
}
|
|
178
169
|
}
|
|
179
170
|
|
|
180
|
-
async function getLogs() {
|
|
181
|
-
|
|
182
|
-
|
|
171
|
+
async function getLogs(page = 1) {
|
|
172
|
+
if (isLoading && page > 1) return;
|
|
173
|
+
|
|
174
|
+
if (page > 1 && !hasMore) return;
|
|
175
|
+
|
|
176
|
+
isLoading = true;
|
|
177
|
+
currentPage = page;
|
|
178
|
+
document.getElementById('loader').style.display = 'block';
|
|
179
|
+
|
|
180
|
+
const { origin, pathname, search: urlSearch } = window.location;
|
|
181
|
+
const searchParams = new URLSearchParams(urlSearch);
|
|
183
182
|
const key = searchParams.get('key');
|
|
184
183
|
|
|
185
|
-
|
|
184
|
+
const types = selectedLogTypes.all
|
|
185
|
+
? []
|
|
186
|
+
: Object.keys(selectedLogTypes).filter(
|
|
187
|
+
(key) => selectedLogTypes[key] && key !== 'all',
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
if (!!socket && socket.readyState === WebSocket.OPEN) {
|
|
186
191
|
socket.send(
|
|
187
192
|
JSON.stringify({
|
|
188
193
|
action: 'getLogs',
|
|
189
194
|
key,
|
|
190
|
-
|
|
195
|
+
page,
|
|
196
|
+
limit,
|
|
197
|
+
search: text,
|
|
198
|
+
types,
|
|
199
|
+
}),
|
|
191
200
|
);
|
|
192
201
|
} else {
|
|
193
|
-
const
|
|
202
|
+
const apiParams = new URLSearchParams(urlSearch);
|
|
203
|
+
apiParams.set('page', page);
|
|
204
|
+
apiParams.set('limit', limit);
|
|
205
|
+
|
|
206
|
+
if (text) {
|
|
207
|
+
apiParams.set('search', text);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (types.length > 0) {
|
|
211
|
+
apiParams.set('types', types.join(','));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const res = await fetch(`${origin}${pathname}api?${apiParams.toString()}`);
|
|
194
215
|
|
|
195
216
|
if (res.ok) {
|
|
196
|
-
|
|
217
|
+
const newLogs = await res.json();
|
|
197
218
|
|
|
198
|
-
|
|
219
|
+
if (page === 1) {
|
|
220
|
+
logs = newLogs;
|
|
221
|
+
} else {
|
|
222
|
+
logs = logs.concat(newLogs);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
hasMore = newLogs.length === limit;
|
|
226
|
+
isLoading = false;
|
|
227
|
+
document.getElementById('loader').style.display = 'none';
|
|
199
228
|
|
|
229
|
+
checkElementsVisibility();
|
|
200
230
|
renderLogs();
|
|
231
|
+
checkAndUpdatePopup();
|
|
201
232
|
} else {
|
|
233
|
+
isLoading = false;
|
|
234
|
+
document.getElementById('loader').style.display = 'none';
|
|
202
235
|
alert('An error occurred while fetching logs.');
|
|
203
236
|
}
|
|
204
237
|
}
|
|
@@ -220,7 +253,7 @@ async function deleteLog(_id) {
|
|
|
220
253
|
data: {
|
|
221
254
|
_id,
|
|
222
255
|
},
|
|
223
|
-
})
|
|
256
|
+
}),
|
|
224
257
|
);
|
|
225
258
|
closePopup();
|
|
226
259
|
getLogs();
|
|
@@ -231,7 +264,7 @@ async function deleteLog(_id) {
|
|
|
231
264
|
`${origin}${pathname}api?${searchParamsWithId.toString()}`,
|
|
232
265
|
{
|
|
233
266
|
method: 'DELETE',
|
|
234
|
-
}
|
|
267
|
+
},
|
|
235
268
|
);
|
|
236
269
|
|
|
237
270
|
if (res.ok) {
|
|
@@ -243,8 +276,85 @@ async function deleteLog(_id) {
|
|
|
243
276
|
}
|
|
244
277
|
}
|
|
245
278
|
|
|
279
|
+
let searchTimeout;
|
|
246
280
|
function search(event) {
|
|
247
281
|
text = event.target.value.toLowerCase();
|
|
248
282
|
|
|
283
|
+
clearTimeout(searchTimeout);
|
|
284
|
+
searchTimeout = setTimeout(() => {
|
|
285
|
+
currentPage = 1;
|
|
286
|
+
hasMore = true;
|
|
287
|
+
getLogs(1);
|
|
288
|
+
}, 300);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Infinite scrolling
|
|
292
|
+
const observer = new IntersectionObserver(
|
|
293
|
+
(entries) => {
|
|
294
|
+
if (entries[0].isIntersecting && !isLoading && hasMore) {
|
|
295
|
+
getLogs(currentPage + 1);
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
{ threshold: 1.0 },
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
302
|
+
const scrollAnchor = document.getElementById('scroll-anchor');
|
|
303
|
+
if (scrollAnchor) {
|
|
304
|
+
observer.observe(scrollAnchor);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
function matchesFilter(log) {
|
|
309
|
+
// Check types
|
|
310
|
+
if (!selectedLogTypes['all'] && !selectedLogTypes[log.type]) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Check search text
|
|
315
|
+
if (text !== '') {
|
|
316
|
+
const matches =
|
|
317
|
+
log.message.toLowerCase().includes(text) ||
|
|
318
|
+
log.trace?.toLowerCase().includes(text) ||
|
|
319
|
+
JSON.stringify(log.context || {})
|
|
320
|
+
.toLowerCase()
|
|
321
|
+
.includes(text);
|
|
322
|
+
|
|
323
|
+
if (!matches) return false;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function handleWsInsert(log) {
|
|
330
|
+
if (matchesFilter(log)) {
|
|
331
|
+
logs.unshift(log);
|
|
332
|
+
checkElementsVisibility();
|
|
333
|
+
renderLogs();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function handleWsUpdate(updatedLog) {
|
|
338
|
+
const idx = logs.findIndex((l) => l._id === updatedLog._id);
|
|
339
|
+
if (idx > -1) {
|
|
340
|
+
logs.splice(idx, 1);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (matchesFilter(updatedLog)) {
|
|
344
|
+
logs.unshift(updatedLog);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
checkElementsVisibility();
|
|
249
348
|
renderLogs();
|
|
349
|
+
checkAndUpdatePopup();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function handleWsDelete(id) {
|
|
353
|
+
const idx = logs.findIndex((l) => l._id === id);
|
|
354
|
+
if (idx > -1) {
|
|
355
|
+
logs.splice(idx, 1);
|
|
356
|
+
checkElementsVisibility();
|
|
357
|
+
renderLogs();
|
|
358
|
+
checkAndUpdatePopup();
|
|
359
|
+
}
|
|
250
360
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const popup = document.getElementById('popup');
|
|
2
|
+
let selectedLogId = null;
|
|
2
3
|
|
|
3
4
|
function showLogDetails(log) {
|
|
5
|
+
selectedLogId = log._id;
|
|
6
|
+
|
|
4
7
|
const context = getObject(log.context);
|
|
5
8
|
const breadcrumbs = getObject(log.breadcrumbs);
|
|
6
9
|
|
|
@@ -18,8 +21,8 @@ function showLogDetails(log) {
|
|
|
18
21
|
)}. First seen: ${getDate(log.createdAt)}`;
|
|
19
22
|
|
|
20
23
|
popup.innerHTML = `
|
|
21
|
-
<div id="drag-handle"
|
|
22
|
-
<div
|
|
24
|
+
<div id="drag-handle" title="Drag to move">
|
|
25
|
+
<div class="handle-indicator"></div>
|
|
23
26
|
</div>
|
|
24
27
|
<div class="content center">
|
|
25
28
|
<div class="container">
|
|
@@ -117,9 +120,21 @@ function getTrace(trace) {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
function closePopup() {
|
|
123
|
+
selectedLogId = null;
|
|
120
124
|
popup.style.display = 'none';
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
function checkAndUpdatePopup() {
|
|
128
|
+
if (selectedLogId) {
|
|
129
|
+
const log = logs.find((log) => log._id === selectedLogId);
|
|
130
|
+
if (log) {
|
|
131
|
+
showLogDetails(log);
|
|
132
|
+
} else {
|
|
133
|
+
closePopup();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
function setPopupLeft(left) {
|
|
124
139
|
if (popup?.style.display === 'block') {
|
|
125
140
|
if (left < 0) {
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
const LS_KEY = 'nestjs-logger';
|
|
2
2
|
|
|
3
|
+
const defaultSettings = {
|
|
4
|
+
popupLeft: `${window.innerWidth / 4}px`,
|
|
5
|
+
};
|
|
6
|
+
|
|
3
7
|
function getLs(propertyName) {
|
|
4
8
|
const item = localStorage.getItem(LS_KEY);
|
|
5
9
|
|
|
6
10
|
if (!item) {
|
|
7
|
-
return;
|
|
11
|
+
return defaultSettings[propertyName];
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
return JSON.parse(item)[propertyName];
|
|
@@ -12,12 +16,8 @@ function getLs(propertyName) {
|
|
|
12
16
|
|
|
13
17
|
function setLs(propertyName, value) {
|
|
14
18
|
const item = localStorage.getItem(LS_KEY);
|
|
19
|
+
const ls = item ? JSON.parse(item) : { ...defaultSettings };
|
|
15
20
|
|
|
16
|
-
if (!item) {
|
|
17
|
-
localStorage.setItem(LS_KEY, JSON.stringify({}));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const ls = JSON.parse(item);
|
|
21
21
|
ls[propertyName] = value;
|
|
22
22
|
localStorage.setItem(LS_KEY, JSON.stringify(ls));
|
|
23
23
|
}
|
package/public/scripts/ws.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
// WebSocket connection
|
|
2
2
|
let socket;
|
|
3
|
+
let connected = false;
|
|
4
|
+
let connectionAttempts = 0;
|
|
3
5
|
let frozen = false;
|
|
4
6
|
|
|
5
7
|
async function connectWebSocket() {
|
|
8
|
+
connectionAttempts++;
|
|
9
|
+
|
|
10
|
+
if (connectionAttempts > 3) {
|
|
11
|
+
alert('Failed to connect to WebSocket. Check the `key` url parameter.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
6
15
|
const { hostname, origin, pathname, search } = window.location;
|
|
7
16
|
|
|
8
17
|
const res = await fetch(`${origin}${pathname}settings${search}`);
|
|
9
18
|
|
|
10
19
|
if (!res.ok) {
|
|
11
20
|
alert(
|
|
12
|
-
'An error occurred while fetching settings. Check the `key` url parameter.'
|
|
21
|
+
'An error occurred while fetching settings. Check the `key` url parameter.',
|
|
13
22
|
);
|
|
14
23
|
return;
|
|
15
24
|
}
|
|
@@ -39,11 +48,14 @@ async function connectWebSocket() {
|
|
|
39
48
|
};
|
|
40
49
|
|
|
41
50
|
socket.onopen = (event) => {
|
|
51
|
+
connected = true;
|
|
52
|
+
connectionAttempts = 0;
|
|
42
53
|
getLogs();
|
|
43
54
|
};
|
|
44
55
|
|
|
45
56
|
socket.onclose = (event) => {
|
|
46
|
-
|
|
57
|
+
connected = false;
|
|
58
|
+
console.error(event);
|
|
47
59
|
setTimeout(connectWebSocket, 5000);
|
|
48
60
|
};
|
|
49
61
|
|
|
@@ -53,22 +65,38 @@ async function connectWebSocket() {
|
|
|
53
65
|
if (data['action'] && !frozen) {
|
|
54
66
|
switch (data['action']) {
|
|
55
67
|
case 'list':
|
|
56
|
-
|
|
68
|
+
if (currentPage === 1) {
|
|
69
|
+
logs = data['data'];
|
|
70
|
+
} else {
|
|
71
|
+
logs = logs.concat(data['data']);
|
|
72
|
+
}
|
|
73
|
+
hasMore = data['data'].length === limit;
|
|
74
|
+
isLoading = false;
|
|
75
|
+
document.getElementById('loader').style.display = 'none';
|
|
57
76
|
checkElementsVisibility(logs);
|
|
58
77
|
renderLogs(logs);
|
|
78
|
+
checkAndUpdatePopup();
|
|
59
79
|
break;
|
|
60
80
|
case 'insert':
|
|
61
|
-
|
|
81
|
+
if (currentPage === 1) {
|
|
82
|
+
handleWsInsert(data['data']);
|
|
83
|
+
}
|
|
62
84
|
break;
|
|
63
85
|
case 'update':
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
handleWsUpdate(data['data']);
|
|
87
|
+
break;
|
|
66
88
|
case 'delete':
|
|
67
|
-
|
|
89
|
+
handleWsDelete(data['data']._id);
|
|
90
|
+
break;
|
|
68
91
|
}
|
|
69
92
|
}
|
|
70
93
|
};
|
|
94
|
+
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
if (!connected) connectWebSocket(); // fix for Safari browser
|
|
97
|
+
}, 300);
|
|
71
98
|
}
|
|
99
|
+
|
|
72
100
|
function sendMessage(message) {
|
|
73
101
|
socket.send(JSON.stringify(message));
|
|
74
102
|
}
|
|
@@ -84,5 +112,6 @@ function toggleFreeze() {
|
|
|
84
112
|
} else {
|
|
85
113
|
button.classList.remove('light');
|
|
86
114
|
button.classList.add('white');
|
|
115
|
+
getLogs();
|
|
87
116
|
}
|
|
88
117
|
}
|
package/public/styles/index.css
CHANGED
|
@@ -54,7 +54,7 @@ h3 {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
#logs {
|
|
57
|
-
margin-top:
|
|
57
|
+
margin-top: 7rem;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
#no-logs {
|
|
@@ -63,6 +63,18 @@ h3 {
|
|
|
63
63
|
text-align: center;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
#loader {
|
|
67
|
+
display: none;
|
|
68
|
+
text-align: center;
|
|
69
|
+
padding: 1rem;
|
|
70
|
+
color: var(--teal);
|
|
71
|
+
font-weight: bold;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#scroll-anchor {
|
|
75
|
+
height: 20px;
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
/* buttons */
|
|
67
79
|
button {
|
|
68
80
|
display: flex;
|
|
@@ -316,7 +328,27 @@ nav ul li:hover {
|
|
|
316
328
|
overflow-y: scroll;
|
|
317
329
|
z-index: 1;
|
|
318
330
|
opacity: 0.97;
|
|
319
|
-
box-shadow:
|
|
331
|
+
box-shadow:
|
|
332
|
+
0 4px 8px 0 rgba(0, 0, 0, 0.2),
|
|
333
|
+
0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
#drag-handle {
|
|
337
|
+
margin: -2rem -2rem 1rem -2rem;
|
|
338
|
+
height: 1.5rem;
|
|
339
|
+
background-color: #f1f1f1;
|
|
340
|
+
border-bottom: 1px solid #ddd;
|
|
341
|
+
cursor: grab;
|
|
342
|
+
display: flex;
|
|
343
|
+
align-items: center;
|
|
344
|
+
justify-content: center;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
#drag-handle .handle-indicator {
|
|
348
|
+
width: 50px;
|
|
349
|
+
height: 5px;
|
|
350
|
+
background-color: #ccc;
|
|
351
|
+
border-radius: 5px;
|
|
320
352
|
}
|
|
321
353
|
|
|
322
354
|
/* JSON viewer */
|
|
@@ -347,3 +379,146 @@ nav ul li:hover {
|
|
|
347
379
|
box-shadow: none;
|
|
348
380
|
}
|
|
349
381
|
}
|
|
382
|
+
|
|
383
|
+
@media (max-width: 768px) {
|
|
384
|
+
/* Allow header to flow naturally */
|
|
385
|
+
header {
|
|
386
|
+
position: relative !important;
|
|
387
|
+
padding-bottom: 1rem;
|
|
388
|
+
height: auto;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* Reset logo from previous media query */
|
|
392
|
+
.logo {
|
|
393
|
+
width: 100%;
|
|
394
|
+
margin: 0 !important;
|
|
395
|
+
justify-content: center;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Show title again for branding */
|
|
399
|
+
.logo h2 {
|
|
400
|
+
display: block !important;
|
|
401
|
+
margin-left: 0.5rem;
|
|
402
|
+
font-size: 1.2rem;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* Wrap controls */
|
|
406
|
+
.controls {
|
|
407
|
+
flex-wrap: wrap;
|
|
408
|
+
padding: 0 1rem;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* Nav */
|
|
412
|
+
nav {
|
|
413
|
+
width: 100%;
|
|
414
|
+
order: 2;
|
|
415
|
+
overflow-x: auto;
|
|
416
|
+
margin-bottom: 1rem;
|
|
417
|
+
-webkit-overflow-scrolling: touch;
|
|
418
|
+
margin-top: 1rem;
|
|
419
|
+
height: 2rem;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
nav ul {
|
|
423
|
+
width: max-content;
|
|
424
|
+
padding: 0 0.5rem;
|
|
425
|
+
gap: 1.5rem;
|
|
426
|
+
justify-content: flex-start;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* Search */
|
|
430
|
+
#search {
|
|
431
|
+
order: 3;
|
|
432
|
+
width: 100%;
|
|
433
|
+
margin-bottom: 1rem;
|
|
434
|
+
box-sizing: border-box;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/* Buttons */
|
|
438
|
+
#refresh,
|
|
439
|
+
#freeze {
|
|
440
|
+
order: 4;
|
|
441
|
+
width: 48%;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
#refresh button,
|
|
445
|
+
#freeze button {
|
|
446
|
+
width: 100%;
|
|
447
|
+
justify-content: center;
|
|
448
|
+
padding: 10px;
|
|
449
|
+
margin-bottom: 1rem;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/* Logs Container */
|
|
453
|
+
#logs {
|
|
454
|
+
margin-top: 0;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/* Hide Table Header */
|
|
458
|
+
.table-header {
|
|
459
|
+
display: none;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* Row Layout */
|
|
463
|
+
.row {
|
|
464
|
+
flex-wrap: wrap;
|
|
465
|
+
height: auto;
|
|
466
|
+
padding: 0.8rem 0;
|
|
467
|
+
border-bottom: 1px solid var(--light);
|
|
468
|
+
align-items: flex-start;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.row:hover {
|
|
472
|
+
border-left: 2px solid transparent;
|
|
473
|
+
background-color: transparent;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.row:active {
|
|
477
|
+
background-color: #f5f5f5;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/* Type */
|
|
481
|
+
.row > :first-child {
|
|
482
|
+
flex: 0 0 3.5rem;
|
|
483
|
+
font-size: 0.75rem;
|
|
484
|
+
text-transform: uppercase;
|
|
485
|
+
font-weight: bold;
|
|
486
|
+
padding-left: 0.5rem;
|
|
487
|
+
text-align: left;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/* Info */
|
|
491
|
+
.row > :nth-child(2) {
|
|
492
|
+
flex: 1 1 auto;
|
|
493
|
+
max-width: calc(100% - 6.5rem);
|
|
494
|
+
padding: 0 0.5rem;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.log-info {
|
|
498
|
+
white-space: normal;
|
|
499
|
+
display: -webkit-box;
|
|
500
|
+
line-clamp: 2;
|
|
501
|
+
-webkit-line-clamp: 2;
|
|
502
|
+
-webkit-box-orient: vertical;
|
|
503
|
+
max-height: 2.8rem;
|
|
504
|
+
margin-bottom: 0.2rem;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/* Hide Context */
|
|
508
|
+
.row > :nth-child(3) {
|
|
509
|
+
display: none;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* Count */
|
|
513
|
+
.row > :last-child {
|
|
514
|
+
flex: 0 0 2rem;
|
|
515
|
+
font-size: 0.8rem;
|
|
516
|
+
color: #aaa;
|
|
517
|
+
text-align: right;
|
|
518
|
+
padding-right: 0.5rem;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
#drag-handle {
|
|
522
|
+
display: none;
|
|
523
|
+
}
|
|
524
|
+
}
|
package/src/log.module.ts
CHANGED
|
@@ -27,10 +27,8 @@ export class LogModule {
|
|
|
27
27
|
app: any,
|
|
28
28
|
options?: LogModuleOptions
|
|
29
29
|
): Promise<void> {
|
|
30
|
-
app.
|
|
31
|
-
|
|
32
|
-
const logService: LogService = await app.resolve(LogService);
|
|
33
|
-
const wsService: WsService = await app.resolve(WsService);
|
|
30
|
+
const logService: LogService = await app.get(LogService);
|
|
31
|
+
const wsService: WsService = await app.get(WsService);
|
|
34
32
|
const logAccessGuard: LogAccessGuard = await app.get(LogAccessGuard);
|
|
35
33
|
|
|
36
34
|
if (options) {
|
|
@@ -66,11 +64,17 @@ export class LogModule {
|
|
|
66
64
|
}
|
|
67
65
|
);
|
|
68
66
|
|
|
69
|
-
// get
|
|
67
|
+
// get logs endpoint
|
|
70
68
|
httpAdapter.get(join(options.path, 'api'), async (req: any, res: any) => {
|
|
71
69
|
logAccessGuard.canActivate(req);
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
const params = querystring.parse(req.url.split('?')[1]);
|
|
72
|
+
const page = params.page ? parseInt(params.page.toString()) : 1;
|
|
73
|
+
const limit = params.limit ? parseInt(params.limit.toString()) : 50;
|
|
74
|
+
const search = params.search ? params.search.toString() : '';
|
|
75
|
+
const types = params.types ? params.types.toString().split(',') : [];
|
|
76
|
+
|
|
77
|
+
res.json(await logService.getAll(page, limit, search, types));
|
|
74
78
|
});
|
|
75
79
|
|
|
76
80
|
// delete log endpoint
|