@universis/ngx-tables 6.13.3 → 6.13.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/bundles/universis-ngx-tables.umd.js +156 -11
  2. package/bundles/universis-ngx-tables.umd.js.map +1 -1
  3. package/bundles/universis-ngx-tables.umd.min.js +1 -1
  4. package/bundles/universis-ngx-tables.umd.min.js.map +1 -1
  5. package/esm2015/lib/components/advanced-aggregator/advanced-aggregator.component.js +6 -3
  6. package/esm2015/lib/components/advanced-aggregator-list/advanced-aggregator-list.component.js +6 -3
  7. package/esm2015/lib/components/advanced-table/advanced-table.component.js +96 -5
  8. package/esm2015/lib/components/advanced-table/advanced-table.formatters.interface.js +6 -31
  9. package/esm2015/lib/components/advanced-table/custom-button.formatter.js +45 -0
  10. package/esm2015/lib/i18n/tables.el.js +3 -2
  11. package/esm2015/lib/i18n/tables.en.js +3 -2
  12. package/esm2015/universis-ngx-tables.js +5 -4
  13. package/esm5/lib/components/advanced-aggregator/advanced-aggregator.component.js +6 -3
  14. package/esm5/lib/components/advanced-aggregator-list/advanced-aggregator-list.component.js +6 -3
  15. package/esm5/lib/components/advanced-table/advanced-table.component.js +101 -5
  16. package/esm5/lib/components/advanced-table/advanced-table.formatters.interface.js +6 -31
  17. package/esm5/lib/components/advanced-table/custom-button.formatter.js +56 -0
  18. package/esm5/lib/i18n/tables.el.js +3 -2
  19. package/esm5/lib/i18n/tables.en.js +3 -2
  20. package/esm5/universis-ngx-tables.js +5 -4
  21. package/fesm2015/universis-ngx-tables.js +140 -10
  22. package/fesm2015/universis-ngx-tables.js.map +1 -1
  23. package/fesm5/universis-ngx-tables.js +155 -11
  24. package/fesm5/universis-ngx-tables.js.map +1 -1
  25. package/lib/components/advanced-aggregator/advanced-aggregator.component.d.ts +2 -1
  26. package/lib/components/advanced-aggregator-list/advanced-aggregator-list.component.d.ts +2 -1
  27. package/lib/components/advanced-table/advanced-table.component.d.ts +6 -2
  28. package/lib/components/advanced-table/advanced-table.formatters.interface.d.ts +5 -17
  29. package/lib/components/advanced-table/custom-button.formatter.d.ts +11 -0
  30. package/lib/i18n/tables.el.d.ts +1 -0
  31. package/lib/i18n/tables.en.d.ts +1 -0
  32. package/package.json +1 -1
  33. package/universis-ngx-tables.d.ts +5 -4
  34. package/universis-ngx-tables.metadata.json +1 -1
@@ -23,7 +23,7 @@ import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
23
23
  import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
24
24
  import { GroupByPipe, NgPipesModule } from 'ngx-pipes';
25
25
  import { template, at, cloneDeep, isEmpty } from 'lodash';
26
- import { Injectable, Directive, Optional, Input, Output, EventEmitter, Pipe, Component, ViewChild, ViewEncapsulation, ElementRef, ChangeDetectorRef, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, HostListener, ChangeDetectionStrategy, InjectionToken, Inject, Injector, ViewContainerRef } from '@angular/core';
26
+ import { Injectable, Directive, Optional, Input, Output, EventEmitter, Component, ElementRef, ViewChild, ViewEncapsulation, Pipe, ChangeDetectorRef, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, HostListener, InjectionToken, Inject, Injector, ViewContainerRef, ChangeDetectionStrategy } from '@angular/core';
27
27
  import { ActivatedRoute, Router, NavigationStart, NavigationEnd, RouterModule } from '@angular/router';
28
28
  import { createFeatureSelector, createSelector, select, Store } from '@ngrx/store';
29
29
  import { skip, first, filter } from 'rxjs/operators';
@@ -1449,6 +1449,7 @@ class AdvancedTableComponent {
1449
1449
  this.height = 800;
1450
1450
  this.showActions = true;
1451
1451
  this.autoLoad = true;
1452
+ this.customEvent = new EventEmitter();
1452
1453
  this.load = new EventEmitter();
1453
1454
  this.init = new EventEmitter();
1454
1455
  this.reload = new EventEmitter();
@@ -1461,6 +1462,8 @@ class AdvancedTableComponent {
1461
1462
  this.beforeServerData = new EventEmitter();
1462
1463
  this.afterServerData = new EventEmitter();
1463
1464
  this.loading = new EventEmitter();
1465
+ this.showDetails = new EventEmitter();
1466
+ this.hideDetails = new EventEmitter();
1464
1467
  this.scrollable = true;
1465
1468
  this.serverSide = true;
1466
1469
  this.lengthMenu = [50, 100, 200, 500];
@@ -2024,7 +2027,7 @@ class AdvancedTableComponent {
2024
2027
  createdCell(cell, cellData, rowData, rowIndex, colIndex) {
2025
2028
  items.forEach((columnFormatter) => {
2026
2029
  /** @type {?} */
2027
- const formatter = self._columnFormatters[columnFormatter.formatter];
2030
+ const formatter = /** @type {?} */ ((self._columnFormatters[columnFormatter.formatter]));
2028
2031
  if (formatter && typeof formatter.afterRender === 'function') {
2029
2032
  formatter.afterRender.bind(column)(cell, cellData, rowData, rowIndex, colIndex);
2030
2033
  }
@@ -2041,12 +2044,14 @@ class AdvancedTableComponent {
2041
2044
  render: formatter.render.bind(column),
2042
2045
  });
2043
2046
  }
2044
- if (formatter && typeof formatter.afterRender === 'function') {
2047
+ /** @type {?} */
2048
+ const afterRenderFormatter = /** @type {?} */ ((formatter));
2049
+ if (afterRenderFormatter && typeof afterRenderFormatter.afterRender === 'function') {
2045
2050
  Object.assign(columnDefinition, {
2046
2051
  render: formatter.render.bind(column),
2047
2052
  });
2048
2053
  Object.assign(columnDefinition, {
2049
- createdCell: formatter.afterRender.bind(column),
2054
+ createdCell: afterRenderFormatter.afterRender.bind(column),
2050
2055
  });
2051
2056
  }
2052
2057
  }
@@ -2174,6 +2179,59 @@ class AdvancedTableComponent {
2174
2179
  }
2175
2180
  });
2176
2181
  }
2182
+ // display row details
2183
+ if (this.detailsTemplate) {
2184
+ /** @type {?} */
2185
+ const detailsString = this._translateService.instant('Tables.RowDetails');
2186
+ /** @type {?} */
2187
+ const firstColumn = this.config.columns[0];
2188
+ /** @type {?} */
2189
+ const showDetailsColumnDefinition = {
2190
+ className: 'details-control pl-4 pr-0',
2191
+ data: firstColumn.property || firstColumn.name,
2192
+ defaultContent: '',
2193
+ title: '',
2194
+ sortable: false,
2195
+ visible: !this.customSelect,
2196
+ name: firstColumn.name,
2197
+ render: () => {
2198
+ return `<button role="button" title="${detailsString}" arial-label="${detailsString}"></button>`;
2199
+ },
2200
+ };
2201
+ // and finally add column
2202
+ tableColumns.unshift(showDetailsColumnDefinition);
2203
+ // user interface additions
2204
+ // Add event listener for opening and closing details
2205
+ tableElement.on('click', 'td.details-control', (e) => {
2206
+ /** @type {?} */
2207
+ const tr = e.target.closest('tr');
2208
+ /** @type {?} */
2209
+ const row = self.dataTable.row(tr);
2210
+ /** @type {?} */
2211
+ const container = document.createElement('div');
2212
+ /** @type {?} */
2213
+ const detailsViewRef = this._viewContainerRef.createEmbeddedView(this.detailsTemplate, {
2214
+ rowData: row.data(),
2215
+ });
2216
+ detailsViewRef.detectChanges();
2217
+ if (detailsViewRef.rootNodes.length !== 1) {
2218
+ throw new Error('DetailsTemplate must have exactly one root node.');
2219
+ }
2220
+ container.appendChild(detailsViewRef.rootNodes[0]);
2221
+ if (row.child.isShown()) {
2222
+ // This row is already open - close it
2223
+ this.hideDetails.emit();
2224
+ row.child.hide();
2225
+ detailsViewRef.destroy();
2226
+ }
2227
+ else {
2228
+ // Open this row
2229
+ this.showDetails.emit({ row });
2230
+ row.child(container).show();
2231
+ row.child().addClass('dt-child');
2232
+ }
2233
+ });
2234
+ }
2177
2235
  /** @type {?} */
2178
2236
  const settings = {
2179
2237
  // set length menu
@@ -2542,6 +2600,9 @@ class AdvancedTableComponent {
2542
2600
  });
2543
2601
  }
2544
2602
  if (this.selectable) ;
2603
+ if (this.dataTable) {
2604
+ this.dataTable.destroy();
2605
+ }
2545
2606
  // handle init.dt event and emit local event
2546
2607
  this.dataTable = tableElement.on('init.dt', (event) => {
2547
2608
  /** @type {?} */
@@ -2587,6 +2648,24 @@ class AdvancedTableComponent {
2587
2648
  infoSelector.classList.add('d-none');
2588
2649
  }
2589
2650
  }
2651
+ /** @type {?} */
2652
+ const onCustomEvent = (event) => {
2653
+ /** @type {?} */
2654
+ const target = /** @type {?} */ (event.currentTarget);
2655
+ /** @type {?} */
2656
+ const customEvent = target.dataset["event"] || 'event';
2657
+ /** @type {?} */
2658
+ const row = this.dataTable.row(target.closest('tr'));
2659
+ /** @type {?} */
2660
+ const data = row.data();
2661
+ this.customEvent.emit({
2662
+ name: customEvent,
2663
+ data,
2664
+ row: row.index()
2665
+ });
2666
+ };
2667
+ this.dataTable.off('click', '.dt-custom');
2668
+ this.dataTable.on('click', '.dt-custom', onCustomEvent);
2590
2669
  // show or hide pager
2591
2670
  if (this.showPaging) {
2592
2671
  this.showPaging = true;
@@ -3119,7 +3198,7 @@ AdvancedTableComponent.decorators = [
3119
3198
  </div>
3120
3199
  `,
3121
3200
  encapsulation: ViewEncapsulation.None,
3122
- styles: ["div.dataTables_processing>div:last-child>div{background-color:var(--secondary)}table.dataTable thead .sorting{background-image:none}table.dataTable thead tr th{border-bottom:none;font-weight:500;font-size:.75rem}table.dataTable thead th{color:#73818e;font-size:.75rem;font-weight:600;padding-top:16px;padding-bottom:4px;border-bottom:none;padding-left:8px}table.dataTable tbody tr:first-child td:first-child{border-radius:6px 0}table.dataTable tbody tr:first-child td:last-child{border-radius:0 6px}table.dataTable tbody tr{border-radius:6px}table.dataTable tbody tr td:first-child{border-left:1px solid #c2cfd6}table.dataTable tbody tr td:last-child{border-right:1px solid #c2cfd6}table.dataTable tbody tr td{padding-top:8px;padding-bottom:8px;border-top:1px solid #c2cfd6}table.dataTable tbody tr:last-child td:first-child{border-radius:0 0 0 6px}table.dataTable tbody tr:last-child td:last-child{border-radius:0 0 6px}table.dataTable tbody tr:last-child td{border-bottom:1px solid #c2cfd6}table.dataTable tbody tr.dtrg-group.dtrg-start th{border:2px solid #c2cfd6;border-bottom:1px solid #c2cfd6;color:#3e515b;background-color:#f0f3f5}table.dataTable tbody tr.dtrg-group.dtrg-end th{border-top:2px solid #c2cfd6;border-right:2px solid #c2cfd6;border-left:2px solid #c2cfd6;color:#3e515b;background-color:#f0f3f5}table.dataTable tbody tr:nth-last-child(1) th{border-bottom:2px solid #c2cfd6}table.dataTable td.dataTables_empty{border:none!important}table.dataTable .error-inner-message>small{overflow-wrap:break-word}table.dataTable.no-footer{border-bottom:none}.dataTables_paginate .btn.previous{margin-right:8px}.dataTables_paginate .btn.next{margin-left:8px}.dataTables_info,.dataTables_paginate{margin-top:1rem}.dataTables_paginate span .btn{border-radius:1.5rem}.dataTables_filter{display:none}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:0;overflow:auto}.dataTables_paginate{display:none}.dataTable.processing{opacity:15%}.dataTables_wrapper .dataTables_processing{background:0 0;position:absolute;display:inline-block;top:25%;z-index:5;color:#73818e}.text-decoration-line-through{text-decoration:line-through!important}tr.removed .checkbox+label{visibility:hidden}"]
3201
+ styles: ["div.dataTables_processing>div:last-child>div{background-color:var(--secondary)}table.dataTable thead .sorting{background-image:none}table.dataTable thead tr th{border-bottom:none;font-weight:500;font-size:.75rem}table.dataTable thead th{color:#73818e;font-size:.75rem;font-weight:600;padding-top:16px;padding-bottom:4px;border-bottom:none;padding-left:8px}table.dataTable tbody tr:first-child td:first-child{border-radius:6px 0}table.dataTable tbody tr:first-child td:last-child{border-radius:0 6px}table.dataTable tbody tr{border-radius:6px}table.dataTable tbody tr td:first-child{border-left:1px solid #c2cfd6}table.dataTable tbody tr td:last-child{border-right:1px solid #c2cfd6}table.dataTable tbody tr td{padding-top:8px;padding-bottom:8px;border-top:1px solid #c2cfd6}table.dataTable tbody tr:last-child td:first-child{border-radius:0 0 0 6px}table.dataTable tbody tr:last-child td:last-child{border-radius:0 0 6px}table.dataTable tbody tr:last-child td{border-bottom:1px solid #c2cfd6}table.dataTable tbody tr.dtrg-group.dtrg-start th{border:2px solid #c2cfd6;border-bottom:1px solid #c2cfd6;color:#3e515b;background-color:#f0f3f5}table.dataTable tbody tr.dtrg-group.dtrg-end th{border-top:2px solid #c2cfd6;border-right:2px solid #c2cfd6;border-left:2px solid #c2cfd6;color:#3e515b;background-color:#f0f3f5}table.dataTable tbody tr:nth-last-child(1) th{border-bottom:2px solid #c2cfd6}table.dataTable td.dataTables_empty{border:none!important}table.dataTable .error-inner-message>small{overflow-wrap:break-word}table.dataTable.no-footer{border-bottom:none}.dataTables_paginate .btn.previous{margin-right:8px}.dataTables_paginate .btn.next{margin-left:8px}.dataTables_info,.dataTables_paginate{margin-top:1rem}.dataTables_paginate span .btn{border-radius:1.5rem}.dataTables_filter{display:none}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:0;overflow:auto}.dataTables_paginate{display:none}.dataTable.processing{opacity:15%}.dataTables_wrapper .dataTables_processing{background:0 0;position:absolute;display:inline-block;top:25%;z-index:5;color:#73818e}.text-decoration-line-through{text-decoration:line-through!important}tr.removed .checkbox+label{visibility:hidden}table.dataTable td.details-control{cursor:pointer}table.dataTable td.details-control button{border:none;background-color:inherit;outline:0}table.dataTable td.details-control button::after{content:'\\25B7'}table.dataTable tr.dt-hasChild td.details-control button::after{content:'\\25BD'}"]
3123
3202
  }] }
3124
3203
  ];
3125
3204
  /** @nocollapse */
@@ -3149,6 +3228,7 @@ AdvancedTableComponent.propDecorators = {
3149
3228
  height: [{ type: Input }],
3150
3229
  showActions: [{ type: Input }],
3151
3230
  autoLoad: [{ type: Input }],
3231
+ customEvent: [{ type: Output, args: ['customEvent',] }],
3152
3232
  load: [{ type: Output, args: ['load',] }],
3153
3233
  init: [{ type: Output, args: ['init',] }],
3154
3234
  reload: [{ type: Input, args: ['reload',] }],
@@ -3161,6 +3241,8 @@ AdvancedTableComponent.propDecorators = {
3161
3241
  beforeServerData: [{ type: Output, args: ['beforeServerData',] }],
3162
3242
  afterServerData: [{ type: Output, args: ['afterServerData',] }],
3163
3243
  loading: [{ type: Output, args: ['loading',] }],
3244
+ showDetails: [{ type: Output, args: ['showDetails',] }],
3245
+ hideDetails: [{ type: Output, args: ['hideDetails',] }],
3164
3246
  scrollable: [{ type: Input }],
3165
3247
  serverSide: [{ type: Input }],
3166
3248
  lengthMenu: [{ type: Input }],
@@ -3180,6 +3262,7 @@ AdvancedTableComponent.propDecorators = {
3180
3262
  rowGroup: [{ type: Input }],
3181
3263
  headerTemplate: [{ type: Input }],
3182
3264
  footerTemplate: [{ type: Input }],
3265
+ detailsTemplate: [{ type: Input }],
3183
3266
  header: [{ type: ViewChild, args: ['header',] }],
3184
3267
  footer: [{ type: ViewChild, args: ['footer',] }],
3185
3268
  config: [{ type: Input, args: ['config',] }],
@@ -5290,6 +5373,48 @@ AdvancedTableSearchComponent.propDecorators = {
5290
5373
  listChange: [{ type: Output, args: ['listChange',] }]
5291
5374
  };
5292
5375
 
5376
+ /**
5377
+ * @fileoverview added by tsickle
5378
+ * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
5379
+ */
5380
+ class CustomButtonFormatter extends ButtonFormatter {
5381
+ constructor() {
5382
+ super();
5383
+ }
5384
+ /**
5385
+ * @param {?} data
5386
+ * @param {?} type
5387
+ * @param {?} row
5388
+ * @param {?} meta
5389
+ * @return {?}
5390
+ */
5391
+ render(data, type, row, meta) {
5392
+ if (data == null || this.injector == null) {
5393
+ return '';
5394
+ }
5395
+ /** @type {?} */
5396
+ const formatOptions = Object.assign({
5397
+ buttonClass: 'btn btn-default',
5398
+ }, this.formatOptions);
5399
+ /** @type {?} */
5400
+ let buttonText;
5401
+ /** @type {?} */
5402
+ let buttonTitle = '';
5403
+ if (formatOptions.buttonText) {
5404
+ buttonText = this.injector.get(TranslateService).instant(formatOptions.buttonText);
5405
+ }
5406
+ else {
5407
+ buttonText = formatOptions.buttonContent;
5408
+ }
5409
+ if (formatOptions.buttonTitle) {
5410
+ buttonTitle = this.injector.get(TranslateService).instant(formatOptions.buttonTitle);
5411
+ }
5412
+ /** @type {?} */
5413
+ const customEvent = formatOptions.event || 'event';
5414
+ return `<button style="cursor:pointer" data-event="${customEvent}" class="dt-custom ${formatOptions.buttonClass}" title="${buttonTitle}">${buttonText}</button>`;
5415
+ }
5416
+ }
5417
+
5293
5418
  /**
5294
5419
  * @fileoverview added by tsickle
5295
5420
  * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
@@ -5309,6 +5434,7 @@ const FORMATTERS = {
5309
5434
  TrueFalseFormatter: new TrueFalseFormatter(),
5310
5435
  ActionButtonFormatter: new ActionButtonFormatter(),
5311
5436
  ActionSplitButtonFormatter: new ActionSplitButtonFormatter(),
5437
+ CustomButtonFormatter: new CustomButtonFormatter(),
5312
5438
  };
5313
5439
 
5314
5440
  /**
@@ -5815,7 +5941,7 @@ AdvancedAggregatorComponent.decorators = [
5815
5941
  { type: Component, args: [{
5816
5942
  // tslint:disable-next-line:component-selector
5817
5943
  selector: 'app-advanced-aggregator',
5818
- 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>",
5944
+ 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 [detailTemplate]=\"detailTemplate\" [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 [detailTemplate]=\"detailTemplate\" [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 [detailTemplate]=\"detailTemplate\" [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>",
5819
5945
  changeDetection: ChangeDetectionStrategy.OnPush
5820
5946
  }] }
5821
5947
  ];
@@ -5833,6 +5959,7 @@ AdvancedAggregatorComponent.propDecorators = {
5833
5959
  selectedGroups$: [{ type: Input, args: ['selectedGroups',] }],
5834
5960
  filters$: [{ type: Input, args: ['filters',] }],
5835
5961
  searchExpression: [{ type: Input, args: ['searchExpression',] }],
5962
+ detailTemplate: [{ type: Input, args: ['detailTemplate',] }],
5836
5963
  eventHandler: [{ type: Output }]
5837
5964
  };
5838
5965
 
@@ -5884,7 +6011,7 @@ AdvancedAggregatorListComponent.decorators = [
5884
6011
  { type: Component, args: [{
5885
6012
  // tslint:disable-next-line:component-selector
5886
6013
  selector: 'app-advanced-aggregator-list',
5887
- 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\" [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 class=\"\" [class]=\"'fas text-indigo ml-2 ' + 'fa-' + action.icon\"></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 <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': !!entry[column.name],\n 'fa-times text-danger': !!entry[column.name] === false && 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\"\n 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],\n 'fa-times text-danger': !!subitem[column.name] === false && 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>"
6014
+ 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\" [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 class=\"\" [class]=\"'fas text-indigo ml-2 ' + 'fa-' + action.icon\"></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 <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': !!entry[column.name],\n 'fa-times text-danger': !!entry[column.name] === false && 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 <ng-container *ngIf=\"detailTemplate\">\n <ng-container *ngTemplateOutlet=\"detailTemplate; context: { row: entry }\"></ng-container>\n </ng-container>\n <div *ngIf=\"entry && entry.subitems\">\n <ng-container *ngFor=\"let subitem of entry.subitems\">\n <div class=\"d-flex d-debug 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],\n 'fa-times text-danger': !!subitem[column.name] === false && 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 </ng-container>\n </div>\n </li>\n </ul>\n</div>"
5888
6015
  }] }
5889
6016
  ];
5890
6017
  /** @nocollapse */
@@ -5894,6 +6021,7 @@ AdvancedAggregatorListComponent.ctorParameters = () => [
5894
6021
  AdvancedAggregatorListComponent.propDecorators = {
5895
6022
  config: [{ type: Input }],
5896
6023
  body: [{ type: Input }],
6024
+ detailTemplate: [{ type: Input, args: ['detailTemplate',] }],
5897
6025
  clickEvent: [{ type: Output }]
5898
6026
  };
5899
6027
 
@@ -6243,7 +6371,8 @@ const TABLES_EL = {
6243
6371
  },
6244
6372
  "ExportList": "Εξαγωγή λίστας",
6245
6373
  "ExportLimitExceeded": "Το πλήθος των στοιχείων προς εξαγωγή ({{dataLength}}) ξεπερνάει το μέγιστο επιτρεπτό ({{exportLimit}}). Παρακαλούμε προσαρμόστε τα φίλτρα της αναζήτησης και προσπαθήστε ξανά.",
6246
- "ExportResults": "Δεδομένα λίστας"
6374
+ "ExportResults": "Δεδομένα λίστας",
6375
+ "RowDetails": "Λεπτομέρειες"
6247
6376
  },
6248
6377
  "TrueFalse": {
6249
6378
  "long": {
@@ -6374,7 +6503,8 @@ const TABLES_EN = {
6374
6503
  },
6375
6504
  "ExportList": "Export list",
6376
6505
  "ExportLimitExceeded": "The number of items that are to be exported ({{dataLength}}) exceeds the export limit ({{exportLimit}}). Please apply more specific filters to the search.",
6377
- "ExportResults": "Exported list"
6506
+ "ExportResults": "Exported list",
6507
+ "RowDetails": "Details"
6378
6508
  },
6379
6509
  "TrueFalse": {
6380
6510
  "long": {
@@ -6898,6 +7028,6 @@ TablesModule.ctorParameters = () => [
6898
7028
  * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6899
7029
  */
6900
7030
 
6901
- export { AdvancedListComponent, AdvancedRowActionComponent, AdvancedSearchFormComponent, AdvancedSelectComponent, AdvancedSelectService, AdvancedTableConfigurationResolver, AdvancedSearchConfigurationResolver, AdvancedColumnFormatter, NestedPropertyFormatter, ButtonFormatter, LinkFormatter, ActionLinkFormatter, ActionButtonFormatter, ActionSplitButtonFormatter, SelectRowFormatter, TemplateFormatter, TrueFalseFormatter, TranslationFormatter, DateTimeFormatter, NgClassFormatter, LanguageFormatter, COLUMN_FORMATTERS, ExportLimitExceededError, AdvancedTableConfiguration, AdvancedTableComponent, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, MAX_EXPORT_ITEMS, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ActivatedTableService, ColumnSelectorService, ColumnSelectorComponent, tableReducer, initialState, tableInitialState, tableReducers, featureName, getTablesState, selectTable, AdvancedSearchState as ɵa, AdvancedTableState as ɵc, AdvancedSearchRouterState as ɵd };
7031
+ export { AdvancedListComponent, AdvancedRowActionComponent, AdvancedSearchFormComponent, AdvancedSelectComponent, AdvancedSelectService, AdvancedTableConfigurationResolver, AdvancedSearchConfigurationResolver, AdvancedColumnFormatter, NestedPropertyFormatter, ButtonFormatter, LinkFormatter, ActionLinkFormatter, ActionButtonFormatter, ActionSplitButtonFormatter, SelectRowFormatter, TemplateFormatter, TrueFalseFormatter, TranslationFormatter, DateTimeFormatter, NgClassFormatter, LanguageFormatter, COLUMN_FORMATTERS, ExportLimitExceededError, AdvancedTableConfiguration, AdvancedTableComponent, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, MAX_EXPORT_ITEMS, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ActivatedTableService, ColumnSelectorService, ColumnSelectorComponent, tableReducer, initialState, tableInitialState, tableReducers, featureName, getTablesState, selectTable, CustomButtonFormatter as ɵa, AdvancedSearchState as ɵb, AdvancedTableState as ɵd, AdvancedSearchRouterState as ɵe };
6902
7032
 
6903
7033
  //# sourceMappingURL=universis-ngx-tables.js.map