@sd-angular/core 1.2.76 → 1.2.79
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/sd-angular-core-api.umd.js +1 -1
- package/bundles/sd-angular-core-api.umd.js.map +1 -1
- package/bundles/sd-angular-core-api.umd.min.js +1 -1
- package/bundles/sd-angular-core-api.umd.min.js.map +1 -1
- package/bundles/sd-angular-core-export.umd.js +34 -13
- package/bundles/sd-angular-core-export.umd.js.map +1 -1
- package/bundles/sd-angular-core-export.umd.min.js +1 -1
- package/bundles/sd-angular-core-export.umd.min.js.map +1 -1
- package/bundles/sd-angular-core-grid-material.umd.js +326 -292
- package/bundles/sd-angular-core-grid-material.umd.js.map +1 -1
- package/bundles/sd-angular-core-grid-material.umd.min.js +2 -2
- package/bundles/sd-angular-core-grid-material.umd.min.js.map +1 -1
- package/bundles/sd-angular-core-upload-excel.umd.js +7 -8
- package/bundles/sd-angular-core-upload-excel.umd.js.map +1 -1
- package/bundles/sd-angular-core-upload-excel.umd.min.js +1 -1
- package/bundles/sd-angular-core-upload-excel.umd.min.js.map +1 -1
- package/esm2015/api/src/lib/api.service.js +2 -2
- package/esm2015/export/src/lib/export.model.js +3 -2
- package/esm2015/export/src/lib/export.service.js +17 -7
- package/esm2015/grid-material/src/lib/components/popup-export/popup-export.component.js +44 -24
- package/esm2015/grid-material/src/lib/grid-material.component.js +56 -29
- package/esm2015/upload-excel/src/lib/upload-excel.component.js +7 -8
- package/esm2015/upload-excel/src/lib/upload-excel.model.js +1 -1
- package/export/sd-angular-core-export.metadata.json +1 -1
- package/export/src/lib/export.model.d.ts +3 -0
- package/export/src/lib/export.service.d.ts +2 -5
- package/fesm2015/sd-angular-core-api.js +1 -1
- package/fesm2015/sd-angular-core-api.js.map +1 -1
- package/fesm2015/sd-angular-core-export.js +18 -7
- package/fesm2015/sd-angular-core-export.js.map +1 -1
- package/fesm2015/sd-angular-core-grid-material.js +98 -51
- package/fesm2015/sd-angular-core-grid-material.js.map +1 -1
- package/fesm2015/sd-angular-core-upload-excel.js +6 -7
- package/fesm2015/sd-angular-core-upload-excel.js.map +1 -1
- package/grid-material/sd-angular-core-grid-material.metadata.json +1 -1
- package/grid-material/src/lib/components/popup-export/popup-export.component.d.ts +6 -1
- package/grid-material/src/lib/grid-material.component.d.ts +1 -0
- package/package.json +1 -1
- package/{sd-angular-core-1.2.76.tgz → sd-angular-core-1.2.79.tgz} +0 -0
- package/upload-excel/src/lib/upload-excel.model.d.ts +2 -0
|
@@ -4,7 +4,6 @@ import { __awaiter, __classPrivateFieldGet, __rest, __classPrivateFieldSet } fro
|
|
|
4
4
|
import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
|
|
5
5
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
6
6
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
7
|
-
import * as uuid from 'uuid';
|
|
8
7
|
import { v4 } from 'uuid';
|
|
9
8
|
import { Subject, Subscription, isObservable } from 'rxjs';
|
|
10
9
|
import { SdNotifyService } from '@sd-angular/core/notify';
|
|
@@ -452,7 +451,7 @@ SdGridFilter.propDecorators = {
|
|
|
452
451
|
filterChange: [{ type: Output }]
|
|
453
452
|
};
|
|
454
453
|
|
|
455
|
-
var _getExportableColumns, _getExportableGroups, _initTemplate;
|
|
454
|
+
var _getExportableColumns, _getExportableGroups, _getExportColumns, _initTemplate;
|
|
456
455
|
class SdPopupExport {
|
|
457
456
|
constructor(ref, loadingService, exportService, notifyService, translateService) {
|
|
458
457
|
this.ref = ref;
|
|
@@ -528,11 +527,35 @@ class SdPopupExport {
|
|
|
528
527
|
this.modal.open();
|
|
529
528
|
this.ref.detectChanges();
|
|
530
529
|
});
|
|
531
|
-
this
|
|
530
|
+
_getExportColumns.set(this, () => {
|
|
531
|
+
if (this.configuration) {
|
|
532
|
+
const { firstColumns, secondColumns } = this.configuration;
|
|
533
|
+
return [...firstColumns, ...secondColumns].map(e => (Object.assign(Object.assign({}, e), { data: this.columns.find(e1 => e1.field === e.field) }))).filter(e => !!e.data)
|
|
534
|
+
.map(e => e.data);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
return this.columns;
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
this.exportDefault = () => {
|
|
532
541
|
this.export.emit({
|
|
533
542
|
file: null,
|
|
534
|
-
columns: this.
|
|
535
|
-
isCSV
|
|
543
|
+
columns: __classPrivateFieldGet(this, _getExportColumns).call(this),
|
|
544
|
+
isCSV: false
|
|
545
|
+
});
|
|
546
|
+
};
|
|
547
|
+
this.exportCSV = () => {
|
|
548
|
+
this.export.emit({
|
|
549
|
+
file: null,
|
|
550
|
+
columns: __classPrivateFieldGet(this, _getExportColumns).call(this),
|
|
551
|
+
isCSV: true
|
|
552
|
+
});
|
|
553
|
+
};
|
|
554
|
+
this.exportRaw = () => {
|
|
555
|
+
this.export.emit({
|
|
556
|
+
file: null,
|
|
557
|
+
columns: __classPrivateFieldGet(this, _getExportColumns).call(this),
|
|
558
|
+
isRaw: true
|
|
536
559
|
});
|
|
537
560
|
};
|
|
538
561
|
this.loadFiles = (group = null) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -573,18 +596,14 @@ class SdPopupExport {
|
|
|
573
596
|
});
|
|
574
597
|
}));
|
|
575
598
|
this.generateTemplate = () => __awaiter(this, void 0, void 0, function* () {
|
|
576
|
-
var _g, _h;
|
|
577
599
|
this.loadingService.start();
|
|
578
|
-
|
|
579
|
-
if (result === null || result === void 0 ? void 0 : result.filePath) {
|
|
580
|
-
this.exportService.download(result.filePath, `${((_h = (_g = this.gridOption) === null || _g === void 0 ? void 0 : _g.export) === null || _h === void 0 ? void 0 : _h.fileName) || uuid}.xlsx`);
|
|
581
|
-
}
|
|
600
|
+
yield __classPrivateFieldGet(this, _initTemplate).call(this).finally(this.loadingService.stop);
|
|
582
601
|
});
|
|
583
602
|
this.generateAndUploadTemplate = (fileName) => __awaiter(this, void 0, void 0, function* () {
|
|
584
|
-
var _j, _k, _l, _m, _o
|
|
603
|
+
var _g, _h, _j, _k, _l, _m, _o;
|
|
585
604
|
const sheets = [];
|
|
586
|
-
if (Array.isArray((
|
|
587
|
-
for (const sheet of (
|
|
605
|
+
if (Array.isArray((_h = (_g = this.gridOption) === null || _g === void 0 ? void 0 : _g.export) === null || _h === void 0 ? void 0 : _h.sheets)) {
|
|
606
|
+
for (const sheet of (_k = (_j = this.gridOption) === null || _j === void 0 ? void 0 : _j.export) === null || _k === void 0 ? void 0 : _k.sheets) {
|
|
588
607
|
if (sheet.name && sheet.items && sheet.fields) {
|
|
589
608
|
if (Array.isArray(sheet.items)) {
|
|
590
609
|
sheets.push({
|
|
@@ -606,11 +625,11 @@ class SdPopupExport {
|
|
|
606
625
|
return yield this.exportService.generateUploadTemplate({
|
|
607
626
|
key: this.key,
|
|
608
627
|
template: {
|
|
609
|
-
fileName: fileName || ((
|
|
628
|
+
fileName: fileName || ((_m = (_l = this.gridOption) === null || _l === void 0 ? void 0 : _l.export) === null || _m === void 0 ? void 0 : _m.fileName),
|
|
610
629
|
columns: this.columns.filter(e => this.selected[e.field]),
|
|
611
630
|
sheets
|
|
612
631
|
},
|
|
613
|
-
group: (
|
|
632
|
+
group: (_o = this.selectedGroup) === null || _o === void 0 ? void 0 : _o.code
|
|
614
633
|
});
|
|
615
634
|
});
|
|
616
635
|
this.onExport = (file) => {
|
|
@@ -621,11 +640,11 @@ class SdPopupExport {
|
|
|
621
640
|
this.ref.detectChanges();
|
|
622
641
|
};
|
|
623
642
|
this.uploadTemplate = () => __awaiter(this, void 0, void 0, function* () {
|
|
624
|
-
var
|
|
643
|
+
var _p, _q, _r;
|
|
625
644
|
const file = yield this.exportService.uploadTemplate({
|
|
626
645
|
key: this.key,
|
|
627
|
-
group: (
|
|
628
|
-
validator: (
|
|
646
|
+
group: (_p = this.selectedGroup) === null || _p === void 0 ? void 0 : _p.code,
|
|
647
|
+
validator: (_r = (_q = this.gridOption) === null || _q === void 0 ? void 0 : _q.export) === null || _r === void 0 ? void 0 : _r.validators
|
|
629
648
|
});
|
|
630
649
|
if (file) {
|
|
631
650
|
this.files = [...this.files, file];
|
|
@@ -647,7 +666,7 @@ class SdPopupExport {
|
|
|
647
666
|
});
|
|
648
667
|
};
|
|
649
668
|
this.createTemplate = () => __awaiter(this, void 0, void 0, function* () {
|
|
650
|
-
var
|
|
669
|
+
var _s, _t, _u, _v, _w;
|
|
651
670
|
const { translate } = this.translateService;
|
|
652
671
|
if (this.form.invalid) {
|
|
653
672
|
this.form.markAllAsTouched();
|
|
@@ -660,8 +679,8 @@ class SdPopupExport {
|
|
|
660
679
|
this.loadingService.start();
|
|
661
680
|
const fileName = this.templateName + '.xlsx';
|
|
662
681
|
try {
|
|
663
|
-
if ((
|
|
664
|
-
this.notifyService.notify.warning((
|
|
682
|
+
if ((_u = (_t = (_s = this.gridOption) === null || _s === void 0 ? void 0 : _s.export) === null || _t === void 0 ? void 0 : _t.validators) === null || _u === void 0 ? void 0 : _u.call(_t, fileName)) {
|
|
683
|
+
this.notifyService.notify.warning((_w = (_v = this.gridOption) === null || _v === void 0 ? void 0 : _v.export) === null || _w === void 0 ? void 0 : _w.validators(fileName));
|
|
665
684
|
return;
|
|
666
685
|
}
|
|
667
686
|
const result = yield this.generateAndUploadTemplate(fileName);
|
|
@@ -721,7 +740,7 @@ class SdPopupExport {
|
|
|
721
740
|
ngAfterViewInit() {
|
|
722
741
|
}
|
|
723
742
|
}
|
|
724
|
-
_getExportableColumns = new WeakMap(), _getExportableGroups = new WeakMap(), _initTemplate = new WeakMap();
|
|
743
|
+
_getExportableColumns = new WeakMap(), _getExportableGroups = new WeakMap(), _getExportColumns = new WeakMap(), _initTemplate = new WeakMap();
|
|
725
744
|
SdPopupExport.decorators = [
|
|
726
745
|
{ type: Component, args: [{
|
|
727
746
|
selector: 'sd-popup-export',
|
|
@@ -741,7 +760,8 @@ SdPopupExport.propDecorators = {
|
|
|
741
760
|
modal: [{ type: ViewChild, args: ['modal',] }],
|
|
742
761
|
listGroups: [{ type: ViewChild, args: ['listGroups',] }],
|
|
743
762
|
export: [{ type: Output }],
|
|
744
|
-
_gridOption: [{ type: Input, args: ['gridOption',] }]
|
|
763
|
+
_gridOption: [{ type: Input, args: ['gridOption',] }],
|
|
764
|
+
configuration: [{ type: Input }]
|
|
745
765
|
};
|
|
746
766
|
|
|
747
767
|
var _COLUMNS, _cache, _getKey, _default, _load, _get, _set, _remove;
|
|
@@ -1564,26 +1584,33 @@ class SdGridMaterial {
|
|
|
1564
1584
|
return ((_b = (_a = this.gridOption.export) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.filter(e => { var _a; return !((_a = e.export) === null || _a === void 0 ? void 0 : _a.disabled); })) || [];
|
|
1565
1585
|
});
|
|
1566
1586
|
_onExport.set(this, (args) => __awaiter(this, void 0, void 0, function* () {
|
|
1567
|
-
var _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
1587
|
+
var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
1568
1588
|
try {
|
|
1569
|
-
const { file,
|
|
1589
|
+
const { file, isCSV, isRaw } = args;
|
|
1590
|
+
let { columns } = args;
|
|
1570
1591
|
const pageSize = ((_h = (_g = this.gridOption) === null || _g === void 0 ? void 0 : _g.export) === null || _h === void 0 ? void 0 : _h.maxItemsPerRequest) || 1000;
|
|
1592
|
+
const batch = ((_k = (_j = this.gridOption) === null || _j === void 0 ? void 0 : _j.export) === null || _k === void 0 ? void 0 : _k.batch) || 1;
|
|
1571
1593
|
let total = this.total;
|
|
1572
1594
|
let pageNumber = 0;
|
|
1573
1595
|
let exportItems = [];
|
|
1574
1596
|
this.isExporting = true;
|
|
1575
1597
|
const items = [];
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1598
|
+
let promises = [];
|
|
1599
|
+
const handleData = () => __awaiter(this, void 0, void 0, function* () {
|
|
1600
|
+
var _u;
|
|
1601
|
+
const results = yield Promise.all(promises);
|
|
1602
|
+
promises = [];
|
|
1603
|
+
exportItems = [];
|
|
1604
|
+
for (const result of results) {
|
|
1605
|
+
if ('items' in result) {
|
|
1606
|
+
exportItems = [...exportItems, ...result.items];
|
|
1607
|
+
total = result.total;
|
|
1608
|
+
}
|
|
1609
|
+
else {
|
|
1610
|
+
exportItems = [...exportItems, ...result];
|
|
1611
|
+
}
|
|
1585
1612
|
}
|
|
1586
|
-
if ((
|
|
1613
|
+
if ((_u = this.gridOption.export) === null || _u === void 0 ? void 0 : _u.mapping) {
|
|
1587
1614
|
const results = this.gridOption.export.mapping(exportItems);
|
|
1588
1615
|
if (results instanceof Promise) {
|
|
1589
1616
|
exportItems = yield results;
|
|
@@ -1593,14 +1620,14 @@ class SdGridMaterial {
|
|
|
1593
1620
|
}
|
|
1594
1621
|
}
|
|
1595
1622
|
const totalPage = total / pageSize;
|
|
1596
|
-
const percent = Math.round(pageNumber * 100.0 / totalPage);
|
|
1623
|
+
const percent = Math.round((pageNumber - 1) * 100.0 / totalPage);
|
|
1597
1624
|
this.exportTitle = `Exporting...${percent}%`;
|
|
1598
1625
|
const allColumns = __classPrivateFieldGet(this, _allColumns).call(this);
|
|
1599
1626
|
const allExportedColumns = __classPrivateFieldGet(this, _allExportedColumns).call(this);
|
|
1600
1627
|
for (const item of exportItems) {
|
|
1601
1628
|
const obj = {};
|
|
1602
1629
|
const handle = (exportColumn) => __awaiter(this, void 0, void 0, function* () {
|
|
1603
|
-
var
|
|
1630
|
+
var _v, _w;
|
|
1604
1631
|
obj[exportColumn.field] = item[exportColumn.field];
|
|
1605
1632
|
const column = allColumns.find(e => e.field === exportColumn.field);
|
|
1606
1633
|
const exportedColumn = allExportedColumns.find(e => e.field === exportColumn.field);
|
|
@@ -1637,10 +1664,10 @@ class SdGridMaterial {
|
|
|
1637
1664
|
else if (column.type === 'bool') {
|
|
1638
1665
|
// Nếu là bool thì gán bằng giá trị trueValue và falseValue (nếu có), mặc định là TRUE/FALSE
|
|
1639
1666
|
if (item[column.field]) {
|
|
1640
|
-
obj[column.field] = ((
|
|
1667
|
+
obj[column.field] = ((_v = column.option) === null || _v === void 0 ? void 0 : _v.displayOnTrue) || 'True';
|
|
1641
1668
|
}
|
|
1642
1669
|
else if (obj[column.field] !== undefined && obj[column.field] !== null) {
|
|
1643
|
-
obj[column.field] = ((
|
|
1670
|
+
obj[column.field] = ((_w = column.option) === null || _w === void 0 ? void 0 : _w.displayOnFalse) || 'False';
|
|
1644
1671
|
}
|
|
1645
1672
|
}
|
|
1646
1673
|
else if (column.type === 'date') {
|
|
@@ -1684,19 +1711,37 @@ class SdGridMaterial {
|
|
|
1684
1711
|
}
|
|
1685
1712
|
items.push(obj);
|
|
1686
1713
|
}
|
|
1714
|
+
});
|
|
1715
|
+
while (pageNumber * pageSize < total) {
|
|
1716
|
+
promises.push(__classPrivateFieldGet(this, _exportedItems).call(this, pageNumber, pageSize));
|
|
1687
1717
|
pageNumber++;
|
|
1718
|
+
if (promises.length < batch) {
|
|
1719
|
+
continue;
|
|
1720
|
+
}
|
|
1721
|
+
yield handleData();
|
|
1722
|
+
}
|
|
1723
|
+
if (promises.length > 0) {
|
|
1724
|
+
yield handleData();
|
|
1688
1725
|
}
|
|
1689
1726
|
if (!(file === null || file === void 0 ? void 0 : file.filePath)) {
|
|
1690
1727
|
if (isCSV) {
|
|
1691
1728
|
yield this.exportService.exportCSV({
|
|
1692
1729
|
columns,
|
|
1693
1730
|
items,
|
|
1694
|
-
fileName: (
|
|
1731
|
+
fileName: (_m = (_l = this.gridOption) === null || _l === void 0 ? void 0 : _l.export) === null || _m === void 0 ? void 0 : _m.fileName
|
|
1732
|
+
});
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
if (isRaw) {
|
|
1736
|
+
yield this.exportService.exportExcelRaw({
|
|
1737
|
+
columns,
|
|
1738
|
+
items,
|
|
1739
|
+
fileName: (_p = (_o = this.gridOption) === null || _o === void 0 ? void 0 : _o.export) === null || _p === void 0 ? void 0 : _p.fileName
|
|
1695
1740
|
});
|
|
1696
1741
|
return;
|
|
1697
1742
|
}
|
|
1698
1743
|
const sheets = [];
|
|
1699
|
-
if (Array.isArray((
|
|
1744
|
+
if (Array.isArray((_r = (_q = this.gridOption) === null || _q === void 0 ? void 0 : _q.export) === null || _r === void 0 ? void 0 : _r.sheets)) {
|
|
1700
1745
|
for (const sheet of this.gridOption.export.sheets) {
|
|
1701
1746
|
if (sheet.name && sheet.items && sheet.fields) {
|
|
1702
1747
|
if (Array.isArray(sheet.items)) {
|
|
@@ -1719,7 +1764,7 @@ class SdGridMaterial {
|
|
|
1719
1764
|
yield this.exportService.export({
|
|
1720
1765
|
columns,
|
|
1721
1766
|
items,
|
|
1722
|
-
fileName: (
|
|
1767
|
+
fileName: (_t = (_s = this.gridOption) === null || _s === void 0 ? void 0 : _s.export) === null || _t === void 0 ? void 0 : _t.fileName,
|
|
1723
1768
|
sheets
|
|
1724
1769
|
});
|
|
1725
1770
|
return;
|
|
@@ -1740,10 +1785,12 @@ class SdGridMaterial {
|
|
|
1740
1785
|
this.onExport = (args) => __awaiter(this, void 0, void 0, function* () {
|
|
1741
1786
|
const { translate } = this.translateService;
|
|
1742
1787
|
if (!args.isCSV && this.gridOption.export.max && this.total > this.gridOption.export.max) {
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1788
|
+
args.isRaw = true;
|
|
1789
|
+
__classPrivateFieldGet(this, _onExport).call(this, args);
|
|
1790
|
+
// this.notifyService.confirm(translate(`Total rows reach limit, do you want to export CSV`)).then(() => {
|
|
1791
|
+
// args.isCSV = true;
|
|
1792
|
+
// this.#onExport(args);
|
|
1793
|
+
// });
|
|
1747
1794
|
return;
|
|
1748
1795
|
}
|
|
1749
1796
|
__classPrivateFieldGet(this, _onExport).call(this, args);
|
|
@@ -1753,8 +1800,8 @@ class SdGridMaterial {
|
|
|
1753
1800
|
this.reload(false);
|
|
1754
1801
|
};
|
|
1755
1802
|
this.onExpand = (rowData) => __awaiter(this, void 0, void 0, function* () {
|
|
1756
|
-
var
|
|
1757
|
-
if ((
|
|
1803
|
+
var _x, _y, _z, _0, _1;
|
|
1804
|
+
if ((_x = this.gridOption.subInformation) === null || _x === void 0 ? void 0 : _x.always) {
|
|
1758
1805
|
return;
|
|
1759
1806
|
}
|
|
1760
1807
|
if (rowData.isExpanding) {
|
|
@@ -1764,8 +1811,8 @@ class SdGridMaterial {
|
|
|
1764
1811
|
rowData.isExpanded = false;
|
|
1765
1812
|
return;
|
|
1766
1813
|
}
|
|
1767
|
-
const data = (
|
|
1768
|
-
if (!((
|
|
1814
|
+
const data = (_0 = (_z = (_y = this.gridOption) === null || _y === void 0 ? void 0 : _y.subInformation) === null || _z === void 0 ? void 0 : _z.onExpand) === null || _0 === void 0 ? void 0 : _0.call(_z, rowData);
|
|
1815
|
+
if (!((_1 = this.gridOption.subInformation) === null || _1 === void 0 ? void 0 : _1.multiple)) {
|
|
1769
1816
|
this.items.forEach(item => item.isExpanding = item.isExpanded = false);
|
|
1770
1817
|
}
|
|
1771
1818
|
if (data instanceof Promise) {
|
|
@@ -2104,7 +2151,7 @@ _paginator = new WeakMap(), _sort = new WeakMap(), _subscription$1 = new WeakMap
|
|
|
2104
2151
|
SdGridMaterial.decorators = [
|
|
2105
2152
|
{ type: Component, args: [{
|
|
2106
2153
|
selector: 'sd-grid-material',
|
|
2107
|
-
template: "<ng-container *ngIf=\"gridConfigurationObserver | async as gridConfiguration\">\r\n <ng-container *ngIf=\"\r\n gridConfiguration\r\n | sdGridConfigurationResult\r\n : gridOption\r\n : sdSubInformation as configuration\r\n \">\r\n <ng-container *ngIf=\"!gridOption.filter?.disabled\">\r\n <sd-grid-filter [filter]=\"gridOption?.filter\" [columns]=\"configuration.firstColumns\" [filterDefs]=\"filterDefs\">\r\n </sd-grid-filter>\r\n </ng-container>\r\n <ng-container *ngIf=\"items | sdGroup:gridOption; $implicit as groupedItems\">\r\n <div class=\"c-container {{ gridOption?.style?.grid }}\" [ngClass]=\"{ 'mat-elevation-z2': gridOption?.shadow }\">\r\n <div class=\"c-loading\" *ngIf=\"isLoading\">\r\n <mat-spinner *ngIf=\"isLoading\"></mat-spinner>\r\n </div>\r\n <ng-container>\r\n <div class=\"c-table\" sdScroll [ngStyle]=\"{\r\n 'max-height': gridOption?.maxHeight,\r\n 'min-height': gridOption?.minHeight\r\n }\">\r\n <table *ngIf=\"items?.length; else elseEmpty\" mat-table [dataSource]=\"groupedItems\" matSort\r\n [matSortDisabled]=\"!gridOption.sortable\" cdkDropList cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListDisabled]=\"!gridOption.dropDragColumnEnable\"\r\n (cdkDropListDropped)=\"drop($event, configuration.displayedColumns)\" multiTemplateDataRows>\r\n\r\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdSubInformation?.templateRef\">\r\n <ng-container *ngIf=\"gridOption?.subInformation?.always;else useExpandCollapse\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdSubInformation.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #useExpandCollapse>\r\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"item.isExpanded\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdSubInformation.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td mat-cell *matCellDef=\"let element\">\r\n <button *ngIf=\"!element.isExpanding && !gridOption?.subInformation?.always\" mat-icon-button\r\n aria-label=\"Expand & Collapse\" (click)=\"onExpand(element)\">\r\n <mat-icon *ngIf=\"!element.isExpanded\">expand_more</mat-icon>\r\n <mat-icon *ngIf=\"element.isExpanded\">expand_less</mat-icon>\r\n </button>\r\n <div *ngIf=\"element.isExpanding\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th class=\"text-center px-15\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <ng-container *ngIf=\"items | selectionVisibleSelectAll: gridOption?.selection | async\">\r\n <mat-checkbox *ngIf=\"!gridOption.selection?.single\" class=\"c-selection\" color=\"primary\"\r\n [(ngModel)]=\"isSelectAll\" (change)=\"onSelectAll()\">\r\n </mat-checkbox>\r\n </ng-container>\r\n\r\n </th>\r\n <td class=\"text-center px-15\" mat-cell *matCellDef=\"let item\" style=\"min-width: 50px; max-width: 50px\">\r\n <ng-container *ngIf=\"item | selectionVisible:gridOption?.selection\">\r\n <mat-checkbox class=\"c-selection\" color=\"primary\" [(ngModel)]=\"item.isSelected\"\r\n (change)=\"onSelect(item)\" [disabled]=\"\r\n selectedItems | selectionDisable: item:gridOption?.selection\r\n \">\r\n </mat-checkbox>\r\n </ng-container>\r\n\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditorValidation\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 2px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0 position-relative\" mat-cell *matCellDef=\"let item; index as idx\">\r\n <sd-desktop-editor-validation [sdId]=\"item.sdId\" [item]=\"item\" [items]=\"items\"\r\n [gridOption]=\"gridOption\">\r\n </sd-desktop-editor-validation>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditor\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <button class=\"c-btn-add\"\r\n *ngIf=\"gridOption.editor?.addable && (!gridOption.editor.limit || gridOption.editor.limit > items.length)\"\r\n (click)=\"onCreate()\" aria-hidden=\"true\" mat-icon-button>\r\n <mat-icon class=\"c-icon-add\">add</mat-icon>\r\n </button>\r\n </th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item; index as idx\">\r\n <ng-container *sdLet=\"item.editorStatus | sdEditorHandlerRow:item:gridOption as editorHandler\">\r\n <div *ngIf=\"editorHandler\" class=\"d-flex align-items-center justify-content-center\">\r\n <button *ngIf=\"editorHandler.editable\" class=\"mx-2\" (click)=\"onUpdate(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">edit</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.removable\" class=\"mx-2\" (click)=\"onRemove(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">delete</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.savable\" class=\"mx-2\" (click)=\"onSave(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">save</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.cancelable\" class=\"mx-2\" (click)=\"onCancel(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">close</mat-icon>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-command [commands]=\"gridOption.commands\" [item]=\"item\"></sd-desktop-command>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\"\r\n [attr.colspan]=\"!item?.sdGroup ? 1 : configuration.displayedColumns.length\">\r\n <div [innerHtml]=\"item?.sdGroup?.htmlTemplate | safeHtml\">\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.firstColumns; let i = index\"\r\n [matColumnDef]=\"column.field\" [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef cdkDrag class=\"px-8 py-8 c-th\"\r\n [ngStyle]=\"{ 'min-width': configuration.firstColumns[i].width }\" [attr.rowspan]=\"\r\n configuration.multipleHeader && column.type !== 'children-col'\r\n ? 2\r\n : 1\r\n \" [attr.colspan]=\"\r\n column.type === 'children-col' ? column.children?.length : 1\r\n \">\r\n <div>\r\n <div aria-hidden=\"false\" role=\"presentation\" mat-sort-header [disabled]=\"\r\n !column.sortable || column.type === 'children-col'\r\n \" [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"configuration.firstColumns[i].titleHtml || configuration.firstColumns[i].title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell class=\"d-block px-8\" *ngIf=\"!item?.sdGroup\" [sdId]=\"item.sdId\" [key]=\"key\"\r\n [value]=\"item[column.field]\" [column]=\"column\" [item]=\"item\" [idx]=\"i\" [cellDef]=\"cellDef\"\r\n [gridOption]=\"gridOption\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"\r\n footerDef[column.field].templateRef;\r\n context: { items: items, column: column }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns; let i = index\"\r\n [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"c-th px-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell class=\"d-block px-8\" [sdId]=\"item.sdId\" [key]=\"key\" [value]=\"item[column.field]\"\r\n [column]=\"column\" [item]=\"item\" [idx]=\"i\" [cellDef]=\"cellDef\" [gridOption]=\"gridOption\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"\r\n footerDef[column.field].templateRef;\r\n context: { items: items, column: column }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\">\r\n </tr>\r\n <ng-container *ngIf=\"configuration.secondHeaders?.length\">\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\">\r\n </tr>\r\n </ng-container>\r\n <tr mat-row *matRowDef=\"let row; columns: configuration.displayedColumns\" matRipple class=\"c-row\"\r\n [class.selected]=\"row.isSelected\" [style]=\"row | sdStyleRowCss:gridOption\"></tr>\r\n\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']\" class=\"c-detail-row\"></tr>\r\n <ng-container *ngIf=\"hasFooter && configuration.displayedFooters?.length\">\r\n <tr mat-footer-row *matFooterRowDef=\"configuration.displayedFooters; sticky: true\"></tr>\r\n </ng-container>\r\n </table>\r\n <ng-template #elseEmpty>\r\n <table mat-table [dataSource]=\"[{}]\">\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th class=\"px-15\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditorValidation\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 4px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\">\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditor\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <button class=\"c-btn-add\"\r\n *ngIf=\"gridOption.editor?.addable && (!gridOption.editor.limit || gridOption.editor.limit > items.length)\"\r\n (click)=\"onCreate()\" aria-hidden=\"true\" mat-icon-button>\r\n <mat-icon class=\"c-icon-add\">add</mat-icon>\r\n </button>\r\n </th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\">\r\n <th class=\"px-8\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEmpty\">\r\n <td class=\"c-empty\" mat-cell *matCellDef=\"let item\"\r\n [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdEmptyData?.templateRef; else sdEmptyDataNoRef\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdEmptyData.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #sdEmptyDataNoRef>\r\n <mat-icon fontSet=\"material-icons-outlined\">leaderboard</mat-icon>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\">\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.columns\" [matColumnDef]=\"column.field\"\r\n [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n </th>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.firstColumns; let i = index\"\r\n [matColumnDef]=\"column.field\" [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': configuration.firstColumns[i].width }\" [attr.rowspan]=\"\r\n configuration.multipleHeader &&\r\n column.type !== 'children-col'\r\n ? 2\r\n : 1\r\n \" [attr.colspan]=\"\r\n column.type === 'children-col' ? column.children?.length : 1\r\n \">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"configuration.firstColumns[i].titleHtml || configuration.firstColumns[i].title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\"></sd-column-inline-filter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns\" [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\"></sd-column-inline-filter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\">\r\n </tr>\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\">\r\n </tr>\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdEmpty']\"></tr>\r\n </table>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n <div class=\"c-paginator\">\r\n <div class=\"c-action\">\r\n <sd-button *ngIf=\"\r\n !gridOption.filter?.disabled && !gridOption.filter?.inlineColumn\r\n \" class=\"mr-10\" [title]=\"'Filter' | sdTranslate\" icon=\"filter_alt\" size=\"sm\" (action)=\"gridFilter.open()\"\r\n type=\"link\">\r\n </sd-button>\r\n <sd-button *ngIf=\"gridOption.reload?.visible\" class=\"mr-10\" [title]=\"'Reload' | sdTranslate\" icon=\"refresh\"\r\n size=\"sm\" (action)=\"reload()\" [disabled]=\"!items?.length\" type=\"link\">\r\n </sd-button>\r\n <ng-container *ngIf=\"gridOption.export?.visible && items?.length\">\r\n <ng-container *ngIf=\"isExporting; else unExporting\">\r\n <sd-button class=\"mr-10\" [loading]=\"isExporting\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\"\r\n size=\"sm\" type=\"link\">\r\n </sd-button>\r\n </ng-container>\r\n <ng-template #unExporting>\r\n <sd-button class=\"mr-10\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\"\r\n [matMenuTriggerFor]=\"menu\" type=\"link\">\r\n </sd-button>\r\n </ng-template>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <button *ngIf=\"gridOption.export?.visibleExcel !== false\" mat-menu-item\r\n (click)=\"sdPopupExport.exportDefault()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> {{ \"Export excel\" | sdTranslate }}</span>\r\n </button>\r\n <button *ngIf=\"gridOption.export?.visibleCSV !== false\" mat-menu-item\r\n (click)=\"sdPopupExport.exportDefault(true)\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> {{ \"Export CSV\" | sdTranslate }}</span>\r\n </button>\r\n <button *ngIf=\"gridOption.export?.key\" mat-menu-item (click)=\"sdPopupExport.open()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">settings</mat-icon>\r\n <span> {{ \"Configure\" | sdTranslate }}</span>\r\n </button>\r\n </mat-menu>\r\n </ng-container>\r\n <sd-button *ngIf=\"gridOption.config?.visible\" class=\"mr-10\" [title]=\"'Configure' | sdTranslate\"\r\n icon=\"settings\" size=\"sm\" (action)=\"popupGridConfiguration.open()\" type=\"link\">\r\n </sd-button>\r\n </div>\r\n <mat-paginator [class.d-none]=\"gridOption.paginate?.hidden\" [length]=\"total\"\r\n [pageSize]=\"gridOption.paginate?.pageSize\" [pageSizeOptions]=\"gridOption.paginate?.pages\"\r\n [showFirstLastButtons]=\"gridOption.paginate?.showFirstLastButtons\"></mat-paginator>\r\n </div>\r\n </div>\r\n <sd-grid-quick-action [gridOption]=\"gridOption\" [selectedItems]=\"selectedItems\"\r\n (clear)=\"onClearSelection(groupedItems)\">\r\n </sd-grid-quick-action>\r\n <sd-popup-export *ngIf=\"gridOption.export?.visible\" [gridOption]=\"gridOption\" (export)=\"onExport($event)\"\r\n #sdPopupExport>\r\n </sd-popup-export>\r\n <sd-popup-grid-configuration [gridOption]=\"gridOption\" [key]=\"key\" #popupGridConfiguration>\r\n </sd-popup-grid-configuration>\r\n </ng-container>\r\n </ng-container>\r\n</ng-container>",
|
|
2154
|
+
template: "<ng-container *ngIf=\"gridConfigurationObserver | async as gridConfiguration\">\r\n <ng-container *ngIf=\"\r\n gridConfiguration\r\n | sdGridConfigurationResult\r\n : gridOption\r\n : sdSubInformation as configuration\r\n \">\r\n <ng-container *ngIf=\"!gridOption.filter?.disabled\">\r\n <sd-grid-filter [filter]=\"gridOption?.filter\" [columns]=\"configuration.firstColumns\" [filterDefs]=\"filterDefs\">\r\n </sd-grid-filter>\r\n </ng-container>\r\n <ng-container *ngIf=\"items | sdGroup:gridOption; $implicit as groupedItems\">\r\n <div class=\"c-container {{ gridOption?.style?.grid }}\" [ngClass]=\"{ 'mat-elevation-z2': gridOption?.shadow }\">\r\n <div class=\"c-loading\" *ngIf=\"isLoading\">\r\n <mat-spinner *ngIf=\"isLoading\"></mat-spinner>\r\n </div>\r\n <ng-container>\r\n <div class=\"c-table\" sdScroll [ngStyle]=\"{\r\n 'max-height': gridOption?.maxHeight,\r\n 'min-height': gridOption?.minHeight\r\n }\">\r\n <table *ngIf=\"items?.length; else elseEmpty\" mat-table [dataSource]=\"groupedItems\" matSort\r\n [matSortDisabled]=\"!gridOption.sortable\" cdkDropList cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListDisabled]=\"!gridOption.dropDragColumnEnable\"\r\n (cdkDropListDropped)=\"drop($event, configuration.displayedColumns)\" multiTemplateDataRows>\r\n\r\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdSubInformation?.templateRef\">\r\n <ng-container *ngIf=\"gridOption?.subInformation?.always;else useExpandCollapse\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdSubInformation.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #useExpandCollapse>\r\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"item.isExpanded\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdSubInformation.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td mat-cell *matCellDef=\"let element\">\r\n <button *ngIf=\"!element.isExpanding && !gridOption?.subInformation?.always\" mat-icon-button\r\n aria-label=\"Expand & Collapse\" (click)=\"onExpand(element)\">\r\n <mat-icon *ngIf=\"!element.isExpanded\">expand_more</mat-icon>\r\n <mat-icon *ngIf=\"element.isExpanded\">expand_less</mat-icon>\r\n </button>\r\n <div *ngIf=\"element.isExpanding\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th class=\"text-center px-15\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <ng-container *ngIf=\"items | selectionVisibleSelectAll: gridOption?.selection | async\">\r\n <mat-checkbox *ngIf=\"!gridOption.selection?.single\" class=\"c-selection\" color=\"primary\"\r\n [(ngModel)]=\"isSelectAll\" (change)=\"onSelectAll()\">\r\n </mat-checkbox>\r\n </ng-container>\r\n\r\n </th>\r\n <td class=\"text-center px-15\" mat-cell *matCellDef=\"let item\" style=\"min-width: 50px; max-width: 50px\">\r\n <ng-container *ngIf=\"item | selectionVisible:gridOption?.selection\">\r\n <mat-checkbox class=\"c-selection\" color=\"primary\" [(ngModel)]=\"item.isSelected\"\r\n (change)=\"onSelect(item)\" [disabled]=\"\r\n selectedItems | selectionDisable: item:gridOption?.selection\r\n \">\r\n </mat-checkbox>\r\n </ng-container>\r\n\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditorValidation\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 2px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0 position-relative\" mat-cell *matCellDef=\"let item; index as idx\">\r\n <sd-desktop-editor-validation [sdId]=\"item.sdId\" [item]=\"item\" [items]=\"items\"\r\n [gridOption]=\"gridOption\">\r\n </sd-desktop-editor-validation>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditor\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <button class=\"c-btn-add\"\r\n *ngIf=\"gridOption.editor?.addable && (!gridOption.editor.limit || gridOption.editor.limit > items.length)\"\r\n (click)=\"onCreate()\" aria-hidden=\"true\" mat-icon-button>\r\n <mat-icon class=\"c-icon-add\">add</mat-icon>\r\n </button>\r\n </th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item; index as idx\">\r\n <ng-container *sdLet=\"item.editorStatus | sdEditorHandlerRow:item:gridOption as editorHandler\">\r\n <div *ngIf=\"editorHandler\" class=\"d-flex align-items-center justify-content-center\">\r\n <button *ngIf=\"editorHandler.editable\" class=\"mx-2\" (click)=\"onUpdate(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">edit</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.removable\" class=\"mx-2\" (click)=\"onRemove(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">delete</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.savable\" class=\"mx-2\" (click)=\"onSave(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">save</mat-icon>\r\n </button>\r\n <button *ngIf=\"editorHandler.cancelable\" class=\"mx-2\" (click)=\"onCancel(item)\" aria-hidden=\"true\"\r\n mat-icon-button>\r\n <mat-icon class=\"c-icon\">close</mat-icon>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-command [commands]=\"gridOption.commands\" [item]=\"item\"></sd-desktop-command>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\"\r\n [attr.colspan]=\"!item?.sdGroup ? 1 : configuration.displayedColumns.length\">\r\n <div [innerHtml]=\"item?.sdGroup?.htmlTemplate | safeHtml\">\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.firstColumns; let i = index\"\r\n [matColumnDef]=\"column.field\" [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef cdkDrag class=\"px-8 py-8 c-th\"\r\n [ngStyle]=\"{ 'min-width': configuration.firstColumns[i].width }\" [attr.rowspan]=\"\r\n configuration.multipleHeader && column.type !== 'children-col'\r\n ? 2\r\n : 1\r\n \" [attr.colspan]=\"\r\n column.type === 'children-col' ? column.children?.length : 1\r\n \">\r\n <div>\r\n <div aria-hidden=\"false\" role=\"presentation\" mat-sort-header [disabled]=\"\r\n !column.sortable || column.type === 'children-col'\r\n \" [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"configuration.firstColumns[i].titleHtml || configuration.firstColumns[i].title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell class=\"d-block px-8\" *ngIf=\"!item?.sdGroup\" [sdId]=\"item.sdId\" [key]=\"key\"\r\n [value]=\"item[column.field]\" [column]=\"column\" [item]=\"item\" [idx]=\"i\" [cellDef]=\"cellDef\"\r\n [gridOption]=\"gridOption\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"\r\n footerDef[column.field].templateRef;\r\n context: { items: items, column: column }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns; let i = index\"\r\n [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"c-th px-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell class=\"d-block px-8\" [sdId]=\"item.sdId\" [key]=\"key\" [value]=\"item[column.field]\"\r\n [column]=\"column\" [item]=\"item\" [idx]=\"i\" [cellDef]=\"cellDef\" [gridOption]=\"gridOption\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"\r\n footerDef[column.field].templateRef;\r\n context: { items: items, column: column }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\">\r\n </tr>\r\n <ng-container *ngIf=\"configuration.secondHeaders?.length\">\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\">\r\n </tr>\r\n </ng-container>\r\n <tr mat-row *matRowDef=\"let row; columns: configuration.displayedColumns\" matRipple class=\"c-row\"\r\n [class.selected]=\"row.isSelected\" [style]=\"row | sdStyleRowCss:gridOption\"></tr>\r\n\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']\" class=\"c-detail-row\"></tr>\r\n <ng-container *ngIf=\"hasFooter && configuration.displayedFooters?.length\">\r\n <tr mat-footer-row *matFooterRowDef=\"configuration.displayedFooters; sticky: true\"></tr>\r\n </ng-container>\r\n </table>\r\n <ng-template #elseEmpty>\r\n <table mat-table [dataSource]=\"[{}]\">\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th class=\"px-15\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditorValidation\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 4px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\">\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEditor\">\r\n <th class=\"px-8 py-8\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <button class=\"c-btn-add\"\r\n *ngIf=\"gridOption.editor?.addable && (!gridOption.editor.limit || gridOption.editor.limit > items.length)\"\r\n (click)=\"onCreate()\" aria-hidden=\"true\" mat-icon-button>\r\n <mat-icon class=\"c-icon-add\">add</mat-icon>\r\n </button>\r\n </th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\">\r\n <th class=\"px-8\" mat-header-cell *matHeaderCellDef style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\">\r\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdEmpty\">\r\n <td class=\"c-empty\" mat-cell *matCellDef=\"let item\"\r\n [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdEmptyData?.templateRef; else sdEmptyDataNoRef\">\r\n <ng-container *ngTemplateOutlet=\"\r\n sdEmptyData.templateRef;\r\n context: { item: item }\r\n \">\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #sdEmptyDataNoRef>\r\n <mat-icon fontSet=\"material-icons-outlined\">leaderboard</mat-icon>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n </th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\">\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.columns\" [matColumnDef]=\"column.field\"\r\n [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n </th>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.firstColumns; let i = index\"\r\n [matColumnDef]=\"column.field\" [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': configuration.firstColumns[i].width }\" [attr.rowspan]=\"\r\n configuration.multipleHeader &&\r\n column.type !== 'children-col'\r\n ? 2\r\n : 1\r\n \" [attr.colspan]=\"\r\n column.type === 'children-col' ? column.children?.length : 1\r\n \">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"configuration.firstColumns[i].titleHtml || configuration.firstColumns[i].title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\"></sd-column-inline-filter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns\" [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef class=\"c-th px-8 py-8\"\r\n [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\" [innerHTML]=\"column.titleHtml || column.title\">\r\n </div>\r\n <sd-column-inline-filter *ngIf=\"gridOption.filter?.inlineColumn\"\r\n [value]=\"columnFilter[column.field]\" [columnFilter]=\"columnFilter\" [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\"></sd-column-inline-filter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\">\r\n </tr>\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\">\r\n </tr>\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdEmpty']\"></tr>\r\n </table>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n <div class=\"c-paginator\">\r\n <div class=\"c-action\">\r\n <sd-button *ngIf=\"\r\n !gridOption.filter?.disabled && !gridOption.filter?.inlineColumn\r\n \" class=\"mr-10\" [title]=\"'Filter' | sdTranslate\" icon=\"filter_alt\" size=\"sm\" (action)=\"gridFilter.open()\"\r\n type=\"link\">\r\n </sd-button>\r\n <sd-button *ngIf=\"gridOption.reload?.visible\" class=\"mr-10\" [title]=\"'Reload' | sdTranslate\" icon=\"refresh\"\r\n size=\"sm\" (action)=\"reload()\" [disabled]=\"!items?.length\" type=\"link\">\r\n </sd-button>\r\n <ng-container *ngIf=\"gridOption.export?.visible && items?.length\">\r\n <ng-container *ngIf=\"isExporting; else unExporting\">\r\n <sd-button class=\"mr-10\" [loading]=\"isExporting\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\"\r\n size=\"sm\" type=\"link\">\r\n </sd-button>\r\n </ng-container>\r\n <ng-template #unExporting>\r\n <sd-button class=\"mr-10\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\"\r\n [matMenuTriggerFor]=\"menu\" type=\"link\">\r\n </sd-button>\r\n </ng-template>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <button *ngIf=\"gridOption.export?.visibleExcel !== false\" mat-menu-item\r\n (click)=\"sdPopupExport.exportDefault()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> {{ \"Export excel\" | sdTranslate }}</span>\r\n </button>\r\n <button *ngIf=\"gridOption.export?.visibleExcelRaw !== false\" mat-menu-item\r\n (click)=\"sdPopupExport.exportRaw()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> {{ \"Export excel raw\" | sdTranslate }}</span>\r\n </button>\r\n <button *ngIf=\"gridOption.export?.visibleCSV !== false\" mat-menu-item\r\n (click)=\"sdPopupExport.exportCSV()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> {{ \"Export CSV\" | sdTranslate }}</span>\r\n </button>\r\n <button *ngIf=\"gridOption.export?.key\" mat-menu-item (click)=\"sdPopupExport.open()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">settings</mat-icon>\r\n <span> {{ \"Configure\" | sdTranslate }}</span>\r\n </button>\r\n </mat-menu>\r\n </ng-container>\r\n <sd-button *ngIf=\"gridOption.config?.visible\" class=\"mr-10\" [title]=\"'Configure' | sdTranslate\"\r\n icon=\"settings\" size=\"sm\" (action)=\"popupGridConfiguration.open()\" type=\"link\">\r\n </sd-button>\r\n </div>\r\n <mat-paginator [class.d-none]=\"gridOption.paginate?.hidden\" [length]=\"total\"\r\n [pageSize]=\"gridOption.paginate?.pageSize\" [pageSizeOptions]=\"gridOption.paginate?.pages\"\r\n [showFirstLastButtons]=\"gridOption.paginate?.showFirstLastButtons\"></mat-paginator>\r\n </div>\r\n </div>\r\n <sd-grid-quick-action [gridOption]=\"gridOption\" [selectedItems]=\"selectedItems\"\r\n (clear)=\"onClearSelection(groupedItems)\">\r\n </sd-grid-quick-action>\r\n <sd-popup-export *ngIf=\"gridOption.export?.visible\" [configuration]=\"configuration\" [gridOption]=\"gridOption\" (export)=\"onExport($event)\"\r\n #sdPopupExport>\r\n </sd-popup-export>\r\n <sd-popup-grid-configuration [gridOption]=\"gridOption\" [key]=\"key\" #popupGridConfiguration>\r\n </sd-popup-grid-configuration>\r\n </ng-container>\r\n </ng-container>\r\n</ng-container>",
|
|
2108
2155
|
animations: [
|
|
2109
2156
|
trigger('detailExpand', [
|
|
2110
2157
|
state('collapsed', style({ height: '0', minHeight: '0', visibility: 'hidden' })),
|