mat-table-ext 0.0.7 → 0.0.9
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/.editorconfig +16 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/tasks.json +42 -0
- package/LICENSE +21 -0
- package/angular.json +150 -0
- package/package.json +46 -58
- package/projects/mat-table-ext/.browserslistrc +16 -0
- package/projects/mat-table-ext/README.md +57 -0
- package/projects/mat-table-ext/karma.conf.js +44 -0
- package/projects/mat-table-ext/ng-package.json +9 -0
- package/projects/mat-table-ext/package.json +38 -0
- package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.html +7 -0
- package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.scss +9 -0
- package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.spec.ts +23 -0
- package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.ts +48 -0
- package/projects/mat-table-ext/src/lib/components/editing/editing.component.html +55 -0
- package/projects/mat-table-ext/src/lib/components/editing/editing.component.scss +19 -0
- package/projects/mat-table-ext/src/lib/components/editing/editing.component.spec.ts +23 -0
- package/projects/mat-table-ext/src/lib/components/editing/editing.component.ts +110 -0
- package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.html +26 -0
- package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.scss +0 -0
- package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.spec.ts +23 -0
- package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.ts +54 -0
- package/projects/mat-table-ext/src/lib/directives/resize-column.directive.ts +103 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.component.html +285 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.component.spec.ts +25 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.component.ts +985 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.module.ts +127 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.scss +181 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.service.spec.ts +16 -0
- package/projects/mat-table-ext/src/lib/mat-table-ext.service.ts +12 -0
- package/projects/mat-table-ext/src/lib/models/tableExtModels.ts +85 -0
- package/{public-api.d.ts → projects/mat-table-ext/src/public-api.ts} +5 -1
- package/projects/mat-table-ext/src/test.ts +27 -0
- package/projects/mat-table-ext/tsconfig.lib.json +15 -0
- package/projects/mat-table-ext/tsconfig.lib.prod.json +10 -0
- package/projects/mat-table-ext/tsconfig.spec.json +17 -0
- package/projects/mat-table-ext-example/.browserslistrc +16 -0
- package/projects/mat-table-ext-example/karma.conf.js +44 -0
- package/projects/mat-table-ext-example/src/app/app.component.html +576 -0
- package/projects/mat-table-ext-example/src/app/app.component.scss +0 -0
- package/projects/mat-table-ext-example/src/app/app.component.spec.ts +31 -0
- package/projects/mat-table-ext-example/src/app/app.component.ts +173 -0
- package/projects/mat-table-ext-example/src/app/app.module.ts +40 -0
- package/projects/mat-table-ext-example/src/app/service/custom-table.service.spec.ts +16 -0
- package/projects/mat-table-ext-example/src/app/service/custom-table.service.ts +18 -0
- package/projects/mat-table-ext-example/src/assets/.gitkeep +0 -0
- package/projects/mat-table-ext-example/src/assets/data.json +100003 -0
- package/projects/mat-table-ext-example/src/environments/environment.prod.ts +3 -0
- package/projects/mat-table-ext-example/src/environments/environment.ts +16 -0
- package/projects/mat-table-ext-example/src/favicon.ico +0 -0
- package/projects/mat-table-ext-example/src/index.html +14 -0
- package/projects/mat-table-ext-example/src/main.ts +12 -0
- package/projects/mat-table-ext-example/src/polyfills.ts +53 -0
- package/projects/mat-table-ext-example/src/styles.scss +23 -0
- package/projects/mat-table-ext-example/src/test.ts +26 -0
- package/projects/mat-table-ext-example/tsconfig.app.json +15 -0
- package/projects/mat-table-ext-example/tsconfig.spec.json +18 -0
- package/tsconfig.json +38 -0
- package/esm2020/lib/components/column-pinning/column-pinning.component.mjs +0 -58
- package/esm2020/lib/components/editing/editing.component.mjs +0 -122
- package/esm2020/lib/components/filter-columns-component/filter-columns-component.component.mjs +0 -68
- package/esm2020/lib/directives/resize-column.directive.mjs +0 -99
- package/esm2020/lib/mat-table-ext.component.mjs +0 -1021
- package/esm2020/lib/mat-table-ext.module.mjs +0 -237
- package/esm2020/lib/mat-table-ext.service.mjs +0 -20
- package/esm2020/lib/models/tableExtModels.mjs +0 -2
- package/esm2020/mat-table-ext.mjs +0 -5
- package/esm2020/public-api.mjs +0 -11
- package/fesm2015/mat-table-ext.mjs +0 -1585
- package/fesm2015/mat-table-ext.mjs.map +0 -1
- package/fesm2020/mat-table-ext.mjs +0 -1582
- package/fesm2020/mat-table-ext.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/components/column-pinning/column-pinning.component.d.ts +0 -27
- package/lib/components/editing/editing.component.d.ts +0 -42
- package/lib/components/filter-columns-component/filter-columns-component.component.d.ts +0 -26
- package/lib/directives/resize-column.directive.d.ts +0 -27
- package/lib/mat-table-ext.component.d.ts +0 -348
- package/lib/mat-table-ext.module.d.ts +0 -58
- package/lib/mat-table-ext.service.d.ts +0 -11
- package/lib/models/tableExtModels.d.ts +0 -76
- /package/{assets → projects/mat-table-ext/assets}/_theming.scss +0 -0
- /package/{assets → projects/mat-table-ext/assets}/pinIcon.svg +0 -0
- /package/{assets → projects/mat-table-ext/assets}/pinLeft.svg +0 -0
- /package/{assets → projects/mat-table-ext/assets}/pinNone.svg +0 -0
- /package/{assets → projects/mat-table-ext/assets}/pinRight.svg +0 -0
- /package/{assets → projects/mat-table-ext/assets}/pinned.svg +0 -0
|
@@ -0,0 +1,985 @@
|
|
|
1
|
+
import {
|
|
2
|
+
animate,
|
|
3
|
+
state,
|
|
4
|
+
style,
|
|
5
|
+
transition,
|
|
6
|
+
trigger,
|
|
7
|
+
} from '@angular/animations';
|
|
8
|
+
import { SelectionModel } from '@angular/cdk/collections';
|
|
9
|
+
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
|
10
|
+
import {
|
|
11
|
+
AfterViewInit,
|
|
12
|
+
ChangeDetectorRef,
|
|
13
|
+
EventEmitter,
|
|
14
|
+
Output,
|
|
15
|
+
} from '@angular/core';
|
|
16
|
+
import {
|
|
17
|
+
Component,
|
|
18
|
+
Input,
|
|
19
|
+
OnChanges,
|
|
20
|
+
OnInit,
|
|
21
|
+
SimpleChanges,
|
|
22
|
+
TemplateRef,
|
|
23
|
+
ViewChild,
|
|
24
|
+
ViewEncapsulation,
|
|
25
|
+
} from '@angular/core';
|
|
26
|
+
import { FormBuilder, FormGroup } from '@angular/forms';
|
|
27
|
+
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
|
|
28
|
+
import { MatMenuTrigger } from '@angular/material/menu';
|
|
29
|
+
import { MatPaginator } from '@angular/material/paginator';
|
|
30
|
+
import { MatSort } from '@angular/material/sort';
|
|
31
|
+
import { MatTableDataSource } from '@angular/material/table';
|
|
32
|
+
import { EditingComponent } from '../lib/components/editing/editing.component';
|
|
33
|
+
import {
|
|
34
|
+
RowChange,
|
|
35
|
+
DisplayColumn,
|
|
36
|
+
MTExColumn,
|
|
37
|
+
MTExColumnPinOption,
|
|
38
|
+
RowSelectionChange,
|
|
39
|
+
CellTemplateRefMap,
|
|
40
|
+
ExpansionChange,
|
|
41
|
+
FilterSearchValue,
|
|
42
|
+
MTExRow,
|
|
43
|
+
ColumnVisibility,
|
|
44
|
+
} from '../lib/models/tableExtModels';
|
|
45
|
+
import { MatTableExtService } from '../lib/mat-table-ext.service';
|
|
46
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
47
|
+
import { MatIconRegistry } from '@angular/material/icon';
|
|
48
|
+
import * as XLSX from 'xlsx';
|
|
49
|
+
@Component({
|
|
50
|
+
selector: 'mat-table-ext',
|
|
51
|
+
templateUrl: 'mat-table-ext.component.html',
|
|
52
|
+
styleUrls: ['mat-table-ext.scss'],
|
|
53
|
+
encapsulation: ViewEncapsulation.None,
|
|
54
|
+
animations: [
|
|
55
|
+
trigger('detailExpand', [
|
|
56
|
+
state('collapsed', style({ height: '0px', minHeight: '0' })),
|
|
57
|
+
state('expanded', style({ height: '*' })),
|
|
58
|
+
transition(
|
|
59
|
+
'expanded <=> collapsed',
|
|
60
|
+
animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)')
|
|
61
|
+
),
|
|
62
|
+
]),
|
|
63
|
+
],
|
|
64
|
+
})
|
|
65
|
+
export class MatTableExtComponent implements OnInit, OnChanges, AfterViewInit {
|
|
66
|
+
@ViewChild(MatMenuTrigger) menuTrigger!: MatMenuTrigger;
|
|
67
|
+
@ViewChild('columnMenuTrigger') columnMenuTrigger!: MatMenuTrigger;
|
|
68
|
+
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
|
69
|
+
@ViewChild(MatSort) sort!: MatSort;
|
|
70
|
+
|
|
71
|
+
// Table inputs
|
|
72
|
+
@Input() dataSource!: MatTableDataSource<any>;
|
|
73
|
+
@Input() columns: MTExColumn[] = [];
|
|
74
|
+
@Input() columnResizable: boolean = false;
|
|
75
|
+
@Input() stripedRows: boolean = false;
|
|
76
|
+
@Input() rowHover: boolean = false;
|
|
77
|
+
@Input() inlineRowEditing: boolean = false;
|
|
78
|
+
@Input() inCellEditing: boolean = false;
|
|
79
|
+
@Input() popupRowEditing: boolean = false;
|
|
80
|
+
@Input() enableDelete: boolean = false;
|
|
81
|
+
@Input() rowSelection: boolean = false;
|
|
82
|
+
@Input() multiRowSelection: boolean = false;
|
|
83
|
+
@Input() stickyFooter: boolean = false;
|
|
84
|
+
@Input() stickyHeader: boolean = false;
|
|
85
|
+
@Input() showFooterRow: boolean = false;
|
|
86
|
+
@Input() columnFilter: boolean = false;
|
|
87
|
+
@Input() loadingIndicator: boolean = false;
|
|
88
|
+
@Input() sorting: boolean = false;
|
|
89
|
+
@Input() showToolbar: boolean = false;
|
|
90
|
+
@Input() toolbarTitle: string = '';
|
|
91
|
+
@Input() tableHeight: string = '';
|
|
92
|
+
@Input() toolbarHeight: string = '50px';
|
|
93
|
+
@Input() tableWidth: string = '100%';
|
|
94
|
+
@Input() scrollbarH: boolean = false;
|
|
95
|
+
@Input() toolbarTemplate: TemplateRef<any> | undefined;
|
|
96
|
+
@Input() columnHidable: boolean = false;
|
|
97
|
+
@Input() columnPinnable: boolean = false;
|
|
98
|
+
@Input() globalSearch: boolean = false;
|
|
99
|
+
@Input() expandRows: boolean = false;
|
|
100
|
+
@Input() dndColumns: boolean = false;
|
|
101
|
+
@Input() showPaginator: boolean = true;
|
|
102
|
+
@Input() showFirstLastButtons: boolean = false;
|
|
103
|
+
@Input() exportButtonEnable: boolean = false;
|
|
104
|
+
@Input() pageSizeOptions: number[] = [10, 50, 100];
|
|
105
|
+
@Input() toolbarTemplateRef!: TemplateRef<any> | undefined;
|
|
106
|
+
@Input() headerTemplateRef!: TemplateRef<any> | undefined;
|
|
107
|
+
@Input() cellTemplateRef!: TemplateRef<any> | undefined;
|
|
108
|
+
@Input() expansionTemplateRef!: TemplateRef<any> | undefined;
|
|
109
|
+
@Input() popupEditingTemplateRef!: TemplateRef<any> | undefined;
|
|
110
|
+
@Input() inlineEditingTemplateRef!: TemplateRef<any> | undefined;
|
|
111
|
+
@Input() cellEditingTemplateRef!: TemplateRef<any> | undefined;
|
|
112
|
+
@Input() cellTemplateRefMap: CellTemplateRefMap = {};
|
|
113
|
+
|
|
114
|
+
// Table outputs
|
|
115
|
+
@Output() inlineChange: EventEmitter<any> = new EventEmitter<RowChange>();
|
|
116
|
+
@Output() cellChange: EventEmitter<any> = new EventEmitter<RowChange>();
|
|
117
|
+
@Output() popupChange: EventEmitter<any> = new EventEmitter<RowChange>();
|
|
118
|
+
@Output() rowDeleted: EventEmitter<any> = new EventEmitter<any>();
|
|
119
|
+
@Output() scroll: EventEmitter<any> = new EventEmitter<any>();
|
|
120
|
+
@Output() selectionChanged: EventEmitter<RowSelectionChange> =
|
|
121
|
+
new EventEmitter<any>();
|
|
122
|
+
@Output() expansionChange: EventEmitter<ExpansionChange> =
|
|
123
|
+
new EventEmitter<any>();
|
|
124
|
+
tableID = new Date().getTime();
|
|
125
|
+
columnPinningOptions: MTExColumnPinOption[] = [];
|
|
126
|
+
exportMenuCtrl: boolean = false;
|
|
127
|
+
columnPinMenuCtrl: boolean = false;
|
|
128
|
+
hideShowMenuCtrl: boolean = false;
|
|
129
|
+
columnFilterBySelection: any = false;
|
|
130
|
+
rowDataTemp: any = {};
|
|
131
|
+
inlineEditingTemplateRefData: any = {};
|
|
132
|
+
displayedColumns: string[] = [];
|
|
133
|
+
showHideColumnsArray: MTExColumn[] = [];
|
|
134
|
+
columnsList: string[] = [];
|
|
135
|
+
columnsArray: MTExColumn[] = [];
|
|
136
|
+
headersFiltersIds: string[] = [];
|
|
137
|
+
columnsToDisplayWithExpand: string[] = [];
|
|
138
|
+
selection = new SelectionModel<any>(false, []);
|
|
139
|
+
hiddenCtrl = new SelectionModel<any>(true, []);
|
|
140
|
+
tableData: any = [];
|
|
141
|
+
filterValues: any = {};
|
|
142
|
+
globalFilter = '';
|
|
143
|
+
showHideFilter = '';
|
|
144
|
+
individualFilter = '';
|
|
145
|
+
toggleFilters = false;
|
|
146
|
+
hideRows = false;
|
|
147
|
+
expandedElement: any | null;
|
|
148
|
+
currentRowIndex: number = -1;
|
|
149
|
+
currentRow: any = {};
|
|
150
|
+
cellEditing: any = {};
|
|
151
|
+
hideShowMenuGroup!: FormGroup;
|
|
152
|
+
cellTemplate!: TemplateRef<any>;
|
|
153
|
+
menuX: number = 0;
|
|
154
|
+
menuY: number = 0;
|
|
155
|
+
dynamicDisplayedColumns: any[] = [
|
|
156
|
+
{ filter: false, name: 'select', show: false },
|
|
157
|
+
{ filter: false, name: 'edit', show: false },
|
|
158
|
+
{ filter: false, name: 'popup', show: false },
|
|
159
|
+
{ filter: false, name: 'delete', show: false },
|
|
160
|
+
{ filter: false, name: 'expand', show: false },
|
|
161
|
+
];
|
|
162
|
+
inputPropertyKeys: string[] = [
|
|
163
|
+
'dataSource',
|
|
164
|
+
'columns',
|
|
165
|
+
'inlineRowEditing',
|
|
166
|
+
'popupRowEditing',
|
|
167
|
+
'enableDelete',
|
|
168
|
+
'rowSelection',
|
|
169
|
+
'multiRowSelection',
|
|
170
|
+
'stickyHeader',
|
|
171
|
+
'stickyFooter',
|
|
172
|
+
'columnFilter',
|
|
173
|
+
'globalSearch',
|
|
174
|
+
'expandRows',
|
|
175
|
+
'sorting',
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
constructor(
|
|
179
|
+
public dialog: MatDialog,
|
|
180
|
+
public service: MatTableExtService,
|
|
181
|
+
public formBuildersService: FormBuilder,
|
|
182
|
+
public domSanitizer: DomSanitizer,
|
|
183
|
+
public matIconRegistry: MatIconRegistry,
|
|
184
|
+
private cdr: ChangeDetectorRef
|
|
185
|
+
) {
|
|
186
|
+
this.addIconsToRegistry();
|
|
187
|
+
if (this.dataSource) {
|
|
188
|
+
this.tableData = this.dataSource.data;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
*
|
|
193
|
+
* @param changes changes captured each time user changes property value.
|
|
194
|
+
*/
|
|
195
|
+
ngOnChanges(changes: SimpleChanges) {
|
|
196
|
+
this.setPropertyValue(changes);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
ngOnInit() {
|
|
200
|
+
if (this.dataSource) {
|
|
201
|
+
this.dataSource.filterPredicate = this.createFilter();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
ngAfterViewInit() {
|
|
206
|
+
if (this.dataSource) {
|
|
207
|
+
this.dataSource.paginator = this.paginator;
|
|
208
|
+
this.dataSource.sort = this.sort;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* @description checks and updates the the column's hide and show properties.
|
|
213
|
+
*/
|
|
214
|
+
setColumnHideShow() {
|
|
215
|
+
if (
|
|
216
|
+
this.hideShowMenuGroup !== undefined &&
|
|
217
|
+
this.hideShowMenuGroup !== null
|
|
218
|
+
) {
|
|
219
|
+
this.updateColumnsHideShow(this.hideShowMenuGroup.value);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* @description set the properties of the table.
|
|
224
|
+
* @param changes changes captured each time user changes property value.
|
|
225
|
+
*/
|
|
226
|
+
setPropertyValue(changes: SimpleChanges) {
|
|
227
|
+
let keys = Object.keys(changes);
|
|
228
|
+
keys.forEach((property) => {
|
|
229
|
+
if (this.inputPropertyKeys.includes(property)) {
|
|
230
|
+
this.setPropertiesMap[property](changes[property]);
|
|
231
|
+
} else if (property == 'showToolbar') {
|
|
232
|
+
if (changes['columns']) {
|
|
233
|
+
this.setToolbarMenuControls(changes['columns'].currentValue);
|
|
234
|
+
} else {
|
|
235
|
+
this.setToolbarMenuControls(this.columnsArray);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* @description This mapping is used to set and update changesin the table.
|
|
242
|
+
*/
|
|
243
|
+
setPropertiesMap: any = {
|
|
244
|
+
dataSource: (value: any) => this.setTableDataSource(value),
|
|
245
|
+
columns: (value: any) => this.setColumnsData(value.currentValue),
|
|
246
|
+
inlineRowEditing: (value: any) =>
|
|
247
|
+
this.showHideColumn('edit', value.currentValue),
|
|
248
|
+
popupRowEditing: (value: any) =>
|
|
249
|
+
this.showHideColumn('popup', value.currentValue),
|
|
250
|
+
enableDelete: (value: any) =>
|
|
251
|
+
this.showHideColumn('delete', value.currentValue),
|
|
252
|
+
rowSelection: (value: any) => this.setRowSelection(value.currentValue),
|
|
253
|
+
multiRowSelection: (value: any) => {
|
|
254
|
+
this.selection = new SelectionModel<any>(value.currentValue, []);
|
|
255
|
+
},
|
|
256
|
+
stickyHeader: (value: any) => {
|
|
257
|
+
this.stickyHeader = value.currentValue;
|
|
258
|
+
},
|
|
259
|
+
stickyFooter: (value: any) => {
|
|
260
|
+
this.stickyFooter = value.currentValue;
|
|
261
|
+
},
|
|
262
|
+
columnFilter: (value: any) => this.setColumnFilter(value.currentValue),
|
|
263
|
+
globalSearch: (value: any) =>
|
|
264
|
+
(this.dataSource.filterPredicate = this.createFilter()),
|
|
265
|
+
expandRows: (value: any) => {
|
|
266
|
+
this.loadingIndicator = true;
|
|
267
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
268
|
+
if (value.currentValue == true) {
|
|
269
|
+
if (!this.displayedColumns.includes('expand')) {
|
|
270
|
+
this.displayedColumns.push('expand');
|
|
271
|
+
this.columnsToDisplayWithExpand = [...this.displayedColumns];
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
this.columnsToDisplayWithExpand = [...this.displayedColumns];
|
|
275
|
+
if (this.displayedColumns.includes('expand')) {
|
|
276
|
+
let index = this.displayedColumns.indexOf('expand');
|
|
277
|
+
this.displayedColumns.splice(index, 1);
|
|
278
|
+
}
|
|
279
|
+
this.expandedElement = null;
|
|
280
|
+
}
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
this.loadingIndicator = false;
|
|
283
|
+
}, 200);
|
|
284
|
+
},
|
|
285
|
+
sorting: (value: any) => (this.dataSource.sort = this.sort),
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* @description used set data source for table.
|
|
289
|
+
* @param value data source value from user.
|
|
290
|
+
*/
|
|
291
|
+
setTableDataSource(value: any) {
|
|
292
|
+
if (value.currentValue) {
|
|
293
|
+
this.tableData = value.currentValue.data;
|
|
294
|
+
this.dataSource = value.currentValue;
|
|
295
|
+
this.reCal();
|
|
296
|
+
} else {
|
|
297
|
+
this.dataSource = new MatTableDataSource([{}]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* @description used create seletion model and set selection column visibility.
|
|
302
|
+
* @param value boolean value to show or hide selection Column from table.
|
|
303
|
+
*/
|
|
304
|
+
setRowSelection(value: boolean) {
|
|
305
|
+
this.selection = new SelectionModel<any>(true, []);
|
|
306
|
+
this.updateSelectionColumnVisibility(value);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @description create filter header row and assigns filter predicate to table data source.
|
|
311
|
+
* @param value boolean value to change visibility of column filter row.
|
|
312
|
+
*/
|
|
313
|
+
setColumnFilter(value: boolean) {
|
|
314
|
+
if (value) {
|
|
315
|
+
let array: string[] = [];
|
|
316
|
+
this.columnsArray.forEach((column, i) => {
|
|
317
|
+
if (
|
|
318
|
+
this.dynamicDisplayedColumns.filter((a) => a.name == column?.field)[0]
|
|
319
|
+
.show
|
|
320
|
+
) {
|
|
321
|
+
array.push(column?.field + '_' + i);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
this.headersFiltersIds = array;
|
|
325
|
+
this.dataSource.filterPredicate = this.createFilter();
|
|
326
|
+
} else {
|
|
327
|
+
this.headersFiltersIds = [];
|
|
328
|
+
this.dataSource.filter = '';
|
|
329
|
+
}
|
|
330
|
+
this.toggleFilters = value;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* @description This method returns the list of visible column names.
|
|
334
|
+
* @returns list of visible column names.
|
|
335
|
+
*/
|
|
336
|
+
getDisplayedColumns(): string[] {
|
|
337
|
+
let list = this.dynamicDisplayedColumns
|
|
338
|
+
.filter((cd) => cd.show)
|
|
339
|
+
.map((cd) => cd.name);
|
|
340
|
+
return list;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* @param menuType type of menu to open from toolbar.
|
|
344
|
+
* @param event mouse event to open menu on that location.
|
|
345
|
+
*/
|
|
346
|
+
openMenu(menuType: string, event: MouseEvent) {
|
|
347
|
+
this.menuX = event.clientX;
|
|
348
|
+
this.menuY = event.clientY;
|
|
349
|
+
switch (menuType) {
|
|
350
|
+
case 'export': {
|
|
351
|
+
this.exportMenuCtrl = true;
|
|
352
|
+
this.menuTrigger.openMenu();
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
case 'hideShow': {
|
|
356
|
+
this.hideShowMenuCtrl = true;
|
|
357
|
+
this.openHideShowMenu(this.columnsArray);
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
case 'columnPin': {
|
|
361
|
+
this.columnPinMenuCtrl = true;
|
|
362
|
+
this.openHideShowMenu(this.columnsArray);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* @description triggers when menu is closed and reset the required controls.
|
|
369
|
+
*/
|
|
370
|
+
menuClosed() {
|
|
371
|
+
this.exportMenuCtrl = false;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* @description set list of columns to display in table.
|
|
375
|
+
* @param columns columns array from user input.
|
|
376
|
+
*/
|
|
377
|
+
setColumnsData(columns: MTExColumn[]) {
|
|
378
|
+
if (columns.length) {
|
|
379
|
+
this.columnsArray = [...columns];
|
|
380
|
+
this.setColumnsList(columns);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* @description set list of columns to display in table.
|
|
385
|
+
* @param columns columns array from user input with configurations.
|
|
386
|
+
*/
|
|
387
|
+
setColumnsList(columns: MTExColumn[]) {
|
|
388
|
+
this.columnsList = [];
|
|
389
|
+
this.displayedColumns = ['select', 'edit', 'popup', 'delete'];
|
|
390
|
+
let columnsArray: DisplayColumn[] = [];
|
|
391
|
+
columns.forEach((col) => {
|
|
392
|
+
if (typeof col?.header == 'string') {
|
|
393
|
+
this.columnsList.push(col?.header);
|
|
394
|
+
this.displayedColumns.push(col?.field);
|
|
395
|
+
columnsArray.push({ filter: true, name: col?.field, show: !col.hide });
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
this.dynamicDisplayedColumns = [
|
|
399
|
+
{ filter: false, name: 'select', show: false },
|
|
400
|
+
{ filter: false, name: 'edit', show: false },
|
|
401
|
+
{ filter: false, name: 'popup', show: false },
|
|
402
|
+
{ filter: false, name: 'delete', show: false },
|
|
403
|
+
];
|
|
404
|
+
this.dynamicDisplayedColumns = columnsArray.concat(
|
|
405
|
+
this.dynamicDisplayedColumns
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* @description Take boolean value and name column and update its visibility status in table.
|
|
410
|
+
* @param name name of the column to set visibility.
|
|
411
|
+
* @param value boolean value to set visibility of the column.
|
|
412
|
+
*/
|
|
413
|
+
showHideColumn(name: string, value: boolean) {
|
|
414
|
+
this.dynamicDisplayedColumns.filter((a) => a.name == name)[0].show = value;
|
|
415
|
+
if (this.columnFilter) {
|
|
416
|
+
this.setColumnFilter(true);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* @description This method will position the selection column to first and also update its visibility.
|
|
421
|
+
* @param value value used to set visibility of the selection column.
|
|
422
|
+
*/
|
|
423
|
+
updateSelectionColumnVisibility(value: boolean) {
|
|
424
|
+
let columnName = 'select';
|
|
425
|
+
let column = this.dynamicDisplayedColumns.filter(
|
|
426
|
+
(a) => a.name == columnName
|
|
427
|
+
)[0];
|
|
428
|
+
let index = this.dynamicDisplayedColumns.findIndex(
|
|
429
|
+
(column: any) => column.name == columnName
|
|
430
|
+
);
|
|
431
|
+
if (index > -1) {
|
|
432
|
+
this.dynamicDisplayedColumns.splice(index, 1);
|
|
433
|
+
this.dynamicDisplayedColumns.unshift(column);
|
|
434
|
+
this.dynamicDisplayedColumns.filter(
|
|
435
|
+
(column) => column.name == columnName
|
|
436
|
+
)[0].show = value;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* @description This method is used to update the position of column in columns array according to its dropped position.
|
|
441
|
+
* @param event CdkDragDrop used to update column position in columns array.
|
|
442
|
+
*/
|
|
443
|
+
onDrop(event: CdkDragDrop<any>) {
|
|
444
|
+
if (this.dndColumns) {
|
|
445
|
+
let adjustedValue = 0;
|
|
446
|
+
if (
|
|
447
|
+
this.dynamicDisplayedColumns[0].name == 'select' &&
|
|
448
|
+
this.dynamicDisplayedColumns[0].show == false
|
|
449
|
+
) {
|
|
450
|
+
adjustedValue = 1;
|
|
451
|
+
}
|
|
452
|
+
moveItemInArray(
|
|
453
|
+
this.dynamicDisplayedColumns,
|
|
454
|
+
event.previousIndex + adjustedValue,
|
|
455
|
+
event.currentIndex + adjustedValue
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* @description This method create filter predicate function which will set search value to table filters
|
|
461
|
+
* for both global and individual colum filtering.
|
|
462
|
+
* @returns returns boolean value to filter rows in table.
|
|
463
|
+
*/
|
|
464
|
+
createFilter(): (data: any, filter: string) => boolean {
|
|
465
|
+
const tableFilterPredicate = (data: any, filter: string): boolean => {
|
|
466
|
+
let result: boolean = true;
|
|
467
|
+
// search all column fields
|
|
468
|
+
if (this.globalFilter) {
|
|
469
|
+
let expression = '';
|
|
470
|
+
let keys = Object.keys(data);
|
|
471
|
+
keys.forEach((key) => {
|
|
472
|
+
expression =
|
|
473
|
+
expression +
|
|
474
|
+
`data.${key}.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1 ||`;
|
|
475
|
+
});
|
|
476
|
+
if (
|
|
477
|
+
expression.charAt(expression.length - 2) +
|
|
478
|
+
expression.charAt(expression.length - 1) ==
|
|
479
|
+
'||'
|
|
480
|
+
) {
|
|
481
|
+
expression = expression.substring(0, expression.length - 2);
|
|
482
|
+
}
|
|
483
|
+
result = eval(expression);
|
|
484
|
+
}
|
|
485
|
+
if (!result) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
let searchString = JSON.parse(filter);
|
|
489
|
+
//search single column field
|
|
490
|
+
if (this.individualFilter) {
|
|
491
|
+
return (
|
|
492
|
+
data[this.individualFilter]
|
|
493
|
+
.toString()
|
|
494
|
+
.trim()
|
|
495
|
+
.toLowerCase()
|
|
496
|
+
.indexOf(
|
|
497
|
+
searchString[this.individualFilter].toString().toLowerCase()
|
|
498
|
+
) !== -1
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return true;
|
|
502
|
+
};
|
|
503
|
+
return tableFilterPredicate;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* @description assigns the search value to mat table data source to apply the filter.
|
|
507
|
+
* @param searchValue value to be searched from table rows.
|
|
508
|
+
*/
|
|
509
|
+
applyGlobalFilter(searchValue: string) {
|
|
510
|
+
this.globalFilter = searchValue;
|
|
511
|
+
let columns: any = {};
|
|
512
|
+
this.columnsArray.forEach((column: MTExColumn) => {
|
|
513
|
+
if (column.field) columns[column.field] = searchValue;
|
|
514
|
+
});
|
|
515
|
+
this.dataSource.filter = JSON.stringify(columns);
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* @description This method is used to apply column based filtering
|
|
519
|
+
* @param searchValue value to be searched from table rows.
|
|
520
|
+
* @param column filter will be applied based on this column field.
|
|
521
|
+
*/
|
|
522
|
+
applyColumnFilter(searchValue: FilterSearchValue, column: MTExColumn) {
|
|
523
|
+
this.individualFilter = column.field;
|
|
524
|
+
this.filterValues[column.field] = searchValue[column.field];
|
|
525
|
+
this.dataSource.filter = JSON.stringify(this.filterValues);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* @description This method will take row and its index enable inline editing tools on that row.
|
|
529
|
+
* @param row row on which user wants to do edit.
|
|
530
|
+
* @param index index of the row where inline editing will be enabled.
|
|
531
|
+
*/
|
|
532
|
+
enableInlineEditing(row: any, index: number) {
|
|
533
|
+
const rowData: any = {};
|
|
534
|
+
rowData['e' + index] = { ...row };
|
|
535
|
+
this.rowDataTemp = rowData;
|
|
536
|
+
setTimeout(() => {
|
|
537
|
+
this.tableData[index]['editable'] = !this.tableData[index]['editable'];
|
|
538
|
+
}, 0);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* @description This method will create and return data to inline editing template.
|
|
542
|
+
* @param row row on which user wants to do edit.
|
|
543
|
+
* @param index index of the row where inline editing will be enabled.
|
|
544
|
+
* @param column current column of the table.
|
|
545
|
+
*/
|
|
546
|
+
getInlineEditingData(row: MTExRow, index: number, column: MTExColumn) {
|
|
547
|
+
this.inlineEditingTemplateRefData = {
|
|
548
|
+
row: { ...row },
|
|
549
|
+
column: { ...column },
|
|
550
|
+
index: index,
|
|
551
|
+
updateFunc: this.updateInlineTemplateData,
|
|
552
|
+
};
|
|
553
|
+
return this.inlineEditingTemplateRefData;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* @description This method will take data from inline editing template and update in table data source.
|
|
557
|
+
* @param row updated row from inline editing template.
|
|
558
|
+
*/
|
|
559
|
+
updateInlineTemplateData = (row: MTExRow) => {
|
|
560
|
+
this.service.selectedRow.next(row);
|
|
561
|
+
};
|
|
562
|
+
/**
|
|
563
|
+
* @description This method set data for in-cell editing.
|
|
564
|
+
* @param row row on which user wants to do edit.
|
|
565
|
+
* @param index index of the row where inline editing will be enabled.
|
|
566
|
+
*/
|
|
567
|
+
setCellData(row: MTExRow, index: number) {
|
|
568
|
+
this.currentRow = { ...row };
|
|
569
|
+
this.currentRowIndex = index;
|
|
570
|
+
this.rowDataTemp['e' + index] = { ...row };
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* @description This will restore the data and cencel the inline editing.
|
|
574
|
+
* @param row row on which user wants to do edit.
|
|
575
|
+
* @param index index of the row where inline editing will be enabled.
|
|
576
|
+
*/
|
|
577
|
+
cancelInlineEditing(row: MTExRow, index: number) {
|
|
578
|
+
this.tableData.filter((a: any, i: number) => i == index)[0]['editable'] =
|
|
579
|
+
!this.tableData.filter((a: any, i: number) => i == index)[0]['editable'];
|
|
580
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
581
|
+
this.rowDataTemp['e' + index] = {};
|
|
582
|
+
this.service.selectedRow.next(undefined);
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* @description This method will save and update the inline editing data and emit the update row and index.
|
|
586
|
+
* @param row row on which user wants to do edit.
|
|
587
|
+
* @param index index of the row where inline editing will be enabled.
|
|
588
|
+
*/
|
|
589
|
+
saveInlineEditing(row: MTExRow, index: number) {
|
|
590
|
+
if (!this.inlineEditingTemplateRef) {
|
|
591
|
+
this.tableData[index] = { ...this.rowDataTemp['e' + index] };
|
|
592
|
+
row = { ...this.rowDataTemp['e' + index] };
|
|
593
|
+
} else {
|
|
594
|
+
let changedData = this.service.selectedRow.value;
|
|
595
|
+
if (changedData) {
|
|
596
|
+
this.tableData[index] = { ...changedData };
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
600
|
+
this.rowDataTemp['e' + index] = {};
|
|
601
|
+
let data: RowChange = {
|
|
602
|
+
row: row,
|
|
603
|
+
index: index,
|
|
604
|
+
};
|
|
605
|
+
this.inlineChange.emit(data);
|
|
606
|
+
this.tableData[index]['editable'] = false;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* @description This method will save and update the cell editing data and emit the update row and index.
|
|
610
|
+
*/
|
|
611
|
+
saveCellEditing() {
|
|
612
|
+
this.cellEditing = {};
|
|
613
|
+
let index = this.currentRowIndex;
|
|
614
|
+
if (index > -1) {
|
|
615
|
+
if (this.cellEditingTemplateRef) {
|
|
616
|
+
let changedData = this.service.selectedRow.value;
|
|
617
|
+
if (changedData) {
|
|
618
|
+
this.tableData[index] = { ...changedData };
|
|
619
|
+
}
|
|
620
|
+
} else {
|
|
621
|
+
this.tableData[index] = { ...this.rowDataTemp['e' + index] };
|
|
622
|
+
}
|
|
623
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
624
|
+
this.rowDataTemp['e' + index] = {};
|
|
625
|
+
let data: RowChange = {
|
|
626
|
+
row: { ...this.tableData[index] },
|
|
627
|
+
index: index,
|
|
628
|
+
};
|
|
629
|
+
this.currentRowIndex = -1;
|
|
630
|
+
this.cellChange.emit(data);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* @description This method will delete the row from the given index and emit the deleted row and index.
|
|
635
|
+
* @param row row to be deleted.
|
|
636
|
+
* @param index index of the row to be deleted.
|
|
637
|
+
*/
|
|
638
|
+
deleteRow(row: any, index: number) {
|
|
639
|
+
this.tableData.splice(index, 1);
|
|
640
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
641
|
+
this.dataSource.paginator = this.paginator;
|
|
642
|
+
this.dataSource.sort = this.sort;
|
|
643
|
+
this.rowDeleted.emit({ removedRow: row, fromIndex: index });
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* @description This method will expand or collapse the row and emit expand event.
|
|
648
|
+
* @param row row to be expanded or collapsed.
|
|
649
|
+
* @param expand value used to expand or collapse the row.
|
|
650
|
+
* @param index index of the row.
|
|
651
|
+
*/
|
|
652
|
+
expandRow(row: MTExRow, expand: boolean, index: number) {
|
|
653
|
+
if (this.expandRows) {
|
|
654
|
+
this.expansionChange.emit({ data: row, expanded: expand, index: index });
|
|
655
|
+
this.expandedElement = this.expandedElement === row ? null : row;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* @description This method is used to set data for popup component and open editing dialog.
|
|
660
|
+
* @param row row which used want to edit.
|
|
661
|
+
*/
|
|
662
|
+
openEditingDialog(row: MTExRow) {
|
|
663
|
+
const dialogConfig = new MatDialogConfig();
|
|
664
|
+
dialogConfig.disableClose = true;
|
|
665
|
+
dialogConfig.width = '40%';
|
|
666
|
+
dialogConfig.height = '70%';
|
|
667
|
+
dialogConfig.maxWidth = '100%';
|
|
668
|
+
let rowData = { ...row };
|
|
669
|
+
dialogConfig.data = {
|
|
670
|
+
row: rowData,
|
|
671
|
+
columns: [...this.columnsArray],
|
|
672
|
+
templateRef: this.popupEditingTemplateRef,
|
|
673
|
+
};
|
|
674
|
+
this.dialog
|
|
675
|
+
.open(EditingComponent, dialogConfig)
|
|
676
|
+
.afterClosed()
|
|
677
|
+
.subscribe((data) => {
|
|
678
|
+
let index = this.tableData.indexOf(row);
|
|
679
|
+
if (data && index > -1) {
|
|
680
|
+
this.tableData[index] = data;
|
|
681
|
+
this.dataSource = new MatTableDataSource(this.tableData);
|
|
682
|
+
let dataChange: RowChange = {
|
|
683
|
+
row: data,
|
|
684
|
+
index: index,
|
|
685
|
+
};
|
|
686
|
+
this.popupChange.emit(dataChange);
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* @description used to check whether all rows are selected.
|
|
692
|
+
*/
|
|
693
|
+
isAllSelected() {
|
|
694
|
+
const numSelected = this.selection.selected.length;
|
|
695
|
+
const numRows = this.dataSource.data.length;
|
|
696
|
+
return numSelected === numRows;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* @description this method is used to toggle the all and no rows selection.
|
|
701
|
+
*/
|
|
702
|
+
toggleAllRows() {
|
|
703
|
+
if (this.isAllSelected()) {
|
|
704
|
+
this.selection.clear();
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
this.selection.select(...this.dataSource.data);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @description This method is used return aria-label for selection column checkboxs.
|
|
712
|
+
* @param row row from table.
|
|
713
|
+
* @returns labels for selection column checkboxs.
|
|
714
|
+
*/
|
|
715
|
+
checkboxLabel(row?: any): string {
|
|
716
|
+
if (!row) {
|
|
717
|
+
return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
|
|
718
|
+
}
|
|
719
|
+
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${
|
|
720
|
+
row.position + 1
|
|
721
|
+
}`;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* @description create form control for columns for hiding and and pinning purpose
|
|
726
|
+
* @param columns list of columns to be displayed
|
|
727
|
+
*/
|
|
728
|
+
setToolbarMenuControls(columns: MTExColumn[]) {
|
|
729
|
+
if (columns.length > 0 && this.showToolbar) {
|
|
730
|
+
const group = this.formBuildersService.group({});
|
|
731
|
+
columns.forEach((column: MTExColumn) => {
|
|
732
|
+
const control = this.formBuildersService.control(true);
|
|
733
|
+
group.addControl(column.field, control);
|
|
734
|
+
});
|
|
735
|
+
this.hideShowMenuGroup = group;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* @param column current column
|
|
741
|
+
* @param event mouse event used to set the menu position
|
|
742
|
+
*/
|
|
743
|
+
openPinnablePropertyMenu(column: MTExColumn, event: MouseEvent): void {
|
|
744
|
+
this.menuX = event.clientX;
|
|
745
|
+
this.menuY = event.clientY;
|
|
746
|
+
let options: MTExColumnPinOption[] = [
|
|
747
|
+
{
|
|
748
|
+
label: 'Pin Left',
|
|
749
|
+
value: 'left',
|
|
750
|
+
selected: false,
|
|
751
|
+
field: column.field,
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
label: 'Pin Right',
|
|
755
|
+
value: 'right',
|
|
756
|
+
selected: false,
|
|
757
|
+
field: column.field,
|
|
758
|
+
},
|
|
759
|
+
{ label: 'No Pin', value: null, selected: false, field: column.field },
|
|
760
|
+
];
|
|
761
|
+
if (column.pinned && column.pinned !== null) {
|
|
762
|
+
options.forEach((opt: MTExColumnPinOption) => {
|
|
763
|
+
if (opt.value === column.pinned) {
|
|
764
|
+
opt.selected = true;
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
} else if (column.pinned == null || column.pinned == 'null') {
|
|
768
|
+
options[2].selected = true;
|
|
769
|
+
}
|
|
770
|
+
this.columnPinningOptions = options;
|
|
771
|
+
this.columnMenuTrigger.openMenu();
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* @description This method is used to reset menu checks when required.
|
|
775
|
+
*/
|
|
776
|
+
resetMenuChecks() {
|
|
777
|
+
this.hideShowMenuCtrl = false;
|
|
778
|
+
this.showHideColumnsArray = [];
|
|
779
|
+
this.columnPinMenuCtrl = false;
|
|
780
|
+
this.columnPinningOptions = [];
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* @description This method is used to filter columns for menus like pinning or hide show menu.
|
|
784
|
+
* @param value search value to filter colunms
|
|
785
|
+
*/
|
|
786
|
+
filterColumns(value: string) {
|
|
787
|
+
if (value !== '') {
|
|
788
|
+
this.showHideColumnsArray = this.columnsArray.filter(
|
|
789
|
+
(col: MTExColumn) => {
|
|
790
|
+
return col.header!.toLowerCase().includes(value.toLowerCase());
|
|
791
|
+
}
|
|
792
|
+
);
|
|
793
|
+
} else {
|
|
794
|
+
this.showHideColumnsArray = this.columnsArray;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* @description This method is used to open hide show column menu.
|
|
799
|
+
* @param columns columns array to display in hide show menu.
|
|
800
|
+
*/
|
|
801
|
+
openHideShowMenu(columns: MTExColumn[]) {
|
|
802
|
+
this.showHideColumnsArray = [...columns];
|
|
803
|
+
this.columnMenuTrigger.openMenu();
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* @param values columns
|
|
807
|
+
*/
|
|
808
|
+
updateColumnsHideShow(values: ColumnVisibility) {
|
|
809
|
+
let keys = Object.keys(values);
|
|
810
|
+
keys.forEach((key: string) => {
|
|
811
|
+
this.showHideColumn(key, values[key]);
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* @description This method is called when the table rows are scrolled.
|
|
817
|
+
* @param event scroll event
|
|
818
|
+
*/
|
|
819
|
+
onScroll(event: any) {
|
|
820
|
+
this.scroll.emit(event);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* @param row row to be toggled
|
|
824
|
+
* @param index index of toggled row
|
|
825
|
+
*/
|
|
826
|
+
setSelectedRows(row: any, index: number) {
|
|
827
|
+
this.selection.toggle(row);
|
|
828
|
+
if (this.selection.isSelected(row)) {
|
|
829
|
+
this.selectionChanged.emit({ row: row, index: index, isSelected: true });
|
|
830
|
+
} else {
|
|
831
|
+
this.selectionChanged.emit({ row: row, index: index, isSelected: false });
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* @description This method is used to display all hidden rows.
|
|
836
|
+
*/
|
|
837
|
+
showHiddenRows() {
|
|
838
|
+
this.hideRows = false;
|
|
839
|
+
this.selection.clear();
|
|
840
|
+
this.hiddenCtrl.clear();
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* @description This method is used to hide all selected rows.
|
|
844
|
+
*/
|
|
845
|
+
hideSelectedRows() {
|
|
846
|
+
if (!this.selection.isEmpty()) {
|
|
847
|
+
let values = [...this.selection.selected];
|
|
848
|
+
values.forEach((value) => {
|
|
849
|
+
if (!this.hiddenCtrl.isSelected(value)) {
|
|
850
|
+
this.hiddenCtrl.toggle(value);
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
this.selection.clear();
|
|
854
|
+
this.hideRows = true;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* @description This method is used to recalculate the required values for table.
|
|
859
|
+
*/
|
|
860
|
+
reCal() {
|
|
861
|
+
if (this.showPaginator) {
|
|
862
|
+
this.dataSource.paginator = this.paginator;
|
|
863
|
+
}
|
|
864
|
+
if (this.sorting) {
|
|
865
|
+
this.dataSource.sort = this.sort;
|
|
866
|
+
}
|
|
867
|
+
if (this.columnFilter) {
|
|
868
|
+
this.dataSource.filterPredicate = this.createFilter();
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* @description This method is called in constructor method to add SVGs into icon registration.
|
|
873
|
+
*/
|
|
874
|
+
addIconsToRegistry() {
|
|
875
|
+
let y = this.domSanitizer.bypassSecurityTrustResourceUrl(
|
|
876
|
+
`assets/pinRight.svg`
|
|
877
|
+
);
|
|
878
|
+
let iconNames = ['pinLeft', 'pinRight', 'pinNone', 'pinned', 'pinIcon'];
|
|
879
|
+
iconNames.forEach((icon) => {
|
|
880
|
+
this.matIconRegistry.addSvgIcon(
|
|
881
|
+
icon,
|
|
882
|
+
this.domSanitizer.bypassSecurityTrustResourceUrl(
|
|
883
|
+
`assets/${icon}.svg`
|
|
884
|
+
)
|
|
885
|
+
);
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* @description This method is used to export table data.
|
|
890
|
+
* @param type type of file to be exported.
|
|
891
|
+
*/
|
|
892
|
+
exportTable(type: string) {
|
|
893
|
+
var element = document.getElementById('matTableExt' + this.tableID);
|
|
894
|
+
var ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(element);
|
|
895
|
+
ws = this.writeSheetData(ws);
|
|
896
|
+
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
|
897
|
+
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
|
|
898
|
+
XLSX.writeFile(wb, `tablesheets.${type}`);
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* @description This method is used to split name of filter row header to get index.
|
|
902
|
+
* @param value value to be splited for index.
|
|
903
|
+
* @returns Will return index of column from value.
|
|
904
|
+
*/
|
|
905
|
+
returnIndex(value: string): number {
|
|
906
|
+
return Number(value.split('_')[1]);
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* @description This method is used to manage column filtering, expanded data for exporting.
|
|
910
|
+
* @param ws work sheet
|
|
911
|
+
* @returns custom generated worksheet to be used in export.
|
|
912
|
+
*/
|
|
913
|
+
writeSheetData(ws: XLSX.WorkSheet): XLSX.WorkSheet {
|
|
914
|
+
let displayedColumns = this.getDisplayedColumns();
|
|
915
|
+
var nMerges = this.getMergeIndex(ws['!merges'] || []);
|
|
916
|
+
var merges = ws['!merges'] || [];
|
|
917
|
+
let data: XLSX.WorkSheet = {
|
|
918
|
+
'!cols': [],
|
|
919
|
+
'!rows': [],
|
|
920
|
+
'!merges': nMerges,
|
|
921
|
+
};
|
|
922
|
+
var range = XLSX.utils.decode_range(ws['!ref'] || '');
|
|
923
|
+
let extracolumns = ['popup', 'delete', 'select', 'edit'];
|
|
924
|
+
let keys = Object.keys(ws);
|
|
925
|
+
let nKey = 'A';
|
|
926
|
+
keys.forEach((key, i) => {
|
|
927
|
+
if (ws[key]?.v && typeof ws[key]?.v === 'string') {
|
|
928
|
+
if (
|
|
929
|
+
!extracolumns.includes(ws[key].v.toLowerCase()) &&
|
|
930
|
+
displayedColumns.includes(ws[key].v.toLowerCase())
|
|
931
|
+
) {
|
|
932
|
+
let lastRowIndex = range?.e?.r;
|
|
933
|
+
data[key] = ws[key];
|
|
934
|
+
let chr = key.charAt(0);
|
|
935
|
+
for (let j = 2; j <= lastRowIndex; j++) {
|
|
936
|
+
if (
|
|
937
|
+
ws[chr + (j + 1)] !== undefined &&
|
|
938
|
+
(typeof ws[chr + (j + 1)].v === 'string' ||
|
|
939
|
+
typeof ws[chr + (j + 1)].v === 'number')
|
|
940
|
+
) {
|
|
941
|
+
data[nKey + j] = ws[chr + (j + 1)];
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
nKey = String.fromCharCode(nKey.charCodeAt(0) + 1);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
if (this.rowSelection) {
|
|
949
|
+
let chr = 'A';
|
|
950
|
+
for (let i = 1; i < range.e.c + 1; i++) {
|
|
951
|
+
data[chr + 1] = data[String.fromCharCode(chr.charCodeAt(0) + 1) + 1];
|
|
952
|
+
chr = String.fromCharCode(chr.charCodeAt(0) + 1);
|
|
953
|
+
if (i == range.e.c) {
|
|
954
|
+
data[chr + 1] = undefined;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
if (this.rowSelection && this.expandRows) {
|
|
959
|
+
merges.forEach((merge) => {
|
|
960
|
+
data['A' + merge.s.r] = ws['A' + (merge.s.r + 1)];
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
range.e.r--;
|
|
964
|
+
let nRef = XLSX.utils.encode_range(range);
|
|
965
|
+
data['!ref'] = nRef;
|
|
966
|
+
data['!fullref'] = nRef;
|
|
967
|
+
return data;
|
|
968
|
+
}
|
|
969
|
+
getMergeIndex(merges: any[]) {
|
|
970
|
+
var arr: any[] = [];
|
|
971
|
+
merges.forEach((element: any) => {
|
|
972
|
+
arr.push({
|
|
973
|
+
e: {
|
|
974
|
+
r: element.e.r == 0 ? element.e.r : element.e.r - 1,
|
|
975
|
+
c: element.e.c,
|
|
976
|
+
},
|
|
977
|
+
s: {
|
|
978
|
+
r: element.s.r == 0 ? element.s.r : element.s.r - 1,
|
|
979
|
+
c: element.s.c,
|
|
980
|
+
},
|
|
981
|
+
});
|
|
982
|
+
});
|
|
983
|
+
return arr;
|
|
984
|
+
}
|
|
985
|
+
}
|