@universis/ngx-tables 0.6.16 → 0.6.18

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.
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('iso-639-1/build'), require('rxjs'), require('jquery'), require('datatables.net'), require('lodash'), require('datatables.net-scroller'), require('rxjs/add/observable/combineLatest'), require('@angular/common/http'), require('@themost/angular'), require('@themost/client'), require('@angular/core'), require('@angular/common'), require('@ngx-translate/core'), require('@angular/forms'), require('@universis/common'), require('@universis/common/routing'), require('@universis/forms'), require('angular-formio'), require('@angular/router'), require('ngx-bootstrap/modal'), require('ngx-bootstrap/progressbar'), require('ngx-pipes')) :
3
- typeof define === 'function' && define.amd ? define('@universis/ngx-tables', ['exports', 'iso-639-1/build', 'rxjs', 'jquery', 'datatables.net', 'lodash', 'datatables.net-scroller', 'rxjs/add/observable/combineLatest', '@angular/common/http', '@themost/angular', '@themost/client', '@angular/core', '@angular/common', '@ngx-translate/core', '@angular/forms', '@universis/common', '@universis/common/routing', '@universis/forms', 'angular-formio', '@angular/router', 'ngx-bootstrap/modal', 'ngx-bootstrap/progressbar', 'ngx-pipes'], factory) :
4
- (factory((global.universis = global.universis || {}, global.universis['ngx-tables'] = {}),global.ISO6391,global.rxjs,global.jQuery_,null,global.lodash,null,global.rxjs['add/observable/combineLatest'],global.ng.common.http,global.i1,global.client,global.ng.core,global.ng.common,global.core,global.ng.forms,global.i2,global.routing,global.forms$1,global.angularFormio,global.ng.router,global.modal,global.progressbar,global.ngxPipes));
5
- }(this, (function (exports,ISO6391,rxjs,jQuery_,datatables_net,lodash,datatables_netScroller,combineLatest,http,i1,client,i0,common,core,forms,i2,routing,forms$1,angularFormio,i1$1,modal,progressbar,ngxPipes) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('iso-639-1/build'), require('rxjs'), require('jquery'), require('datatables.net'), require('lodash'), require('datatables.net-scroller'), require('rxjs/add/observable/combineLatest'), require('@angular/common/http'), require('@themost/client'), require('@themost/angular'), require('@angular/core'), require('@angular/common'), require('@ngx-translate/core'), require('@angular/forms'), require('@universis/common'), require('@universis/common/routing'), require('@universis/forms'), require('angular-formio'), require('@angular/router'), require('ngx-bootstrap/modal'), require('ngx-bootstrap/progressbar'), require('ngx-pipes')) :
3
+ typeof define === 'function' && define.amd ? define('@universis/ngx-tables', ['exports', 'iso-639-1/build', 'rxjs', 'jquery', 'datatables.net', 'lodash', 'datatables.net-scroller', 'rxjs/add/observable/combineLatest', '@angular/common/http', '@themost/client', '@themost/angular', '@angular/core', '@angular/common', '@ngx-translate/core', '@angular/forms', '@universis/common', '@universis/common/routing', '@universis/forms', 'angular-formio', '@angular/router', 'ngx-bootstrap/modal', 'ngx-bootstrap/progressbar', 'ngx-pipes'], factory) :
4
+ (factory((global.universis = global.universis || {}, global.universis['ngx-tables'] = {}),global.ISO6391,global.rxjs,global.jQuery_,null,global.lodash,null,global.rxjs['add/observable/combineLatest'],global.ng.common.http,global.client,global.i1,global.ng.core,global.ng.common,global.core,global.ng.forms,global.i2,global.routing,global.forms$1,global.angularFormio,global.ng.router,global.modal,global.progressbar,global.ngxPipes));
5
+ }(this, (function (exports,ISO6391,rxjs,jQuery_,datatables_net,lodash,datatables_netScroller,combineLatest,http,client,i1,i0,common,core,forms,i2,routing,forms$1,angularFormio,i1$1,modal,progressbar,ngxPipes) { 'use strict';
6
6
 
7
7
  /*! *****************************************************************************
8
8
  Copyright (c) Microsoft Corporation.
@@ -176,507 +176,6 @@
176
176
  return ar;
177
177
  }
178
178
 
179
- var AddItemsComponent = /** @class */ (function (_super) {
180
- __extends(AddItemsComponent, _super);
181
- function AddItemsComponent(router, activatedRoute, _errorService, _modalService, _appEvent, _toastService, _loadingService, _translateService, _context) {
182
- var _this = _super.call(this, router, activatedRoute) || this;
183
- _this._errorService = _errorService;
184
- _this._modalService = _modalService;
185
- _this._appEvent = _appEvent;
186
- _this._toastService = _toastService;
187
- _this._loadingService = _loadingService;
188
- _this._translateService = _translateService;
189
- _this._context = _context;
190
- _this.loading = false;
191
- _this.items = [];
192
- _this.messages = [];
193
- // set modal size
194
- _this.modalClass = 'modal-lg';
195
- _this.okButtonDisabled = true;
196
- return _this;
197
- }
198
- AddItemsComponent.prototype.ngOnInit = function () {
199
- var _this = this;
200
- this.selectedSubscription = this.selectComponent.advancedTable.selectedItems.subscribe(function (items) {
201
- if (_this.formName == null) {
202
- _this.okButtonDisabled = items.length === 0;
203
- }
204
- });
205
- if (this.formName != null) {
206
- this.formChangeSubscription = this.formComponent.form.change.subscribe(function (event) {
207
- if (Object.prototype.hasOwnProperty.call(event, 'isValid')) {
208
- // enable or disable button based on form status
209
- _this.okButtonDisabled = (!event.isValid);
210
- }
211
- });
212
- }
213
- if (this.target) {
214
- var target = this.target;
215
- }
216
- };
217
- AddItemsComponent.prototype.cancel = function () {
218
- this.clearMessages();
219
- if (this.loading) {
220
- return;
221
- }
222
- // close
223
- if (this._modalService.modalRef) {
224
- return this._modalService.modalRef.hide();
225
- }
226
- };
227
- AddItemsComponent.prototype.ngOnDestroy = function () {
228
- if (this.formLoadSubscription) {
229
- this.formLoadSubscription.unsubscribe();
230
- }
231
- if (this.formChangeSubscription) {
232
- this.formChangeSubscription.unsubscribe();
233
- }
234
- if (this.selectedSubscription) {
235
- this.selectedSubscription.unsubscribe();
236
- }
237
- };
238
- Object.defineProperty(AddItemsComponent.prototype, "formData", {
239
- get: function () {
240
- if (this.formComponent === null) {
241
- return null;
242
- }
243
- return this.formComponent.form.formio.data;
244
- },
245
- enumerable: true,
246
- configurable: true
247
- });
248
- AddItemsComponent.prototype.ok = function () {
249
- var _this = this;
250
- try {
251
- this.clearMessages();
252
- return new Promise(function (resolve, reject) {
253
- _this.loading = false;
254
- _this.lastError = null;
255
- // set courses
256
- _this.items = _this.selectComponent.advancedTable.selected;
257
- // execute add
258
- _this.executeSubscription = _this.execute.subscribe(function (result) {
259
- _this.loading = false;
260
- if (_this.executeSubscription) {
261
- _this.executeSubscription.unsubscribe();
262
- }
263
- // close modal
264
- if (_this._modalService.modalRef) {
265
- _this._modalService.modalRef.hide();
266
- }
267
- return resolve();
268
- }, function (err) {
269
- _this.loading = false;
270
- // ensure that loading is hidden
271
- _this._loadingService.hideLoading();
272
- // set last error
273
- _this.lastError = err;
274
- return resolve();
275
- });
276
- });
277
- }
278
- catch (err) {
279
- this.loading = false;
280
- this._loadingService.hideLoading();
281
- this.lastError = err;
282
- }
283
- };
284
- AddItemsComponent.prototype.onChange = function ($event) { };
285
- AddItemsComponent.prototype.clearMessages = function () {
286
- this.messages = [];
287
- };
288
- AddItemsComponent.prototype.onFilterChange = function (event) { };
289
- AddItemsComponent.decorators = [
290
- { type: i0.Component, args: [{
291
- selector: 'app-add-items',
292
- template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"alert alert-danger col-12\" role=\"alert\">\n <span [translate]=\"'E' + (lastError.statusCode || 500) + '.title'\"></span><br>\n <small *ngIf=\"lastError.statusCode >= 0\" [translate]=\"'E' + (lastError.statusCode || 500) + '.message'\"></small>\n <small *ngIf=\"lastError.statusCode == null\">{{lastError.message}}</small>\n </div>\n </div>\n <div class=\"row d-none\" *ngIf=\"items\">\n <div class=\"col-12\">\n <p [translate]=\"'StudyPrograms.AddCoursesHelp'\" [translateParams]=\"items\" ></p>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col-12\">\n <ng-container>\n <ul style=\"margin-left: -24px\" class=\"nav nav-tabs mb-1\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\" *ngIf=\"tableConfiguration\">\n <a class=\"nav-link active\" id=\"courses-tab\" data-toggle=\"tab\" href=\"#courses\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\" [translate]=\"'AddItems.SelectCourses'\" ></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"formName\">\n <a class=\"nav-link\" [ngClass]=\"{ 'disabled': !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) }\" id=\"attributes-tab\" data-toggle=\"tab\" href=\"#attributes\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.EditAttributes'\"></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"messages && messages.length > 0\">\n <a class=\"nav-link\" id=\"messages-tab\" data-toggle=\"tab\" href=\"#messages\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.Messages'\"></a>\n </li>\n </ul>\n <div class=\"tab-content border-0\" id=\"myTabContent\">\n <div class=\"tab-pane fade show active\" id=\"courses\" role=\"tabpanel\" aria-labelledby=\"home-tab\">\n <app-advanced-table-modal #selectComponent (filter)=\"onFilterChange($event)\" [tableConfig]=\"tableConfiguration\"></app-advanced-table-modal>\n </div>\n <div class=\"tab-pane fade\" id=\"attributes\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(formName == null)}\">\n<!-- <advanced-form-edit #formComponent [formName]=\"formName\" ></advanced-form-edit>-->\n </div>\n <div class=\"tab-pane fade\" id=\"messages\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(messages == null)}\">\n <ul *ngIf=\"messages && messages.length>0\" class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center\">\n <div class=\"sis--list-group-item_lg_column\" [translate]=\"'AddItems.Messages'\"></div>\n </div>\n </li>\n </ul>\n <ul class=\"sis--list-group sis--list-group-body\">\n <li *ngFor=\"let message of messages\" class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <div class=\"sis--list-group-item_lg_column\">{{ message?.message }}</div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"messages && messages.length>0\">\n <button [disabled]=\"loading\" (click)=\"clearMessages()\" type=\"button\" class=\"btn btn-indigo mt-3\">\n {{'Clear' | translate}}\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) \" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{'OK' | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{'Cancel' | translate}}\n </button>\n </div>\n</div>\n"
293
- }] }
294
- ];
295
- /** @nocollapse */
296
- AddItemsComponent.ctorParameters = function () {
297
- return [
298
- { type: i1$1.Router },
299
- { type: i1$1.ActivatedRoute },
300
- { type: i2.ErrorService },
301
- { type: i2.ModalService },
302
- { type: i2.AppEventService },
303
- { type: i2.ToastService },
304
- { type: i2.LoadingService },
305
- { type: core.TranslateService },
306
- { type: i1.AngularDataContext }
307
- ];
308
- };
309
- AddItemsComponent.propDecorators = {
310
- execute: [{ type: i0.Input }],
311
- items: [{ type: i0.Input }],
312
- target: [{ type: i0.Input }],
313
- tableConfiguration: [{ type: i0.Input }],
314
- formName: [{ type: i0.Input }],
315
- messages: [{ type: i0.Input }],
316
- formComponent: [{ type: i0.ViewChild, args: ['formComponent',] }],
317
- selectComponent: [{ type: i0.ViewChild, args: ['selectComponent',] }]
318
- };
319
- return AddItemsComponent;
320
- }(routing.RouterModalOkCancel));
321
-
322
- var AdvancedAggregatorService = /** @class */ (function () {
323
- function AdvancedAggregatorService(_context, _template) {
324
- this._context = _context;
325
- this._template = _template;
326
- }
327
- /**
328
- *
329
- * Formats and executes the data query
330
- *
331
- * @param {string} model The target model
332
- * @param {object} fixedParams Pairs of parameters to always be applied
333
- * @param {string} queryStatement The default query to use for fetching the data (e.g. expands etc)
334
- * @param {Array<string>} filters A list of filter expressions to append at the query
335
- * @param {string} searchTemplate The template to use for searching expressions
336
- * @param {string} searchValue The value of the user search
337
- *
338
- * @returns {Promise<any>} The response of the query execution
339
- */
340
- AdvancedAggregatorService.prototype.fetchData = function (model, fixedParams, queryStatement, filters, searchTemplate, searchValue) {
341
- if (queryStatement === void 0) {
342
- queryStatement = '';
343
- }
344
- return __awaiter(this, void 0, void 0, function () {
345
- var e_1, _a, query, filterExpressions, _b, _c, param, evaluatedSearch, words;
346
- var _this = this;
347
- return __generator(this, function (_d) {
348
- query = this._context.model(model).asQueryable();
349
- if (!fixedParams || typeof fixedParams !== 'object') {
350
- fixedParams = {};
351
- }
352
- filterExpressions = [];
353
- if (fixedParams) {
354
- try {
355
- for (_b = __values(Object.keys(fixedParams)), _c = _b.next(); !_c.done; _c = _b.next()) {
356
- param = _c.value;
357
- filterExpressions.push(param + " eq " + fixedParams[param]);
358
- }
359
- }
360
- catch (e_1_1) {
361
- e_1 = { error: e_1_1 };
362
- }
363
- finally {
364
- try {
365
- if (_c && !_c.done && (_a = _b.return))
366
- _a.call(_b);
367
- }
368
- finally {
369
- if (e_1)
370
- throw e_1.error;
371
- }
372
- }
373
- }
374
- if (filters && Array.isArray(filters)) {
375
- filterExpressions = __spread(filterExpressions, filters);
376
- }
377
- if (searchTemplate && searchValue) {
378
- evaluatedSearch = void 0;
379
- if (/^"(.*?)"$/.test(searchValue)) { // validate search text in double quotes
380
- evaluatedSearch = this._template.transform(searchTemplate, __assign({}, fixedParams, { text: searchValue.replace(/^"|"$/g, '') }));
381
- }
382
- else {
383
- words = searchValue.split(' ');
384
- // join words to a single filter
385
- evaluatedSearch = words.map(function (word) {
386
- return _this._template.transform(searchTemplate, __assign({}, fixedParams, { text: word }));
387
- }).join(' and ');
388
- }
389
- filterExpressions.push(evaluatedSearch);
390
- }
391
- query.setParam('$filter', filterExpressions.join('and'));
392
- return [2 /*return*/, query.expand(queryStatement).take(-1).getItems()];
393
- });
394
- });
395
- };
396
- /**
397
- *
398
- * Formats the received data to use flat keys
399
- *
400
- * @param config The applied configuration
401
- * @param data The raw data
402
- *
403
- * @returns {Array<any>} The flat-key object list
404
- *
405
- */
406
- AdvancedAggregatorService.prototype.formatData = function (config, data) {
407
- var _this = this;
408
- try {
409
- return data.map(function (entry) {
410
- if (entry.subitems && Array.isArray(entry.subitems)) {
411
- entry.subitems = _this.formatData(config, entry.subitems);
412
- }
413
- var entryObject = {};
414
- for (var i = 0; i < config.columns.length; i++) {
415
- var keys = config.columns[i].name.split('/');
416
- var helperObject = entry[keys[0]];
417
- if (helperObject && keys.length > 1) {
418
- for (var i_1 = 1; i_1 < keys.length; i_1++) {
419
- if (helperObject === undefined || helperObject === null) {
420
- break;
421
- }
422
- else {
423
- helperObject = helperObject[keys[i_1]] !== undefined && helperObject[keys[i_1]] !== null
424
- ? helperObject[keys[i_1]]
425
- : undefined;
426
- }
427
- }
428
- }
429
- entryObject[config.columns[i].name] = helperObject;
430
- }
431
- if (entry.subitems) {
432
- entryObject.subitems = entry.subitems;
433
- }
434
- return entryObject;
435
- });
436
- }
437
- catch (err) {
438
- console.error(err);
439
- }
440
- };
441
- AdvancedAggregatorService.decorators = [
442
- { type: i0.Injectable, args: [{
443
- providedIn: 'root'
444
- },] }
445
- ];
446
- /** @nocollapse */
447
- AdvancedAggregatorService.ctorParameters = function () {
448
- return [
449
- { type: i1.AngularDataContext },
450
- { type: i2.TemplatePipe }
451
- ];
452
- };
453
- AdvancedAggregatorService.ngInjectableDef = i0.defineInjectable({ factory: function AdvancedAggregatorService_Factory() { return new AdvancedAggregatorService(i0.inject(i1.AngularDataContext), i0.inject(i2.TemplatePipe)); }, token: AdvancedAggregatorService, providedIn: "root" });
454
- return AdvancedAggregatorService;
455
- }());
456
-
457
- /**
458
- *
459
- * @class AdvancedAggregatorComponent
460
- * @classdesc An advanced list with the capability of aggregate data based on configurable filters
461
- *
462
- */
463
- var AdvancedAggregatorComponent = /** @class */ (function () {
464
- function AdvancedAggregatorComponent(_changeDetector, _advancedAggregatorService, _loadingService) {
465
- this._changeDetector = _changeDetector;
466
- this._advancedAggregatorService = _advancedAggregatorService;
467
- this._loadingService = _loadingService;
468
- this.groups = [];
469
- this.eventHandler = new i0.EventEmitter();
470
- }
471
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "config", {
472
- get: function () {
473
- return this._config;
474
- },
475
- set: function (value) {
476
- this._config = value;
477
- },
478
- enumerable: true,
479
- configurable: true
480
- });
481
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "aggregators", {
482
- get: function () {
483
- return this._aggregators;
484
- },
485
- set: function (value) {
486
- this._aggregators = value;
487
- },
488
- enumerable: true,
489
- configurable: true
490
- });
491
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "postProcessors", {
492
- get: function () {
493
- return this._postProcessors;
494
- },
495
- set: function (value) {
496
- this._postProcessors = value;
497
- },
498
- enumerable: true,
499
- configurable: true
500
- });
501
- AdvancedAggregatorComponent.prototype.ngOnInit = function () {
502
- return __awaiter(this, void 0, void 0, function () {
503
- var _this = this;
504
- return __generator(this, function (_a) {
505
- this.selectedGroups$.subscribe(function (data) {
506
- _this.groups = data;
507
- _this._changeDetector.markForCheck();
508
- });
509
- this.filters$.subscribe(function (filters) {
510
- return __awaiter(_this, void 0, void 0, function () {
511
- var err_1;
512
- return __generator(this, function (_a) {
513
- switch (_a.label) {
514
- case 0:
515
- _a.trys.push([0, 2, , 3]);
516
- return [4 /*yield*/, this.fetch(filters)];
517
- case 1:
518
- _a.sent();
519
- return [3 /*break*/, 3];
520
- case 2:
521
- err_1 = _a.sent();
522
- console.error(err_1);
523
- return [3 /*break*/, 3];
524
- case 3: return [2 /*return*/];
525
- }
526
- });
527
- });
528
- });
529
- return [2 /*return*/];
530
- });
531
- });
532
- };
533
- AdvancedAggregatorComponent.prototype.ngOnDestroy = function () {
534
- return __awaiter(this, void 0, void 0, function () {
535
- return __generator(this, function (_a) {
536
- this.selectedGroups$.unsubscribe();
537
- this.filters$.unsubscribe();
538
- return [2 /*return*/];
539
- });
540
- });
541
- };
542
- /**
543
- *
544
- * Retrieves the data
545
- *
546
- */
547
- AdvancedAggregatorComponent.prototype.fetch = function (filters) {
548
- return __awaiter(this, void 0, void 0, function () {
549
- var data, i, err_2;
550
- return __generator(this, function (_a) {
551
- switch (_a.label) {
552
- case 0:
553
- _a.trys.push([0, 6, 7, 8]);
554
- this._loadingService.showLoading();
555
- return [4 /*yield*/, this._advancedAggregatorService.fetchData(this.config.model, this.params, this.config.query, filters.filters, this.searchExpression, filters.text)];
556
- case 1:
557
- data = _a.sent();
558
- if (!(this.postProcessors && Object.keys(this.postProcessors).length > 0 && this.config.postProcessors && this.config.postProcessors.length > 0))
559
- return [3 /*break*/, 5];
560
- i = 0;
561
- _a.label = 2;
562
- case 2:
563
- if (!(i < this.config.postProcessors.length))
564
- return [3 /*break*/, 5];
565
- return [4 /*yield*/, this.postProcessors[this.config.postProcessors[i].name](data)];
566
- case 3:
567
- data = _a.sent();
568
- _a.label = 4;
569
- case 4:
570
- i++;
571
- return [3 /*break*/, 2];
572
- case 5:
573
- this.body = this._advancedAggregatorService.formatData(this.config, data);
574
- this._changeDetector.markForCheck();
575
- return [3 /*break*/, 8];
576
- case 6:
577
- err_2 = _a.sent();
578
- console.error(err_2);
579
- return [3 /*break*/, 8];
580
- case 7:
581
- this._loadingService.hideLoading();
582
- return [7 /*endfinally*/];
583
- case 8: return [2 /*return*/];
584
- }
585
- });
586
- });
587
- };
588
- /**
589
- *
590
- * Triggers the event handler event
591
- *
592
- * @param {*} event The event data
593
- *
594
- */
595
- AdvancedAggregatorComponent.prototype.onActionEvent = function (event) {
596
- this.eventHandler.emit(event);
597
- };
598
- AdvancedAggregatorComponent.decorators = [
599
- { type: i0.Component, args: [{
600
- selector: 'app-advanced-aggregator',
601
- template: "<ng-container *ngIf=\"config && body\">\n <div class=\"w-100 text-center\" *ngIf=\"body && body.length === 0\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"groups.length === 0\">\n <div class=\"row mt-4\">\n <app-advanced-aggregator-list [body]=\"body\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\" class=\"col-12\">\n </app-advanced-aggregator-list>\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ body | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"groups.length === 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <app-advanced-aggregator-list [body]=\"group.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for the group -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ group.value | callAggregator: aggregators: aggregator.name }} </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"groups.length > 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <div *ngFor=\"let subgroup of group.value | groupBy: groups[1].name | keyvalue\" class=\"col-12 ml-4 pl-4\">\n <div class=\"row mt-4\">\n <h6 class=\"col-12 text-secondary\"> {{ groups[1].title | aggregatorListTitle: subgroup.key }} </h6>\n <app-advanced-aggregator-list [body]=\"subgroup.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for each subgroup -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ subgroup.value | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</ng-container>",
602
- changeDetection: i0.ChangeDetectionStrategy.OnPush
603
- }] }
604
- ];
605
- /** @nocollapse */
606
- AdvancedAggregatorComponent.ctorParameters = function () {
607
- return [
608
- { type: i0.ChangeDetectorRef },
609
- { type: AdvancedAggregatorService },
610
- { type: i2.LoadingService }
611
- ];
612
- };
613
- AdvancedAggregatorComponent.propDecorators = {
614
- config: [{ type: i0.Input, args: ['config',] }],
615
- aggregators: [{ type: i0.Input, args: ['aggregators',] }],
616
- postProcessors: [{ type: i0.Input, args: ['postProcessors',] }],
617
- params: [{ type: i0.Input, args: ['params',] }],
618
- selectedGroups$: [{ type: i0.Input, args: ['selectedGroups',] }],
619
- filters$: [{ type: i0.Input, args: ['filters',] }],
620
- searchExpression: [{ type: i0.Input, args: ['searchExpression',] }],
621
- eventHandler: [{ type: i0.Output }]
622
- };
623
- return AdvancedAggregatorComponent;
624
- }());
625
-
626
- var Lengths;
627
- (function (Lengths) {
628
- Lengths["XL"] = "xl";
629
- Lengths["LG"] = "lg";
630
- Lengths["MD"] = "md";
631
- Lengths["SM"] = "sm";
632
- Lengths["XS"] = "xs";
633
- })(Lengths || (Lengths = {}));
634
- var AdvancedAggregatorListComponent = /** @class */ (function () {
635
- function AdvancedAggregatorListComponent(_template) {
636
- this._template = _template;
637
- this.clickEvent = new i0.EventEmitter();
638
- }
639
- AdvancedAggregatorListComponent.prototype.ngOnInit = function () {
640
- var _this = this;
641
- this.config.columns.forEach(function (x) {
642
- x.length = Object.values(Lengths).includes(x.length) ? _this._template.transform("sis--list-group-item_" + x.length + "_column", x) :
643
- !x.length ? 'sis--list-group-item_sm_column' : x.length;
644
- });
645
- };
646
- /**
647
- *
648
- * Triggers the output event emitter
649
- *
650
- * @param type The type of the event as it's declared in the configuration
651
- * @param item The value of the current item
652
- * }
653
- */
654
- AdvancedAggregatorListComponent.prototype.callCallback = function (type, data) {
655
- this.clickEvent.emit({
656
- type: type,
657
- data: data
658
- });
659
- };
660
- AdvancedAggregatorListComponent.decorators = [
661
- { type: i0.Component, args: [{
662
- selector: 'app-advanced-aggregator-list',
663
- template: "<div id=\"group-list\" class=\"flex-column\" *ngIf=\"config && config.columns\">\n <ul class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item text-wrap\">\n <div class=\"d-flex justify-content-center align-items-center\" *ngIf=\"body && body.length > 0\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column\"></div>\n <div *ngFor=\"let column of config.columns; let i = index\" class=\"text-left\"\n [class]=\"config.columns[i].length\"\n [translate]=\"config.columns[i].type === 'action' ? '' : column.title\" [ngClass]=\"{\n 'd-none': config.columns[i].hidden\n }\"></div>\n </div>\n </li>\n </ul>\n\n <!-- The list of entries -->\n <ul class=\"sis--list-group sis--list-group-body\" *ngIf=\"body && body.length > 0\">\n <li class=\"sis--list-group-item text-wrap\" *ngFor=\"let entry of body | orderBy: config.orderBy\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <!-- The list of actions -->\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, entry)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n\n </div>\n <!-- The list of data -->\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && entry[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !entry[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length <= 3\n }\">\n {{entry[column.name] || '-'}}\n </span>\n\n <button *ngIf=\"config.columns[i].type === 'action' && config.columns[i].variant === 'edit'\"\n (click)=\"callCallback(config.columns[i].identifier, entry)\"\n [title]=\"(config.columns[i].title ? config.columns[i].title : '') | translate \"\n class=\"btn btn-default px-0 mx-0\">\n <i class=\"fas fa-edit text-indigo\"></i>\n </button>\n\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': entry[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n <div *ngIf=\"entry && entry.subitems\">\n <div *ngFor=\"let subitem of entry.subitems\" class=\"d-flex justify-content-center align-items-center list-color\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, subitem)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n </div>\n <div class=\"text-left\"></div>\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && subitem[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !subitem[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length <= 3\n }\">\n {{subitem[column.name] || '-'}}\n </span>\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': subitem[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n </div>\n </li>\n </ul>\n</div>\n"
664
- }] }
665
- ];
666
- /** @nocollapse */
667
- AdvancedAggregatorListComponent.ctorParameters = function () {
668
- return [
669
- { type: i2.TemplatePipe }
670
- ];
671
- };
672
- AdvancedAggregatorListComponent.propDecorators = {
673
- config: [{ type: i0.Input }],
674
- body: [{ type: i0.Input }],
675
- clickEvent: [{ type: i0.Output }]
676
- };
677
- return AdvancedAggregatorListComponent;
678
- }());
679
-
680
179
  var AdvancedColumnFormatter = /** @class */ (function () {
681
180
  function AdvancedColumnFormatter() {
682
181
  }
@@ -3878,604 +3377,1105 @@
3878
3377
  queryParamsHandling: 'merge',
3879
3378
  });
3880
3379
  }
3881
- else {
3882
- // clear filter
3883
- this.filter = {};
3884
- // clear list
3885
- this.selectedList = null;
3886
- // raise filter change event
3887
- this.filterChange.emit(this.filter);
3380
+ else {
3381
+ // clear filter
3382
+ this.filter = {};
3383
+ // clear list
3384
+ this.selectedList = null;
3385
+ // raise filter change event
3386
+ this.filterChange.emit(this.filter);
3387
+ }
3388
+ };
3389
+ Object.defineProperty(AdvancedTableSearchComponent.prototype, "viewState", {
3390
+ /**
3391
+ * Gets the view state of search control
3392
+ */
3393
+ get: function () {
3394
+ return {
3395
+ advancedView: !this.collapsed,
3396
+ };
3397
+ },
3398
+ enumerable: true,
3399
+ configurable: true
3400
+ });
3401
+ /**
3402
+ * Switches view between simple and advanced search
3403
+ */
3404
+ AdvancedTableSearchComponent.prototype.toggleView = function () {
3405
+ return __awaiter(this, void 0, void 0, function () {
3406
+ return __generator(this, function (_a) {
3407
+ this.collapsed = !this.collapsed;
3408
+ // emit event for view status change
3409
+ this.viewChange.emit(this.viewState);
3410
+ return [2 /*return*/];
3411
+ });
3412
+ });
3413
+ };
3414
+ AdvancedTableSearchComponent.decorators = [
3415
+ { type: i0.Component, args: [{
3416
+ // tslint:disable-next-line: component-selector
3417
+ selector: 'app-advanced-table-search',
3418
+ template: "<div class=\"s--list-navbar d-none d-sm-block\">\n\n <div id=\"collapse-header\" [ngClass]=\"{'show':collapsed}\" class=\"collapse multi-collapse\">\n <form class=\"form-inline p-3 col\">\n <div class=\"form-group col-7\" [ngClass]= \"{ 'col-12': !showMore }\">\n <label class=\"pr-3\" for=\"searchText\" [translate]=\"'Tables.Search'\"></label>\n <input (keydown)=\"onSearchKeyDown($event)\" spellcheck=\"false\" type=\"text\" id=\"searchText\" name=\"searchText\"\n class=\"form-control col text-left\" placeholder=\"{{ 'Tables.SearchPlaceholder' | translate }}\" #searchText>\n </div>\n <div *ngIf=\"showMore\" class=\"col-5 text-right text-secondary\" id=\"heading3\">\n <button class=\"d-inline-block btn btn-link collapsed float-right text-secondary text-decoration-none\"\n type=\"button\" (click)=\"toggleView();\">\n <span class=\"d-none d-sm-inline\" [translate]=\"'AdvancedSearch.More'\"></span>\n <i class=\"ml-2 pt-1 fa fa-chevron-down\"></i>\n </button>\n </div>\n </form>\n </div>\n\n <div id=\"collapse3\" [ngClass]=\"{'show':!collapsed}\" class=\"collapse multi-collapse\" aria-labelledby=\"heading3\">\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <div id=\"advanced-form\">\n <ng-content select=\"advanced-search\"></ng-content>\n <hr class=\"mt-0 mb-0\" width=\"97%\">\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <div class=\"form-inline pb-3 pt-3 pr-1 pl-1 col\">\n\n <div class=\"form-group col-4\">\n <div class=\"d-flex flex-row w-100\" *ngIf=\"allowSave\">\n <label class=\"pr-3 d-none\" [translate]=\"'AdvancedSearch.SavedSearches'\"></label>\n <select *ngIf=\"userSearchList\" class=\"custom-select text-secondary flex col-12\" (change)=\"onSelectUserSearch($event)\" [(ngModel)]=\"selectedList\">\n <option [ngValue]=\"null\" [translate]=\"'AdvancedSearch.Choose'\"></option>\n <option *ngFor=\"let item of userSearchList\" [ngValue]=\"item\">{{ item.name }}</option>\n </select>\n <select *ngIf=\"!userSearchList\" class=\"custom-select flex col-6\">\n <option [value]=\"null\" [translate]=\"'AdvancedSearch.Choose'\"></option>\n </select>\n </div>\n </div>\n\n <div class=\"col-3 d-flex flex-row w-100\">\n <div class=\"btn-group\" *ngIf=\"allowSave\">\n <button type=\"button\" class=\"btn btn-sm btn-primary\" (click)=\"saveSearch(templateToUse, ( (selectedList && selectedList.readOnly) ? true : false ) )\" [translate]=\"'AdvancedSearch.SaveCurrentSearch'\"></button>\n <button type=\"button\" dropdownToggle class=\"btn btn-sm btn-primary dropdown-toggle dropdown-toggle-split\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <span class=\"sr-only\" [translate]=\"'AdvancedSearch.ToggleDropdown'\"></span>\n </button>\n\n <div class=\"dropdown-menu\">\n <a [ngClass]=\"{'disabled': selectedList && selectedList.readOnly}\" class=\"dropdown-item\" (click)=\"saveSearch(templateToUse, false)\" [translate]=\"'AdvancedSearch.Save'\" href=\"javascript:void(0)\"></a>\n <a class=\"dropdown-item\" (click)=\"saveSearch(templateToUse)\" [translate]=\"'AdvancedSearch.SaveAs'\" href=\"javascript:void(0)\"></a>\n <div class=\"dropdown-divider\"></div>\n <a [ngClass]=\"{'disabled': selectedList && selectedList.readOnly}\" class=\"dropdown-item\" (click)=\"deleteItemFromSavedSearchListByObject(selectedList)\" [translate]=\"'AdvancedSearch.Delete'\" href=\"javascript:void(0)\"></a>\n </div>\n </div>\n </div>\n\n <div class=\"col-5 text-right text-secondary\">\n <button type=\"button\" class=\"btn btn-light text-secondary pl-2 pr-2 mr-2\" (click)=\"clear()\">\n <i class=\"fa fa-eraser\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-success pl-4 pr-4 mr-2\" (click)=\"advancedSearch($event);\"\n [translate]=\"'Tables.Search'\"></button>\n <button class=\"d-inline-block btn btn-link collapsed float-right text-secondary text-decoration-none\"\n type=\"button\" (click)=\"toggleView();\">\n <span class=\"d-none d-sm-inline\" [translate]=\"'AdvancedSearch.Less'\"></span>\n <i class=\"ml-2 pt-1 fa fa-chevron-up\"></i>\n </button>\n </div>\n\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #templateToUse>\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\" [translate]=\"'AdvancedSearch.Modal.Title'\"></h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"modalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body mt-0 mb-0 text-center\">\n <div>\n <p class=\"text-secondary text-left\" [translate]=\"'AdvancedSearch.Modal.Help'\"></p>\n </div>\n <form class=\"p-3 text-center\" #newListForm=\"ngForm\" >\n <div [ngVar]=\"{ name: ( selectedList?.name ? ( selectedList?.name + ' (1)' ) : null ) }\" #model=\"ngVar\">\n <input [(ngModel)]=\"model.value.name\" [required]=\"true\" id=\"newListName\" name=\"newListName\" type=\"text\" class=\"form-control\" placeholder=\"{{ 'AdvancedSearch.Modal.SaveNamePlaceholder' | translate }}\"/>\n <div class=\"btn-group mt-4\">\n <button [disabled]=\"newListForm.invalid\" type=\"button\" class=\"btn btn-primary\" (click)=\"confirmModal(model.value.name)\" [translate]=\"'AdvancedSearch.Modal.Accept'\"></button>\n <button type=\"button\" class=\"btn btn-gray-300 text-white\" (click)=\"closeModal()\" [translate]=\"'AdvancedSearch.Modal.Close'\"></button>\n </div>\n </div>\n </form>\n </div>\n </ng-template>\n\n</div>\n",
3419
+ encapsulation: i0.ViewEncapsulation.None
3420
+ }] }
3421
+ ];
3422
+ /** @nocollapse */
3423
+ AdvancedTableSearchComponent.ctorParameters = function () {
3424
+ return [
3425
+ { type: i1.AngularDataContext },
3426
+ { type: i1$1.ActivatedRoute },
3427
+ { type: common.DatePipe },
3428
+ { type: modal.BsModalService },
3429
+ { type: i2.UserStorageService },
3430
+ { type: core.TranslateService },
3431
+ { type: AdvancedFilterValueProvider },
3432
+ { type: i2.TemplatePipe },
3433
+ { type: i1$1.Router },
3434
+ { type: i2.ModalService }
3435
+ ];
3436
+ };
3437
+ AdvancedTableSearchComponent.propDecorators = {
3438
+ table: [{ type: i0.Input }],
3439
+ collapsed: [{ type: i0.Input }],
3440
+ allowSave: [{ type: i0.Input }],
3441
+ showMore: [{ type: i0.Input }],
3442
+ mergeQueryParams: [{ type: i0.Input }],
3443
+ searchText: [{ type: i0.ViewChild, args: ['searchText',] }],
3444
+ viewChange: [{ type: i0.Output, args: ['viewChange',] }]
3445
+ };
3446
+ return AdvancedTableSearchComponent;
3447
+ }(AdvancedTableSearchBaseComponent));
3448
+
3449
+ var FORMATTERS = {
3450
+ ActionLinkFormatter: new ActionLinkFormatter(),
3451
+ ButtonFormatter: new ButtonFormatter(),
3452
+ DateTimeFormatter: new DateTimeFormatter(),
3453
+ LanguageFormatter: new LanguageFormatter(),
3454
+ LinkFormatter: new LinkFormatter(),
3455
+ NestedPropertyFormatter: new NestedPropertyFormatter(),
3456
+ NgClassFormatter: new NgClassFormatter(),
3457
+ SelectRowFormatter: new SelectRowFormatter(),
3458
+ TemplateFormatter: new TemplateFormatter(),
3459
+ TranslationFormatter: new TranslationFormatter(),
3460
+ TrueFalseFormatter: new TrueFalseFormatter(),
3461
+ ActionButtonFormatter: new ActionButtonFormatter(),
3462
+ ActionSplitButtonFormatter: new ActionSplitButtonFormatter(),
3463
+ };
3464
+
3465
+ var SimpleHeaderToolsComponent = /** @class */ (function () {
3466
+ function SimpleHeaderToolsComponent() {
3467
+ }
3468
+ SimpleHeaderToolsComponent.decorators = [
3469
+ { type: i0.Component, args: [{
3470
+ selector: 'table-simple-header-tools',
3471
+ template: "\n <ng-content></ng-content>\n "
3472
+ }] }
3473
+ ];
3474
+ return SimpleHeaderToolsComponent;
3475
+ }());
3476
+ var TableSimpleHeaderComponent = /** @class */ (function () {
3477
+ function TableSimpleHeaderComponent() {
3478
+ }
3479
+ TableSimpleHeaderComponent.prototype.ngOnChanges = function (changes) {
3480
+ var _this = this;
3481
+ if (changes.table) {
3482
+ if (changes.table.currentValue == null) {
3483
+ if (this.dataLoadSubscription) {
3484
+ this.dataLoadSubscription.unsubscribe();
3485
+ return;
3486
+ }
3487
+ }
3488
+ if (changes.table.currentValue != changes.table.previousValue) {
3489
+ this.dataLoadSubscription = changes.table.currentValue.load.subscribe(function (data) {
3490
+ _this.recordsTotal = data.recordsTotal;
3491
+ });
3492
+ }
3493
+ }
3494
+ };
3495
+ TableSimpleHeaderComponent.prototype.ngOnDestroy = function () {
3496
+ if (this.dataLoadSubscription) {
3497
+ this.dataLoadSubscription.unsubscribe();
3498
+ }
3499
+ };
3500
+ TableSimpleHeaderComponent.prototype.ngOnInit = function () {
3501
+ //
3502
+ };
3503
+ TableSimpleHeaderComponent.decorators = [
3504
+ { type: i0.Component, args: [{
3505
+ selector: 'app-table-simple-header',
3506
+ template: "<div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 0\">\n <span>&nbsp;</span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-2\">\n <ng-content select=\"table-simple-header-tools\"></ng-content>\n </div>\n </div>\n</div>\n\n"
3507
+ }] }
3508
+ ];
3509
+ /** @nocollapse */
3510
+ TableSimpleHeaderComponent.ctorParameters = function () { return []; };
3511
+ TableSimpleHeaderComponent.propDecorators = {
3512
+ table: [{ type: i0.Input }]
3513
+ };
3514
+ return TableSimpleHeaderComponent;
3515
+ }());
3516
+
3517
+ var AdvancedTableNotNullError = /** @class */ (function (_super) {
3518
+ __extends(AdvancedTableNotNullError, _super);
3519
+ function AdvancedTableNotNullError() {
3520
+ return _super.call(this, 'Advanced table component cannot be empty at this context.') || this;
3521
+ }
3522
+ return AdvancedTableNotNullError;
3523
+ }(Error));
3524
+ var AdvancedTableEditorDirective = /** @class */ (function () {
3525
+ function AdvancedTableEditorDirective(table) {
3526
+ this.table = table;
3527
+ this.dirty = false;
3528
+ this.dirtyChange = new i0.EventEmitter(false);
3529
+ //
3530
+ }
3531
+ /**
3532
+ * Add rows to table and mark them as added rows
3533
+ */
3534
+ AdvancedTableEditorDirective.prototype.add = function () {
3535
+ var addItems = [];
3536
+ for (var _i = 0; _i < arguments.length; _i++) {
3537
+ addItems[_i] = arguments[_i];
3538
+ }
3539
+ var e_1, _a;
3540
+ if (this.table == null) {
3541
+ throw new AdvancedTableNotNullError();
3542
+ }
3543
+ // decorate items
3544
+ var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3545
+ try {
3546
+ for (var addItems_1 = __values(addItems), addItems_1_1 = addItems_1.next(); !addItems_1_1.done; addItems_1_1 = addItems_1.next()) {
3547
+ var element = addItems_1_1.value;
3548
+ var tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3549
+ if (tr.hasClass('removed')) {
3550
+ tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3551
+ }
3552
+ else {
3553
+ this.table.dataTable.rows.add([element]);
3554
+ tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3555
+ tr.toggleClass('added font-weight-bold text-success');
3556
+ }
3557
+ }
3558
+ }
3559
+ catch (e_1_1) {
3560
+ e_1 = { error: e_1_1 };
3561
+ }
3562
+ finally {
3563
+ try {
3564
+ if (addItems_1_1 && !addItems_1_1.done && (_a = addItems_1.return))
3565
+ _a.call(addItems_1);
3566
+ }
3567
+ finally {
3568
+ if (e_1)
3569
+ throw e_1.error;
3570
+ }
3571
+ }
3572
+ this.table.dataTable.draw();
3573
+ // find removed
3574
+ var removedLength = this.table.dataTable.rows('.removed')[0].length;
3575
+ // find added
3576
+ var addedLength = this.table.dataTable.rows('.added')[0].length;
3577
+ // and emit event
3578
+ var items = this.table.dataTable.rows().data();
3579
+ this.table.load.emit({
3580
+ data: items,
3581
+ recordsFiltered: items.length - removedLength,
3582
+ recordsTotal: items.length - removedLength,
3583
+ });
3584
+ this.dirty = (removedLength > 0 || addedLength > 0);
3585
+ this.dirtyChange.emit(this.dirty);
3586
+ };
3587
+ /**
3588
+ * Marks rows as removed rows
3589
+ */
3590
+ AdvancedTableEditorDirective.prototype.remove = function () {
3591
+ var removeItems = [];
3592
+ for (var _i = 0; _i < arguments.length; _i++) {
3593
+ removeItems[_i] = arguments[_i];
3594
+ }
3595
+ var e_2, _a;
3596
+ if (this.table == null) {
3597
+ throw new AdvancedTableNotNullError();
3598
+ }
3599
+ // get key
3600
+ var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3601
+ var _loop_1 = function (element) {
3602
+ var tr = this_1.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3603
+ // if row is marked as added
3604
+ if (tr.hasClass('added')) {
3605
+ // remove this dirty row
3606
+ this_1.table.dataTable.rows(tr).remove();
3607
+ }
3608
+ else {
3609
+ // otherwise unmarked row
3610
+ tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3611
+ }
3612
+ // check if item is selected
3613
+ var selectedIndex = this_1.table.selected.findIndex(function (item) {
3614
+ return item[key] === element[key];
3615
+ });
3616
+ // and remove it from selected collection
3617
+ if (selectedIndex >= 0) {
3618
+ this_1.table.selected.splice(selectedIndex, 1);
3619
+ }
3620
+ };
3621
+ var this_1 = this;
3622
+ try {
3623
+ // loop items
3624
+ for (var removeItems_1 = __values(removeItems), removeItems_1_1 = removeItems_1.next(); !removeItems_1_1.done; removeItems_1_1 = removeItems_1.next()) {
3625
+ var element = removeItems_1_1.value;
3626
+ _loop_1(element);
3627
+ }
3628
+ }
3629
+ catch (e_2_1) {
3630
+ e_2 = { error: e_2_1 };
3631
+ }
3632
+ finally {
3633
+ try {
3634
+ if (removeItems_1_1 && !removeItems_1_1.done && (_a = removeItems_1.return))
3635
+ _a.call(removeItems_1);
3636
+ }
3637
+ finally {
3638
+ if (e_2)
3639
+ throw e_2.error;
3640
+ }
3641
+ }
3642
+ // re-draw table
3643
+ this.table.dataTable.draw();
3644
+ // get number of table items
3645
+ var items = this.table.dataTable.rows().data();
3646
+ // get number of removed items
3647
+ var removedLength = this.table.dataTable.rows('.removed')[0].length;
3648
+ // get number of added items
3649
+ var addedLength = this.table.dataTable.rows('.added')[0].length;
3650
+ // refresh
3651
+ this.table.load.emit({
3652
+ data: items,
3653
+ recordsFiltered: items.length - removedLength,
3654
+ recordsTotal: items.length - removedLength,
3655
+ });
3656
+ this.dirty = (removedLength > 0 || addedLength > 0);
3657
+ this.dirtyChange.emit(this.dirty);
3658
+ };
3659
+ AdvancedTableEditorDirective.prototype.set = function (items) {
3660
+ if (this.table == null) {
3661
+ throw new AdvancedTableNotNullError();
3888
3662
  }
3663
+ // clear rows
3664
+ this.table.selected = [];
3665
+ this.table.dataTable.clear();
3666
+ // set items
3667
+ this.table.dataTable.rows.add(items).draw();
3668
+ this.table.load.emit({
3669
+ data: items,
3670
+ recordsFiltered: items.length,
3671
+ recordsTotal: items.length,
3672
+ });
3889
3673
  };
3890
- Object.defineProperty(AdvancedTableSearchComponent.prototype, "viewState", {
3891
- /**
3892
- * Gets the view state of search control
3893
- */
3894
- get: function () {
3895
- return {
3896
- advancedView: !this.collapsed,
3897
- };
3898
- },
3899
- enumerable: true,
3900
- configurable: true
3901
- });
3902
3674
  /**
3903
- * Switches view between simple and advanced search
3675
+ * Undo changes
3904
3676
  */
3905
- AdvancedTableSearchComponent.prototype.toggleView = function () {
3906
- return __awaiter(this, void 0, void 0, function () {
3907
- return __generator(this, function (_a) {
3908
- this.collapsed = !this.collapsed;
3909
- // emit event for view status change
3910
- this.viewChange.emit(this.viewState);
3911
- return [2 /*return*/];
3912
- });
3677
+ AdvancedTableEditorDirective.prototype.undo = function () {
3678
+ if (this.table == null) {
3679
+ throw new AdvancedTableNotNullError();
3680
+ }
3681
+ // reset removed rows
3682
+ this.table.dataTable.rows('.removed').nodes().to$().toggleClass('removed text-gray-400 text-decoration-line-through');
3683
+ // remove added rows
3684
+ this.table.dataTable.rows('.added').remove();
3685
+ // clear selected items
3686
+ this.table.selected = [];
3687
+ var items = this.table.dataTable.rows().data();
3688
+ this.table.dataTable.draw();
3689
+ this.table.load.emit({
3690
+ data: items,
3691
+ recordsFiltered: items.length,
3692
+ recordsTotal: items.length,
3913
3693
  });
3694
+ this.dirty = false;
3695
+ this.dirtyChange.emit(this.dirty);
3914
3696
  };
3915
- AdvancedTableSearchComponent.decorators = [
3916
- { type: i0.Component, args: [{
3917
- // tslint:disable-next-line: component-selector
3918
- selector: 'app-advanced-table-search',
3919
- template: "<div class=\"s--list-navbar d-none d-sm-block\">\n\n <div id=\"collapse-header\" [ngClass]=\"{'show':collapsed}\" class=\"collapse multi-collapse\">\n <form class=\"form-inline p-3 col\">\n <div class=\"form-group col-7\" [ngClass]= \"{ 'col-12': !showMore }\">\n <label class=\"pr-3\" for=\"searchText\" [translate]=\"'Tables.Search'\"></label>\n <input (keydown)=\"onSearchKeyDown($event)\" spellcheck=\"false\" type=\"text\" id=\"searchText\" name=\"searchText\"\n class=\"form-control col text-left\" placeholder=\"{{ 'Tables.SearchPlaceholder' | translate }}\" #searchText>\n </div>\n <div *ngIf=\"showMore\" class=\"col-5 text-right text-secondary\" id=\"heading3\">\n <button class=\"d-inline-block btn btn-link collapsed float-right text-secondary text-decoration-none\"\n type=\"button\" (click)=\"toggleView();\">\n <span class=\"d-none d-sm-inline\" [translate]=\"'AdvancedSearch.More'\"></span>\n <i class=\"ml-2 pt-1 fa fa-chevron-down\"></i>\n </button>\n </div>\n </form>\n </div>\n\n <div id=\"collapse3\" [ngClass]=\"{'show':!collapsed}\" class=\"collapse multi-collapse\" aria-labelledby=\"heading3\">\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <div id=\"advanced-form\">\n <ng-content select=\"advanced-search\"></ng-content>\n <hr class=\"mt-0 mb-0\" width=\"97%\">\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <div class=\"form-inline pb-3 pt-3 pr-1 pl-1 col\">\n\n <div class=\"form-group col-4\">\n <div class=\"d-flex flex-row w-100\" *ngIf=\"allowSave\">\n <label class=\"pr-3 d-none\" [translate]=\"'AdvancedSearch.SavedSearches'\"></label>\n <select *ngIf=\"userSearchList\" class=\"custom-select text-secondary flex col-12\" (change)=\"onSelectUserSearch($event)\" [(ngModel)]=\"selectedList\">\n <option [ngValue]=\"null\" [translate]=\"'AdvancedSearch.Choose'\"></option>\n <option *ngFor=\"let item of userSearchList\" [ngValue]=\"item\">{{ item.name }}</option>\n </select>\n <select *ngIf=\"!userSearchList\" class=\"custom-select flex col-6\">\n <option [value]=\"null\" [translate]=\"'AdvancedSearch.Choose'\"></option>\n </select>\n </div>\n </div>\n\n <div class=\"col-3 d-flex flex-row w-100\">\n <div class=\"btn-group\" *ngIf=\"allowSave\">\n <button type=\"button\" class=\"btn btn-sm btn-primary\" (click)=\"saveSearch(templateToUse, ( (selectedList && selectedList.readOnly) ? true : false ) )\" [translate]=\"'AdvancedSearch.SaveCurrentSearch'\"></button>\n <button type=\"button\" dropdownToggle class=\"btn btn-sm btn-primary dropdown-toggle dropdown-toggle-split\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <span class=\"sr-only\" [translate]=\"'AdvancedSearch.ToggleDropdown'\"></span>\n </button>\n\n <div class=\"dropdown-menu\">\n <a [ngClass]=\"{'disabled': selectedList && selectedList.readOnly}\" class=\"dropdown-item\" (click)=\"saveSearch(templateToUse, false)\" [translate]=\"'AdvancedSearch.Save'\" href=\"javascript:void(0)\"></a>\n <a class=\"dropdown-item\" (click)=\"saveSearch(templateToUse)\" [translate]=\"'AdvancedSearch.SaveAs'\" href=\"javascript:void(0)\"></a>\n <div class=\"dropdown-divider\"></div>\n <a [ngClass]=\"{'disabled': selectedList && selectedList.readOnly}\" class=\"dropdown-item\" (click)=\"deleteItemFromSavedSearchListByObject(selectedList)\" [translate]=\"'AdvancedSearch.Delete'\" href=\"javascript:void(0)\"></a>\n </div>\n </div>\n </div>\n\n <div class=\"col-5 text-right text-secondary\">\n <button type=\"button\" class=\"btn btn-light text-secondary pl-2 pr-2 mr-2\" (click)=\"clear()\">\n <i class=\"fa fa-eraser\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-success pl-4 pr-4 mr-2\" (click)=\"advancedSearch($event);\"\n [translate]=\"'Tables.Search'\"></button>\n <button class=\"d-inline-block btn btn-link collapsed float-right text-secondary text-decoration-none\"\n type=\"button\" (click)=\"toggleView();\">\n <span class=\"d-none d-sm-inline\" [translate]=\"'AdvancedSearch.Less'\"></span>\n <i class=\"ml-2 pt-1 fa fa-chevron-up\"></i>\n </button>\n </div>\n\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #templateToUse>\n <div class=\"modal-header\">\n <h4 class=\"modal-title pull-left\" [translate]=\"'AdvancedSearch.Modal.Title'\"></h4>\n <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"modalRef.hide()\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body mt-0 mb-0 text-center\">\n <div>\n <p class=\"text-secondary text-left\" [translate]=\"'AdvancedSearch.Modal.Help'\"></p>\n </div>\n <form class=\"p-3 text-center\" #newListForm=\"ngForm\" >\n <div [ngVar]=\"{ name: ( selectedList?.name ? ( selectedList?.name + ' (1)' ) : null ) }\" #model=\"ngVar\">\n <input [(ngModel)]=\"model.value.name\" [required]=\"true\" id=\"newListName\" name=\"newListName\" type=\"text\" class=\"form-control\" placeholder=\"{{ 'AdvancedSearch.Modal.SaveNamePlaceholder' | translate }}\"/>\n <div class=\"btn-group mt-4\">\n <button [disabled]=\"newListForm.invalid\" type=\"button\" class=\"btn btn-primary\" (click)=\"confirmModal(model.value.name)\" [translate]=\"'AdvancedSearch.Modal.Accept'\"></button>\n <button type=\"button\" class=\"btn btn-gray-300 text-white\" (click)=\"closeModal()\" [translate]=\"'AdvancedSearch.Modal.Close'\"></button>\n </div>\n </div>\n </form>\n </div>\n </ng-template>\n\n</div>\n",
3920
- encapsulation: i0.ViewEncapsulation.None
3921
- }] }
3697
+ AdvancedTableEditorDirective.prototype.rows = function () {
3698
+ if (this.table == null) {
3699
+ throw new AdvancedTableNotNullError();
3700
+ }
3701
+ return Array.from(this.table.dataTable.rows(':not(.removed)').data());
3702
+ };
3703
+ AdvancedTableEditorDirective.decorators = [
3704
+ { type: i0.Directive, args: [{
3705
+ // tslint:disable-next-line: directive-selector
3706
+ selector: '[tableEditor]',
3707
+ },] }
3922
3708
  ];
3923
3709
  /** @nocollapse */
3924
- AdvancedTableSearchComponent.ctorParameters = function () {
3710
+ AdvancedTableEditorDirective.ctorParameters = function () {
3925
3711
  return [
3926
- { type: i1.AngularDataContext },
3927
- { type: i1$1.ActivatedRoute },
3928
- { type: common.DatePipe },
3929
- { type: modal.BsModalService },
3930
- { type: i2.UserStorageService },
3931
- { type: core.TranslateService },
3932
- { type: AdvancedFilterValueProvider },
3933
- { type: i2.TemplatePipe },
3934
- { type: i1$1.Router },
3935
- { type: i2.ModalService }
3712
+ { type: AdvancedTableComponent }
3936
3713
  ];
3937
3714
  };
3938
- AdvancedTableSearchComponent.propDecorators = {
3939
- table: [{ type: i0.Input }],
3940
- collapsed: [{ type: i0.Input }],
3941
- allowSave: [{ type: i0.Input }],
3942
- showMore: [{ type: i0.Input }],
3943
- mergeQueryParams: [{ type: i0.Input }],
3944
- searchText: [{ type: i0.ViewChild, args: ['searchText',] }],
3945
- viewChange: [{ type: i0.Output, args: ['viewChange',] }]
3715
+ AdvancedTableEditorDirective.propDecorators = {
3716
+ dirtyChange: [{ type: i0.Output }]
3946
3717
  };
3947
- return AdvancedTableSearchComponent;
3948
- }(AdvancedTableSearchBaseComponent));
3949
-
3950
- var FORMATTERS = {
3951
- ActionLinkFormatter: new ActionLinkFormatter(),
3952
- ButtonFormatter: new ButtonFormatter(),
3953
- DateTimeFormatter: new DateTimeFormatter(),
3954
- LanguageFormatter: new LanguageFormatter(),
3955
- LinkFormatter: new LinkFormatter(),
3956
- NestedPropertyFormatter: new NestedPropertyFormatter(),
3957
- NgClassFormatter: new NgClassFormatter(),
3958
- SelectRowFormatter: new SelectRowFormatter(),
3959
- TemplateFormatter: new TemplateFormatter(),
3960
- TranslationFormatter: new TranslationFormatter(),
3961
- TrueFalseFormatter: new TrueFalseFormatter(),
3962
- ActionButtonFormatter: new ActionButtonFormatter(),
3963
- ActionSplitButtonFormatter: new ActionSplitButtonFormatter(),
3964
- };
3965
-
3966
- var SimpleHeaderToolsComponent = /** @class */ (function () {
3967
- function SimpleHeaderToolsComponent() {
3968
- }
3969
- SimpleHeaderToolsComponent.decorators = [
3970
- { type: i0.Component, args: [{
3971
- selector: 'table-simple-header-tools',
3972
- template: "\n <ng-content></ng-content>\n "
3973
- }] }
3974
- ];
3975
- return SimpleHeaderToolsComponent;
3718
+ return AdvancedTableEditorDirective;
3976
3719
  }());
3977
- var TableSimpleHeaderComponent = /** @class */ (function () {
3978
- function TableSimpleHeaderComponent() {
3720
+
3721
+ var MAX_EXPORT_ITEMS = 500;
3722
+ var BtnExpDirective = /** @class */ (function () {
3723
+ function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
3724
+ this._activatedTable = _activatedTable;
3725
+ this._context = _context;
3726
+ this._config = _config;
3727
+ this._translate = _translate;
3728
+ this._loadingService = _loadingService;
3729
+ this._errorService = _errorService;
3979
3730
  }
3980
- TableSimpleHeaderComponent.prototype.ngOnChanges = function (changes) {
3981
- var _this = this;
3982
- if (changes.table) {
3983
- if (changes.table.currentValue == null) {
3984
- if (this.dataLoadSubscription) {
3985
- this.dataLoadSubscription.unsubscribe();
3986
- return;
3731
+ BtnExpDirective.prototype.clickEvent = function (event) {
3732
+ return __awaiter(this, void 0, void 0, function () {
3733
+ var lastQuery, tableConfig, serviceHeaders, queryModel, query, queryParams, maxExportItems, url;
3734
+ return __generator(this, function (_a) {
3735
+ event.preventDefault();
3736
+ event.stopPropagation();
3737
+ if (this._activatedTable.activeTable) {
3738
+ lastQuery = this._activatedTable.activeTable.lastQuery;
3739
+ tableConfig = this._activatedTable.activeTable.config;
3740
+ serviceHeaders = this._context.getService().getHeaders();
3741
+ queryModel = lastQuery.getModel();
3742
+ query = this._context.model(queryModel).asQueryable();
3743
+ queryParams = lastQuery.getParams();
3744
+ query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
3745
+ maxExportItems = 1000;
3746
+ if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
3747
+ query.skip(0).take(maxExportItems);
3748
+ }
3749
+ else {
3750
+ query.skip(0).take(MAX_EXPORT_ITEMS);
3751
+ }
3752
+ url = this.constructURL(query);
3753
+ this.downloadFile(url, query.getService().getHeaders(), query.getModel());
3987
3754
  }
3988
- }
3989
- if (changes.table.currentValue != changes.table.previousValue) {
3990
- this.dataLoadSubscription = changes.table.currentValue.load.subscribe(function (data) {
3991
- _this.recordsTotal = data.recordsTotal;
3992
- });
3993
- }
3994
- }
3755
+ return [2 /*return*/];
3756
+ });
3757
+ });
3995
3758
  };
3996
- TableSimpleHeaderComponent.prototype.ngOnDestroy = function () {
3997
- if (this.dataLoadSubscription) {
3998
- this.dataLoadSubscription.unsubscribe();
3759
+ /**
3760
+ * Sets the parameters to the query based on
3761
+ * the active filters of the activated table
3762
+ * @param {ClientDataQueryable} query
3763
+ * @param params: The filters of the last query of the activated table
3764
+ * @return ClientDataQueryable
3765
+ */
3766
+ BtnExpDirective.prototype.setParams = function (query, params) {
3767
+ if (params && typeof params === 'object') {
3768
+ Object.keys(params).forEach(function (key) {
3769
+ query.setParam(key, params[key]);
3770
+ });
3999
3771
  }
3772
+ return query;
4000
3773
  };
4001
- TableSimpleHeaderComponent.prototype.ngOnInit = function () {
4002
- //
4003
- };
4004
- TableSimpleHeaderComponent.decorators = [
4005
- { type: i0.Component, args: [{
4006
- selector: 'app-table-simple-header',
4007
- template: "<div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 0\">\n <span>&nbsp;</span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-2\">\n <ng-content select=\"table-simple-header-tools\"></ng-content>\n </div>\n </div>\n</div>\n\n"
4008
- }] }
4009
- ];
4010
- /** @nocollapse */
4011
- TableSimpleHeaderComponent.ctorParameters = function () { return []; };
4012
- TableSimpleHeaderComponent.propDecorators = {
4013
- table: [{ type: i0.Input }]
3774
+ /**
3775
+ * Sets the headers to the query based on
3776
+ * the default headers of the DataContext
3777
+ * and appending the accept header to get
3778
+ * an xlsx file from the API
3779
+ * @param {ClientDataQueryable} query
3780
+ * @param {Headers} headers: The headers to append to the query
3781
+ * @return ClientDataQueryable
3782
+ */
3783
+ BtnExpDirective.prototype.setHeaders = function (query, headers) {
3784
+ Object.keys(headers).forEach(function (key) {
3785
+ if (headers.hasOwnProperty(key)) {
3786
+ query.getService().setHeader(key, headers[key]);
3787
+ }
3788
+ });
3789
+ // sets a header to accept xlsx files
3790
+ query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
3791
+ return query;
4014
3792
  };
4015
- return TableSimpleHeaderComponent;
4016
- }());
4017
-
4018
- var AdvancedTableNotNullError = /** @class */ (function (_super) {
4019
- __extends(AdvancedTableNotNullError, _super);
4020
- function AdvancedTableNotNullError() {
4021
- return _super.call(this, 'Advanced table component cannot be empty at this context.') || this;
4022
- }
4023
- return AdvancedTableNotNullError;
4024
- }(Error));
4025
- var AdvancedTableEditorDirective = /** @class */ (function () {
4026
- function AdvancedTableEditorDirective(table) {
4027
- this.table = table;
4028
- this.dirty = false;
4029
- this.dirtyChange = new i0.EventEmitter(false);
4030
- //
4031
- }
4032
3793
  /**
4033
- * Add rows to table and mark them as added rows
3794
+ * Constructs the select parameter of the
3795
+ * ClientDataQuery by replacing the target name
3796
+ * of the field based on the localized translation
3797
+ * of that property on the advanced tabled
3798
+ * @param {ClientDataQueryable} query
3799
+ * @param tableConfig: The configuration of the activated table
3800
+ * @return ClientDataQueryable
4034
3801
  */
4035
- AdvancedTableEditorDirective.prototype.add = function () {
4036
- var addItems = [];
4037
- for (var _i = 0; _i < arguments.length; _i++) {
4038
- addItems[_i] = arguments[_i];
4039
- }
4040
- var e_1, _a;
4041
- if (this.table == null) {
4042
- throw new AdvancedTableNotNullError();
4043
- }
4044
- // decorate items
4045
- var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
4046
- try {
4047
- for (var addItems_1 = __values(addItems), addItems_1_1 = addItems_1.next(); !addItems_1_1.done; addItems_1_1 = addItems_1.next()) {
4048
- var element = addItems_1_1.value;
4049
- var tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
4050
- if (tr.hasClass('removed')) {
4051
- tr.toggleClass('removed text-gray-400 text-decoration-line-through');
4052
- }
4053
- else {
4054
- this.table.dataTable.rows.add([element]);
4055
- tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
4056
- tr.toggleClass('added font-weight-bold text-success');
3802
+ BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
3803
+ var _this = this;
3804
+ var selectQuery = query.getParams().$select;
3805
+ var selectQueryArray = selectQuery.split(',');
3806
+ selectQueryArray = selectQueryArray.map(function (select) {
3807
+ var e_1, _a, e_2, _b;
3808
+ var words = select.split(' ');
3809
+ if (words.length === 3) {
3810
+ if (tableConfig && tableConfig.columns) {
3811
+ try {
3812
+ for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
3813
+ var column = _d.value;
3814
+ if (column.property === words[2] && column.title) {
3815
+ words[2] = "\"" + _this._translate.instant(column.title) + "\"";
3816
+ }
3817
+ else if (column.property === words[2]) {
3818
+ words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
3819
+ }
3820
+ }
3821
+ }
3822
+ catch (e_1_1) {
3823
+ e_1 = { error: e_1_1 };
3824
+ }
3825
+ finally {
3826
+ try {
3827
+ if (_d && !_d.done && (_a = _c.return))
3828
+ _a.call(_c);
3829
+ }
3830
+ finally {
3831
+ if (e_1)
3832
+ throw e_1.error;
3833
+ }
3834
+ }
4057
3835
  }
4058
3836
  }
4059
- }
4060
- catch (e_1_1) {
4061
- e_1 = { error: e_1_1 };
4062
- }
4063
- finally {
4064
- try {
4065
- if (addItems_1_1 && !addItems_1_1.done && (_a = addItems_1.return))
4066
- _a.call(addItems_1);
4067
- }
4068
- finally {
4069
- if (e_1)
4070
- throw e_1.error;
3837
+ if (words.length === 1) {
3838
+ if (tableConfig && tableConfig.columns) {
3839
+ try {
3840
+ for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
3841
+ var column = _f.value;
3842
+ if (column.name === words[0] && column.title) {
3843
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
3844
+ break;
3845
+ }
3846
+ else if (column.name === words[0] && column.property) {
3847
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
3848
+ break;
3849
+ }
3850
+ else if (words[0] === column.name && words[0] === "id" && column.hidden) {
3851
+ break;
3852
+ }
3853
+ else if (words[0] == column.name || words[0] === column.property) {
3854
+ words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
3855
+ }
3856
+ }
3857
+ }
3858
+ catch (e_2_1) {
3859
+ e_2 = { error: e_2_1 };
3860
+ }
3861
+ finally {
3862
+ try {
3863
+ if (_f && !_f.done && (_b = _e.return))
3864
+ _b.call(_e);
3865
+ }
3866
+ finally {
3867
+ if (e_2)
3868
+ throw e_2.error;
3869
+ }
3870
+ }
3871
+ }
3872
+ return words[0];
4071
3873
  }
4072
- }
4073
- this.table.dataTable.draw();
4074
- // find removed
4075
- var removedLength = this.table.dataTable.rows('.removed')[0].length;
4076
- // find added
4077
- var addedLength = this.table.dataTable.rows('.added')[0].length;
4078
- // and emit event
4079
- var items = this.table.dataTable.rows().data();
4080
- this.table.load.emit({
4081
- data: items,
4082
- recordsFiltered: items.length - removedLength,
4083
- recordsTotal: items.length - removedLength,
3874
+ return words.join(' ');
4084
3875
  });
4085
- this.dirty = (removedLength > 0 || addedLength > 0);
4086
- this.dirtyChange.emit(this.dirty);
3876
+ selectQuery = selectQueryArray.join(',');
3877
+ query.setParam('$select', selectQuery);
3878
+ return query;
4087
3879
  };
4088
3880
  /**
4089
- * Marks rows as removed rows
3881
+ * Constructs the fetch URL based the query parameters
3882
+ * @param {ClientDataQueryable} query
3883
+ * @return String
4090
3884
  */
4091
- AdvancedTableEditorDirective.prototype.remove = function () {
4092
- var removeItems = [];
4093
- for (var _i = 0; _i < arguments.length; _i++) {
4094
- removeItems[_i] = arguments[_i];
4095
- }
4096
- var e_2, _a;
4097
- if (this.table == null) {
4098
- throw new AdvancedTableNotNullError();
4099
- }
4100
- // get key
4101
- var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
4102
- var _loop_1 = function (element) {
4103
- var tr = this_1.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
4104
- // if row is marked as added
4105
- if (tr.hasClass('added')) {
4106
- // remove this dirty row
4107
- this_1.table.dataTable.rows(tr).remove();
3885
+ BtnExpDirective.prototype.constructURL = function (query) {
3886
+ var baseURL = query.getService().getBase();
3887
+ var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
3888
+ Object.keys(query.getParams()).forEach(function (key, index) {
3889
+ if (index === 0) {
3890
+ url += key + '=' + query.getParams()[key];
4108
3891
  }
4109
3892
  else {
4110
- // otherwise unmarked row
4111
- tr.toggleClass('removed text-gray-400 text-decoration-line-through');
4112
- }
4113
- // check if item is selected
4114
- var selectedIndex = this_1.table.selected.findIndex(function (item) {
4115
- return item[key] === element[key];
4116
- });
4117
- // and remove it from selected collection
4118
- if (selectedIndex >= 0) {
4119
- this_1.table.selected.splice(selectedIndex, 1);
4120
- }
4121
- };
4122
- var this_1 = this;
4123
- try {
4124
- // loop items
4125
- for (var removeItems_1 = __values(removeItems), removeItems_1_1 = removeItems_1.next(); !removeItems_1_1.done; removeItems_1_1 = removeItems_1.next()) {
4126
- var element = removeItems_1_1.value;
4127
- _loop_1(element);
4128
- }
4129
- }
4130
- catch (e_2_1) {
4131
- e_2 = { error: e_2_1 };
4132
- }
4133
- finally {
4134
- try {
4135
- if (removeItems_1_1 && !removeItems_1_1.done && (_a = removeItems_1.return))
4136
- _a.call(removeItems_1);
3893
+ url += '&' + key + '=' + query.getParams()[key];
4137
3894
  }
4138
- finally {
4139
- if (e_2)
4140
- throw e_2.error;
3895
+ });
3896
+ return url;
3897
+ };
3898
+ /**
3899
+ * Constructs the query by setting the parameters of the
3900
+ * advanced table's active filters, sets the necessary headers
3901
+ * and build the select parameter of the query
3902
+ * @param {ClientDataQueryable} query
3903
+ * @param params: The filters of the last query of the activated table
3904
+ * @param tableConfig: The configuration of the activated table
3905
+ * @param {Headers} headers: The headers to append to the query
3906
+ * @return ClientDataQueryable
3907
+ */
3908
+ BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
3909
+ var _query = this.setParams(query, params);
3910
+ _query = this.setHeaders(_query, headers);
3911
+ _query = this.constructQueryParam(_query, tableConfig);
3912
+ return _query;
3913
+ };
3914
+ /**
3915
+ * Fetches and saves the xlsx file
3916
+ * @param {String} url
3917
+ * @param {Headers} serviceHeaders: The headers to append to the query
3918
+ * @param modelName: The model name of the advanced table
3919
+ */
3920
+ BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
3921
+ var _this = this;
3922
+ this._loadingService.showLoading();
3923
+ fetch(encodeURI(url), {
3924
+ headers: serviceHeaders,
3925
+ credentials: 'include'
3926
+ }).then(function (response) {
3927
+ if (response && !response.ok) {
3928
+ throw new client.ResponseError(response.statusText, response.status);
4141
3929
  }
4142
- }
4143
- // re-draw table
4144
- this.table.dataTable.draw();
4145
- // get number of table items
4146
- var items = this.table.dataTable.rows().data();
4147
- // get number of removed items
4148
- var removedLength = this.table.dataTable.rows('.removed')[0].length;
4149
- // get number of added items
4150
- var addedLength = this.table.dataTable.rows('.added')[0].length;
4151
- // refresh
4152
- this.table.load.emit({
4153
- data: items,
4154
- recordsFiltered: items.length - removedLength,
4155
- recordsTotal: items.length - removedLength,
3930
+ return response.blob();
3931
+ }).then(function (blob) {
3932
+ var objectUrl = window.URL.createObjectURL(blob);
3933
+ var a = document.createElement('a');
3934
+ document.body.appendChild(a);
3935
+ a.setAttribute('style', 'display: none');
3936
+ a.href = objectUrl;
3937
+ var downloadName = modelName + ".xlsx";
3938
+ a.download = downloadName;
3939
+ // this adds support for IE and MS Edge (up to version 44.19041)
3940
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
3941
+ window.navigator.msSaveOrOpenBlob(blob, downloadName);
3942
+ }
3943
+ else {
3944
+ // for all other browsers
3945
+ a.click();
3946
+ }
3947
+ window.URL.revokeObjectURL(objectUrl);
3948
+ a.remove();
3949
+ _this._loadingService.hideLoading();
3950
+ }).catch(function (err) {
3951
+ _this._loadingService.hideLoading();
3952
+ _this._errorService.showError(err, {
3953
+ continueLink: '.'
3954
+ });
4156
3955
  });
4157
- this.dirty = (removedLength > 0 || addedLength > 0);
4158
- this.dirtyChange.emit(this.dirty);
4159
3956
  };
4160
- AdvancedTableEditorDirective.prototype.set = function (items) {
4161
- if (this.table == null) {
4162
- throw new AdvancedTableNotNullError();
4163
- }
4164
- // clear rows
4165
- this.table.selected = [];
4166
- this.table.dataTable.clear();
4167
- // set items
4168
- this.table.dataTable.rows.add(items).draw();
4169
- this.table.load.emit({
4170
- data: items,
4171
- recordsFiltered: items.length,
4172
- recordsTotal: items.length,
4173
- });
3957
+ BtnExpDirective.decorators = [
3958
+ { type: i0.Directive, args: [{
3959
+ selector: '.universis-btn-export'
3960
+ },] }
3961
+ ];
3962
+ /** @nocollapse */
3963
+ BtnExpDirective.ctorParameters = function () {
3964
+ return [
3965
+ { type: ActivatedTableService },
3966
+ { type: i1.AngularDataContext },
3967
+ { type: i2.ConfigurationService },
3968
+ { type: core.TranslateService },
3969
+ { type: i2.LoadingService },
3970
+ { type: i2.ErrorService }
3971
+ ];
4174
3972
  };
3973
+ BtnExpDirective.propDecorators = {
3974
+ clickEvent: [{ type: i0.HostListener, args: ['click', ['$event'],] }]
3975
+ };
3976
+ return BtnExpDirective;
3977
+ }());
3978
+
3979
+ var AdvancedAggregatorService = /** @class */ (function () {
3980
+ function AdvancedAggregatorService(_context, _template) {
3981
+ this._context = _context;
3982
+ this._template = _template;
3983
+ }
4175
3984
  /**
4176
- * Undo changes
3985
+ *
3986
+ * Formats and executes the data query
3987
+ *
3988
+ * @param {string} model The target model
3989
+ * @param {object} fixedParams Pairs of parameters to always be applied
3990
+ * @param {string} queryStatement The default query to use for fetching the data (e.g. expands etc)
3991
+ * @param {Array<string>} filters A list of filter expressions to append at the query
3992
+ * @param {string} searchTemplate The template to use for searching expressions
3993
+ * @param {string} searchValue The value of the user search
3994
+ *
3995
+ * @returns {Promise<any>} The response of the query execution
4177
3996
  */
4178
- AdvancedTableEditorDirective.prototype.undo = function () {
4179
- if (this.table == null) {
4180
- throw new AdvancedTableNotNullError();
3997
+ AdvancedAggregatorService.prototype.fetchData = function (model, fixedParams, queryStatement, filters, searchTemplate, searchValue) {
3998
+ if (queryStatement === void 0) {
3999
+ queryStatement = '';
4181
4000
  }
4182
- // reset removed rows
4183
- this.table.dataTable.rows('.removed').nodes().to$().toggleClass('removed text-gray-400 text-decoration-line-through');
4184
- // remove added rows
4185
- this.table.dataTable.rows('.added').remove();
4186
- // clear selected items
4187
- this.table.selected = [];
4188
- var items = this.table.dataTable.rows().data();
4189
- this.table.dataTable.draw();
4190
- this.table.load.emit({
4191
- data: items,
4192
- recordsFiltered: items.length,
4193
- recordsTotal: items.length,
4001
+ return __awaiter(this, void 0, void 0, function () {
4002
+ var e_1, _a, query, filterExpressions, _b, _c, param, evaluatedSearch, words;
4003
+ var _this = this;
4004
+ return __generator(this, function (_d) {
4005
+ query = this._context.model(model).asQueryable();
4006
+ if (!fixedParams || typeof fixedParams !== 'object') {
4007
+ fixedParams = {};
4008
+ }
4009
+ filterExpressions = [];
4010
+ if (fixedParams) {
4011
+ try {
4012
+ for (_b = __values(Object.keys(fixedParams)), _c = _b.next(); !_c.done; _c = _b.next()) {
4013
+ param = _c.value;
4014
+ filterExpressions.push(param + " eq " + fixedParams[param]);
4015
+ }
4016
+ }
4017
+ catch (e_1_1) {
4018
+ e_1 = { error: e_1_1 };
4019
+ }
4020
+ finally {
4021
+ try {
4022
+ if (_c && !_c.done && (_a = _b.return))
4023
+ _a.call(_b);
4024
+ }
4025
+ finally {
4026
+ if (e_1)
4027
+ throw e_1.error;
4028
+ }
4029
+ }
4030
+ }
4031
+ if (filters && Array.isArray(filters)) {
4032
+ filterExpressions = __spread(filterExpressions, filters);
4033
+ }
4034
+ if (searchTemplate && searchValue) {
4035
+ evaluatedSearch = void 0;
4036
+ if (/^"(.*?)"$/.test(searchValue)) { // validate search text in double quotes
4037
+ evaluatedSearch = this._template.transform(searchTemplate, __assign({}, fixedParams, { text: searchValue.replace(/^"|"$/g, '') }));
4038
+ }
4039
+ else {
4040
+ words = searchValue.split(' ');
4041
+ // join words to a single filter
4042
+ evaluatedSearch = words.map(function (word) {
4043
+ return _this._template.transform(searchTemplate, __assign({}, fixedParams, { text: word }));
4044
+ }).join(' and ');
4045
+ }
4046
+ filterExpressions.push(evaluatedSearch);
4047
+ }
4048
+ query.setParam('$filter', filterExpressions.join('and'));
4049
+ return [2 /*return*/, query.expand(queryStatement).take(-1).getItems()];
4050
+ });
4194
4051
  });
4195
- this.dirty = false;
4196
- this.dirtyChange.emit(this.dirty);
4197
4052
  };
4198
- AdvancedTableEditorDirective.prototype.rows = function () {
4199
- if (this.table == null) {
4200
- throw new AdvancedTableNotNullError();
4053
+ /**
4054
+ *
4055
+ * Formats the received data to use flat keys
4056
+ *
4057
+ * @param config The applied configuration
4058
+ * @param data The raw data
4059
+ *
4060
+ * @returns {Array<any>} The flat-key object list
4061
+ *
4062
+ */
4063
+ AdvancedAggregatorService.prototype.formatData = function (config, data) {
4064
+ var _this = this;
4065
+ try {
4066
+ return data.map(function (entry) {
4067
+ if (entry.subitems && Array.isArray(entry.subitems)) {
4068
+ entry.subitems = _this.formatData(config, entry.subitems);
4069
+ }
4070
+ var entryObject = {};
4071
+ for (var i = 0; i < config.columns.length; i++) {
4072
+ var keys = config.columns[i].name.split('/');
4073
+ var helperObject = entry[keys[0]];
4074
+ if (helperObject && keys.length > 1) {
4075
+ for (var i_1 = 1; i_1 < keys.length; i_1++) {
4076
+ if (helperObject === undefined || helperObject === null) {
4077
+ break;
4078
+ }
4079
+ else {
4080
+ helperObject = helperObject[keys[i_1]] !== undefined && helperObject[keys[i_1]] !== null
4081
+ ? helperObject[keys[i_1]]
4082
+ : undefined;
4083
+ }
4084
+ }
4085
+ }
4086
+ entryObject[config.columns[i].name] = helperObject;
4087
+ }
4088
+ if (entry.subitems) {
4089
+ entryObject.subitems = entry.subitems;
4090
+ }
4091
+ return entryObject;
4092
+ });
4093
+ }
4094
+ catch (err) {
4095
+ console.error(err);
4201
4096
  }
4202
- return Array.from(this.table.dataTable.rows(':not(.removed)').data());
4203
4097
  };
4204
- AdvancedTableEditorDirective.decorators = [
4205
- { type: i0.Directive, args: [{
4206
- // tslint:disable-next-line: directive-selector
4207
- selector: '[tableEditor]',
4098
+ AdvancedAggregatorService.decorators = [
4099
+ { type: i0.Injectable, args: [{
4100
+ providedIn: 'root'
4208
4101
  },] }
4209
4102
  ];
4210
4103
  /** @nocollapse */
4211
- AdvancedTableEditorDirective.ctorParameters = function () {
4104
+ AdvancedAggregatorService.ctorParameters = function () {
4212
4105
  return [
4213
- { type: AdvancedTableComponent }
4106
+ { type: i1.AngularDataContext },
4107
+ { type: i2.TemplatePipe }
4214
4108
  ];
4215
4109
  };
4216
- AdvancedTableEditorDirective.propDecorators = {
4217
- dirtyChange: [{ type: i0.Output }]
4218
- };
4219
- return AdvancedTableEditorDirective;
4110
+ AdvancedAggregatorService.ngInjectableDef = i0.defineInjectable({ factory: function AdvancedAggregatorService_Factory() { return new AdvancedAggregatorService(i0.inject(i1.AngularDataContext), i0.inject(i2.TemplatePipe)); }, token: AdvancedAggregatorService, providedIn: "root" });
4111
+ return AdvancedAggregatorService;
4220
4112
  }());
4221
4113
 
4222
- var MAX_EXPORT_ITEMS = 500;
4223
- var BtnExpDirective = /** @class */ (function () {
4224
- function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
4225
- this._activatedTable = _activatedTable;
4226
- this._context = _context;
4227
- this._config = _config;
4228
- this._translate = _translate;
4114
+ /**
4115
+ *
4116
+ * @class AdvancedAggregatorComponent
4117
+ * @classdesc An advanced list with the capability of aggregate data based on configurable filters
4118
+ *
4119
+ */
4120
+ var AdvancedAggregatorComponent = /** @class */ (function () {
4121
+ function AdvancedAggregatorComponent(_changeDetector, _advancedAggregatorService, _loadingService) {
4122
+ this._changeDetector = _changeDetector;
4123
+ this._advancedAggregatorService = _advancedAggregatorService;
4229
4124
  this._loadingService = _loadingService;
4230
- this._errorService = _errorService;
4125
+ this.groups = [];
4126
+ this.eventHandler = new i0.EventEmitter();
4231
4127
  }
4232
- BtnExpDirective.prototype.clickEvent = function (event) {
4128
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "config", {
4129
+ get: function () {
4130
+ return this._config;
4131
+ },
4132
+ set: function (value) {
4133
+ this._config = value;
4134
+ },
4135
+ enumerable: true,
4136
+ configurable: true
4137
+ });
4138
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "aggregators", {
4139
+ get: function () {
4140
+ return this._aggregators;
4141
+ },
4142
+ set: function (value) {
4143
+ this._aggregators = value;
4144
+ },
4145
+ enumerable: true,
4146
+ configurable: true
4147
+ });
4148
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "postProcessors", {
4149
+ get: function () {
4150
+ return this._postProcessors;
4151
+ },
4152
+ set: function (value) {
4153
+ this._postProcessors = value;
4154
+ },
4155
+ enumerable: true,
4156
+ configurable: true
4157
+ });
4158
+ AdvancedAggregatorComponent.prototype.ngOnInit = function () {
4233
4159
  return __awaiter(this, void 0, void 0, function () {
4234
- var lastQuery, tableConfig, serviceHeaders, queryModel, query, queryParams, maxExportItems, url;
4160
+ var _this = this;
4235
4161
  return __generator(this, function (_a) {
4236
- event.preventDefault();
4237
- event.stopPropagation();
4238
- if (this._activatedTable.activeTable) {
4239
- lastQuery = this._activatedTable.activeTable.lastQuery;
4240
- tableConfig = this._activatedTable.activeTable.config;
4241
- serviceHeaders = this._context.getService().getHeaders();
4242
- queryModel = lastQuery.getModel();
4243
- query = this._context.model(queryModel).asQueryable();
4244
- queryParams = lastQuery.getParams();
4245
- query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
4246
- maxExportItems = 1000;
4247
- if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
4248
- query.skip(0).take(maxExportItems);
4249
- }
4250
- else {
4251
- query.skip(0).take(MAX_EXPORT_ITEMS);
4252
- }
4253
- url = this.constructURL(query);
4254
- this.downloadFile(url, query.getService().getHeaders(), query.getModel());
4255
- }
4162
+ this.selectedGroups$.subscribe(function (data) {
4163
+ _this.groups = data;
4164
+ _this._changeDetector.markForCheck();
4165
+ });
4166
+ this.filters$.subscribe(function (filters) {
4167
+ return __awaiter(_this, void 0, void 0, function () {
4168
+ var err_1;
4169
+ return __generator(this, function (_a) {
4170
+ switch (_a.label) {
4171
+ case 0:
4172
+ _a.trys.push([0, 2, , 3]);
4173
+ return [4 /*yield*/, this.fetch(filters)];
4174
+ case 1:
4175
+ _a.sent();
4176
+ return [3 /*break*/, 3];
4177
+ case 2:
4178
+ err_1 = _a.sent();
4179
+ console.error(err_1);
4180
+ return [3 /*break*/, 3];
4181
+ case 3: return [2 /*return*/];
4182
+ }
4183
+ });
4184
+ });
4185
+ });
4256
4186
  return [2 /*return*/];
4257
4187
  });
4258
4188
  });
4259
4189
  };
4260
- /**
4261
- * Sets the parameters to the query based on
4262
- * the active filters of the activated table
4263
- * @param {ClientDataQueryable} query
4264
- * @param params: The filters of the last query of the activated table
4265
- * @return ClientDataQueryable
4266
- */
4267
- BtnExpDirective.prototype.setParams = function (query, params) {
4268
- if (params && typeof params === 'object') {
4269
- Object.keys(params).forEach(function (key) {
4270
- query.setParam(key, params[key]);
4190
+ AdvancedAggregatorComponent.prototype.ngOnDestroy = function () {
4191
+ return __awaiter(this, void 0, void 0, function () {
4192
+ return __generator(this, function (_a) {
4193
+ this.selectedGroups$.unsubscribe();
4194
+ this.filters$.unsubscribe();
4195
+ return [2 /*return*/];
4271
4196
  });
4272
- }
4273
- return query;
4197
+ });
4274
4198
  };
4275
4199
  /**
4276
- * Sets the headers to the query based on
4277
- * the default headers of the DataContext
4278
- * and appending the accept header to get
4279
- * an xlsx file from the API
4280
- * @param {ClientDataQueryable} query
4281
- * @param {Headers} headers: The headers to append to the query
4282
- * @return ClientDataQueryable
4200
+ *
4201
+ * Retrieves the data
4202
+ *
4283
4203
  */
4284
- BtnExpDirective.prototype.setHeaders = function (query, headers) {
4285
- Object.keys(headers).forEach(function (key) {
4286
- if (headers.hasOwnProperty(key)) {
4287
- query.getService().setHeader(key, headers[key]);
4288
- }
4204
+ AdvancedAggregatorComponent.prototype.fetch = function (filters) {
4205
+ return __awaiter(this, void 0, void 0, function () {
4206
+ var data, i, err_2;
4207
+ return __generator(this, function (_a) {
4208
+ switch (_a.label) {
4209
+ case 0:
4210
+ _a.trys.push([0, 6, 7, 8]);
4211
+ this._loadingService.showLoading();
4212
+ return [4 /*yield*/, this._advancedAggregatorService.fetchData(this.config.model, this.params, this.config.query, filters.filters, this.searchExpression, filters.text)];
4213
+ case 1:
4214
+ data = _a.sent();
4215
+ if (!(this.postProcessors && Object.keys(this.postProcessors).length > 0 && this.config.postProcessors && this.config.postProcessors.length > 0))
4216
+ return [3 /*break*/, 5];
4217
+ i = 0;
4218
+ _a.label = 2;
4219
+ case 2:
4220
+ if (!(i < this.config.postProcessors.length))
4221
+ return [3 /*break*/, 5];
4222
+ return [4 /*yield*/, this.postProcessors[this.config.postProcessors[i].name](data)];
4223
+ case 3:
4224
+ data = _a.sent();
4225
+ _a.label = 4;
4226
+ case 4:
4227
+ i++;
4228
+ return [3 /*break*/, 2];
4229
+ case 5:
4230
+ this.body = this._advancedAggregatorService.formatData(this.config, data);
4231
+ this._changeDetector.markForCheck();
4232
+ return [3 /*break*/, 8];
4233
+ case 6:
4234
+ err_2 = _a.sent();
4235
+ console.error(err_2);
4236
+ return [3 /*break*/, 8];
4237
+ case 7:
4238
+ this._loadingService.hideLoading();
4239
+ return [7 /*endfinally*/];
4240
+ case 8: return [2 /*return*/];
4241
+ }
4242
+ });
4289
4243
  });
4290
- // sets a header to accept xlsx files
4291
- query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
4292
- return query;
4293
4244
  };
4294
4245
  /**
4295
- * Constructs the select parameter of the
4296
- * ClientDataQuery by replacing the target name
4297
- * of the field based on the localized translation
4298
- * of that property on the advanced tabled
4299
- * @param {ClientDataQueryable} query
4300
- * @param tableConfig: The configuration of the activated table
4301
- * @return ClientDataQueryable
4246
+ *
4247
+ * Triggers the event handler event
4248
+ *
4249
+ * @param {*} event The event data
4250
+ *
4302
4251
  */
4303
- BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
4304
- var _this = this;
4305
- var selectQuery = query.getParams().$select;
4306
- var selectQueryArray = selectQuery.split(',');
4307
- selectQueryArray = selectQueryArray.map(function (select) {
4308
- var e_1, _a, e_2, _b;
4309
- var words = select.split(' ');
4310
- if (words.length === 3) {
4311
- if (tableConfig && tableConfig.columns) {
4312
- try {
4313
- for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
4314
- var column = _d.value;
4315
- if (column.property === words[2] && column.title) {
4316
- words[2] = "\"" + _this._translate.instant(column.title) + "\"";
4317
- }
4318
- else if (column.property === words[2]) {
4319
- words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
4320
- }
4321
- }
4322
- }
4323
- catch (e_1_1) {
4324
- e_1 = { error: e_1_1 };
4325
- }
4326
- finally {
4327
- try {
4328
- if (_d && !_d.done && (_a = _c.return))
4329
- _a.call(_c);
4330
- }
4331
- finally {
4332
- if (e_1)
4333
- throw e_1.error;
4334
- }
4335
- }
4336
- }
4337
- }
4338
- if (words.length === 1) {
4339
- if (tableConfig && tableConfig.columns) {
4340
- try {
4341
- for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
4342
- var column = _f.value;
4343
- if (column.name === words[0] && column.title) {
4344
- words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
4345
- break;
4346
- }
4347
- else if (column.name === words[0] && column.property) {
4348
- words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
4349
- break;
4350
- }
4351
- else if (words[0] === column.name && words[0] === "id" && column.hidden) {
4352
- break;
4353
- }
4354
- else if (words[0] == column.name || words[0] === column.property) {
4355
- words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
4356
- }
4357
- }
4358
- }
4359
- catch (e_2_1) {
4360
- e_2 = { error: e_2_1 };
4361
- }
4362
- finally {
4363
- try {
4364
- if (_f && !_f.done && (_b = _e.return))
4365
- _b.call(_e);
4366
- }
4367
- finally {
4368
- if (e_2)
4369
- throw e_2.error;
4370
- }
4371
- }
4372
- }
4373
- return words[0];
4374
- }
4375
- return words.join(' ');
4252
+ AdvancedAggregatorComponent.prototype.onActionEvent = function (event) {
4253
+ this.eventHandler.emit(event);
4254
+ };
4255
+ AdvancedAggregatorComponent.decorators = [
4256
+ { type: i0.Component, args: [{
4257
+ selector: 'app-advanced-aggregator',
4258
+ template: "<ng-container *ngIf=\"config && body\">\n <div class=\"w-100 text-center\" *ngIf=\"body && body.length === 0\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"groups.length === 0\">\n <div class=\"row mt-4\">\n <app-advanced-aggregator-list [body]=\"body\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\" class=\"col-12\">\n </app-advanced-aggregator-list>\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ body | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"groups.length === 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <app-advanced-aggregator-list [body]=\"group.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for the group -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ group.value | callAggregator: aggregators: aggregator.name }} </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"groups.length > 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <div *ngFor=\"let subgroup of group.value | groupBy: groups[1].name | keyvalue\" class=\"col-12 ml-4 pl-4\">\n <div class=\"row mt-4\">\n <h6 class=\"col-12 text-secondary\"> {{ groups[1].title | aggregatorListTitle: subgroup.key }} </h6>\n <app-advanced-aggregator-list [body]=\"subgroup.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for each subgroup -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ subgroup.value | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</ng-container>",
4259
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
4260
+ }] }
4261
+ ];
4262
+ /** @nocollapse */
4263
+ AdvancedAggregatorComponent.ctorParameters = function () {
4264
+ return [
4265
+ { type: i0.ChangeDetectorRef },
4266
+ { type: AdvancedAggregatorService },
4267
+ { type: i2.LoadingService }
4268
+ ];
4269
+ };
4270
+ AdvancedAggregatorComponent.propDecorators = {
4271
+ config: [{ type: i0.Input, args: ['config',] }],
4272
+ aggregators: [{ type: i0.Input, args: ['aggregators',] }],
4273
+ postProcessors: [{ type: i0.Input, args: ['postProcessors',] }],
4274
+ params: [{ type: i0.Input, args: ['params',] }],
4275
+ selectedGroups$: [{ type: i0.Input, args: ['selectedGroups',] }],
4276
+ filters$: [{ type: i0.Input, args: ['filters',] }],
4277
+ searchExpression: [{ type: i0.Input, args: ['searchExpression',] }],
4278
+ eventHandler: [{ type: i0.Output }]
4279
+ };
4280
+ return AdvancedAggregatorComponent;
4281
+ }());
4282
+
4283
+ var Lengths;
4284
+ (function (Lengths) {
4285
+ Lengths["XL"] = "xl";
4286
+ Lengths["LG"] = "lg";
4287
+ Lengths["MD"] = "md";
4288
+ Lengths["SM"] = "sm";
4289
+ Lengths["XS"] = "xs";
4290
+ })(Lengths || (Lengths = {}));
4291
+ var AdvancedAggregatorListComponent = /** @class */ (function () {
4292
+ function AdvancedAggregatorListComponent(_template) {
4293
+ this._template = _template;
4294
+ this.clickEvent = new i0.EventEmitter();
4295
+ }
4296
+ AdvancedAggregatorListComponent.prototype.ngOnInit = function () {
4297
+ var _this = this;
4298
+ this.config.columns.forEach(function (x) {
4299
+ x.length = Object.values(Lengths).includes(x.length) ? _this._template.transform("sis--list-group-item_" + x.length + "_column", x) :
4300
+ !x.length ? 'sis--list-group-item_sm_column' : x.length;
4376
4301
  });
4377
- selectQuery = selectQueryArray.join(',');
4378
- query.setParam('$select', selectQuery);
4379
- return query;
4380
4302
  };
4381
4303
  /**
4382
- * Constructs the fetch URL based the query parameters
4383
- * @param {ClientDataQueryable} query
4384
- * @return String
4304
+ *
4305
+ * Triggers the output event emitter
4306
+ *
4307
+ * @param type The type of the event as it's declared in the configuration
4308
+ * @param item The value of the current item
4309
+ * }
4385
4310
  */
4386
- BtnExpDirective.prototype.constructURL = function (query) {
4387
- var baseURL = query.getService().getBase();
4388
- var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
4389
- Object.keys(query.getParams()).forEach(function (key, index) {
4390
- if (index === 0) {
4391
- url += key + '=' + query.getParams()[key];
4392
- }
4393
- else {
4394
- url += '&' + key + '=' + query.getParams()[key];
4395
- }
4311
+ AdvancedAggregatorListComponent.prototype.callCallback = function (type, data) {
4312
+ this.clickEvent.emit({
4313
+ type: type,
4314
+ data: data
4396
4315
  });
4397
- return url;
4398
4316
  };
4399
- /**
4400
- * Constructs the query by setting the parameters of the
4401
- * advanced table's active filters, sets the necessary headers
4402
- * and build the select parameter of the query
4403
- * @param {ClientDataQueryable} query
4404
- * @param params: The filters of the last query of the activated table
4405
- * @param tableConfig: The configuration of the activated table
4406
- * @param {Headers} headers: The headers to append to the query
4407
- * @return ClientDataQueryable
4408
- */
4409
- BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
4410
- var _query = this.setParams(query, params);
4411
- _query = this.setHeaders(_query, headers);
4412
- _query = this.constructQueryParam(_query, tableConfig);
4413
- return _query;
4317
+ AdvancedAggregatorListComponent.decorators = [
4318
+ { type: i0.Component, args: [{
4319
+ selector: 'app-advanced-aggregator-list',
4320
+ template: "<div id=\"group-list\" class=\"flex-column\" *ngIf=\"config && config.columns\">\n <ul class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item text-wrap\">\n <div class=\"d-flex justify-content-center align-items-center\" *ngIf=\"body && body.length > 0\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column\"></div>\n <div *ngFor=\"let column of config.columns; let i = index\" class=\"text-left\"\n [class]=\"config.columns[i].length\"\n [translate]=\"config.columns[i].type === 'action' ? '' : column.title\" [ngClass]=\"{\n 'd-none': config.columns[i].hidden\n }\"></div>\n </div>\n </li>\n </ul>\n\n <!-- The list of entries -->\n <ul class=\"sis--list-group sis--list-group-body\" *ngIf=\"body && body.length > 0\">\n <li class=\"sis--list-group-item text-wrap\" *ngFor=\"let entry of body | orderBy: config.orderBy\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <!-- The list of actions -->\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, entry)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n\n </div>\n <!-- The list of data -->\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && entry[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !entry[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length <= 3\n }\">\n {{entry[column.name] || '-'}}\n </span>\n\n <button *ngIf=\"config.columns[i].type === 'action' && config.columns[i].variant === 'edit'\"\n (click)=\"callCallback(config.columns[i].identifier, entry)\"\n [title]=\"(config.columns[i].title ? config.columns[i].title : '') | translate \"\n class=\"btn btn-default px-0 mx-0\">\n <i class=\"fas fa-edit text-indigo\"></i>\n </button>\n\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': entry[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n <div *ngIf=\"entry && entry.subitems\">\n <div *ngFor=\"let subitem of entry.subitems\" class=\"d-flex justify-content-center align-items-center list-color\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, subitem)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n </div>\n <div class=\"text-left\"></div>\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && subitem[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !subitem[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length <= 3\n }\">\n {{subitem[column.name] || '-'}}\n </span>\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': subitem[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n </div>\n </li>\n </ul>\n</div>\n"
4321
+ }] }
4322
+ ];
4323
+ /** @nocollapse */
4324
+ AdvancedAggregatorListComponent.ctorParameters = function () {
4325
+ return [
4326
+ { type: i2.TemplatePipe }
4327
+ ];
4414
4328
  };
4415
- /**
4416
- * Fetches and saves the xlsx file
4417
- * @param {String} url
4418
- * @param {Headers} serviceHeaders: The headers to append to the query
4419
- * @param modelName: The model name of the advanced table
4420
- */
4421
- BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
4329
+ AdvancedAggregatorListComponent.propDecorators = {
4330
+ config: [{ type: i0.Input }],
4331
+ body: [{ type: i0.Input }],
4332
+ clickEvent: [{ type: i0.Output }]
4333
+ };
4334
+ return AdvancedAggregatorListComponent;
4335
+ }());
4336
+
4337
+ var AddItemsComponent = /** @class */ (function (_super) {
4338
+ __extends(AddItemsComponent, _super);
4339
+ function AddItemsComponent(router, activatedRoute, _errorService, _modalService, _appEvent, _toastService, _loadingService, _translateService, _context) {
4340
+ var _this = _super.call(this, router, activatedRoute) || this;
4341
+ _this._errorService = _errorService;
4342
+ _this._modalService = _modalService;
4343
+ _this._appEvent = _appEvent;
4344
+ _this._toastService = _toastService;
4345
+ _this._loadingService = _loadingService;
4346
+ _this._translateService = _translateService;
4347
+ _this._context = _context;
4348
+ _this.loading = false;
4349
+ _this.items = [];
4350
+ _this.messages = [];
4351
+ // set modal size
4352
+ _this.modalClass = 'modal-lg';
4353
+ _this.okButtonDisabled = true;
4354
+ return _this;
4355
+ }
4356
+ AddItemsComponent.prototype.ngOnInit = function () {
4422
4357
  var _this = this;
4423
- this._loadingService.showLoading();
4424
- fetch(encodeURI(url), {
4425
- headers: serviceHeaders,
4426
- credentials: 'include'
4427
- }).then(function (response) {
4428
- if (response && !response.ok) {
4429
- throw new client.ResponseError(response.statusText, response.status);
4430
- }
4431
- return response.blob();
4432
- }).then(function (blob) {
4433
- var objectUrl = window.URL.createObjectURL(blob);
4434
- var a = document.createElement('a');
4435
- document.body.appendChild(a);
4436
- a.setAttribute('style', 'display: none');
4437
- a.href = objectUrl;
4438
- var downloadName = modelName + ".xlsx";
4439
- a.download = downloadName;
4440
- // this adds support for IE and MS Edge (up to version 44.19041)
4441
- if (window.navigator && window.navigator.msSaveOrOpenBlob) {
4442
- window.navigator.msSaveOrOpenBlob(blob, downloadName);
4358
+ this.selectedSubscription = this.selectComponent.advancedTable.selectedItems.subscribe(function (items) {
4359
+ if (_this.formName == null) {
4360
+ _this.okButtonDisabled = items.length === 0;
4443
4361
  }
4444
- else {
4445
- // for all other browsers
4446
- a.click();
4362
+ });
4363
+ if (this.formName != null) {
4364
+ this.formChangeSubscription = this.formComponent.form.change.subscribe(function (event) {
4365
+ if (Object.prototype.hasOwnProperty.call(event, 'isValid')) {
4366
+ // enable or disable button based on form status
4367
+ _this.okButtonDisabled = (!event.isValid);
4368
+ }
4369
+ });
4370
+ }
4371
+ if (this.target) {
4372
+ var target = this.target;
4373
+ }
4374
+ };
4375
+ AddItemsComponent.prototype.cancel = function () {
4376
+ this.clearMessages();
4377
+ if (this.loading) {
4378
+ return;
4379
+ }
4380
+ // close
4381
+ if (this._modalService.modalRef) {
4382
+ return this._modalService.modalRef.hide();
4383
+ }
4384
+ };
4385
+ AddItemsComponent.prototype.ngOnDestroy = function () {
4386
+ if (this.formLoadSubscription) {
4387
+ this.formLoadSubscription.unsubscribe();
4388
+ }
4389
+ if (this.formChangeSubscription) {
4390
+ this.formChangeSubscription.unsubscribe();
4391
+ }
4392
+ if (this.selectedSubscription) {
4393
+ this.selectedSubscription.unsubscribe();
4394
+ }
4395
+ };
4396
+ Object.defineProperty(AddItemsComponent.prototype, "formData", {
4397
+ get: function () {
4398
+ if (this.formComponent === null) {
4399
+ return null;
4447
4400
  }
4448
- window.URL.revokeObjectURL(objectUrl);
4449
- a.remove();
4450
- _this._loadingService.hideLoading();
4451
- }).catch(function (err) {
4452
- _this._loadingService.hideLoading();
4453
- _this._errorService.showError(err, {
4454
- continueLink: '.'
4401
+ return this.formComponent.form.formio.data;
4402
+ },
4403
+ enumerable: true,
4404
+ configurable: true
4405
+ });
4406
+ AddItemsComponent.prototype.ok = function () {
4407
+ var _this = this;
4408
+ try {
4409
+ this.clearMessages();
4410
+ return new Promise(function (resolve, reject) {
4411
+ _this.loading = false;
4412
+ _this.lastError = null;
4413
+ // set courses
4414
+ _this.items = _this.selectComponent.advancedTable.selected;
4415
+ // execute add
4416
+ _this.executeSubscription = _this.execute.subscribe(function (result) {
4417
+ _this.loading = false;
4418
+ if (_this.executeSubscription) {
4419
+ _this.executeSubscription.unsubscribe();
4420
+ }
4421
+ // close modal
4422
+ if (_this._modalService.modalRef) {
4423
+ _this._modalService.modalRef.hide();
4424
+ }
4425
+ return resolve();
4426
+ }, function (err) {
4427
+ _this.loading = false;
4428
+ // ensure that loading is hidden
4429
+ _this._loadingService.hideLoading();
4430
+ // set last error
4431
+ _this.lastError = err;
4432
+ return resolve();
4433
+ });
4455
4434
  });
4456
- });
4435
+ }
4436
+ catch (err) {
4437
+ this.loading = false;
4438
+ this._loadingService.hideLoading();
4439
+ this.lastError = err;
4440
+ }
4457
4441
  };
4458
- BtnExpDirective.decorators = [
4459
- { type: i0.Directive, args: [{
4460
- selector: '.universis-btn-export'
4461
- },] }
4442
+ AddItemsComponent.prototype.onChange = function ($event) { };
4443
+ AddItemsComponent.prototype.clearMessages = function () {
4444
+ this.messages = [];
4445
+ };
4446
+ AddItemsComponent.prototype.onFilterChange = function (event) { };
4447
+ AddItemsComponent.decorators = [
4448
+ { type: i0.Component, args: [{
4449
+ selector: 'app-add-items',
4450
+ template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"alert alert-danger col-12\" role=\"alert\">\n <span [translate]=\"'E' + (lastError.statusCode || 500) + '.title'\"></span><br>\n <small *ngIf=\"lastError.statusCode >= 0\" [translate]=\"'E' + (lastError.statusCode || 500) + '.message'\"></small>\n <small *ngIf=\"lastError.statusCode == null\">{{lastError.message}}</small>\n </div>\n </div>\n <div class=\"row d-none\" *ngIf=\"items\">\n <div class=\"col-12\">\n <p [translate]=\"'StudyPrograms.AddCoursesHelp'\" [translateParams]=\"items\" ></p>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col-12\">\n <ng-container>\n <ul style=\"margin-left: -24px\" class=\"nav nav-tabs mb-1\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\" *ngIf=\"tableConfiguration\">\n <a class=\"nav-link active\" id=\"courses-tab\" data-toggle=\"tab\" href=\"#courses\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\" [translate]=\"'AddItems.SelectCourses'\" ></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"formName\">\n <a class=\"nav-link\" [ngClass]=\"{ 'disabled': !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) }\" id=\"attributes-tab\" data-toggle=\"tab\" href=\"#attributes\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.EditAttributes'\"></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"messages && messages.length > 0\">\n <a class=\"nav-link\" id=\"messages-tab\" data-toggle=\"tab\" href=\"#messages\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.Messages'\"></a>\n </li>\n </ul>\n <div class=\"tab-content border-0\" id=\"myTabContent\">\n <div class=\"tab-pane fade show active\" id=\"courses\" role=\"tabpanel\" aria-labelledby=\"home-tab\">\n <app-advanced-table-modal #selectComponent (filter)=\"onFilterChange($event)\" [tableConfig]=\"tableConfiguration\"></app-advanced-table-modal>\n </div>\n <div class=\"tab-pane fade\" id=\"attributes\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(formName == null)}\">\n<!-- <advanced-form-edit #formComponent [formName]=\"formName\" ></advanced-form-edit>-->\n </div>\n <div class=\"tab-pane fade\" id=\"messages\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(messages == null)}\">\n <ul *ngIf=\"messages && messages.length>0\" class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center\">\n <div class=\"sis--list-group-item_lg_column\" [translate]=\"'AddItems.Messages'\"></div>\n </div>\n </li>\n </ul>\n <ul class=\"sis--list-group sis--list-group-body\">\n <li *ngFor=\"let message of messages\" class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <div class=\"sis--list-group-item_lg_column\">{{ message?.message }}</div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"messages && messages.length>0\">\n <button [disabled]=\"loading\" (click)=\"clearMessages()\" type=\"button\" class=\"btn btn-indigo mt-3\">\n {{'Clear' | translate}}\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) \" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{'OK' | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{'Cancel' | translate}}\n </button>\n </div>\n</div>\n"
4451
+ }] }
4462
4452
  ];
4463
4453
  /** @nocollapse */
4464
- BtnExpDirective.ctorParameters = function () {
4454
+ AddItemsComponent.ctorParameters = function () {
4465
4455
  return [
4466
- { type: ActivatedTableService },
4467
- { type: i1.AngularDataContext },
4468
- { type: i2.ConfigurationService },
4469
- { type: core.TranslateService },
4456
+ { type: i1$1.Router },
4457
+ { type: i1$1.ActivatedRoute },
4458
+ { type: i2.ErrorService },
4459
+ { type: i2.ModalService },
4460
+ { type: i2.AppEventService },
4461
+ { type: i2.ToastService },
4470
4462
  { type: i2.LoadingService },
4471
- { type: i2.ErrorService }
4463
+ { type: core.TranslateService },
4464
+ { type: i1.AngularDataContext }
4472
4465
  ];
4473
4466
  };
4474
- BtnExpDirective.propDecorators = {
4475
- clickEvent: [{ type: i0.HostListener, args: ['click', ['$event'],] }]
4467
+ AddItemsComponent.propDecorators = {
4468
+ execute: [{ type: i0.Input }],
4469
+ items: [{ type: i0.Input }],
4470
+ target: [{ type: i0.Input }],
4471
+ tableConfiguration: [{ type: i0.Input }],
4472
+ formName: [{ type: i0.Input }],
4473
+ messages: [{ type: i0.Input }],
4474
+ formComponent: [{ type: i0.ViewChild, args: ['formComponent',] }],
4475
+ selectComponent: [{ type: i0.ViewChild, args: ['selectComponent',] }]
4476
4476
  };
4477
- return BtnExpDirective;
4478
- }());
4477
+ return AddItemsComponent;
4478
+ }(routing.RouterModalOkCancel));
4479
4479
 
4480
4480
  /**
4481
4481
  *
@@ -4875,9 +4875,6 @@
4875
4875
  * Generated bundle index. Do not edit.
4876
4876
  */
4877
4877
 
4878
- exports.AddItemsComponent = AddItemsComponent;
4879
- exports.AdvancedAggregatorComponent = AdvancedAggregatorComponent;
4880
- exports.AdvancedAggregatorListComponent = AdvancedAggregatorListComponent;
4881
4878
  exports.AdvancedListComponent = AdvancedListComponent;
4882
4879
  exports.AdvancedRowActionComponent = AdvancedRowActionComponent;
4883
4880
  exports.AdvancedSearchFormComponent = AdvancedSearchFormComponent;
@@ -4914,6 +4911,9 @@
4914
4911
  exports.AdvancedTableNotNullError = AdvancedTableNotNullError;
4915
4912
  exports.AdvancedTableEditorDirective = AdvancedTableEditorDirective;
4916
4913
  exports.BtnExpDirective = BtnExpDirective;
4914
+ exports.AdvancedAggregatorComponent = AdvancedAggregatorComponent;
4915
+ exports.AdvancedAggregatorListComponent = AdvancedAggregatorListComponent;
4916
+ exports.AddItemsComponent = AddItemsComponent;
4917
4917
  exports.AdvancedAggregatorPipe = AdvancedAggregatorPipe;
4918
4918
  exports.ParseTitlePipe = ParseTitlePipe;
4919
4919
  exports.AdvancedAggregatorService = AdvancedAggregatorService;