@porscheinformatik/material-addons 10.2.5 → 10.3.0

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.
@@ -8,7 +8,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
8
8
  import { MatInputModule } from '@angular/material/input';
9
9
  import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
10
10
  import { Title } from '@angular/platform-browser';
11
- import { TranslateService } from '@ngx-translate/core';
11
+ import { TranslateService, TranslateModule } from '@ngx-translate/core';
12
12
  import { of, Subject, Subscription } from 'rxjs';
13
13
  import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
14
14
  import { map, throttleTime, switchMap, tap, startWith, takeUntil, distinctUntilChanged } from 'rxjs/operators';
@@ -20,6 +20,10 @@ import { trigger, transition, style, animate, state } from '@angular/animations'
20
20
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
21
21
  import { MatSort, MatSortModule } from '@angular/material/sort';
22
22
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
23
+ import { SelectionModel } from '@angular/cdk/collections';
24
+ import { v4 } from 'uuid';
25
+ import { MatCheckboxModule } from '@angular/material/checkbox';
26
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
23
27
  import { Directionality } from '@angular/cdk/bidi';
24
28
  import { CdkStepHeader, STEP_STATE, CdkStep, CdkStepper, CdkStepperModule } from '@angular/cdk/stepper';
25
29
  import { FocusMonitor } from '@angular/cdk/a11y';
@@ -1499,30 +1503,49 @@ TableModule.decorators = [
1499
1503
  },] }
1500
1504
  ];
1501
1505
 
1506
+ class DataTableActionType {
1507
+ }
1508
+ DataTableActionType.SINGLE = "SINGLE";
1509
+ DataTableActionType.BATCH = "BATCH";
1510
+ DataTableActionType.NONE = "NONE";
1511
+
1502
1512
  class DataTableComponent {
1503
1513
  constructor() {
1504
1514
  var _a;
1505
- this.ACTION_COLUMN_NAME = '__action__';
1515
+ this.ACTION_COLUMN_NAME = "__action__";
1516
+ this.SINGLE = DataTableActionType.SINGLE;
1517
+ this.BATCH = DataTableActionType.BATCH;
1518
+ this.NONE = DataTableActionType.NONE;
1506
1519
  this.columns = [];
1507
- this.filterLabel = 'NOT SET';
1508
- this.filterPlaceholder = 'NOT SET';
1520
+ this.filterLabel = "Filter";
1521
+ this.filterPlaceholder = "";
1522
+ this.noDataText = "No matching data found";
1509
1523
  this.pageSizeOptions = [5, 10, 15];
1510
1524
  this.defaultPageSize = ((_a = this.pageSizeOptions) === null || _a === void 0 ? void 0 : _a[0]) || 10;
1511
- this.rowActions = [];
1512
- this.tableActions = [];
1513
- this.tableAction = new EventEmitter();
1514
- this.rowAction = new EventEmitter();
1525
+ this.actions = [];
1515
1526
  this.sortEvent = new EventEmitter();
1527
+ this.actionEvent = new EventEmitter();
1528
+ this.pagingEvent = new EventEmitter();
1529
+ this.tableActions = [];
1530
+ this.rowActions = [];
1531
+ this.allSelected = false;
1532
+ this.displayedDataMap = new Map();
1533
+ this.actualDataMap = new Map();
1534
+ this.selectionModel = new SelectionModel(true);
1516
1535
  this.isFilterEnabled = false;
1517
1536
  this.isPaginationEnabled = false;
1537
+ this.mode = this.NONE;
1538
+ this.isRowClickable = false;
1539
+ this.isLoading = false;
1518
1540
  }
1519
- set displayedData(data) {
1541
+ set tableData(data) {
1520
1542
  if (!this.dataSource) {
1521
1543
  this.dataSource = new MatTableDataSource(data);
1522
1544
  }
1523
- else {
1524
- this.dataSource.data = data;
1525
- }
1545
+ this.createDataMapsAndSetDisplayedDataSourceData(data);
1546
+ }
1547
+ set loading(isLoading) {
1548
+ this.isLoading = isLoading;
1526
1549
  }
1527
1550
  set paginationEnabled(isPaginationEnabled) {
1528
1551
  this.isPaginationEnabled = isPaginationEnabled;
@@ -1536,47 +1559,203 @@ class DataTableComponent {
1536
1559
  this.isFilterEnabled = isFilterEnabled;
1537
1560
  this.setFilterValue(undefined);
1538
1561
  }
1562
+ set forceMode(mode) {
1563
+ if (mode === this.SINGLE || mode === this.BATCH || mode === this.NONE) {
1564
+ this._forceMode = mode;
1565
+ this.mode = mode;
1566
+ this.setActions();
1567
+ }
1568
+ }
1539
1569
  ngOnInit() {
1540
1570
  this.columnNames = this.columns.map(column => column.label);
1541
- this.isRowClickable = this.rowActions.length > 0;
1542
- if (this.isRowClickable) {
1543
- this.columnNames.unshift(this.ACTION_COLUMN_NAME);
1571
+ this.mode = this.getTableMode();
1572
+ this.setActions();
1573
+ if (this.mode !== this.NONE) {
1574
+ this.isRowClickable = true;
1544
1575
  this.defaultAction = this.rowActions[0];
1545
1576
  }
1577
+ this.columnNames.unshift(this.ACTION_COLUMN_NAME);
1546
1578
  }
1547
1579
  ngAfterViewInit() {
1548
1580
  this.dataSource.paginator = this.paginator;
1549
1581
  this.dataSource.sort = this.sort;
1550
1582
  }
1551
- onFilter(value) {
1552
- this.setFilterValue(value);
1583
+ get selectedCount() {
1584
+ var _a;
1585
+ return ((_a = this.selectionModel) === null || _a === void 0 ? void 0 : _a.selected) ? this.selectionModel.selected.length : 0;
1586
+ }
1587
+ get rowCount() {
1588
+ var _a;
1589
+ return ((_a = this.dataSource) === null || _a === void 0 ? void 0 : _a._pageData(this.dataSource.data)) ? this.dataSource._pageData(this.dataSource.data).length : 0;
1590
+ }
1591
+ getSelectedCount(actionType) {
1592
+ const count = this.selectedCount;
1593
+ if (actionType != this.BATCH || count < 2) {
1594
+ return "";
1595
+ }
1596
+ return " (" + count + ")";
1597
+ }
1598
+ isDisabled(actionType) {
1599
+ switch (actionType) {
1600
+ case this.SINGLE:
1601
+ return this.selectedCount != 1;
1602
+ case this.BATCH:
1603
+ return this.selectedCount < 1;
1604
+ default:
1605
+ return false;
1606
+ }
1607
+ }
1608
+ onToggleSelectAll() {
1609
+ // clear all selection first
1610
+ this.selectionModel.clear();
1611
+ // toggle all checkbox
1612
+ this.allSelected = !this.allSelected;
1613
+ if (this.allSelected) {
1614
+ // select all rows of the current page
1615
+ this.dataSource._pageData(this.dataSource.data).forEach((row) => {
1616
+ const dataRow = row;
1617
+ const rowId = "" + dataRow.rowId;
1618
+ this.selectionModel.select(rowId);
1619
+ });
1620
+ }
1621
+ }
1622
+ isSelected(rowId) {
1623
+ return this.selectionModel.isSelected(rowId);
1624
+ }
1625
+ setFilterValue(value) {
1626
+ this.dataSource.filter = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
1627
+ }
1628
+ onRowCheckbox(event, row) {
1629
+ event.stopPropagation(); // no click event on row
1630
+ this.selectionModel.toggle(row.rowId);
1553
1631
  }
1554
1632
  onRowEvent(event, row, action = this.defaultAction) {
1555
- if (!!action && !this.isClickOnRowMenuIcon(event)) {
1556
- this.rowAction.emit(Object.assign(Object.assign({}, action), { outputRow: row }));
1633
+ switch (this.mode) {
1634
+ case this.BATCH:
1635
+ this.onRowCheckbox(event, row);
1636
+ break;
1637
+ case this.SINGLE:
1638
+ // emit the default action if the row (not the icon!) was clicked
1639
+ if (!!action && !DataTableComponent.isClickOnRowMenuIcon(event)) {
1640
+ const selected = [];
1641
+ // if ID-generator is provided, return the ID, else return the ACTUAL data
1642
+ selected.push(this.idGenerator ? row.rowId : this.actualDataMap.get(row.rowId));
1643
+ this.emitTableAction(action, selected);
1644
+ }
1645
+ break;
1646
+ default:
1647
+ // do nothing if mode is NONE (or null)
1648
+ return;
1557
1649
  }
1558
1650
  }
1559
1651
  onSortingEvent(sortingParams) {
1560
1652
  this.sortEvent.emit(sortingParams);
1561
1653
  }
1654
+ onPaginationEvent(event) {
1655
+ this.pagingEvent.emit(event);
1656
+ }
1562
1657
  onTableAction(tableAction) {
1563
1658
  if (!!tableAction) {
1564
- this.tableAction.emit(tableAction);
1659
+ const selection = [];
1660
+ for (const selected of this.selectionModel.selected) {
1661
+ selection.push(this.idGenerator ? selected : this.actualDataMap.get(selected));
1662
+ }
1663
+ tableAction.selected = selection;
1664
+ this.actionEvent.emit(tableAction);
1565
1665
  }
1566
1666
  }
1567
- setFilterValue(value) {
1568
- this.dataSource.filter = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
1667
+ static transformData(value, transformer, transformerParams) {
1668
+ if (!transformer || !(transformer instanceof Function)) {
1669
+ return value;
1670
+ }
1671
+ return transformer(value, transformerParams);
1569
1672
  }
1570
- isClickOnRowMenuIcon(event) {
1673
+ static generateRowId() {
1674
+ return v4();
1675
+ }
1676
+ static isClickOnRowMenuIcon(event) {
1571
1677
  var _a;
1572
- return (_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.classList.contains('mat-icon');
1678
+ return (_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.classList.contains("mat-icon");
1679
+ }
1680
+ emitTableAction(action, selected) {
1681
+ const emitAction = Object.assign({}, action);
1682
+ if (action.type !== this.NONE) {
1683
+ emitAction.selected = [...selected];
1684
+ }
1685
+ this.actionEvent.emit(emitAction);
1686
+ }
1687
+ generateDisplayedDataElement(rowId, actualDataElement) {
1688
+ const displayedDataElement = {};
1689
+ displayedDataElement["rowId"] = rowId;
1690
+ for (const column of this.columns) {
1691
+ const actualValue = actualDataElement[column.dataPropertyName];
1692
+ displayedDataElement[column.dataPropertyName] = DataTableComponent.transformData(actualValue, column.transformer, column.transformerParams);
1693
+ }
1694
+ return displayedDataElement;
1695
+ }
1696
+ setActions() {
1697
+ this.rowActions = [];
1698
+ this.tableActions = [];
1699
+ for (const action of this.actions) {
1700
+ if (this.mode !== action.hiddenInMode) {
1701
+ switch (action.type) {
1702
+ case this.SINGLE:
1703
+ if (this.mode === this.SINGLE) {
1704
+ this.rowActions.push(action);
1705
+ }
1706
+ else {
1707
+ this.tableActions.push(action);
1708
+ }
1709
+ break;
1710
+ case this.BATCH:
1711
+ if (this.mode !== this.SINGLE) {
1712
+ this.tableActions.push(action);
1713
+ }
1714
+ break;
1715
+ default:
1716
+ this.tableActions.push(action);
1717
+ }
1718
+ }
1719
+ }
1720
+ }
1721
+ createDataMapsAndSetDisplayedDataSourceData(data) {
1722
+ const displayedDataList = [];
1723
+ this.actualDataMap.clear();
1724
+ this.displayedDataMap.clear();
1725
+ for (const dataEntry of data) {
1726
+ const rowId = (this.idGenerator) ? this.idGenerator(dataEntry) : DataTableComponent.generateRowId();
1727
+ this.actualDataMap.set(rowId, dataEntry);
1728
+ const displayedDataElement = this.generateDisplayedDataElement(rowId, dataEntry);
1729
+ this.displayedDataMap.set(rowId, displayedDataElement);
1730
+ displayedDataList.push(displayedDataElement);
1731
+ }
1732
+ this.dataSource.data = displayedDataList;
1733
+ }
1734
+ getTableMode() {
1735
+ if (this._forceMode) {
1736
+ return this._forceMode;
1737
+ }
1738
+ if (!this.actions) {
1739
+ return this.NONE;
1740
+ }
1741
+ const distinctActionTypes = new Set();
1742
+ for (const rowAction of this.actions) {
1743
+ distinctActionTypes.add(rowAction.type);
1744
+ }
1745
+ if (distinctActionTypes.has(this.BATCH)) {
1746
+ return this.BATCH;
1747
+ }
1748
+ if (distinctActionTypes.has(this.SINGLE)) {
1749
+ return this.SINGLE;
1750
+ }
1751
+ return this.NONE;
1573
1752
  }
1574
1753
  }
1575
1754
  DataTableComponent.decorators = [
1576
1755
  { type: Component, args: [{
1577
- selector: 'mad-data-table',
1578
- template: "<!-- Table actions -->\n<div *ngIf=\"tableActions?.length\">\n <mad-primary-button class=\"table-action\" *ngFor=\"let tableAction of tableActions\" (click)=\"onTableAction(tableAction)\">\n {{ tableAction.label }}\n </mad-primary-button>\n</div>\n\n<!-- Row action buttons -->\n<mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent let-element=\"element\">\n <button *ngFor=\"let rowAction of rowActions\" mat-menu-item class=\"row-action\" (click)=\"onRowEvent($event, element, rowAction)\">\n {{ rowAction.label }}\n </button>\n </ng-template>\n</mat-menu>\n\n<!-- Table filter -->\n<mat-form-field *ngIf=\"isFilterEnabled\">\n <mat-label>{{ filterLabel }}</mat-label>\n <input matInput autocomplete=\"off\" (keyup)=\"onFilter($event?.target?.value)\" placeholder=\"{{ filterPlaceholder }}\" />\n</mat-form-field>\n\n<!-- Table -->\n<div *ngIf=\"dataSource?.data?.length > 0; else noData\" class=\"mad-table\">\n <table mat-table [dataSource]=\"dataSource\" matSort (matSortChange)=\"onSortingEvent($event)\">\n <!-- Row actions column -->\n <ng-container [matColumnDef]=\"ACTION_COLUMN_NAME\" *ngIf=\"rowActions?.length\">\n <th scope=\"col\" mat-header-cell *matHeaderCellDef class=\"row-action-button\"></th>\n <td mat-cell *matCellDef=\"let element\" class=\"row-action-button\">\n <mad-icon-button [matMenuTriggerData]=\"{ element: element }\" [matMenuTriggerFor]=\"menu\">\n <mat-icon>more_vert</mat-icon>\n </mad-icon-button>\n </td>\n </ng-container>\n <!-- Columns with data -->\n <ng-container *ngFor=\"let column of columns\" [matColumnDef]=\"column.label\">\n <ng-container *ngIf=\"column.isSortable; else noSort\">\n <th\n scope=\"col\"\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header=\"{{ column.label }}\"\n [arrowPosition]=\"column.isRightAligned ? 'before' : 'after'\"\n [class.text-right]=\"column.isRightAligned\"\n >\n {{ column.label }}\n </th>\n </ng-container>\n <ng-template #noSort>\n <th scope=\"col\" mat-header-cell *matHeaderCellDef [class.text-right]=\"column.isRightAligned\">\n {{ column.label }}\n </th>\n </ng-template>\n <td mat-cell *matCellDef=\"let element\" [class.text-right]=\"column.isRightAligned\">\n {{ element[column.dataPropertyName] }}\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"columnNames\"></tr>\n <tr\n mat-row\n [class.clickable-table-row]=\"isRowClickable\"\n (click)=\"onRowEvent($event, row)\"\n *matRowDef=\"let row; columns: columnNames\"\n ></tr>\n </table>\n\n <!-- Pagination -->\n <mat-paginator\n [style.display]=\"isPaginationEnabled ? 'block' : 'none'\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n showFirstLastButtons\n >\n </mat-paginator>\n</div>\n\n<!-- No data alert -->\n<ng-template #noData>\n <div class=\"noDataText\">\n {{ noDataText }}\n </div>\n</ng-template>\n",
1579
- styles: [".text-right{padding-right:24px!important;text-align:right!important}.table-action{margin-bottom:.5em;margin-right:.5em}.row-action-button{width:10px}.noDataText{text-align:center;width:100%}.mad-table{overflow-x:auto;width:100%}"]
1756
+ selector: "mad-data-table",
1757
+ template: "<div class=\"mad-datatable-action-bar\">\n <!-- Table actions: displayed before the table -->\n <div *ngIf=\"tableActions?.length\">\n <mad-outline-button\n [disabled]=\"isDisabled(tableAction.type)\"\n class=\"table-action\"\n *ngFor=\"let tableAction of tableActions\"\n (click)=\"onTableAction(tableAction)\">\n {{ tableAction.label | translate }} {{ getSelectedCount(tableAction.type) }}\n </mad-outline-button>\n </div>\n <!-- Table filter -->\n <mat-form-field *ngIf=\"isFilterEnabled\">\n <mat-label>{{ filterLabel | translate }}</mat-label>\n <input matInput autocomplete=\"off\" (keyup)=\"setFilterValue($event?.target?.value)\"\n placeholder=\"{{ filterPlaceholder }}\" />\n </mat-form-field>\n</div>\n\n\n<!-- Row action menu -->\n<mat-menu #rowActionMenu=\"matMenu\">\n <ng-template matMenuContent let-element=\"element\">\n <button *ngFor=\"let rowAction of rowActions\" mat-menu-item class=\"row-action\"\n (click)=\"onRowEvent($event, element, rowAction)\">\n {{ rowAction.label | translate }}\n </button>\n </ng-template>\n</mat-menu>\n\n<!-- Table -->\n<div *ngIf=\"rowCount > 0; else noData\" class=\"mad-table\">\n <div class=\"datatable-spinner-wrapper\" *ngIf=\"isLoading\">\n <mat-spinner [diameter]=\"50\" [strokeWidth]=\"3\"></mat-spinner>\n </div>\n\n <table mat-table [dataSource]=\"dataSource\" matSort (matSortChange)=\"onSortingEvent($event)\">\n <!-- Row actions column-->\n <ng-container [matColumnDef]=\"ACTION_COLUMN_NAME\">\n <th scope=\"col\" mat-header-cell *matHeaderCellDef class=\"row-action-button\">\n <!-- BATCH: master checkbox -->\n <div *ngIf=\"mode === BATCH\" class=\"mad-datatable-checkbox-container\">\n <mat-checkbox\n (change)=\"onToggleSelectAll()\"\n [checked]=\"allSelected\"\n >\n </mat-checkbox>\n </div>\n <!-- SINGLE / NONE: nothing in header row -->\n </th>\n <td mat-cell *matCellDef=\"let element\" class=\"row-action-button\">\n <!-- BATCH: row checkbox -->\n <div *ngIf=\"mode === BATCH\" class=\"mad-datatable-checkbox-container\">\n <mat-checkbox\n (click)=\"onRowCheckbox($event, element.rowId)\"\n [checked]=\"isSelected(element.rowId)\"\n >\n </mat-checkbox>\n </div>\n <!-- SINGLE: row action menu icon -->\n <mad-icon-button\n *ngIf=\"mode === SINGLE\"\n [matMenuTriggerData]=\"{ element: element }\" [matMenuTriggerFor]=\"rowActionMenu\"\n >\n <mat-icon>more_vert</mat-icon>\n </mad-icon-button>\n <!-- NONE: nothing -->\n </td>\n </ng-container>\n <!-- Columns with data -->\n <ng-container *ngFor=\"let column of columns\" [matColumnDef]=\"column.label\">\n <ng-container *ngIf=\"column.isSortable; else noSort\">\n <th\n scope=\"col\"\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header=\"{{ column.label | translate}}\"\n [arrowPosition]=\"column.isRightAligned ? 'before' : 'after'\"\n [class.text-right]=\"column.isRightAligned\"\n >\n {{ column.label }}\n </th>\n </ng-container>\n <ng-template #noSort>\n <th scope=\"col\" mat-header-cell *matHeaderCellDef [class.text-right]=\"column.isRightAligned\">\n {{ column.label }}\n </th>\n </ng-template>\n <td mat-cell *matCellDef=\"let element\" [class.text-right]=\"column.isRightAligned\" [ngSwitch]=\"column.transformer\">\n <span>\n {{ element[column.dataPropertyName] }}\n </span>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"columnNames\"></tr>\n <tr\n mat-row\n [class.clickable-table-row]=\"isRowClickable\"\n (click)=\"onRowEvent($event, row)\"\n *matRowDef=\"let row; columns: columnNames\"\n ></tr>\n </table>\n\n <!-- Pagination -->\n <mat-paginator\n [style.display]=\"isPaginationEnabled ? 'block' : 'none'\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"onPaginationEvent($event)\"\n showFirstLastButtons\n >\n </mat-paginator>\n</div>\n\n<!-- No data alert -->\n<ng-template #noData>\n <div class=\"noDataText\">\n <div class=\"datatable-spinner-wrapper\" *ngIf=\"isLoading\">\n <mat-spinner [diameter]=\"50\" [strokeWidth]=\"3\"></mat-spinner>\n </div>\n {{ noDataText }}\n </div>\n</ng-template>\n",
1758
+ styles: [".text-right{padding-right:24px!important;text-align:right!important}.table-action{margin-bottom:.5em;margin-right:.5em}.row-action-button{width:10px}.noDataText{text-align:center}.mad-table,.noDataText{position:relative;width:100%}.mad-table{overflow-x:auto}.mad-datatable-action-bar{align-items:baseline;display:flex;justify-content:space-between}.mad-datatable-checkbox-container{margin-right:16px}.datatable-spinner-wrapper{align-items:center;background-color:#fff;display:flex;height:100%;justify-content:center;left:0;opacity:.8;pointer-events:unset;position:absolute;top:0;width:100%;z-index:99999}"]
1580
1759
  },] }
1581
1760
  ];
1582
1761
  DataTableComponent.propDecorators = {
@@ -1586,14 +1765,16 @@ DataTableComponent.propDecorators = {
1586
1765
  noDataText: [{ type: Input }],
1587
1766
  pageSizeOptions: [{ type: Input }],
1588
1767
  defaultPageSize: [{ type: Input }],
1589
- rowActions: [{ type: Input }],
1590
- tableActions: [{ type: Input }],
1591
- displayedData: [{ type: Input }],
1768
+ actions: [{ type: Input }],
1769
+ idGenerator: [{ type: Input }],
1770
+ tableData: [{ type: Input }],
1771
+ loading: [{ type: Input }],
1592
1772
  paginationEnabled: [{ type: Input }],
1593
1773
  filterEnabled: [{ type: Input }],
1594
- tableAction: [{ type: Output }],
1595
- rowAction: [{ type: Output }],
1774
+ forceMode: [{ type: Input }],
1596
1775
  sortEvent: [{ type: Output }],
1776
+ actionEvent: [{ type: Output }],
1777
+ pagingEvent: [{ type: Output }],
1597
1778
  paginator: [{ type: ViewChild, args: [MatPaginator, { static: false },] }],
1598
1779
  sort: [{ type: ViewChild, args: [MatSort, { static: true },] }]
1599
1780
  };
@@ -1613,9 +1794,13 @@ DataTableModule.decorators = [
1613
1794
  MatPaginatorModule,
1614
1795
  MatSortModule,
1615
1796
  MatTableModule,
1797
+ MatProgressSpinnerModule,
1616
1798
  ButtonModule,
1799
+ TranslateModule,
1800
+ MatCheckboxModule,
1801
+ MatBadgeModule
1617
1802
  ],
1618
- exports: [DataTableComponent],
1803
+ exports: [DataTableComponent]
1619
1804
  },] }
1620
1805
  ];
1621
1806