@universis/ngx-tables 0.6.18 → 0.6.21

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.
@@ -600,6 +600,9 @@ var AdvancedTableComponent = /** @class */ (function () {
600
600
  this.init = new EventEmitter();
601
601
  this.reload = new EventEmitter();
602
602
  this.select = new EventEmitter();
603
+ this.draw = new EventEmitter();
604
+ this.page = new EventEmitter();
605
+ this.scroll = new EventEmitter();
603
606
  this.selectedItems = new EventEmitter();
604
607
  this.scrollable = true;
605
608
  this.serverSide = true;
@@ -748,32 +751,55 @@ var AdvancedTableComponent = /** @class */ (function () {
748
751
  AdvancedTableComponent.prototype.search = function (searchText) {
749
752
  var _this = this;
750
753
  this.query = this.query || this._context.model(this.config.model).asQueryable();
751
- if (searchText && this.config.searchExpression) {
752
- // validate search text in double quotes
753
- if (/^"(.*?)"$/.test(searchText)) {
754
- this.query.setParam('$filter', this._template.transform(this.config.searchExpression, {
755
- text: searchText.replace(/^"|"$/g, ''),
756
- }));
754
+ if (this.serverSide) {
755
+ if (searchText && this.config.searchExpression) {
756
+ // validate search text in double quotes
757
+ if (/^"(.*?)"$/.test(searchText)) {
758
+ this.query.setParam('$filter', this._template.transform(this.config.searchExpression, {
759
+ text: searchText.replace(/^"|"$/g, ''),
760
+ }));
761
+ }
762
+ else {
763
+ // try to split words
764
+ var words = searchText.split(' ');
765
+ // join words to a single filter
766
+ var filter = words.map(function (word) {
767
+ return _this._template.transform(_this.config.searchExpression, {
768
+ text: word,
769
+ });
770
+ }).join(' and ');
771
+ // set filter
772
+ this.query.setParam('$filter', filter);
773
+ }
757
774
  }
758
775
  else {
759
- // try to split words
760
- var words = searchText.split(' ');
761
- // join words to a single filter
762
- var filter = words.map(function (word) {
763
- return _this._template.transform(_this.config.searchExpression, {
764
- text: word,
765
- });
766
- }).join(' and ');
767
- // set filter
768
- this.query.setParam('$filter', filter);
776
+ // clear filter
777
+ this.query.setParam('$filter', null);
769
778
  }
779
+ this._firstLoad = false;
780
+ this.dataTable.draw();
770
781
  }
771
782
  else {
772
- // clear filter
773
- this.query.setParam('$filter', null);
783
+ // ensure empty table layout
784
+ this.resetEmptyTable();
785
+ // search locally
786
+ this.dataTable.search(searchText.trim()).draw();
787
+ // get indexes of filtered rows
788
+ var indexes = Array.from(this.dataTable.context[0].aiDisplay);
789
+ // set recordsFiltered
790
+ var recordsFiltered = indexes.length;
791
+ // set recordsTotal
792
+ var recordsTotal = indexes.length;
793
+ // retrieve data from indexes
794
+ var rows_1 = Array.from(this.dataTable.rows().data());
795
+ var data = indexes.map(function (index) { return rows_1[index]; });
796
+ // emit results to load output
797
+ this.load.emit({
798
+ data: data,
799
+ recordsFiltered: recordsFiltered,
800
+ recordsTotal: recordsTotal
801
+ });
774
802
  }
775
- this._firstLoad = false;
776
- this.dataTable.draw();
777
803
  };
778
804
  AdvancedTableComponent.prototype.fetch = function (clearSelected) {
779
805
  // if data table is null
@@ -1101,6 +1127,20 @@ var AdvancedTableComponent = /** @class */ (function () {
1101
1127
  }, 0);
1102
1128
  }
1103
1129
  });
1130
+ tableElement_1.on('draw.dt', function (event) {
1131
+ _this.draw.emit();
1132
+ if (_this.dataTable) {
1133
+ var info = _this.dataTable.page.info();
1134
+ _this.page.emit(info);
1135
+ try {
1136
+ _this.dataTable.columns.adjust();
1137
+ }
1138
+ catch (err) {
1139
+ console.error('ERROR', 'An error occurred while adjusting table columns');
1140
+ console.error(err);
1141
+ }
1142
+ }
1143
+ });
1104
1144
  // allow selection
1105
1145
  if (this.selectable) {
1106
1146
  // get first column (as row primary key)
@@ -1125,10 +1165,6 @@ var AdvancedTableComponent = /** @class */ (function () {
1125
1165
  // user interface additions
1126
1166
  // handle page change event (a trick for firing draw.dt events)
1127
1167
  tableElement_1
1128
- // for each page
1129
- .on('page.dt', function ($event) {
1130
- var info = _this.dataTable.page.info();
1131
- })
1132
1168
  // handle draw events
1133
1169
  .on('draw.dt', function () {
1134
1170
  if (_this.customSelect) {
@@ -1233,7 +1269,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1233
1269
  // get page size param
1234
1270
  var top = aoData[4].value;
1235
1271
  // get search value
1236
- var searchText = aoData[5].value;
1272
+ var search = aoData[5].value;
1237
1273
  // get data queryable
1238
1274
  var q = self._query instanceof ClientDataQueryable ? self._query : self._context.model(self.config.model).asQueryable();
1239
1275
  // apply paging params
@@ -1360,15 +1396,22 @@ var AdvancedTableComponent = /** @class */ (function () {
1360
1396
  }
1361
1397
  if (this.selectable) ;
1362
1398
  // handle init.dt event and emit local event
1363
- this.dataTable = tableElement_1.DataTable(settings);
1364
- tableElement_1.on('init.dt', function () {
1365
- if (_this.dataTable == null) {
1366
- return;
1367
- }
1368
- // restore default empty table html
1369
- // (due to ng async binding)
1370
- _this.init.emit(_this.dataTable);
1371
- });
1399
+ this.dataTable = tableElement_1.on('init.dt', function (event) {
1400
+ var scroller = jQuery(event.target).parent();
1401
+ // handle scrolling
1402
+ scroller.on('scroll', function (scrollEvent) {
1403
+ var target = jQuery(scrollEvent.target);
1404
+ var top = target.scrollTop();
1405
+ var left = target.scrollLeft();
1406
+ if (_this.dataTable) {
1407
+ _this.scroll.emit({
1408
+ top: top,
1409
+ left: left
1410
+ });
1411
+ }
1412
+ });
1413
+ _this.init.emit();
1414
+ }).DataTable(settings);
1372
1415
  // show or hide header
1373
1416
  if (!this.showHeader) {
1374
1417
  this._element.nativeElement
@@ -1387,6 +1430,16 @@ var AdvancedTableComponent = /** @class */ (function () {
1387
1430
  }
1388
1431
  }
1389
1432
  };
1433
+ AdvancedTableComponent.prototype.scrollTop = function (value) {
1434
+ if (this.dataTable) {
1435
+ this.dataTable.parent().scrollTop(value);
1436
+ }
1437
+ };
1438
+ AdvancedTableComponent.prototype.scrollLeft = function (value) {
1439
+ if (this.dataTable) {
1440
+ this.dataTable.parent().scrollLeft(value);
1441
+ }
1442
+ };
1390
1443
  Object.defineProperty(AdvancedTableComponent.prototype, "lastQuery", {
1391
1444
  get: function () {
1392
1445
  var _this = this;
@@ -1443,6 +1496,10 @@ var AdvancedTableComponent = /** @class */ (function () {
1443
1496
  var query_1 = this._context.model(this.config.model).asQueryable();
1444
1497
  // select attributes
1445
1498
  query_1.setParam('$select', this.lastQueryParams.$select);
1499
+ if (this.lastQueryParams.$expand) {
1500
+ // apply expand attributes
1501
+ query_1.setParam('$expand', this.lastQueryParams.$expand);
1502
+ }
1446
1503
  // apply filter for row
1447
1504
  findKeys_1.forEach(function (key) {
1448
1505
  var column = _this.config.columns.find(function (col) {
@@ -1529,7 +1586,8 @@ var AdvancedTableComponent = /** @class */ (function () {
1529
1586
  // due to ng data binding
1530
1587
  // empty table template has no translated text during ngOnInit()
1531
1588
  if (this.dataTable && this.dataTable.context[0]) {
1532
- this.dataTable.context[0].oLanguage.sEmptyTable = this.emptyTable.nativeElement.innerHTML;
1589
+ this.dataTable.context[0].oLanguage.sEmptyTable =
1590
+ this.dataTable.context[0].oLanguage.sZeroRecords = this.emptyTable.nativeElement.innerHTML;
1533
1591
  }
1534
1592
  };
1535
1593
  AdvancedTableComponent.prototype.clearEmptyTable = function () {
@@ -1612,6 +1670,9 @@ var AdvancedTableComponent = /** @class */ (function () {
1612
1670
  init: [{ type: Output, args: ['init',] }],
1613
1671
  reload: [{ type: Input, args: ['reload',] }],
1614
1672
  select: [{ type: Output, args: ['select',] }],
1673
+ draw: [{ type: Output, args: ['draw',] }],
1674
+ page: [{ type: Output, args: ['page',] }],
1675
+ scroll: [{ type: Output, args: ['scroll',] }],
1615
1676
  selectedItems: [{ type: Output, args: ['selectedItems',] }],
1616
1677
  scrollable: [{ type: Input }],
1617
1678
  serverSide: [{ type: Input }],
@@ -2083,7 +2144,10 @@ var AdvancedSearchFormComponent = /** @class */ (function (_super) {
2083
2144
  var value = _this.formComponent.submission.data[key];
2084
2145
  // the filter with type is a string and is not empty
2085
2146
  var isEmptyString = typeof value === 'string' && value.length === 0;
2086
- if (!isEmptyString) {
2147
+ // do not include empty objects in filter
2148
+ var isEmptyObject = typeof value === 'object' && Object.keys(value).length === 0;
2149
+ // make isEmptyString, isEmptyObject mutex
2150
+ if (!isEmptyString && !isEmptyObject) {
2087
2151
  Object.defineProperty(_this.filter, key, {
2088
2152
  configurable: true,
2089
2153
  enumerable: true,
@@ -4062,7 +4126,7 @@ var AdvancedAggregatorListComponent = /** @class */ (function () {
4062
4126
  AdvancedAggregatorListComponent.decorators = [
4063
4127
  { type: Component, args: [{
4064
4128
  selector: 'app-advanced-aggregator-list',
4065
- 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"
4129
+ 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 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].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"
4066
4130
  }] }
4067
4131
  ];
4068
4132
  /** @nocollapse */