@rosoftlab/material 1.0.0-alpha-0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/README.md +27 -0
  2. package/esm2022/lib/components/generic-table/generic-table.component.mjs +435 -0
  3. package/esm2022/lib/components/index.mjs +3 -0
  4. package/esm2022/lib/components/searchable-dropdown/searchable-dropdown.component.mjs +234 -0
  5. package/esm2022/lib/core.mjs +6 -0
  6. package/esm2022/lib/decorators/grid-layout.decorator.mjs +23 -0
  7. package/esm2022/lib/decorators/index.mjs +2 -0
  8. package/esm2022/lib/models/grid-layout.mjs +18 -0
  9. package/esm2022/lib/models/index.mjs +3 -0
  10. package/esm2022/lib/models/material-base-model.mjs +17 -0
  11. package/esm2022/lib/rsl-material-module.mjs +96 -0
  12. package/esm2022/lib/services/grid-layout.service.mjs +22 -0
  13. package/esm2022/lib/services/index.mjs +2 -0
  14. package/esm2022/public-api.mjs +5 -0
  15. package/esm2022/rosoftlab-material.mjs +5 -0
  16. package/fesm2022/rosoftlab-material.mjs +823 -0
  17. package/fesm2022/rosoftlab-material.mjs.map +1 -0
  18. package/index.d.ts +5 -0
  19. package/lib/components/generic-table/generic-table.component.d.ts +88 -0
  20. package/lib/components/index.d.ts +2 -0
  21. package/lib/components/searchable-dropdown/searchable-dropdown.component.d.ts +61 -0
  22. package/lib/core.d.ts +5 -0
  23. package/lib/decorators/grid-layout.decorator.d.ts +2 -0
  24. package/lib/decorators/index.d.ts +1 -0
  25. package/lib/models/grid-layout.d.ts +13 -0
  26. package/lib/models/index.d.ts +2 -0
  27. package/lib/models/material-base-model.d.ts +5 -0
  28. package/lib/rsl-material-module.d.ts +45 -0
  29. package/lib/services/grid-layout.service.d.ts +11 -0
  30. package/lib/services/index.d.ts +1 -0
  31. package/package.json +31 -0
  32. package/public-api.d.ts +1 -0
@@ -0,0 +1,823 @@
1
+ import * as i13 from '@angular/cdk/drag-drop';
2
+ import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
3
+ import * as i3 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i0 from '@angular/core';
6
+ import { NgModule, Injectable, EventEmitter, ElementRef, Component, ViewEncapsulation, Input, ViewChild, Output, Optional, Self } from '@angular/core';
7
+ import * as i8 from '@angular/material/paginator';
8
+ import { MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
9
+ import * as i10 from '@angular/material/sort';
10
+ import { MatSortModule, MatSort } from '@angular/material/sort';
11
+ import * as i11 from '@angular/material/table';
12
+ import { MatTableModule, MatTableDataSource } from '@angular/material/table';
13
+ import * as i2 from '@angular/router';
14
+ import * as i1$1 from '@rosoftlab/core';
15
+ import { CellTextAlign, GridLayoutFormat, BaseModel } from '@rosoftlab/core';
16
+ import * as jsonLogic from 'json-logic-js/logic.js';
17
+ import { Subject, merge, of, fromEvent } from 'rxjs';
18
+ import { debounceTime, distinctUntilChanged, startWith, switchMap, map, catchError, filter, tap, finalize, takeUntil } from 'rxjs/operators';
19
+ import { PortalModule } from '@angular/cdk/portal';
20
+ import { CdkStepperModule } from '@angular/cdk/stepper';
21
+ import * as i2$1 from '@angular/forms';
22
+ import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
23
+ import * as i4 from '@angular/material/autocomplete';
24
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
25
+ import { MatBadgeModule } from '@angular/material/badge';
26
+ import * as i6$1 from '@angular/material/button';
27
+ import { MatButtonModule } from '@angular/material/button';
28
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
29
+ import { MatCardModule } from '@angular/material/card';
30
+ import { MatCheckboxModule } from '@angular/material/checkbox';
31
+ import { MatChipsModule } from '@angular/material/chips';
32
+ import * as i5$1 from '@angular/material/core';
33
+ import { MatNativeDateModule, MatRippleModule, MatOptionModule } from '@angular/material/core';
34
+ import { MatDatepickerModule } from '@angular/material/datepicker';
35
+ import { MatDialogModule } from '@angular/material/dialog';
36
+ import { MatDividerModule } from '@angular/material/divider';
37
+ import { MatExpansionModule } from '@angular/material/expansion';
38
+ import { MatGridListModule } from '@angular/material/grid-list';
39
+ import * as i5 from '@angular/material/icon';
40
+ import { MatIconModule } from '@angular/material/icon';
41
+ import * as i6 from '@angular/material/input';
42
+ import { MatInputModule } from '@angular/material/input';
43
+ import { MatListModule } from '@angular/material/list';
44
+ import { MatMenuModule } from '@angular/material/menu';
45
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
46
+ import * as i9 from '@angular/material/progress-spinner';
47
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
48
+ import { MatRadioModule } from '@angular/material/radio';
49
+ import { MatSelectModule } from '@angular/material/select';
50
+ import { MatSidenavModule } from '@angular/material/sidenav';
51
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
52
+ import { MatSliderModule } from '@angular/material/slider';
53
+ import { MatSnackBarModule } from '@angular/material/snack-bar';
54
+ import { MatStepperModule } from '@angular/material/stepper';
55
+ import { MatTabsModule } from '@angular/material/tabs';
56
+ import { MatToolbarModule } from '@angular/material/toolbar';
57
+ import * as i12 from '@angular/material/tooltip';
58
+ import { MatTooltipModule } from '@angular/material/tooltip';
59
+ import { MatTreeModule } from '@angular/material/tree';
60
+ import * as i1 from '@ngx-translate/core';
61
+ import { TranslateModule } from '@ngx-translate/core';
62
+ import * as i7 from '@angular/material/form-field';
63
+ import * as i1$2 from '@angular/cdk/a11y';
64
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
65
+
66
+ const COMMON_MODULES = [
67
+ CommonModule,
68
+ ReactiveFormsModule,
69
+ MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
70
+ MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
71
+ MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
72
+ MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
73
+ MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
74
+ MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
75
+ CdkStepperModule
76
+ ];
77
+ class RSLMaterialModule {
78
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: RSLMaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
79
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.1", ngImport: i0, type: RSLMaterialModule, imports: [CommonModule,
80
+ ReactiveFormsModule,
81
+ MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
82
+ MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
83
+ MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
84
+ MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
85
+ MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
86
+ MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
87
+ CdkStepperModule, i1.TranslateModule], exports: [CommonModule,
88
+ ReactiveFormsModule,
89
+ MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
90
+ MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
91
+ MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
92
+ MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
93
+ MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
94
+ MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
95
+ CdkStepperModule, TranslateModule] }); }
96
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: RSLMaterialModule, imports: [COMMON_MODULES, TranslateModule.forRoot({}), CommonModule,
97
+ ReactiveFormsModule,
98
+ MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
99
+ MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
100
+ MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
101
+ MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
102
+ MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
103
+ MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
104
+ CdkStepperModule, TranslateModule] }); }
105
+ }
106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: RSLMaterialModule, decorators: [{
107
+ type: NgModule,
108
+ args: [{
109
+ imports: [
110
+ ...COMMON_MODULES,
111
+ TranslateModule.forRoot({})
112
+ ],
113
+ exports: [
114
+ ...COMMON_MODULES,
115
+ TranslateModule
116
+ ],
117
+ }]
118
+ }] });
119
+
120
+ class GridLayoutService {
121
+ constructor(baseService) {
122
+ this.baseService = baseService;
123
+ }
124
+ getGridLayout() {
125
+ var model = this.baseService.newModel();
126
+ return model.getGridLayout();
127
+ }
128
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: GridLayoutService, deps: [{ token: i1$1.BaseService }], target: i0.ɵɵFactoryTarget.Injectable }); }
129
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: GridLayoutService, providedIn: 'root' }); }
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: GridLayoutService, decorators: [{
132
+ type: Injectable,
133
+ args: [{
134
+ providedIn: 'root'
135
+ }]
136
+ }], ctorParameters: function () { return [{ type: i1$1.BaseService }]; } });
137
+
138
+ class GenericTableComponent {
139
+ // ruleEngineService: RuleEngineService<T>;
140
+ constructor(dialogService, router, datePipe, numberPipe, percentPipe, renderer) {
141
+ this.dialogService = dialogService;
142
+ this.router = router;
143
+ this.datePipe = datePipe;
144
+ this.numberPipe = numberPipe;
145
+ this.percentPipe = percentPipe;
146
+ this.renderer = renderer;
147
+ this.defaultSort = null;
148
+ this.defaultSortDirection = null;
149
+ this.deletePropertyName = 'name';
150
+ this.stickyColumns = null;
151
+ this.editOnClick = false;
152
+ this.editOnDblClick = false;
153
+ this.allowEdit = true;
154
+ this.popupEdit = false;
155
+ this.customInclude = null;
156
+ this.infiniteScroll = false;
157
+ this.dataSource = new MatTableDataSource();
158
+ this.resultsLength = 0;
159
+ this.isLoadingResults = true;
160
+ this.isRateLimitReached = false;
161
+ this.filterChanged = new Subject();
162
+ this.selectedObject = new EventEmitter();
163
+ this.click = new EventEmitter();
164
+ this.editModel = new EventEmitter();
165
+ }
166
+ ngOnChanges() {
167
+ if (this.baseService !== undefined || this.baseService !== null) {
168
+ if (this.gridLayoutService != null) {
169
+ this.gridLayout = this.gridLayoutService.getGridLayout();
170
+ }
171
+ else {
172
+ const model = this.baseService.newModel();
173
+ this.gridLayout = model.getGridLayout();
174
+ }
175
+ this.displayedColumns = [];
176
+ if (this.allowReorderItems) {
177
+ this.displayedColumns.push('position');
178
+ }
179
+ this.displayedColumns.push.apply(this.displayedColumns, this.gridLayout.map(x => x.propertyName));
180
+ if (!this.editOnClick && !this.editOnDblClick && this.allowEdit) {
181
+ this.displayedColumns.push('delete');
182
+ }
183
+ }
184
+ }
185
+ ngOnInit() {
186
+ this.filterChangedSubscription = this.filterChanged
187
+ .pipe(debounceTime(300), distinctUntilChanged())
188
+ .subscribe(newText => {
189
+ if (newText.length >= 3 || newText.length == 0) {
190
+ this.filterValue = newText;
191
+ this.paginator.pageIndex = 0;
192
+ this.refreshForm();
193
+ }
194
+ });
195
+ // this.getGridLayout();
196
+ this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
197
+ this.paginator.pageSize = 15;
198
+ if (this.defaultSort) {
199
+ this.sort.active = this.defaultSort;
200
+ if (this.defaultSortDirection) {
201
+ this.sort.direction = this.defaultSortDirection;
202
+ }
203
+ else {
204
+ this.sort.direction = 'asc';
205
+ }
206
+ }
207
+ // this.dataSource.paginator = this.paginator;
208
+ merge(this.sort.sortChange, this.paginator.page)
209
+ .pipe(startWith({}), switchMap(() => {
210
+ this.isLoadingResults = true;
211
+ return this.getData();
212
+ }), map(data => {
213
+ // Flip flag to show that loading has finished.
214
+ this.isLoadingResults = false;
215
+ this.isRateLimitReached = false;
216
+ if (data) {
217
+ this.resultsLength = data.getMeta().meta.count;
218
+ return data.getModels();
219
+ }
220
+ else {
221
+ this.resultsLength = 0;
222
+ return [];
223
+ }
224
+ }), catchError(() => {
225
+ this.isLoadingResults = false;
226
+ // Catch if the GitHub API has reached its rate limit. Return empty data.
227
+ this.isRateLimitReached = true;
228
+ return of([]);
229
+ })).subscribe(data => {
230
+ // if (this.infiniteScroll) {
231
+ // let oldData = this.dataSource.data ?? null;
232
+ // // if (oldData.length === 0) {
233
+ // // oldData = data;
234
+ // // } else {
235
+ // oldData=oldData.concat(data);
236
+ // // }
237
+ // this.dataSource.data = oldData;
238
+ // }
239
+ // else {
240
+ this.dataSource.data = data;
241
+ // }
242
+ });
243
+ // this.paginator.nextPage()
244
+ }
245
+ getData() {
246
+ this.isLoadingResults = true;
247
+ const pageIndex = (this.paginator.pageIndex || 0) + 1;
248
+ const pageSize = this.paginator.pageSize || 20;
249
+ const filters = [];
250
+ let sorts = '';
251
+ if (this.sort.active) {
252
+ if (this.sort.direction === 'desc') {
253
+ sorts = '-' + this.sort.active;
254
+ }
255
+ else {
256
+ sorts = this.sort.active;
257
+ }
258
+ }
259
+ if (this.hasSearch) {
260
+ if (this.filterValue) {
261
+ // const filtersArr = this.searchFields.split(",");
262
+ // filtersArr.forEach(element => {
263
+ // filters.push(element + '@=*' + this.filterValue);
264
+ // });
265
+ const y = '(' + this.searchFields.replace(',', '|') + ')';
266
+ filters.push(y + '@=*' + this.filterValue);
267
+ }
268
+ }
269
+ if (this.defaultFilter) {
270
+ filters.push(this.defaultFilter);
271
+ }
272
+ const filtersValue = filters.join(', ');
273
+ return this.baseService.getAll(pageIndex, pageSize, sorts, filtersValue, this.customInclude);
274
+ }
275
+ refreshForm() {
276
+ this.getData().subscribe(data => {
277
+ if (data) {
278
+ this.isLoadingResults = false;
279
+ this.isRateLimitReached = false;
280
+ this.resultsLength = data.getMeta().meta.count;
281
+ this.dataSource.data = data.getModels();
282
+ }
283
+ else {
284
+ this.isLoadingResults = false;
285
+ this.isRateLimitReached = false;
286
+ this.resultsLength = 0;
287
+ this.dataSource.data = [];
288
+ }
289
+ });
290
+ }
291
+ highlight(element) {
292
+ if (this.selectedItem) {
293
+ this.selectedItem.highlighted = element.highlighted;
294
+ }
295
+ this.selectedItem = null;
296
+ element.highlighted = !element.highlighted;
297
+ if (element.highlighted) {
298
+ this.selectedItem = element;
299
+ this.selectedObject.emit(element);
300
+ }
301
+ else {
302
+ this.selectedObject.emit(null);
303
+ }
304
+ }
305
+ deleteObject(model) {
306
+ const msg = 'Do you want to delete ' + model[this.deletePropertyName] + '?';
307
+ this.dialogService.confirm(msg).subscribe((response) => {
308
+ if (response) {
309
+ this.baseService.delete(model.id).subscribe(() => {
310
+ const tempData = [];
311
+ this.selectedObject.emit(null);
312
+ this.dataSource.data.map((item) => {
313
+ if (item.id !== model.id) {
314
+ tempData.push(item);
315
+ }
316
+ });
317
+ this.dataSource.data = tempData;
318
+ });
319
+ }
320
+ });
321
+ }
322
+ editObject(model) {
323
+ if (!this.popupEdit) {
324
+ const id = model.id;
325
+ this.router.navigate([this.editLink, id]);
326
+ }
327
+ else {
328
+ this.editModel.emit(model);
329
+ }
330
+ }
331
+ getFlexStyle(column) {
332
+ if (column.width) {
333
+ const style = column.grow + ' ' + column.shrink + ' ' + column.width + 'px';
334
+ return style;
335
+ }
336
+ return null;
337
+ }
338
+ getCellTextAlign(column) {
339
+ return column.textAlign ?? CellTextAlign.left;
340
+ }
341
+ showPictureCell(column) {
342
+ return (column?.formating ?? GridLayoutFormat.none) === GridLayoutFormat.picture;
343
+ }
344
+ deleteDisabled(model) {
345
+ if (this.deleteDisableRule) {
346
+ return this.evaluateRule(this.deleteDisableRule, model);
347
+ }
348
+ else {
349
+ return false;
350
+ }
351
+ }
352
+ cellClick(model, propertyName) {
353
+ this.click.emit({ propertyName, model });
354
+ }
355
+ evaluateRule(rules, model) {
356
+ let result = true;
357
+ rules.forEach(rule => {
358
+ let jsonRule;
359
+ if (typeof rule.rule === 'string') {
360
+ jsonRule = JSON.parse(rule.rule);
361
+ }
362
+ else {
363
+ jsonRule = rule.rule;
364
+ }
365
+ if (rule.parameters) {
366
+ const data = '{' + rule.parameters.map((item) => {
367
+ return '"' + item + '":"' + model[item] + '"';
368
+ }).join(',') + '}';
369
+ result = jsonLogic.apply(jsonRule, JSON.parse(data));
370
+ }
371
+ else {
372
+ result = jsonLogic.apply(jsonRule);
373
+ }
374
+ });
375
+ return result;
376
+ }
377
+ getCelValue(row, propertyName) {
378
+ if (!row)
379
+ return "";
380
+ // if (propertyName == 'kompetenzenStdev')
381
+ // console.log(propertyName);
382
+ if (propertyName.indexOf('.') === -1) {
383
+ var gridLayout = this.gridLayout.find(f => f.propertyName.indexOf(propertyName) > -1);
384
+ return this.getFormatedValue(gridLayout, row[propertyName]);
385
+ }
386
+ else {
387
+ const prop = propertyName.split('.')[0];
388
+ const subProp = propertyName.replace(prop + '.', '');
389
+ return this.getCelValue(row[prop], subProp);
390
+ }
391
+ }
392
+ getFormatedValue(gridLayout, value) {
393
+ if (gridLayout) {
394
+ switch (gridLayout.formating) {
395
+ case GridLayoutFormat.date:
396
+ return this.datePipe.transform(value, gridLayout.format);
397
+ break;
398
+ case GridLayoutFormat.number:
399
+ return this.numberPipe.transform(value, gridLayout.format);
400
+ case GridLayoutFormat.percent:
401
+ const valuePrc = value / 100;
402
+ return this.percentPipe.transform(valuePrc, gridLayout.format);
403
+ default:
404
+ return value;
405
+ break;
406
+ }
407
+ }
408
+ return value;
409
+ }
410
+ applyFilter(event) {
411
+ }
412
+ dropTable(event) {
413
+ if (this.changeItemPosition) {
414
+ const prevItem = this.dataSource.data[event.previousIndex];
415
+ const currentItem = this.dataSource.data[event.currentIndex];
416
+ if (this.changeItemPosition(prevItem, currentItem)) {
417
+ const prevIndex = this.dataSource.data.findIndex((d) => d === event.item.data);
418
+ moveItemInArray(this.dataSource.data, prevIndex, event.currentIndex);
419
+ this.table.renderRows();
420
+ }
421
+ }
422
+ }
423
+ isColumnSticky(name) {
424
+ if (this.stickyColumns) {
425
+ const filtersArr = this.stickyColumns.split(",");
426
+ return filtersArr.findIndex(f => f == name) !== -1;
427
+ }
428
+ return false;
429
+ }
430
+ updateElement(model) {
431
+ //Find if element exist
432
+ var currentElement = this.dataSource.data.find(f => f.id === model.id);
433
+ if (currentElement !== null) {
434
+ const index = this.dataSource.data.indexOf(currentElement);
435
+ this.dataSource.data[index] = model;
436
+ }
437
+ else {
438
+ this.dataSource.data.push(model);
439
+ }
440
+ const newData = [...this.dataSource.data];
441
+ this.dataSource.data = newData;
442
+ this.dataSource._updateChangeSubscription();
443
+ }
444
+ ngAfterViewInit() {
445
+ fromEvent(this.matTableRef.nativeElement, 'scroll')
446
+ .pipe(debounceTime(700))
447
+ .subscribe((e) => this.onTableScroll(e));
448
+ }
449
+ onTableScroll(e) {
450
+ const tableViewHeight = e.target.offsetHeight; // viewport: ~500px
451
+ const tableScrollHeight = e.target.scrollHeight; // length of all table
452
+ const scrollLocation = e.target.scrollTop; // how far user scrolled
453
+ // If the user has scrolled within 200px of the bottom, add more data
454
+ const scrollThreshold = 200;
455
+ const scrollUpLimit = scrollThreshold;
456
+ if (scrollLocation < scrollUpLimit && this.paginator.pageIndex > 0) {
457
+ // this.firstPage--;
458
+ console.log(`onTableScroll() UP: firstPage decreased to ${this.paginator.pageIndex}. Now fetching data...`);
459
+ // this.fetchData();
460
+ this.scrollTo(tableScrollHeight / 2 - 2 * tableViewHeight);
461
+ }
462
+ const scrollDownLimit = tableScrollHeight - tableViewHeight - scrollThreshold;
463
+ if (scrollLocation > scrollDownLimit && this.paginator.pageIndex < this.paginator.getNumberOfPages()) {
464
+ // this.firstPage++;
465
+ console.log(`onTableScroll(): firstPage increased to ${this.paginator.pageIndex}. Now fetching data...`);
466
+ this.paginator.nextPage();
467
+ // this.scrollTo(tableScrollHeight / 2 + tableViewHeight);
468
+ }
469
+ }
470
+ scrollTo(position) {
471
+ this.renderer.setProperty(this.matTableRef.nativeElement, 'scrollTop', position);
472
+ }
473
+ getCellClass(model, property) {
474
+ return model.getCellClass(property);
475
+ }
476
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: GenericTableComponent, deps: [{ token: i1$1.DialogService }, { token: i2.Router }, { token: i3.DatePipe }, { token: i3.DecimalPipe }, { token: i3.PercentPipe }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
477
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: GenericTableComponent, isStandalone: true, selector: "rsl-generic-table", inputs: { modelType: "modelType", baseService: "baseService", gridLayoutService: "gridLayoutService", editLink: "editLink", defaultSort: "defaultSort", defaultSortDirection: "defaultSortDirection", deleteDisableRule: "deleteDisableRule", deletePropertyName: "deletePropertyName", hasSearch: "hasSearch", searchFields: "searchFields", defaultFilter: "defaultFilter", allowReorderItems: "allowReorderItems", stickyColumns: "stickyColumns", editOnClick: "editOnClick", editOnDblClick: "editOnDblClick", allowEdit: "allowEdit", popupEdit: "popupEdit", customInclude: "customInclude", changeItemPosition: "changeItemPosition", infiniteScroll: "infiniteScroll" }, outputs: { selectedObject: "selectedObject", click: "click", editModel: "editModel" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "filter", first: true, predicate: ElementRef, descendants: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matTableRef", first: true, predicate: ["table"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div class=\"containerX\" *ngIf=\"hasSearch\">\r\n <div fxLayout=\"row\" fxLayout.xs=\"column\" fxLayout.sm=\"column\" fxFlexFill>\r\n <mat-form-field fxFlex>\r\n <mat-label>Filter</mat-label>\r\n <input matInput [ngModel]='filterValue' (ngModelChange)='filterChanged.next($event)' #filter>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-container\">\r\n <div class=\"mat-elevation-z2\">\r\n <!-- #applicationsContainer -->\r\n <div class=\"example-loading-shade\" *ngIf=\"isLoadingResults || isRateLimitReached\">\r\n <mat-spinner *ngIf=\"isLoadingResults\"></mat-spinner>\r\n <div class=\"example-rate-limit-reached\" *ngIf=\"isRateLimitReached\">\r\n {{'General.LoadingData' | translate}}\r\n </div>\r\n </div>\r\n\r\n\r\n <mat-table fxFlex #table [dataSource]=\"dataSource\" id=\"tempalte-forms-table\" matSort matSortDisableClear\r\n matSortDirection=\"asc\" cdkDropList [cdkDropListData]=\"dataSource\" (cdkDropListDropped)=\"dropTable($event)\">\r\n <!-- (scroll)=\"onTableScroll($event)\" -->\r\n\r\n\r\n <ng-container matColumnDef=\"position\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n <!-- {{'General.Order' | translate}} -->\r\n </mat-header-cell>\r\n <mat-cell fxFlex *matCellDef=\"let element;\">\r\n <mat-icon cdkDragHandle>reorder</mat-icon>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container *ngFor=\"let column of gridLayout\" [matColumnDef]=\"column.propertyName\"\r\n [sticky]=\"isColumnSticky(column.propertyName)\">\r\n <mat-header-cell mat-sort-header disableClear [style.flex]=\"getFlexStyle(column)\" *matHeaderCellDef>\r\n {{column.translateKey | translate}}\r\n </mat-header-cell>\r\n <mat-cell matTooltip={{getCelValue(row,column.propertyName)}} [style.flex]=\"getFlexStyle(column)\"\r\n [style.text-align]=\"getCellTextAlign(column)\" *matCellDef=\"let row\" (click)=\"cellClick(row,column.propertyName)\">\r\n <div [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"!showPictureCell(column)\">\r\n {{getCelValue(row,column.propertyName)}}\r\n </div>\r\n <img [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"showPictureCell(column)\">\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container matColumnDef=\"delete\" stickyEnd *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let row\">\r\n <button class=\"btn btn-green btn-fill btn-wd btn-just-icon\" (click)=\"editObject(row)\"\r\n matTooltip=\"{{'General.Edit' | translate}}\">\r\n <!-- <mat-icon>edit</mat-icon> -->\r\n <i class=\"material-icons\">edit</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n <button class=\"btn btn-red btn-fill btn-wd btn-just-icon\" (click)=\"deleteObject(row)\"\r\n [disabled]=\"deleteDisabled(row)\" matTooltip=\"{{'General.Delete' | translate}}\">\r\n <i class=\"material-icons\">delete</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-header-row *matHeaderRowDef=\"displayedColumns;sticky: true\"></mat-header-row>\r\n\r\n <ng-container *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"highlight(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\">\r\n </mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"editObject(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!editOnClick && editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (dblclick)=\"editObject(row)\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\"\r\n style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <!-- [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" -->\r\n </mat-table>\r\n <mat-paginator #paginator [hidden]=\"infiniteScroll\" [length]=\"resultsLength\" [pageSize]=\"15\"\r\n [pageSizeOptions]=\"[15, 30, 100]\" [showFirstLastButtons]=\"true\">\r\n </mat-paginator>\r\n </div>\r\n</div>", styles: [".mat-column-delete{flex:0 0 90px;padding-right:30px}.mat-sort-header-button{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-column-position{flex:0 0 60px!important}.mat-table{overflow-x:auto}[hidden]{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: RSLMaterialModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i9.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i10.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i10.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i11.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i11.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i11.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i11.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i11.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i11.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i11.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i11.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i11.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i11.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i13.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i13.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i13.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
478
+ }
479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: GenericTableComponent, decorators: [{
480
+ type: Component,
481
+ args: [{ standalone: true, selector: 'rsl-generic-table', encapsulation: ViewEncapsulation.None, imports: [RSLMaterialModule], template: "<div class=\"containerX\" *ngIf=\"hasSearch\">\r\n <div fxLayout=\"row\" fxLayout.xs=\"column\" fxLayout.sm=\"column\" fxFlexFill>\r\n <mat-form-field fxFlex>\r\n <mat-label>Filter</mat-label>\r\n <input matInput [ngModel]='filterValue' (ngModelChange)='filterChanged.next($event)' #filter>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-container\">\r\n <div class=\"mat-elevation-z2\">\r\n <!-- #applicationsContainer -->\r\n <div class=\"example-loading-shade\" *ngIf=\"isLoadingResults || isRateLimitReached\">\r\n <mat-spinner *ngIf=\"isLoadingResults\"></mat-spinner>\r\n <div class=\"example-rate-limit-reached\" *ngIf=\"isRateLimitReached\">\r\n {{'General.LoadingData' | translate}}\r\n </div>\r\n </div>\r\n\r\n\r\n <mat-table fxFlex #table [dataSource]=\"dataSource\" id=\"tempalte-forms-table\" matSort matSortDisableClear\r\n matSortDirection=\"asc\" cdkDropList [cdkDropListData]=\"dataSource\" (cdkDropListDropped)=\"dropTable($event)\">\r\n <!-- (scroll)=\"onTableScroll($event)\" -->\r\n\r\n\r\n <ng-container matColumnDef=\"position\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n <!-- {{'General.Order' | translate}} -->\r\n </mat-header-cell>\r\n <mat-cell fxFlex *matCellDef=\"let element;\">\r\n <mat-icon cdkDragHandle>reorder</mat-icon>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container *ngFor=\"let column of gridLayout\" [matColumnDef]=\"column.propertyName\"\r\n [sticky]=\"isColumnSticky(column.propertyName)\">\r\n <mat-header-cell mat-sort-header disableClear [style.flex]=\"getFlexStyle(column)\" *matHeaderCellDef>\r\n {{column.translateKey | translate}}\r\n </mat-header-cell>\r\n <mat-cell matTooltip={{getCelValue(row,column.propertyName)}} [style.flex]=\"getFlexStyle(column)\"\r\n [style.text-align]=\"getCellTextAlign(column)\" *matCellDef=\"let row\" (click)=\"cellClick(row,column.propertyName)\">\r\n <div [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"!showPictureCell(column)\">\r\n {{getCelValue(row,column.propertyName)}}\r\n </div>\r\n <img [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"showPictureCell(column)\">\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container matColumnDef=\"delete\" stickyEnd *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let row\">\r\n <button class=\"btn btn-green btn-fill btn-wd btn-just-icon\" (click)=\"editObject(row)\"\r\n matTooltip=\"{{'General.Edit' | translate}}\">\r\n <!-- <mat-icon>edit</mat-icon> -->\r\n <i class=\"material-icons\">edit</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n <button class=\"btn btn-red btn-fill btn-wd btn-just-icon\" (click)=\"deleteObject(row)\"\r\n [disabled]=\"deleteDisabled(row)\" matTooltip=\"{{'General.Delete' | translate}}\">\r\n <i class=\"material-icons\">delete</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-header-row *matHeaderRowDef=\"displayedColumns;sticky: true\"></mat-header-row>\r\n\r\n <ng-container *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"highlight(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\">\r\n </mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"editObject(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!editOnClick && editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (dblclick)=\"editObject(row)\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\"\r\n style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <!-- [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" -->\r\n </mat-table>\r\n <mat-paginator #paginator [hidden]=\"infiniteScroll\" [length]=\"resultsLength\" [pageSize]=\"15\"\r\n [pageSizeOptions]=\"[15, 30, 100]\" [showFirstLastButtons]=\"true\">\r\n </mat-paginator>\r\n </div>\r\n</div>", styles: [".mat-column-delete{flex:0 0 90px;padding-right:30px}.mat-sort-header-button{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-column-position{flex:0 0 60px!important}.mat-table{overflow-x:auto}[hidden]{display:none!important}\n"] }]
482
+ }], ctorParameters: function () { return [{ type: i1$1.DialogService }, { type: i2.Router }, { type: i3.DatePipe }, { type: i3.DecimalPipe }, { type: i3.PercentPipe }, { type: i0.Renderer2 }]; }, propDecorators: { modelType: [{
483
+ type: Input
484
+ }], baseService: [{
485
+ type: Input
486
+ }], gridLayoutService: [{
487
+ type: Input
488
+ }], editLink: [{
489
+ type: Input
490
+ }], defaultSort: [{
491
+ type: Input
492
+ }], defaultSortDirection: [{
493
+ type: Input
494
+ }], deleteDisableRule: [{
495
+ type: Input
496
+ }], deletePropertyName: [{
497
+ type: Input
498
+ }], hasSearch: [{
499
+ type: Input
500
+ }], searchFields: [{
501
+ type: Input
502
+ }], defaultFilter: [{
503
+ type: Input
504
+ }], allowReorderItems: [{
505
+ type: Input
506
+ }], stickyColumns: [{
507
+ type: Input
508
+ }], editOnClick: [{
509
+ type: Input
510
+ }], editOnDblClick: [{
511
+ type: Input
512
+ }], allowEdit: [{
513
+ type: Input
514
+ }], popupEdit: [{
515
+ type: Input
516
+ }], customInclude: [{
517
+ type: Input
518
+ }], changeItemPosition: [{
519
+ type: Input
520
+ }], infiniteScroll: [{
521
+ type: Input
522
+ }], paginator: [{
523
+ type: ViewChild,
524
+ args: [MatPaginator, { static: true }]
525
+ }], sort: [{
526
+ type: ViewChild,
527
+ args: [MatSort, { static: true }]
528
+ }], filter: [{
529
+ type: ViewChild,
530
+ args: [ElementRef, { static: false }]
531
+ }], table: [{
532
+ type: ViewChild,
533
+ args: ['table']
534
+ }], matTableRef: [{
535
+ type: ViewChild,
536
+ args: ['table', { read: ElementRef }]
537
+ }], selectedObject: [{
538
+ type: Output
539
+ }], click: [{
540
+ type: Output
541
+ }], editModel: [{
542
+ type: Output
543
+ }] } });
544
+
545
+ class SearchableDropdownComponent {
546
+ static { this.nextId = 0; }
547
+ get empty() {
548
+ return !this.value;
549
+ }
550
+ get required() { return this._required; }
551
+ set required(value) {
552
+ this._required = coerceBooleanProperty(value);
553
+ this.stateChanges.next();
554
+ }
555
+ get disabled() { return this._disabled; }
556
+ set disabled(value) {
557
+ this._disabled = coerceBooleanProperty(value);
558
+ this.stateChanges.next();
559
+ }
560
+ get value() {
561
+ return this._value;
562
+ }
563
+ set value(value) {
564
+ if (value)
565
+ if (this._value !== value) {
566
+ this.loadModel(value);
567
+ }
568
+ this._value = value;
569
+ this.stateChanges.next();
570
+ }
571
+ constructor(_focusMonitor, _elementRef, ngControl) {
572
+ this._focusMonitor = _focusMonitor;
573
+ this._elementRef = _elementRef;
574
+ this.ngControl = ngControl;
575
+ this.onChange = (_) => { };
576
+ this.onTouched = () => { };
577
+ this.stateChanges = new Subject();
578
+ this.focused = false;
579
+ this.errorState = false;
580
+ this.id = `rsl-searchable-dropdown-${SearchableDropdownComponent.nextId++}`;
581
+ // label for the search dropdown
582
+ this.label = '';
583
+ //Fields for sorting the API data
584
+ this.sortFields = '';
585
+ // The value used to populate the control value
586
+ this.valueField = 'id';
587
+ // The minumum char for search
588
+ this.minLengthTerm = 3;
589
+ this.modelSelected = new EventEmitter();
590
+ this._required = false;
591
+ this._disabled = false;
592
+ this.showSerach = true;
593
+ this.isLoading = false;
594
+ this.options = [];
595
+ this.filteredOptions = [];
596
+ /** Subject that emits when the component has been destroyed. */
597
+ this._onDestroy = new Subject();
598
+ this.searchControl = new UntypedFormControl('');
599
+ _focusMonitor.monitor(_elementRef, true).subscribe(origin => {
600
+ if (this.focused && !origin) {
601
+ this.onTouched();
602
+ }
603
+ this.focused = !!origin;
604
+ this.stateChanges.next();
605
+ });
606
+ if (this.ngControl) {
607
+ this.ngControl.valueAccessor = this;
608
+ }
609
+ }
610
+ ngOnInit() {
611
+ if (!this.displayFields)
612
+ this.displayFields = this.searchFields;
613
+ this.loadModel(this.ngControl.value);
614
+ if (this.preloadElementsCount) {
615
+ this.serviceRef.getAll(1, this.preloadElementsCount).subscribe({
616
+ next: (data) => {
617
+ this.showSerach = false;
618
+ this.options = data.getModels();
619
+ this.filteredOptions = this.options;
620
+ }
621
+ });
622
+ }
623
+ this.searchControl.valueChanges
624
+ .pipe(filter((res) => {
625
+ const result = res !== null && res.length >= this.minLengthTerm;
626
+ if (!result) {
627
+ this.options = [];
628
+ this.filteredOptions = [];
629
+ }
630
+ this.showSerach = !result;
631
+ return result;
632
+ }), debounceTime(300), tap(() => {
633
+ this.filteredOptions = [];
634
+ this.isLoading = true;
635
+ }), switchMap((value) => this.serviceRef
636
+ .getAll(1, 10, this.sortFields, `${this.searchFields.replace(',', '|')}@=*${value}`)
637
+ .pipe(finalize(() => {
638
+ this.isLoading = false;
639
+ }))), takeUntil(this._onDestroy))
640
+ .subscribe((options) => {
641
+ this.filteredOptions = options.getModels();
642
+ });
643
+ }
644
+ onSelected($event) {
645
+ const value = $event.option.value;
646
+ this.searchControl.setValue(value);
647
+ this.modelSelected.emit(value);
648
+ if (this.valueField in value) {
649
+ this.setControlValue(value[this.valueField]);
650
+ }
651
+ }
652
+ setControlValue(value) {
653
+ this.value = value;
654
+ this.ngControl.control.setValue(value);
655
+ }
656
+ displayWith(value) {
657
+ return this.getConcatedFields(value);
658
+ }
659
+ clearSelection() {
660
+ this.modelSelected.emit(null);
661
+ this.setControlValue(null);
662
+ this.searchControl.setValue(null);
663
+ this.filteredOptions = this.options;
664
+ }
665
+ getConcatedFields(option) {
666
+ if (!option)
667
+ return null;
668
+ const filtersArr = this.displayFields.split(',');
669
+ return filtersArr.reduce((acc, cv) => {
670
+ return acc.concat(option[cv] + ' ');
671
+ }, '');
672
+ }
673
+ ngOnDestroy() {
674
+ this.searchControl = null;
675
+ this.stateChanges.complete();
676
+ this._focusMonitor.stopMonitoring(this._elementRef);
677
+ this._onDestroy.next();
678
+ this._onDestroy.complete();
679
+ }
680
+ getSearchText() {
681
+ return `Enter ${this.minLengthTerm} characters to start search`;
682
+ }
683
+ writeValue(model) {
684
+ console.log(model);
685
+ this.value = model;
686
+ }
687
+ registerOnChange(fn) {
688
+ this.onChange = fn;
689
+ }
690
+ registerOnTouched(fn) {
691
+ this.onTouched = fn;
692
+ }
693
+ setDisabledState(isDisabled) {
694
+ this.disabled = isDisabled;
695
+ }
696
+ loadModel(id) {
697
+ //Load the model from API to display the value
698
+ let needLoad = false;
699
+ if (id) {
700
+ if (!this.searchControl.value)
701
+ needLoad = true;
702
+ else {
703
+ if (this.searchControl.value[this.valueField] !== id) {
704
+ needLoad = true;
705
+ }
706
+ }
707
+ }
708
+ if (needLoad) {
709
+ this.serviceRef.get(id).subscribe({
710
+ next: (model) => {
711
+ this.options.push(model);
712
+ this.filteredOptions = this.options;
713
+ this.searchControl.setValue(model);
714
+ }
715
+ });
716
+ }
717
+ }
718
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SearchableDropdownComponent, deps: [{ token: i1$2.FocusMonitor }, { token: i0.ElementRef }, { token: i2$1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
719
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: SearchableDropdownComponent, isStandalone: true, selector: "rsl-searchable-dropdown", inputs: { label: "label", fControlName: "fControlName", serviceRef: "serviceRef", searchFields: "searchFields", displayFields: "displayFields", sortFields: "sortFields", valueField: "valueField", minLengthTerm: "minLengthTerm", preloadElementsCount: "preloadElementsCount", required: "required", disabled: "disabled", value: "value" }, outputs: { modelSelected: "modelSelected" }, host: { properties: { "class.example-floating": "shouldLabelFloat", "id": "id", "attr.aria-describedby": "describedBy" } }, ngImport: i0, template: "<div class=\"form-group\">\r\n <label>{{label | translate}}</label>\r\n <mat-form-field appearance=\"outline\" fxFlex>\r\n <input matInput [matAutocomplete]=\"auto\" [formControl]=\"searchControl\">\r\n <button *ngIf=\"searchControl.value\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clearSelection()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"onSelected($event)\"\r\n [displayWith]=\"displayWith.bind(this)\">\r\n <mat-option *ngIf=\"isLoading\">Loading...</mat-option>\r\n <mat-option *ngIf=\"!isLoading && filteredOptions.length == 0 && !showSerach\" disabled>Not found</mat-option>\r\n <mat-option *ngIf=\"showSerach\" disabled>{{getSearchText()}}</mat-option>\r\n <ng-container *ngIf=\"!isLoading && filteredOptions.length > 0\">\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n <span><b>{{getConcatedFields(option)}}</b></span>\r\n </mat-option>\r\n </ng-container>\r\n\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n</div>", dependencies: [{ kind: "ngmodule", type: RSLMaterialModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple", "hideSingleSelectionIndicator"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i6$1.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
720
+ }
721
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SearchableDropdownComponent, decorators: [{
722
+ type: Component,
723
+ args: [{ standalone: true, selector: 'rsl-searchable-dropdown', host: {
724
+ '[class.example-floating]': 'shouldLabelFloat',
725
+ '[id]': 'id',
726
+ '[attr.aria-describedby]': 'describedBy',
727
+ }, imports: [RSLMaterialModule], template: "<div class=\"form-group\">\r\n <label>{{label | translate}}</label>\r\n <mat-form-field appearance=\"outline\" fxFlex>\r\n <input matInput [matAutocomplete]=\"auto\" [formControl]=\"searchControl\">\r\n <button *ngIf=\"searchControl.value\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clearSelection()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"onSelected($event)\"\r\n [displayWith]=\"displayWith.bind(this)\">\r\n <mat-option *ngIf=\"isLoading\">Loading...</mat-option>\r\n <mat-option *ngIf=\"!isLoading && filteredOptions.length == 0 && !showSerach\" disabled>Not found</mat-option>\r\n <mat-option *ngIf=\"showSerach\" disabled>{{getSearchText()}}</mat-option>\r\n <ng-container *ngIf=\"!isLoading && filteredOptions.length > 0\">\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n <span><b>{{getConcatedFields(option)}}</b></span>\r\n </mat-option>\r\n </ng-container>\r\n\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n</div>" }]
728
+ }], ctorParameters: function () { return [{ type: i1$2.FocusMonitor }, { type: i0.ElementRef }, { type: i2$1.NgControl, decorators: [{
729
+ type: Optional
730
+ }, {
731
+ type: Self
732
+ }] }]; }, propDecorators: { label: [{
733
+ type: Input
734
+ }], fControlName: [{
735
+ type: Input
736
+ }], serviceRef: [{
737
+ type: Input
738
+ }], searchFields: [{
739
+ type: Input
740
+ }], displayFields: [{
741
+ type: Input
742
+ }], sortFields: [{
743
+ type: Input
744
+ }], valueField: [{
745
+ type: Input
746
+ }], minLengthTerm: [{
747
+ type: Input
748
+ }], preloadElementsCount: [{
749
+ type: Input
750
+ }], modelSelected: [{
751
+ type: Output
752
+ }], required: [{
753
+ type: Input
754
+ }], disabled: [{
755
+ type: Input
756
+ }], value: [{
757
+ type: Input
758
+ }] } });
759
+
760
+ function GridLayout(translateKey, width, grow = 0, shrink = 0, subProperty, formating = GridLayoutFormat.none, format = '', order = 0, textAlign = CellTextAlign.left) {
761
+ return (target, propertyName) => {
762
+ const annotations = Reflect.getMetadata('GridLayout', target) || [];
763
+ let propName = propertyName;
764
+ if (subProperty) {
765
+ propName = propertyName.toString() + '.' + subProperty;
766
+ }
767
+ annotations.push({
768
+ propertyName: propName,
769
+ translateKey,
770
+ width,
771
+ grow,
772
+ shrink,
773
+ formating,
774
+ format,
775
+ order,
776
+ textAlign
777
+ });
778
+ Reflect.defineMetadata('GridLayout', annotations, target);
779
+ };
780
+ }
781
+
782
+ class GridLayoutModel {
783
+ constructor(propertyName, translateKey = null, width = null, grow = 0, shrink = 0, formating = GridLayoutFormat.none, format = '', order = 0, textAlign = CellTextAlign.left) {
784
+ this.formating = GridLayoutFormat.none;
785
+ this.order = 0;
786
+ this.textAlign = CellTextAlign.left;
787
+ this.propertyName = propertyName;
788
+ this.translateKey = translateKey;
789
+ this.width = width;
790
+ this.grow = grow;
791
+ this.shrink = shrink;
792
+ this.formating = formating;
793
+ this.format = format;
794
+ this.order = order;
795
+ this.textAlign = textAlign;
796
+ }
797
+ }
798
+
799
+ class MaterialBaseModel extends BaseModel {
800
+ getGridLayout() {
801
+ const result = Array();
802
+ const gridLayout = Reflect.getMetadata('GridLayout', this);
803
+ if (gridLayout) {
804
+ for (const layout of gridLayout) {
805
+ const data = new GridLayoutModel(layout.propertyName, layout.translateKey, layout.width, layout.shrink, layout.grow, layout.formating, layout.format, layout.order, layout.textAlign);
806
+ result.push(data);
807
+ }
808
+ }
809
+ return result.sort(function (a, b) { return a.order - b.order; });
810
+ //result;
811
+ }
812
+ }
813
+
814
+ /*
815
+ * Public API Surface of core
816
+ */
817
+
818
+ /**
819
+ * Generated bundle index. Do not edit.
820
+ */
821
+
822
+ export { GenericTableComponent, GridLayout, GridLayoutModel, GridLayoutService, MaterialBaseModel, RSLMaterialModule, SearchableDropdownComponent };
823
+ //# sourceMappingURL=rosoftlab-material.mjs.map