@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.
- package/bundles/universis-ngx-tables.umd.js +101 -37
- package/bundles/universis-ngx-tables.umd.js.map +1 -1
- package/bundles/universis-ngx-tables.umd.min.js +1 -1
- package/bundles/universis-ngx-tables.umd.min.js.map +1 -1
- package/esm2015/lib/components/advanced-aggregator-list/advanced-aggregator-list.component.js +2 -2
- package/esm2015/lib/components/advanced-search-form/advanced-search-form.component.js +5 -2
- package/esm2015/lib/components/advanced-table/advanced-table.component.js +100 -39
- package/esm5/lib/components/advanced-aggregator-list/advanced-aggregator-list.component.js +2 -2
- package/esm5/lib/components/advanced-search-form/advanced-search-form.component.js +5 -2
- package/esm5/lib/components/advanced-table/advanced-table.component.js +98 -37
- package/fesm2015/universis-ngx-tables.js +103 -39
- package/fesm2015/universis-ngx-tables.js.map +1 -1
- package/fesm5/universis-ngx-tables.js +101 -37
- package/fesm5/universis-ngx-tables.js.map +1 -1
- package/lib/components/advanced-table/advanced-table.component.d.ts +8 -0
- package/package.json +1 -1
- package/universis-ngx-tables.metadata.json +1 -1
|
@@ -540,6 +540,9 @@ class AdvancedTableComponent {
|
|
|
540
540
|
this.init = new EventEmitter();
|
|
541
541
|
this.reload = new EventEmitter();
|
|
542
542
|
this.select = new EventEmitter();
|
|
543
|
+
this.draw = new EventEmitter();
|
|
544
|
+
this.page = new EventEmitter();
|
|
545
|
+
this.scroll = new EventEmitter();
|
|
543
546
|
this.selectedItems = new EventEmitter();
|
|
544
547
|
this.scrollable = true;
|
|
545
548
|
this.serverSide = true;
|
|
@@ -667,32 +670,55 @@ class AdvancedTableComponent {
|
|
|
667
670
|
// simple search
|
|
668
671
|
search(searchText) {
|
|
669
672
|
this.query = this.query || this._context.model(this.config.model).asQueryable();
|
|
670
|
-
if (
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
673
|
+
if (this.serverSide) {
|
|
674
|
+
if (searchText && this.config.searchExpression) {
|
|
675
|
+
// validate search text in double quotes
|
|
676
|
+
if (/^"(.*?)"$/.test(searchText)) {
|
|
677
|
+
this.query.setParam('$filter', this._template.transform(this.config.searchExpression, {
|
|
678
|
+
text: searchText.replace(/^"|"$/g, ''),
|
|
679
|
+
}));
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
// try to split words
|
|
683
|
+
const words = searchText.split(' ');
|
|
684
|
+
// join words to a single filter
|
|
685
|
+
const filter = words.map((word) => {
|
|
686
|
+
return this._template.transform(this.config.searchExpression, {
|
|
687
|
+
text: word,
|
|
688
|
+
});
|
|
689
|
+
}).join(' and ');
|
|
690
|
+
// set filter
|
|
691
|
+
this.query.setParam('$filter', filter);
|
|
692
|
+
}
|
|
676
693
|
}
|
|
677
694
|
else {
|
|
678
|
-
//
|
|
679
|
-
|
|
680
|
-
// join words to a single filter
|
|
681
|
-
const filter = words.map((word) => {
|
|
682
|
-
return this._template.transform(this.config.searchExpression, {
|
|
683
|
-
text: word,
|
|
684
|
-
});
|
|
685
|
-
}).join(' and ');
|
|
686
|
-
// set filter
|
|
687
|
-
this.query.setParam('$filter', filter);
|
|
695
|
+
// clear filter
|
|
696
|
+
this.query.setParam('$filter', null);
|
|
688
697
|
}
|
|
698
|
+
this._firstLoad = false;
|
|
699
|
+
this.dataTable.draw();
|
|
689
700
|
}
|
|
690
701
|
else {
|
|
691
|
-
//
|
|
692
|
-
this.
|
|
702
|
+
// ensure empty table layout
|
|
703
|
+
this.resetEmptyTable();
|
|
704
|
+
// search locally
|
|
705
|
+
this.dataTable.search(searchText.trim()).draw();
|
|
706
|
+
// get indexes of filtered rows
|
|
707
|
+
const indexes = Array.from(this.dataTable.context[0].aiDisplay);
|
|
708
|
+
// set recordsFiltered
|
|
709
|
+
const recordsFiltered = indexes.length;
|
|
710
|
+
// set recordsTotal
|
|
711
|
+
const recordsTotal = indexes.length;
|
|
712
|
+
// retrieve data from indexes
|
|
713
|
+
const rows = Array.from(this.dataTable.rows().data());
|
|
714
|
+
const data = indexes.map(index => rows[index]);
|
|
715
|
+
// emit results to load output
|
|
716
|
+
this.load.emit({
|
|
717
|
+
data: data,
|
|
718
|
+
recordsFiltered: recordsFiltered,
|
|
719
|
+
recordsTotal: recordsTotal
|
|
720
|
+
});
|
|
693
721
|
}
|
|
694
|
-
this._firstLoad = false;
|
|
695
|
-
this.dataTable.draw();
|
|
696
722
|
}
|
|
697
723
|
fetch(clearSelected) {
|
|
698
724
|
// if data table is null
|
|
@@ -1019,6 +1045,20 @@ class AdvancedTableComponent {
|
|
|
1019
1045
|
}, 0);
|
|
1020
1046
|
}
|
|
1021
1047
|
});
|
|
1048
|
+
tableElement.on('draw.dt', (event) => {
|
|
1049
|
+
this.draw.emit();
|
|
1050
|
+
if (this.dataTable) {
|
|
1051
|
+
const info = this.dataTable.page.info();
|
|
1052
|
+
this.page.emit(info);
|
|
1053
|
+
try {
|
|
1054
|
+
this.dataTable.columns.adjust();
|
|
1055
|
+
}
|
|
1056
|
+
catch (err) {
|
|
1057
|
+
console.error('ERROR', 'An error occurred while adjusting table columns');
|
|
1058
|
+
console.error(err);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1022
1062
|
// allow selection
|
|
1023
1063
|
if (this.selectable) {
|
|
1024
1064
|
// get first column (as row primary key)
|
|
@@ -1043,10 +1083,6 @@ class AdvancedTableComponent {
|
|
|
1043
1083
|
// user interface additions
|
|
1044
1084
|
// handle page change event (a trick for firing draw.dt events)
|
|
1045
1085
|
tableElement
|
|
1046
|
-
// for each page
|
|
1047
|
-
.on('page.dt', ($event) => {
|
|
1048
|
-
const info = this.dataTable.page.info();
|
|
1049
|
-
})
|
|
1050
1086
|
// handle draw events
|
|
1051
1087
|
.on('draw.dt', () => {
|
|
1052
1088
|
if (this.customSelect) {
|
|
@@ -1147,11 +1183,11 @@ class AdvancedTableComponent {
|
|
|
1147
1183
|
// get order expression
|
|
1148
1184
|
const order = aoData[2].value;
|
|
1149
1185
|
// get skip records param
|
|
1150
|
-
|
|
1186
|
+
let skip = aoData[3].value;
|
|
1151
1187
|
// get page size param
|
|
1152
|
-
|
|
1188
|
+
let top = aoData[4].value;
|
|
1153
1189
|
// get search value
|
|
1154
|
-
const
|
|
1190
|
+
const search = aoData[5].value;
|
|
1155
1191
|
// get data queryable
|
|
1156
1192
|
const q = self._query instanceof ClientDataQueryable ? self._query : self._context.model(self.config.model).asQueryable();
|
|
1157
1193
|
// apply paging params
|
|
@@ -1278,15 +1314,22 @@ class AdvancedTableComponent {
|
|
|
1278
1314
|
}
|
|
1279
1315
|
if (this.selectable) ;
|
|
1280
1316
|
// handle init.dt event and emit local event
|
|
1281
|
-
this.dataTable = tableElement.
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1317
|
+
this.dataTable = tableElement.on('init.dt', (event) => {
|
|
1318
|
+
const scroller = jQuery(event.target).parent();
|
|
1319
|
+
// handle scrolling
|
|
1320
|
+
scroller.on('scroll', (scrollEvent) => {
|
|
1321
|
+
const target = jQuery(scrollEvent.target);
|
|
1322
|
+
const top = target.scrollTop();
|
|
1323
|
+
const left = target.scrollLeft();
|
|
1324
|
+
if (this.dataTable) {
|
|
1325
|
+
this.scroll.emit({
|
|
1326
|
+
top,
|
|
1327
|
+
left
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
this.init.emit();
|
|
1332
|
+
}).DataTable(settings);
|
|
1290
1333
|
// show or hide header
|
|
1291
1334
|
if (!this.showHeader) {
|
|
1292
1335
|
this._element.nativeElement
|
|
@@ -1305,6 +1348,16 @@ class AdvancedTableComponent {
|
|
|
1305
1348
|
}
|
|
1306
1349
|
}
|
|
1307
1350
|
}
|
|
1351
|
+
scrollTop(value) {
|
|
1352
|
+
if (this.dataTable) {
|
|
1353
|
+
this.dataTable.parent().scrollTop(value);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
scrollLeft(value) {
|
|
1357
|
+
if (this.dataTable) {
|
|
1358
|
+
this.dataTable.parent().scrollLeft(value);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1308
1361
|
get lastQuery() {
|
|
1309
1362
|
if (this.config == null) {
|
|
1310
1363
|
return null;
|
|
@@ -1355,6 +1408,10 @@ class AdvancedTableComponent {
|
|
|
1355
1408
|
const query = this._context.model(this.config.model).asQueryable();
|
|
1356
1409
|
// select attributes
|
|
1357
1410
|
query.setParam('$select', this.lastQueryParams.$select);
|
|
1411
|
+
if (this.lastQueryParams.$expand) {
|
|
1412
|
+
// apply expand attributes
|
|
1413
|
+
query.setParam('$expand', this.lastQueryParams.$expand);
|
|
1414
|
+
}
|
|
1358
1415
|
// apply filter for row
|
|
1359
1416
|
findKeys.forEach((key) => {
|
|
1360
1417
|
const column = this.config.columns.find((col) => {
|
|
@@ -1441,7 +1498,8 @@ class AdvancedTableComponent {
|
|
|
1441
1498
|
// due to ng data binding
|
|
1442
1499
|
// empty table template has no translated text during ngOnInit()
|
|
1443
1500
|
if (this.dataTable && this.dataTable.context[0]) {
|
|
1444
|
-
this.dataTable.context[0].oLanguage.sEmptyTable =
|
|
1501
|
+
this.dataTable.context[0].oLanguage.sEmptyTable =
|
|
1502
|
+
this.dataTable.context[0].oLanguage.sZeroRecords = this.emptyTable.nativeElement.innerHTML;
|
|
1445
1503
|
}
|
|
1446
1504
|
}
|
|
1447
1505
|
clearEmptyTable() {
|
|
@@ -1538,6 +1596,9 @@ AdvancedTableComponent.propDecorators = {
|
|
|
1538
1596
|
init: [{ type: Output, args: ['init',] }],
|
|
1539
1597
|
reload: [{ type: Input, args: ['reload',] }],
|
|
1540
1598
|
select: [{ type: Output, args: ['select',] }],
|
|
1599
|
+
draw: [{ type: Output, args: ['draw',] }],
|
|
1600
|
+
page: [{ type: Output, args: ['page',] }],
|
|
1601
|
+
scroll: [{ type: Output, args: ['scroll',] }],
|
|
1541
1602
|
selectedItems: [{ type: Output, args: ['selectedItems',] }],
|
|
1542
1603
|
scrollable: [{ type: Input }],
|
|
1543
1604
|
serverSide: [{ type: Input }],
|
|
@@ -1983,7 +2044,10 @@ class AdvancedSearchFormComponent extends AdvancedTableSearchBaseComponent {
|
|
|
1983
2044
|
const value = this.formComponent.submission.data[key];
|
|
1984
2045
|
// the filter with type is a string and is not empty
|
|
1985
2046
|
const isEmptyString = typeof value === 'string' && value.length === 0;
|
|
1986
|
-
|
|
2047
|
+
// do not include empty objects in filter
|
|
2048
|
+
const isEmptyObject = typeof value === 'object' && Object.keys(value).length === 0;
|
|
2049
|
+
// make isEmptyString, isEmptyObject mutex
|
|
2050
|
+
if (!isEmptyString && !isEmptyObject) {
|
|
1987
2051
|
Object.defineProperty(this.filter, key, {
|
|
1988
2052
|
configurable: true,
|
|
1989
2053
|
enumerable: true,
|
|
@@ -3863,7 +3927,7 @@ class AdvancedAggregatorListComponent {
|
|
|
3863
3927
|
AdvancedAggregatorListComponent.decorators = [
|
|
3864
3928
|
{ type: Component, args: [{
|
|
3865
3929
|
selector: 'app-advanced-aggregator-list',
|
|
3866
|
-
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
|
|
3930
|
+
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\"> </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\"> </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"
|
|
3867
3931
|
}] }
|
|
3868
3932
|
];
|
|
3869
3933
|
/** @nocollapse */
|