iguazio.dashboard-controls 1.0.13 → 1.1.1

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.
Files changed (24) hide show
  1. package/dist/i18n/en/common.json +95 -83
  2. package/dist/i18n/en/functions.json +110 -109
  3. package/dist/js/iguazio.dashboard-controls.js +6660 -5230
  4. package/dist/less/iguazio.dashboard-controls.less +1430 -881
  5. package/package.json +1 -1
  6. package/src/i18n/en/common.json +95 -83
  7. package/src/i18n/en/functions.json +110 -109
  8. package/src/igz_controls/components/date-time-picker/date-time-picker.component.js +689 -0
  9. package/src/igz_controls/components/date-time-picker/date-time-picker.component.spec.js +356 -0
  10. package/src/igz_controls/components/date-time-picker/date-time-picker.less +418 -0
  11. package/src/igz_controls/components/date-time-picker/date-time-picker.tpl.html +90 -0
  12. package/src/igz_controls/components/date-time-picker/prevent-parent-scroll.directive.js +27 -0
  13. package/src/igz_controls/components/log-table-row/log-table-row.component.js +57 -0
  14. package/src/igz_controls/components/log-table-row/log-table-row.component.spec.js +49 -0
  15. package/src/igz_controls/components/log-table-row/log-table-row.less +29 -0
  16. package/src/igz_controls/components/log-table-row/log-table-row.tpl.html +16 -0
  17. package/src/igz_controls/components/multiple-checkboxes/multiple-checkboxes.component.js +39 -5
  18. package/src/igz_controls/services/control-panel-logs-data.service.js +203 -0
  19. package/src/nuclio/common/components/deploy-log/deploy-log.component.js +1 -1
  20. package/src/nuclio/common/services/export.service.js +28 -5
  21. package/src/nuclio/functions/version/version-execution-log/version-execution-log.component.js +463 -0
  22. package/src/nuclio/functions/version/version-execution-log/version-execution-log.less +99 -0
  23. package/src/nuclio/functions/version/version-execution-log/version-execution-log.tpl.html +177 -0
  24. package/src/nuclio/functions/version/version.component.js +29 -2
@@ -0,0 +1,463 @@
1
+ /*
2
+ Copyright 2018 Iguazio Systems Ltd.
3
+ Licensed under the Apache License, Version 2.0 (the "License") with
4
+ an addition restriction as set forth herein. You may not use this
5
+ file except in compliance with the License. You may obtain a copy of
6
+ the License at http://www.apache.org/licenses/LICENSE-2.0.
7
+ Unless required by applicable law or agreed to in writing, software
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10
+ implied. See the License for the specific language governing
11
+ permissions and limitations under the License.
12
+ In addition, you may not use the software for any purposes that are
13
+ illegal under applicable law, and the grant of the foregoing license
14
+ under the Apache 2.0 license is conditioned upon your compliance with
15
+ such restriction.
16
+ */
17
+ /* eslint max-statements: ["error", 100] */
18
+ (function () {
19
+ 'use strict';
20
+
21
+ angular.module('iguazio.dashboard-controls')
22
+ .component('nclVersionExecutionLog', {
23
+ bindings: {
24
+ version: '<',
25
+ isFunctionDeploying: '&'
26
+ },
27
+ templateUrl: 'nuclio/functions/version/version-execution-log/version-execution-log.tpl.html',
28
+ controller: NclVersionExecutionLogController
29
+ });
30
+
31
+ function NclVersionExecutionLogController(lodash, $interval, i18next, $i18next, $rootScope, moment, ConfigService,
32
+ ControlPanelLogsDataService, ExportService, LoginService,PaginationService) {
33
+ var ctrl = this;
34
+
35
+ var lng = i18next.language;
36
+ var refreshInterval = null;
37
+ var initialTimeRange = null;
38
+ var initialDatePreset = '7d';
39
+ var initialReplicas = [];
40
+ var defaultFilter = {
41
+ name: '',
42
+ message: '',
43
+ level: {
44
+ debug: false,
45
+ info: false,
46
+ warn: false,
47
+ error: false
48
+ }
49
+ };
50
+
51
+ ctrl.isSplashShowed = {
52
+ value: false
53
+ };
54
+ ctrl.lastEntryTimestamp = null;
55
+ ctrl.logs = {};
56
+ ctrl.replicasList = [];
57
+ ctrl.filter = {};
58
+ ctrl.scrollConfig = {
59
+ axis: 'y',
60
+ theme: 'light',
61
+ advanced: {
62
+ updateOnContentResize: true
63
+ }
64
+ };
65
+ ctrl.datePreset = initialDatePreset;
66
+ ctrl.timeRange = null;
67
+ ctrl.searchStates = {};
68
+ ctrl.selectedReplicas = [];
69
+ ctrl.isFiltersShowed = {
70
+ value: false,
71
+ changeValue: function (newVal) {
72
+ this.value = newVal;
73
+ }
74
+ };
75
+ ctrl.filtersCounter = 0;
76
+ ctrl.filterQuery = '';
77
+ ctrl.refreshRate = {
78
+ value: '10',
79
+ options: [
80
+ {
81
+ name: '5 ' + $i18next.t('common:SECONDS', {lng: lng}),
82
+ value: '5'
83
+ },
84
+ {
85
+ name: '10 ' + $i18next.t('common:SECONDS', {lng: lng}),
86
+ value: '10'
87
+ },
88
+ {
89
+ name: '20 ' + $i18next.t('common:SECONDS', {lng: lng}),
90
+ value: '20'
91
+ },
92
+ {
93
+ name: '30 ' + $i18next.t('common:SECONDS', {lng: lng}),
94
+ value: '30'
95
+ },
96
+ {
97
+ name: '1 ' + $i18next.t('common:MINUTE', {lng: lng}),
98
+ value: '60'
99
+ },
100
+ {
101
+ name: $i18next.t('common:NO_REFRESH', {lng: lng}),
102
+ value: 'no'
103
+ },
104
+ ]
105
+ };
106
+ ctrl.customDatePresets = {
107
+ '1d': {
108
+ label: $i18next.t('common:LAST', {lng: lng}) + ' 24 ' + $i18next.t('common:HOURS', {lng: lng}),
109
+ getRange: function () {
110
+ return {
111
+ from: moment().subtract(24, 'hours')
112
+ };
113
+ }
114
+ },
115
+ '2d': {
116
+ label: $i18next.t('common:LAST', {lng: lng}) + ' 48 ' + $i18next.t('common:HOURS', {lng: lng}),
117
+ getRange: function () {
118
+ return {
119
+ from: moment().subtract(48, 'hours')
120
+ };
121
+ }
122
+ },
123
+ '7d': {
124
+ label: $i18next.t('common:LAST', {lng: lng}) + ' 7 ' + $i18next.t('common:DAYS', {lng: lng}),
125
+ getRange: function () {
126
+ return {
127
+ from: moment().subtract(7, 'days')
128
+ };
129
+ }
130
+ },
131
+ '30d': {
132
+ label: $i18next.t('common:LAST', {lng: lng}) + ' 30 ' + $i18next.t('common:DAYS', {lng: lng}),
133
+ getRange: function () {
134
+ return {
135
+ from: moment().subtract(30, 'days')
136
+ };
137
+ }
138
+ }
139
+ };
140
+ ctrl.perPageValues = [
141
+ {
142
+ id: 50,
143
+ name: '50'
144
+ },
145
+ {
146
+ id: 100,
147
+ name: '100'
148
+ },
149
+ {
150
+ id: 200,
151
+ name: '200'
152
+ },
153
+ {
154
+ id: 500,
155
+ name: '500'
156
+ }
157
+ ];
158
+
159
+ ctrl.$onInit = onInit;
160
+ ctrl.$onDestroy = onDestroy;
161
+
162
+ ctrl.applyFilters = applyFilters;
163
+ // ctrl.downloadLogFiles = downloadLogFiles;
164
+ ctrl.onCheckboxChange = onCheckboxChange;
165
+ ctrl.onRefreshRateChange = onRefreshRateChange;
166
+ ctrl.onTimeRangeChange = onTimeRangeChange;
167
+ ctrl.onQueryChanged = onQueryChanged;
168
+ ctrl.refreshLogs = refreshLogs;
169
+ ctrl.resetFilters = resetFilters;
170
+ ctrl.searchWithParams = searchWithParams;
171
+ ctrl.toggleFilters = toggleFilters;
172
+
173
+ //
174
+ // Hook methods
175
+ //
176
+
177
+ /**
178
+ * Initialization method
179
+ */
180
+ function onInit() {
181
+ defaultFilter.name = ctrl.version.metadata.name;
182
+ ctrl.filter = lodash.cloneDeep(defaultFilter);
183
+
184
+ PaginationService.addPagination(ctrl, 'logs', 'ControlPanelLogsDataService', onChangePageCallback, true);
185
+
186
+ ctrl.page.size = ctrl.perPageValues[0].id;
187
+
188
+ applyFilters();
189
+ }
190
+
191
+ /**
192
+ * Destructor method
193
+ */
194
+ function onDestroy() {
195
+ stopAutoUpdate();
196
+ }
197
+
198
+ //
199
+ // Public methods
200
+ //
201
+
202
+ /**
203
+ * Run search query again
204
+ */
205
+ function applyFilters() {
206
+ stopAutoUpdate();
207
+ calcActiveFilters();
208
+ generateFilterQuery();
209
+ searchWithParams(0, ctrl.page.size);
210
+ }
211
+
212
+ // /**
213
+ // * Downloads log to the file
214
+ // */
215
+ // function downloadLogFiles() {
216
+ // ExportService.exportLogs(prepareLogs(), ctrl.version.metadata.name);
217
+ //
218
+ // function prepareLogs() {
219
+ // return ctrl.logs.map(function (log) {
220
+ // return log['@timestamp'] + ' ' + log.name + ' (' + log.level + ') ' + log.message + ' ' + log.more;
221
+ // });
222
+ // }
223
+ // }
224
+
225
+ /**
226
+ * Triggered when search text was changed
227
+ * @param {string} query - Search query
228
+ * @param {string} field - Search field
229
+ */
230
+ function onQueryChanged(query, field) {
231
+ lodash.set(ctrl.filter, field, query);
232
+ }
233
+
234
+ /**
235
+ * Triggered when selected replicas list was changed
236
+ */
237
+ function onCheckboxChange() {
238
+ if (!ctrl.selectedReplicas) {
239
+ ctrl.selectedReplicas = angular.copy(initialReplicas);
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Handles Refresh Rate dropdown change
245
+ * @param {Object} item - new item
246
+ * @param {boolean} isItemChanged - was value changed or not
247
+ * @param {string} field - what field was changed
248
+ */
249
+ function onRefreshRateChange(item, isItemChanged, field) {
250
+ if (isItemChanged) {
251
+ lodash.set(ctrl, field, item.value);
252
+
253
+ stopAutoUpdate();
254
+ refreshLogs();
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Handles Time Range dropdown change
260
+ * @param {{from: number, to: number}} dateTimeRange - the time range selected in date-time range picker
261
+ * @param {string} preset - the selected preset name, if a preset was selected or an empty string
262
+ */
263
+ function onTimeRangeChange(dateTimeRange, preset) {
264
+ ctrl.datePreset = preset;
265
+ ctrl.timeRange = lodash.mapValues(dateTimeRange, function (range) {
266
+ return new Date(range).toISOString();
267
+ });
268
+
269
+ ctrl.lastEntryTimestamp = null;
270
+ }
271
+
272
+ /**
273
+ * Refreshes logs and generates replicas list
274
+ */
275
+ function refreshLogs() {
276
+ startAutoUpdate();
277
+
278
+ ControlPanelLogsDataService.logsPaginated(ctrl.page.number, ctrl.page.size, queryParams(), true)
279
+ .then(function (logs) {
280
+ if (logs.length > 0) {
281
+ ctrl.logs = lodash.cloneDeep(logs);
282
+ }
283
+ });
284
+ }
285
+
286
+ /**
287
+ * Reset filters
288
+ */
289
+ function resetFilters() {
290
+ ctrl.timeRange = initialTimeRange;
291
+ ctrl.selectedReplicas = initialReplicas;
292
+
293
+ lodash.merge(ctrl.filter, defaultFilter);
294
+
295
+ $rootScope.$broadcast('search-input_reset');
296
+
297
+ applyFilters();
298
+ }
299
+
300
+ /**
301
+ * Called when user navigates between pages
302
+ * Extend standard `changePage` call with query parameters
303
+ * @param {number} page - new page number to get data from
304
+ * @param {number} perPage - how many items should be present on a page
305
+ */
306
+ function searchWithParams(page, perPage) {
307
+ ctrl.changePage(page, perPage, queryParams());
308
+ }
309
+
310
+ /**
311
+ * Show/hide filters panel
312
+ */
313
+ function toggleFilters() {
314
+ ctrl.isFiltersShowed.value = !ctrl.isFiltersShowed.value;
315
+ }
316
+
317
+ //
318
+ // Private methods
319
+ //
320
+
321
+ /**
322
+ * Perform auto updating request and extends current data set with new items
323
+ */
324
+ function autoUpdate() {
325
+ // since this function is used for polling - stop polling if user is not logged in
326
+ if (!LoginService.isLoggedIn()) {
327
+ return;
328
+ }
329
+
330
+ ControlPanelLogsDataService.logsPaginated(ctrl.page.number, ctrl.page.size, queryParamsAutoUpdate(), true)
331
+ .then(function (logs) {
332
+ if (logs.length > 0) {
333
+ ctrl.logs = lodash.cloneDeep(logs);
334
+ ctrl.page.total = logs['total_pages'];
335
+
336
+ // set lastItemTimeStamp and start autoupdate
337
+ onChangePageCallback();
338
+ }
339
+ });
340
+ }
341
+
342
+ /**
343
+ * Calculates count of active filters
344
+ */
345
+ function calcActiveFilters() {
346
+ var filters = [
347
+ ctrl.datePreset,
348
+ !lodash.isEmpty(ctrl.filter.message),
349
+ ctrl.selectedReplicas,
350
+ !lodash.chain(ctrl.filter.level).values().compact().isEmpty().value()
351
+ ];
352
+
353
+ ctrl.activeFilters = lodash.size(lodash.compact(filters));
354
+ }
355
+
356
+ /**
357
+ * Updates latest timestamp when new data received and generates replicas list
358
+ */
359
+ function onChangePageCallback() {
360
+ if (ctrl.logs.length > 0) {
361
+ ctrl.lastEntryTimestamp = ctrl.logs[0].time;
362
+
363
+ if (ctrl.logs.replicas && (lodash.isEmpty(initialReplicas) ||
364
+ initialReplicas.length !== ctrl.replicasList.length)) {
365
+ ctrl.replicasList = ctrl.logs.replicas.map(function (replica) {
366
+ return {
367
+ label: replica,
368
+ id: replica,
369
+ value: replica,
370
+ checked: true
371
+ }
372
+ });
373
+ ctrl.selectedReplicas = angular.copy(ctrl.logs.replicas);
374
+ initialReplicas = ctrl.logs.replicas;
375
+ }
376
+ }
377
+
378
+ startAutoUpdate();
379
+ }
380
+
381
+ /**
382
+ * Generates query string from all filters
383
+ */
384
+ function generateFilterQuery() {
385
+ var levels = lodash.chain(ctrl.filter.level).pickBy().keys().join(' OR ').value();
386
+ var queries = ['system-id:"' + ConfigService.systemId + '"', '_exists_:nuclio'];
387
+
388
+ if (!lodash.isEmpty(ctrl.version.metadata.name)) {
389
+ queries.push('name:' + ctrl.version.metadata.name);
390
+ }
391
+
392
+ if (ctrl.selectedReplicas.length && ctrl.selectedReplicas.length !== initialReplicas.length) {
393
+ var replicas = ctrl.selectedReplicas.join(' OR ');
394
+
395
+ queries.push('kubernetes.pod.name:(' + replicas + ')');
396
+ }
397
+
398
+ if (!lodash.isEmpty(ctrl.filter.message)) {
399
+ // Escape reserved characters: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
400
+ var escapedMessage = ctrl.filter.message.replace(/[+\-=&|!(){}[\]^"~*?:\\/]/g, '\\$&')
401
+ .replace(/<|>/g, '');
402
+ queries.push('(message:' + escapedMessage + ' OR more:' + escapedMessage + ')');
403
+ }
404
+
405
+ if (!lodash.isEmpty(levels)) {
406
+ queries.push('level:(' + levels + ')');
407
+ }
408
+
409
+ ctrl.filterQuery = lodash.join(queries, ' AND ');
410
+ }
411
+
412
+ /**
413
+ * Generates query params for ordinary request, for example, when page was changed
414
+ * @returns {Object}
415
+ */
416
+ function queryParams() {
417
+ return {
418
+ query: ctrl.filterQuery,
419
+ timeFrame: ctrl.datePreset,
420
+ customTimeFrame: ctrl.timeRange
421
+ };
422
+ }
423
+
424
+ /**
425
+ * Generates query params for auto update request
426
+ * @returns {Object}
427
+ */
428
+ function queryParamsAutoUpdate() {
429
+ return lodash.defaults(queryParams(), {
430
+ lastEntryTimestamp: ctrl.lastEntryTimestamp
431
+ });
432
+ }
433
+
434
+ /**
435
+ * Starts auto update process
436
+ * @param {bool} [force] - used for making first update immediately after refreshInterval is created
437
+ */
438
+ function startAutoUpdate(force) {
439
+ // proceed only if auto update was switched on
440
+ if (ctrl.refreshRate.value !== ctrl.refreshRate.options[5].value) {
441
+ stopAutoUpdate();
442
+ refreshInterval = $interval(autoUpdate, parseInt(ctrl.refreshRate.value) * 1000);
443
+
444
+ // call function to refresh data immediately if Force flag is set
445
+ // for pagination, Force is not used, but when date range filter is changed, update should be immediate
446
+ if (angular.isDefined(force) && force) {
447
+ autoUpdate();
448
+ }
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Stops auto update process
454
+ */
455
+ function stopAutoUpdate() {
456
+ // if automatic update was already set, cancel it
457
+ if (!lodash.isNull(refreshInterval)) {
458
+ $interval.cancel(refreshInterval);
459
+ refreshInterval = null;
460
+ }
461
+ }
462
+ }
463
+ }());
@@ -0,0 +1,99 @@
1
+ .ncl-version-execution-log {
2
+ .control-panel-log-color-set();
3
+
4
+ min-width: 1200px;
5
+ padding: 24px 25px 22px 41px;
6
+
7
+ .ncl-version-execution-log-wrapper {
8
+ height: 95%;
9
+
10
+ .igz-info-page-actions-bar {
11
+ z-index: 990;
12
+ }
13
+
14
+ > .row {
15
+ position: relative;
16
+ padding: 16px 23px 16px;
17
+ background-color: @white;
18
+ border: solid 1px @pale-grey;
19
+ overflow: hidden;
20
+ margin-right: 16px;
21
+ margin-bottom: 16px;
22
+ transition: @igz-basic-transition;
23
+ height: 100%;
24
+
25
+ .logs-container {
26
+ padding-bottom: 50px;
27
+ }
28
+
29
+ &.filters-shown {
30
+ padding-right: 310px;
31
+ }
32
+
33
+ .info-page-filters {
34
+ width: 300px;
35
+
36
+ .info-page-filters-item {
37
+ &.search-input-item {
38
+ padding-top: 10px;
39
+ }
40
+ }
41
+
42
+ .filter-label {
43
+ font-weight: bold;
44
+ color: @log-filters-filter-label-color;
45
+ }
46
+
47
+ .filter-level-wrapper {
48
+ .filter-level-item {
49
+ margin: 5px 0;
50
+ }
51
+
52
+ .level-icon {
53
+ display: inline-block;
54
+ margin-right: 8px;
55
+ width: 20px;
56
+ text-align: center;
57
+
58
+ &::before {
59
+ font-size: 16px;
60
+ vertical-align: text-bottom;
61
+ }
62
+
63
+ &.ncl-icon-debug {
64
+ color: @log-filters-level-debug-icon-color;
65
+ }
66
+
67
+ &.igz-icon-info-round {
68
+ color: @log-filters-level-info-icon-color;
69
+ }
70
+
71
+ &.igz-icon-warning {
72
+ color: @log-filters-level-warn-icon-color;
73
+
74
+ &::before {
75
+ font-size: 15px;
76
+ }
77
+ }
78
+
79
+ &.igz-icon-cancel-path {
80
+ color: @log-filters-level-error-icon-color;
81
+ }
82
+ }
83
+ }
84
+
85
+ .checkboxes-dropdown-field {
86
+ height: 36px;
87
+ padding-left: 15px;
88
+ padding-right: 15px;
89
+ }
90
+ }
91
+ }
92
+
93
+ .igz-multiple-checkboxes {
94
+ .checkboxes-dropdown-container {
95
+ position: unset;
96
+ }
97
+ }
98
+ }
99
+ }