@esfaenza/es-table 13.3.3 → 13.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/esm2020/lib/components/es-table/es_table.component.loc.mjs +7 -4
  2. package/esm2020/lib/components/es-table/es_table.component.mjs +542 -116
  3. package/esm2020/lib/components/es-table-template/es_table_template.component.mjs +21 -0
  4. package/esm2020/lib/components/es-td/es_td.component.mjs +23 -55
  5. package/esm2020/lib/components/es-th/es_th.component.mjs +5 -5
  6. package/esm2020/lib/components/pager/table_pager.component.loc.mjs +3 -3
  7. package/esm2020/lib/components/pager/table_pager.component.mjs +5 -5
  8. package/esm2020/lib/components/pipes/est-format.pipe.mjs +44 -0
  9. package/esm2020/lib/components/pipes/est-lookup.pipe.mjs +19 -0
  10. package/esm2020/lib/components/pipes/est-renderer.pipe.mjs +36 -0
  11. package/esm2020/lib/components/pipes/est-routerlink.pipe.mjs +41 -0
  12. package/esm2020/lib/components/pipes/est_editor.pipe.mjs +36 -0
  13. package/esm2020/lib/core/CopyPasteDetector.mjs +28 -0
  14. package/esm2020/lib/core/Logger.mjs +26 -0
  15. package/esm2020/lib/core/handlers/ColumnMetadataHandler.mjs +75 -35
  16. package/esm2020/lib/core/handlers/DynamicModeHandler.mjs +80 -37
  17. package/esm2020/lib/core/handlers/ExportHandler.mjs +53 -14
  18. package/esm2020/lib/core/handlers/ItemsHandler.mjs +13 -5
  19. package/esm2020/lib/core/handlers/ReportModeHandler.mjs +15 -2
  20. package/esm2020/lib/core/handlers/SelectionHandler.mjs +267 -1
  21. package/esm2020/lib/core/handlers/UtilitiesHandler.mjs +7 -8
  22. package/esm2020/lib/directives/es_td.directive.mjs +24 -6
  23. package/esm2020/lib/directives/es_td_editor.directive.mjs +24 -0
  24. package/esm2020/lib/directives/es_th.directive.mjs +39 -9
  25. package/esm2020/lib/domain/configuration/EsTableDefaultable.mjs +1 -1
  26. package/esm2020/lib/domain/externals/EsTableColumnsDefinition.mjs +39 -22
  27. package/esm2020/lib/domain/externals/EsTableModelChange.mjs +19 -0
  28. package/esm2020/lib/domain/externals/ItemPropEditableReference.mjs +4 -0
  29. package/esm2020/lib/domain/externals/appsearch/AppSearch.mjs +33 -14
  30. package/esm2020/lib/domain/externals/report/ReportColumn.mjs +1 -1
  31. package/esm2020/lib/domain/externals/report/ReportRow.mjs +1 -1
  32. package/esm2020/lib/domain/internals/EsTableColumn.mjs +3 -2
  33. package/esm2020/lib/domain/internals/GroupPager.mjs +4 -3
  34. package/esm2020/lib/domain/internals/PagerInfos.mjs +15 -0
  35. package/esm2020/lib/domain/internals/TdElement.mjs +1 -1
  36. package/esm2020/lib/domain/internals/ThElement.mjs +1 -1
  37. package/esm2020/lib/domain/internals/ThGroup.mjs +2 -0
  38. package/esm2020/lib/domain/types.mjs +2 -0
  39. package/esm2020/lib/es-table.module.mjs +78 -37
  40. package/esm2020/public-api.mjs +6 -1
  41. package/fesm2015/esfaenza-es-table.mjs +1576 -359
  42. package/fesm2015/esfaenza-es-table.mjs.map +1 -1
  43. package/fesm2020/esfaenza-es-table.mjs +1555 -356
  44. package/fesm2020/esfaenza-es-table.mjs.map +1 -1
  45. package/lib/components/es-table/es_table.component.d.ts +172 -79
  46. package/lib/components/es-table-template/es_table_template.component.d.ts +18 -0
  47. package/lib/components/es-td/es_td.component.d.ts +14 -34
  48. package/lib/components/pipes/est-format.pipe.d.ts +10 -0
  49. package/lib/components/pipes/est-lookup.pipe.d.ts +13 -0
  50. package/lib/components/pipes/est-renderer.pipe.d.ts +15 -0
  51. package/lib/components/pipes/est-routerlink.pipe.d.ts +20 -0
  52. package/lib/components/pipes/est_editor.pipe.d.ts +15 -0
  53. package/lib/core/CopyPasteDetector.d.ts +15 -0
  54. package/lib/core/Logger.d.ts +10 -0
  55. package/lib/core/handlers/ColumnMetadataHandler.d.ts +8 -0
  56. package/lib/core/handlers/DynamicModeHandler.d.ts +13 -23
  57. package/lib/core/handlers/ExportHandler.d.ts +4 -0
  58. package/lib/core/handlers/ItemsHandler.d.ts +1 -1
  59. package/lib/core/handlers/ReportModeHandler.d.ts +9 -0
  60. package/lib/core/handlers/SelectionHandler.d.ts +90 -0
  61. package/lib/core/handlers/UtilitiesHandler.d.ts +4 -1
  62. package/lib/directives/es_td.directive.d.ts +18 -2
  63. package/lib/directives/es_td_editor.directive.d.ts +14 -0
  64. package/lib/directives/es_th.directive.d.ts +43 -11
  65. package/lib/domain/configuration/EsTableDefaultable.d.ts +1 -0
  66. package/lib/domain/externals/EsTableColumnsDefinition.d.ts +48 -23
  67. package/lib/domain/externals/EsTableModelChange.d.ts +17 -0
  68. package/lib/domain/externals/ItemPropEditableReference.d.ts +34 -0
  69. package/lib/domain/externals/appsearch/AppSearch.d.ts +15 -2
  70. package/lib/domain/externals/report/ReportColumn.d.ts +4 -0
  71. package/lib/domain/externals/report/ReportRow.d.ts +4 -0
  72. package/lib/domain/internals/EsTableColumn.d.ts +4 -1
  73. package/lib/domain/internals/GroupPager.d.ts +3 -2
  74. package/lib/domain/internals/PagerInfos.d.ts +13 -0
  75. package/lib/domain/internals/TdElement.d.ts +18 -5
  76. package/lib/domain/internals/ThElement.d.ts +6 -0
  77. package/lib/domain/internals/ThGroup.d.ts +10 -0
  78. package/lib/domain/types.d.ts +2 -0
  79. package/lib/es-table.module.d.ts +26 -19
  80. package/package.json +9 -10
  81. package/public-api.d.ts +5 -0
@@ -1,32 +1,31 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, Directive, ViewChild, HostListener, Self, ContentChildren, ContentChild, NgModule } from '@angular/core';
2
+ import { InjectionToken, Injectable, Optional, Inject, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, Directive, Self, ViewChild, HostListener, Pipe, ContentChildren, ContentChild, NgModule } from '@angular/core';
3
3
  import * as i2 from '@esfaenza/localizations';
4
4
  import { LocalizationService, LocalizationModule } from '@esfaenza/localizations';
5
5
  import * as i5 from '@esfaenza/extensions';
6
6
  import { UtilityService, ExportService, HashingService, MessageService } from '@esfaenza/extensions';
7
7
  import * as i3 from '@angular/material/form-field';
8
- import * as i11 from '@angular/common';
8
+ import * as i13 from '@angular/common';
9
9
  import { CommonModule } from '@angular/common';
10
10
  import * as i5$1 from '@angular/material/input';
11
11
  import { MatInputModule } from '@angular/material/input';
12
12
  import * as i1 from '@angular/forms';
13
13
  import { FormsModule } from '@angular/forms';
14
- import * as i16 from '@angular/cdk/drag-drop';
14
+ import * as i17 from '@angular/cdk/drag-drop';
15
15
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
16
16
  import { Subject } from 'rxjs';
17
17
  import * as i2$1 from '@esfaenza/preferences';
18
- import * as i1$1 from '@angular/platform-browser';
19
- import * as i9 from '@esfaenza/forms-and-validations';
18
+ import * as i10 from '@esfaenza/forms-and-validations';
20
19
  import { FormsAndValidationsModule } from '@esfaenza/forms-and-validations';
21
- import * as i10 from '@esfaenza/ngx-contextmenu';
20
+ import * as i1$1 from '@angular/material/tooltip';
21
+ import { MatTooltipModule } from '@angular/material/tooltip';
22
+ import * as i12 from '@esfaenza/ngx-contextmenu';
22
23
  import { ContextMenuModule } from '@esfaenza/ngx-contextmenu';
23
- import * as i12 from '@ctrl/ngx-csv';
24
- import { CsvModule } from '@ctrl/ngx-csv';
25
- import * as i13 from 'ngx-bootstrap/dropdown';
24
+ import * as i14 from 'ngx-bootstrap/dropdown';
26
25
  import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
27
- import * as i14 from '@angular/router';
26
+ import * as i15 from '@angular/router';
28
27
  import { RouterModule } from '@angular/router';
29
- import * as i15 from 'ngx-bootstrap/modal';
28
+ import * as i16 from 'ngx-bootstrap/modal';
30
29
  import { ModalModule } from 'ngx-bootstrap/modal';
31
30
  import { MatSelectModule } from '@angular/material/select';
32
31
 
@@ -49,9 +48,9 @@ class TablePagerLoc extends LocalizationService {
49
48
  super.set("en->it", "This might slow down the page and possibly crash the entire application", ["L'operazione potrebbe rallentare la pagina fino al crash dell'applicazione"]);
50
49
  }
51
50
  }
52
- TablePagerLoc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerLoc, deps: [{ token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
53
- TablePagerLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerLoc });
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerLoc, decorators: [{
51
+ TablePagerLoc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerLoc, deps: [{ token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
52
+ TablePagerLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerLoc });
53
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerLoc, decorators: [{
55
54
  type: Injectable
56
55
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
57
56
  type: Optional
@@ -127,11 +126,11 @@ class TablePagerComponent {
127
126
  }
128
127
  }
129
128
  }
130
- TablePagerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerComponent, deps: [{ token: i5.MessageService }, { token: i2.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
131
- TablePagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: TablePagerComponent, selector: "app-paging", inputs: { CurrentPageSize: "CurrentPageSize", View: "View", WarnOnAll: "WarnOnAll", AllSearch: "AllSearch", DefaultAll: "DefaultAll", GroupMode: "GroupMode", GroupCount: "GroupCount", CountLabel: "CountLabel", ShowCount: "ShowCount", ShowPaging: "ShowPaging", PagerCount: "PagerCount", Hidden: "Hidden" }, outputs: { pagingSelected: "pagingSelected" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && (Model == DefaultAll || PagerCount >= Model || PagerCount == -1)\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"], components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5$1.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"] }, { type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], pipes: { "localize": i2.LocalizePipe, "number": i11.DecimalPipe }, viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
132
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerComponent, decorators: [{
129
+ TablePagerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerComponent, deps: [{ token: i5.MessageService }, { token: i2.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
130
+ TablePagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TablePagerComponent, selector: "app-paging", inputs: { CurrentPageSize: "CurrentPageSize", View: "View", WarnOnAll: "WarnOnAll", AllSearch: "AllSearch", DefaultAll: "DefaultAll", GroupMode: "GroupMode", GroupCount: "GroupCount", CountLabel: "CountLabel", ShowCount: "ShowCount", ShowPaging: "ShowPaging", PagerCount: "PagerCount", Hidden: "Hidden" }, outputs: { pagingSelected: "pagingSelected" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && PagerCount > 10\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"], components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i13.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5$1.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"] }, { type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i13.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], pipes: { "localize": i2.LocalizePipe, "number": i13.DecimalPipe }, viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerComponent, decorators: [{
133
132
  type: Component,
134
- args: [{ selector: "app-paging", viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && (Model == DefaultAll || PagerCount >= Model || PagerCount == -1)\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"] }]
133
+ args: [{ selector: "app-paging", viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && PagerCount > 10\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"] }]
135
134
  }], ctorParameters: function () { return [{ type: i5.MessageService }, { type: i2.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
136
135
  type: Optional
137
136
  }, {
@@ -183,20 +182,54 @@ class AppSearch {
183
182
  this.firstsearch = true;
184
183
  }
185
184
  /**
186
- * Permette di resettare questo oggetto ai valori di default
185
+ * Permette di resettare un AppSearch ai valori di default.
186
+ * Reso statico perché fra una deserializzazione e l'altra si potrebbe perdere il prototype del costruttore
187
+ *
188
+ * @param {AppSearch<any>} aps AppSearch da resettare
187
189
  */
188
- reset() {
189
- this.pages = 1;
190
- this.objectcount = 0;
191
- this.searchinprogress = false;
192
- this.firstsearch = false;
193
- this.page = 1;
194
- this.itemsperpageoverride = 15;
195
- this.items = [];
196
- this.orders = [];
197
- this.columns = [];
198
- this.column_ordering = [];
199
- this.savedstate = false;
190
+ static reset(aps) {
191
+ aps.pages = 1;
192
+ aps.objectcount = 0;
193
+ aps.searchinprogress = false;
194
+ aps.firstsearch = false;
195
+ aps.page = 1;
196
+ aps.itemsperpageoverride = 15;
197
+ aps.items = [];
198
+ aps.orders = [];
199
+ aps.columns = [];
200
+ aps.column_ordering = [];
201
+ aps.savedstate = false;
202
+ aps.selfsearch = false;
203
+ }
204
+ /**
205
+ * Permette di ottenere un nuovo riferimento all'AppSearch passata come parametro.
206
+ * Internamente utilizza il JSON.parse(JSON.stringify(X)) con la differenza che prima stacca il riferimento agli items per evitare di
207
+ * reserializzare potenzialmente centinaia di elementi. Il riferimento viene poi ricollegato alla nuova appsearch generata
208
+ *
209
+ * @param {AppSearch<any>} aps AppSearch di cui estrarre un nuovo riferimento equivalente
210
+ */
211
+ static newref(aps) {
212
+ var items = aps.items;
213
+ aps.items = [];
214
+ var newref = JSON.parse(JSON.stringify(aps));
215
+ newref.items = items;
216
+ newref.page = 1;
217
+ return newref;
218
+ }
219
+ }
220
+
221
+ /** Classe che rappresenta le informazioni di paginazione della tabella attuale */
222
+ class PagerInfos {
223
+ constructor() {
224
+ this.PagerCount = null;
225
+ this.ShowCount = true;
226
+ this.ShowPaging = true;
227
+ this.ShowButtons = true;
228
+ this.ShowPagingOptions = true;
229
+ this.UsesView = true;
230
+ this.View = null;
231
+ this.Ready = false;
232
+ this.Searches = 'items';
200
233
  }
201
234
  }
202
235
 
@@ -237,6 +270,25 @@ class GroupFilter {
237
270
  }
238
271
  }
239
272
 
273
+ /** Classe che rappresenta la modifica ad un singolo oggetto in una singola proprietà */
274
+ class EsTableModelChange {
275
+ /**
276
+ * Costruttore
277
+ * @param {any} item Oggetto modificato
278
+ * @param {string} header Nome dell'Header che è stato modificato
279
+ * @param {string} property Nome della proprietà modificata
280
+ * @param {string} old_value Vecchio valore della proprietà **property** dell'oggetto **item**
281
+ * @param {string} new_value Nuovo valore della proprietà **property** dell'oggetto **item**
282
+ */
283
+ constructor(item, header, property, old_value, new_value) {
284
+ this.item = item;
285
+ this.header = header;
286
+ this.property = property;
287
+ this.old_value = old_value;
288
+ this.new_value = new_value;
289
+ }
290
+ }
291
+
240
292
  /** Direttiva per la dichiarazione snella di un EsTd da emettere per ogni elemento, data una colonna */
241
293
  class EsTdDirective {
242
294
  /**
@@ -254,21 +306,39 @@ class EsTdDirective {
254
306
  this.tdIf = true;
255
307
  }
256
308
  }
257
- EsTdDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTdDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
258
- EsTdDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.9", type: EsTdDirective, selector: "[td]", inputs: { tdVisible: "tdVisible", td: "td", tdIf: "tdIf", tdClass: "tdClass", tdPropertyAccessor: "tdPropertyAccessor" }, ngImport: i0 });
259
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTdDirective, decorators: [{
309
+ EsTdDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdDirective, deps: [{ token: i0.TemplateRef, self: true }], target: i0.ɵɵFactoryTarget.Directive });
310
+ EsTdDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: EsTdDirective, selector: "[td]", inputs: { tdVisible: "tdVisible", td: "td", tdForProperty: "tdForProperty", tdIf: "tdIf", tdClass: "tdClass", tdPropertyAccessor: "tdPropertyAccessor", tdAlignment: "tdAlignment", tdFormat: "tdFormat", tdIconClass: "tdIconClass", tdConditionField: "tdConditionField", tdConditionValue: "tdConditionValue", tdTitle: "tdTitle", tdContent: "tdContent" }, ngImport: i0 });
311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdDirective, decorators: [{
260
312
  type: Directive,
261
313
  args: [{ selector: '[td]' }]
262
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { tdVisible: [{
314
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
315
+ type: Self
316
+ }] }]; }, propDecorators: { tdVisible: [{
263
317
  type: Input
264
318
  }], td: [{
265
319
  type: Input
320
+ }], tdForProperty: [{
321
+ type: Input
266
322
  }], tdIf: [{
267
323
  type: Input
268
324
  }], tdClass: [{
269
325
  type: Input
270
326
  }], tdPropertyAccessor: [{
271
327
  type: Input
328
+ }], tdAlignment: [{
329
+ type: Input
330
+ }], tdFormat: [{
331
+ type: Input
332
+ }], tdIconClass: [{
333
+ type: Input
334
+ }], tdConditionField: [{
335
+ type: Input
336
+ }], tdConditionValue: [{
337
+ type: Input
338
+ }], tdTitle: [{
339
+ type: Input
340
+ }], tdContent: [{
341
+ type: Input
272
342
  }] } });
273
343
 
274
344
  /** Direttiva per la dichiarazione snella di un EsTh da emettere come header */
@@ -316,16 +386,26 @@ class EsThDirective {
316
386
  this.thGroup = false;
317
387
  /** Indica che bisogna fare una aggregazione su questa colonna, a fronte di almeno un altra con un raggruppamento */
318
388
  this.thAggregation = null;
319
- /** Impostazioni per la modifica inline di questo campo: la **Property** di riferimento e il **Type** (a scelta fra quelli supportati dal form-adaptive) */
320
- this.thUserEdits = null;
389
+ /** Proprietà JS a cui si riferisce questa cella */
390
+ this.thProperty = null;
391
+ /** Tipo della proprietà JS a cui si riferisce questa cella. Se valorizzato l'utente la potrà modificare facendo doppio click */
392
+ this.thType = null;
393
+ /** Sorgente dei valori disponibili per questa cella se il **Type** è di tipo 'enum' */
394
+ this.thSource = null;
395
+ /** Indica un contenuto statico da mostrare piuttosto che utilizzare il **Template**. Serve in caso questo oggetto venga generato programmaticamente */
396
+ this.thStaticContent = null;
397
+ /** Opzioni da applicare all'editor di questa colonna */
398
+ this.thEditorOptions = {};
321
399
  }
322
400
  }
323
- EsThDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsThDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
324
- EsThDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.9", type: EsThDirective, selector: "[th]", inputs: { th: "th", thPinned: "thPinned", thPinnable: "thPinnable", thPinnedWidth: "thPinnedWidth", thVisible: "thVisible", thFixed: "thFixed", thParent: "thParent", thOrder: "thOrder", thOrderable: "thOrderable", thWrap: "thWrap", thResizable: "thResizable", thClass: "thClass", thGroupClass: "thGroupClass", thIf: "thIf", thEmpty: "thEmpty", thGroup: "thGroup", thAggregation: "thAggregation", thUserEdits: "thUserEdits", thMulti: "thMulti", thStaticContent: "thStaticContent", thBackgroundColor: "thBackgroundColor" }, ngImport: i0 });
325
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsThDirective, decorators: [{
401
+ EsThDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsThDirective, deps: [{ token: i0.TemplateRef, self: true }], target: i0.ɵɵFactoryTarget.Directive });
402
+ EsThDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: EsThDirective, selector: "[th]", inputs: { th: "th", thPinned: "thPinned", thPinnable: "thPinnable", thPinnedWidth: "thPinnedWidth", thVisible: "thVisible", thFixed: "thFixed", thParent: "thParent", thOrder: "thOrder", thOrderable: "thOrderable", thWrap: "thWrap", thResizable: "thResizable", thClass: "thClass", thShrink: "thShrink", thGroupClass: "thGroupClass", thIf: "thIf", thEmpty: "thEmpty", thGroup: "thGroup", thAggregation: "thAggregation", thProperty: "thProperty", thType: "thType", thSource: "thSource", thMulti: "thMulti", thStaticContent: "thStaticContent", thBackgroundColor: "thBackgroundColor", thAlignment: "thAlignment", thFormat: "thFormat", thEditorName: "thEditorName", thEditorOptions: "thEditorOptions", thRendererName: "thRendererName", thRoutePath: "thRoutePath", thRouteParameterProperties: "thRouteParameterProperties" }, ngImport: i0 });
403
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsThDirective, decorators: [{
326
404
  type: Directive,
327
405
  args: [{ selector: '[th]' }]
328
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { th: [{
406
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
407
+ type: Self
408
+ }] }]; }, propDecorators: { th: [{
329
409
  type: Input
330
410
  }], thPinned: [{
331
411
  type: Input
@@ -349,6 +429,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
349
429
  type: Input
350
430
  }], thClass: [{
351
431
  type: Input
432
+ }], thShrink: [{
433
+ type: Input
352
434
  }], thGroupClass: [{
353
435
  type: Input
354
436
  }], thIf: [{
@@ -359,7 +441,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
359
441
  type: Input
360
442
  }], thAggregation: [{
361
443
  type: Input
362
- }], thUserEdits: [{
444
+ }], thProperty: [{
445
+ type: Input
446
+ }], thType: [{
447
+ type: Input
448
+ }], thSource: [{
363
449
  type: Input
364
450
  }], thMulti: [{
365
451
  type: Input
@@ -367,6 +453,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
367
453
  type: Input
368
454
  }], thBackgroundColor: [{
369
455
  type: Input
456
+ }], thAlignment: [{
457
+ type: Input
458
+ }], thFormat: [{
459
+ type: Input
460
+ }], thEditorName: [{
461
+ type: Input
462
+ }], thEditorOptions: [{
463
+ type: Input
464
+ }], thRendererName: [{
465
+ type: Input
466
+ }], thRoutePath: [{
467
+ type: Input
468
+ }], thRouteParameterProperties: [{
469
+ type: Input
470
+ }] } });
471
+
472
+ /** Direttiva che rappresenta il template dell'editor di una cella all'interno della tabella */
473
+ class EsTdEditorDirective {
474
+ /** @ignore */
475
+ constructor(Template) {
476
+ this.Template = Template;
477
+ }
478
+ }
479
+ EsTdEditorDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdEditorDirective, deps: [{ token: i0.TemplateRef, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
480
+ EsTdEditorDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: EsTdEditorDirective, selector: "[editor]", inputs: { editor: "editor", editorForProperty: "editorForProperty" }, ngImport: i0 });
481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdEditorDirective, decorators: [{
482
+ type: Directive,
483
+ args: [{ selector: '[editor]' }]
484
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
485
+ type: Self
486
+ }, {
487
+ type: Optional
488
+ }] }]; }, propDecorators: { editor: [{
489
+ type: Input
490
+ }], editorForProperty: [{
491
+ type: Input
370
492
  }] } });
371
493
 
372
494
  /** Classe di localizzazione per il componente **EsTableComponent** */
@@ -392,11 +514,14 @@ class EsTableLoc extends LocalizationService {
392
514
  super.set("en->it", "Select Everything", ["Seleziona Tutto"]);
393
515
  super.set("en->it", "Reset Selection", ["Resetta Selezione"]);
394
516
  super.set("en->it", "No operations available", ["Nessuna operazione disponibile"]);
517
+ super.set("en->it", "Values copied in the clipboard", ["Valori copiati nella clipboard"]);
518
+ super.set("en->it", "Size of copied data is different from the size of the selection", ["La dimensione dei dati copiati differisce dalla dimensione della selezione"]);
519
+ super.set("en->it", "Data for this table cannot be edited", ["I dati di questa tabella non possono essere modificati"]);
395
520
  }
396
521
  }
397
- EsTableLoc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc, deps: [{ token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
398
- EsTableLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc });
399
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc, decorators: [{
522
+ EsTableLoc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableLoc, deps: [{ token: EST_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
523
+ EsTableLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableLoc });
524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableLoc, decorators: [{
400
525
  type: Injectable
401
526
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
402
527
  type: Optional
@@ -433,8 +558,7 @@ class ExportHandler {
433
558
  }
434
559
  this.setupExport(data);
435
560
  if (format == "CSV") {
436
- this.est.cdr.detectChanges();
437
- setTimeout(() => { this.est.exportDownloader.nativeElement.click(); });
561
+ this.exportCSV();
438
562
  }
439
563
  else if (format == "XLSX") {
440
564
  if (this.ExcelJS != null) {
@@ -453,6 +577,33 @@ class ExportHandler {
453
577
  throw "Formato di esportazione non riconosciuto";
454
578
  }, format);
455
579
  }
580
+ /** Effettua l'esportazione in file CSV, va a sostituire quel coso inutile di @ctrl/ngx-csv */
581
+ exportCSV() {
582
+ var csvData = this.convertToCSV();
583
+ var blob = new Blob([csvData], { type: 'text/csv' });
584
+ var objectUrl = window.URL.createObjectURL(blob);
585
+ let fn = this.est.ExportFileName;
586
+ this.utiExts.fileDownload(objectUrl, fn.endsWith('.xlsx') ? fn.replace('.xlsx', '.csv') : fn.endsWith('.csv') ? fn : fn + ".csv");
587
+ }
588
+ /** Generazione specifica del CSV */
589
+ convertToCSV() {
590
+ let csv = '', row = '', sep = ';';
591
+ for (let i = 0; i < this.est.headers.length; i++) {
592
+ let h = this.est.headers[i];
593
+ row += `${row != '' ? sep : ''}"${h.label}"`;
594
+ }
595
+ csv += row + '\r\n';
596
+ for (let i = 0; i < this.est.data.length; i++) {
597
+ row = '';
598
+ let item = this.est.data[i];
599
+ for (let j = 0; j < this.est.headers.length; j++) {
600
+ let val = item[this.est.headers[j].key];
601
+ row += `${row != '' ? sep : ''}"${val}"`;
602
+ }
603
+ csv += row + '\r\n';
604
+ }
605
+ return csv;
606
+ }
456
607
  /** Effettua l'esportazione del file Excel basandosi sul modulo **ExcelJS**, sugli header **this.est.headers** e sui dati **this.est.data** */
457
608
  async exportExcel() {
458
609
  let iFix = 1;
@@ -474,17 +625,28 @@ class ExportHandler {
474
625
  let h = this.est.headers[i];
475
626
  let cell = row.getCell(i + 1);
476
627
  let val = item[h.key];
477
- if (val == null || val == undefined)
628
+ if (!val) {
478
629
  cell.value = "";
479
- else {
480
- switch (h.type) {
481
- case 'date':
482
- cell.value = this.dateExts.getDateConvertion(val).toDate();
483
- case 'number':
484
- cell.value = parseFloat(val.replace(',', '.'));
485
- default:
486
- cell.value = val;
487
- }
630
+ continue;
631
+ }
632
+ switch (h.type) {
633
+ case 'date':
634
+ // ExcelJS va di default in UTC quindi rischierebbe di tirare giù 2 ore ad ogni esportazione
635
+ // Bisogna aggiungere l'utc offset alla data attuale
636
+ let date = this.dateExts.getDateConvertion(val);
637
+ if (date) {
638
+ let correctedDate = date.add(date.utcOffset(), 'minute');
639
+ cell.value = correctedDate.toDate();
640
+ cell.numFmt = val.length > 10 ? 'dd/mm/yyyy h:m:s' : '';
641
+ }
642
+ break;
643
+ case 'number':
644
+ let converted = parseFloat(val.replace(',', '.'));
645
+ cell.value = isNaN(converted) ? "" : converted;
646
+ break;
647
+ default:
648
+ cell.value = val;
649
+ break;
488
650
  }
489
651
  }
490
652
  }
@@ -501,7 +663,9 @@ class ExportHandler {
501
663
  */
502
664
  setupExport(items) {
503
665
  let drcd = this.est.DynamicRowColumnsDefinition;
504
- this.est.headers = drcd && drcd.length > 0 ? this.expExts.setupForGenericExport(items, drcd.map(t => { return { label: t.description, key: t.propertyName, order: t.columnOrder, type: 'string' }; })) : this.expExts.setupForExport(items);
666
+ this.est.headers = drcd && drcd.length > 0 ?
667
+ this.expExts.setupForGenericExport(items, drcd.map(t => { return { label: t.Description, key: t.PropertyName, propKey: t.PropertyName, order: t.ColumnOrder, type: 'string' }; })) :
668
+ this.expExts.setupForExport(items, this.est.ExportOnlyVisibleColumns ? this.est.ColumnsList.filter(t => t.visible).map(t => t.id) : null);
505
669
  this.est.data = items;
506
670
  }
507
671
  }
@@ -531,10 +695,11 @@ class EsTableColumn {
531
695
  * @param {string} description Descrizione (Header)
532
696
  * @param {boolean} visible Indica se di default mostrarla o meno
533
697
  * @param {boolean} fixed Indica se è una colonna fixed
698
+ * @param {boolean} pinnable Indica se una colonna può essere pinnata
534
699
  * @param {boolean} pinned Indica se è una colonna pinnata
535
700
  * @param {number} pinnedWidth Indica la dimensione da assegnare a questa colonna quando è pinnata
536
701
  * @param {TemplateRef<any>} template Indica il template da usare per mostrare il testo dell'Header
537
- * @param {{ tmpl: TemplateRef<any>, content: string }[]} parentTemplates Indica la lista di template padri collegata a questo header, rappresentati come Template o come stringa qualora fosse generato automaticamente (caso **Multi**)
702
+ * @param {{ id: string, tmpl: TemplateRef<any>, content: string }[]} parentTemplates Indica la lista di template padri collegata a questo header, rappresentati come Template o come stringa qualora fosse generato automaticamente (caso **Multi**)
538
703
  * @param {boolean} multi Indica che la colonna deriva da una direttiva **Multi**
539
704
  * @param {string} multiContent Indica il contenuto della direttiva **Multi** per questa colonna
540
705
  */
@@ -603,6 +768,12 @@ class ColumnMetadataHandler {
603
768
  this.est.arrayOrders = [new AppOrdering(id, order)];
604
769
  }
605
770
  }
771
+ //Salvo le preferences di questa view
772
+ //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
773
+ if (this.est.SavePreferences) {
774
+ let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
775
+ this.registerViewPreferences(castedView);
776
+ }
606
777
  this.est.onOrderChanged.emit({ id, order });
607
778
  if (this.est.viewMode) {
608
779
  if (this.est.groupSearchRequestsCache.length > 0)
@@ -613,6 +784,30 @@ class ColumnMetadataHandler {
613
784
  else if (this.est.arrayMode)
614
785
  this.est.internalWriteValue();
615
786
  }
787
+ /**
788
+ * Registra le preference relative alla view passata come parametro
789
+ *
790
+ * @param {any} castedView View di cui salvare colonne e ordinamento colonne
791
+ */
792
+ registerViewPreferences(castedView) {
793
+ if (!this.est.ngControl.name) {
794
+ console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
795
+ return false;
796
+ }
797
+ if (!this.prefService) {
798
+ console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
799
+ return false;
800
+ }
801
+ let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
802
+ let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
803
+ let columnOrders = this.est.arrayMode ? [] : castedView.orders;
804
+ var toStore = {
805
+ columns: this.utiExts.deepClone(columns),
806
+ column_ordering: this.utiExts.deepClone(columnsOrderings),
807
+ orders: this.utiExts.deepClone(columnOrders)
808
+ };
809
+ this.prefService.setItem(this.est.ngControl.name, toStore).subscribe();
810
+ }
616
811
  /**
617
812
  * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
618
813
  *
@@ -644,6 +839,7 @@ class ColumnMetadataHandler {
644
839
  this.est.ColumnsList = [];
645
840
  this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
646
841
  }
842
+ /** In caso siano configurati dei th "Multi" (vedere la descrizione del campo **thMulti** di **EsThDirective**) questo metodo li "srotola" in tutti i th/td che devono effettivamente diventare */
647
843
  expandMultiThsAndTds(ths, tds, items) {
648
844
  // Registro le info sui multiprovider
649
845
  let multiDefs = {};
@@ -695,6 +891,7 @@ class ColumnMetadataHandler {
695
891
  newtH._multi_content = headerValue;
696
892
  newtH.th = `${prop}_${ii}`;
697
893
  newtH.thClass = refth.thClass;
894
+ newtH.thShrink = refth.thShrink;
698
895
  newtH.thIf = refth.thIf;
699
896
  newtH.thVisible = refth.thVisible;
700
897
  newtH.thWrap = refth.thWrap;
@@ -752,7 +949,6 @@ class ColumnMetadataHandler {
752
949
  * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
753
950
  */
754
951
  moveFixedColumnsAtTheBeginning(ths, tds) {
755
- let thsCache = {};
756
952
  let fixeds = 0, pinneds = 0;
757
953
  let columnsCache = {};
758
954
  let columnsIndexCache = {};
@@ -777,7 +973,6 @@ class ColumnMetadataHandler {
777
973
  // Sposto tutti gli header fixed o pinned all'inizio
778
974
  for (let i = 0; i < ths.length; i++) {
779
975
  let th = ths[i];
780
- thsCache[th.th] = th;
781
976
  // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
782
977
  th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
783
978
  if (th.thPinned) {
@@ -820,6 +1015,7 @@ class ColumnMetadataHandler {
820
1015
  * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
821
1016
  *
822
1017
  * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
1018
+ * @param {boolean} useLocalVisibility Indica di utilizzare le impostazioni di visibilità locali senza allinearle alla view
823
1019
  */
824
1020
  alignColumnsIfLoadedView(view) {
825
1021
  let emitChanged = this.est.viewMode && view.savedstate;
@@ -837,10 +1033,10 @@ class ColumnMetadataHandler {
837
1033
  if (c.visible && columns.length == 0)
838
1034
  newColset.push(c.id);
839
1035
  // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
840
- else if (exCl.length == 1 && !c.visible)
1036
+ else if (exCl.length == 1 && !c.visible && !this.est.useLocalVisibility)
841
1037
  c.visible = true;
842
1038
  // Allineamento sull'AppSearch per casistiche inverse al di sopra
843
- else if (exCl.length == 0 && c.visible)
1039
+ else if (exCl.length == 0 && c.visible && !this.est.useLocalVisibility)
844
1040
  c.visible = false;
845
1041
  });
846
1042
  // Non ho colonne nella appsearch, vuol dire che sono al primo binding
@@ -869,6 +1065,9 @@ class ColumnMetadataHandler {
869
1065
  // In ogni caso questo non mi serve più, lo resetto **
870
1066
  if (this.est.viewMode)
871
1067
  view.savedstate = false;
1068
+ // Reset di questa variabile usata one-bind
1069
+ if (this.est.useLocalVisibility)
1070
+ this.est.useLocalVisibility = false;
872
1071
  if (emitChanged)
873
1072
  this.est.changed();
874
1073
  }
@@ -972,22 +1171,22 @@ class ColumnMetadataHandler {
972
1171
  evaluateHeaderGroups(infos) {
973
1172
  if (infos.groupingLevel == 0)
974
1173
  return;
975
- // Giro 2.5, creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate
1174
+ /****** STEP 1: Creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate ******/
976
1175
  let expandedGroups = [];
977
- let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
1176
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
978
1177
  for (let l = 0; l < infos.groupingLevel; l++) {
979
1178
  expandedGroups.push([]);
980
1179
  for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
981
1180
  expandedGroups[l].push("");
982
1181
  }
983
- // Ordino le foglie in base agli ordinamenti delle colonne
1182
+ /****** STEP 2: Ordino le foglie in base agli ordinamenti delle colonne ******/
984
1183
  let orderedLeafs = [];
985
1184
  for (let i = 0; i < this.est.OrderDirectives.length; i++) {
986
1185
  let leaf = infos.thsCache[this.est.OrderDirectives[i]];
987
- if (leaf.thVisible && !leaf.thPinned)
1186
+ if (leaf.thVisible && leaf.thIf && !leaf.thPinned)
988
1187
  orderedLeafs.push(leaf);
989
1188
  }
990
- // Terzo giro per creare l'array group con tutti i riferimenti del caso
1189
+ /****** STEP 3: Creo l'array group con tutti i riferimenti del caso ******/
991
1190
  let currentParent = "";
992
1191
  for (let i = 0; i < orderedLeafs.length; i++) {
993
1192
  let refTh = orderedLeafs[i];
@@ -1008,35 +1207,51 @@ class ColumnMetadataHandler {
1008
1207
  }
1009
1208
  }
1010
1209
  }
1011
- // Quarto giro per compattarlo nell'elemento finale su cui bindarmi
1210
+ /****** STEP 4: Compatto nell'elemento finale su cui bindarmi. L'ID assegnato è SOLO per ottimizzare gli ngFor ******/
1012
1211
  currentParent = "";
1013
1212
  let currentSpan = 0;
1014
- this.est.TMPRowThGroups = [];
1213
+ let finalHeaders = [];
1015
1214
  for (let l = 0; l < expandedGroups.length; l++) {
1016
1215
  let levelArray = [];
1017
- this.est.TMPRowThGroups.push(levelArray);
1216
+ finalHeaders.push(levelArray);
1018
1217
  if (this.est.Selection || this.est.HasPinnedColumns)
1019
- levelArray.push({ Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1218
+ levelArray.push({ ID: "_base_sel_pinned", Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1020
1219
  for (let h = 0; h < expandedGroups[l].length; h++) {
1021
1220
  let item = expandedGroups[l][h];
1022
1221
  if (item == currentParent)
1023
1222
  currentSpan++;
1024
1223
  else {
1025
1224
  if (currentSpan > 0)
1026
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1225
+ levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1027
1226
  currentSpan = 1;
1028
1227
  currentParent = item;
1029
1228
  }
1030
1229
  }
1031
1230
  // Ultima aggiunta che altrimenti mi rimarrebbe in cache
1032
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1231
+ levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1232
+ // Aggiungo i pezzettini per la rimozione e gli export, se presenti
1033
1233
  if (this.est.Removal)
1034
- levelArray.push({ Span: 1, Template: null });
1234
+ levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
1035
1235
  if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
1036
- levelArray.push({ Span: 1, Template: null });
1236
+ levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
1037
1237
  currentSpan = 0;
1038
1238
  currentParent = "";
1039
1239
  }
1240
+ /****** STEP 5: Secco le righe in cui non c'è nulla ******/
1241
+ this.est.TMPRowThGroups = [];
1242
+ for (let i = 0; i < finalHeaders.length; i++) {
1243
+ let level = finalHeaders[i];
1244
+ let empty = true;
1245
+ for (let j = 0; j < level.length; j++) {
1246
+ let item = level[j];
1247
+ if (item.Template || item.Content) {
1248
+ empty = false;
1249
+ break;
1250
+ }
1251
+ }
1252
+ if (!empty)
1253
+ this.est.TMPRowThGroups.push(level);
1254
+ }
1040
1255
  }
1041
1256
  /**
1042
1257
  * Calcola il numero di salti da un header foglia all'ultimo parent della catena
@@ -1054,9 +1269,9 @@ class ColumnMetadataHandler {
1054
1269
  if (parent) {
1055
1270
  th = thsCache[parent];
1056
1271
  if (!th.thEmpty && !th._multi_content)
1057
- parentsPrepend.unshift({ tmpl: th.Template });
1272
+ parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
1058
1273
  else if (!th.thEmpty && th._multi_content)
1059
- parentsPrepend.unshift({ content: th._multi_content });
1274
+ parentsPrepend.unshift({ id: th.th, content: th._multi_content });
1060
1275
  jumps++;
1061
1276
  }
1062
1277
  } while (parent);
@@ -1117,7 +1332,9 @@ class ColumnMetadataHandler {
1117
1332
  let newContext = [];
1118
1333
  this.est.OrderDirectives.forEach(o => {
1119
1334
  let contextItem = context.filter(t => t.ID == o)[0];
1120
- newContext.push(contextItem);
1335
+ // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
1336
+ if (contextItem)
1337
+ newContext.push(contextItem);
1121
1338
  });
1122
1339
  this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
1123
1340
  }
@@ -1269,20 +1486,8 @@ class ColumnMetadataHandler {
1269
1486
  this.refreshColumnsVisibility(null, null, castedView);
1270
1487
  //Salvo le preferences di questa view
1271
1488
  //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
1272
- if (this.est.SavePreferences) {
1273
- if (!this.est.ngControl.name) {
1274
- console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
1275
- return false;
1276
- }
1277
- if (!this.prefService) {
1278
- console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
1279
- return false;
1280
- }
1281
- let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
1282
- let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
1283
- var toStore = { columns: JSON.parse(JSON.stringify(columns)), column_ordering: JSON.parse(JSON.stringify(columnsOrderings)) };
1284
- this.prefService.setItem(this.est.ngControl.name, toStore, 'preference').subscribe();
1285
- }
1489
+ if (this.est.SavePreferences)
1490
+ this.registerViewPreferences(castedView);
1286
1491
  // Rieseguo l'ultima ricerca bindata alla tabella
1287
1492
  // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
1288
1493
  if (this.est.viewMode)
@@ -1329,29 +1534,46 @@ class EsTableColumnsDefinition {
1329
1534
  /**
1330
1535
  * Costruttore
1331
1536
  *
1332
- * @param {string} description Descrizione della colonna
1333
- * @param {string} propertyName Nome della proprietà del modello in cui sono contenuti i dati da visualizzare per questa colonna
1334
- * @param {string} routePath Route di navigazione. Es. "['/pages/mod/mod_detail', { 'idItem': '{0}', 'idItem2' : '{1}' }]"
1335
- * @param {string[]} routeParameterProperties Proprietà da bindare a **routePath** per generare la route completa.
1537
+ * @param {string} Description Descrizione della colonna
1538
+ * @param {string} PropertyName Nome della proprietà del modello in cui sono contenuti i dati da visualizzare per questa colonna
1539
+ * @param {string} RoutePath Route di navigazione. Es. "['/pages/mod/mod_detail', { 'idItem': '{0}', 'idItem2' : '{1}' }]"
1540
+ * @param {string[]} RouteParameterProperties Proprietà da bindare a **routePath** per generare la route completa.
1336
1541
  * L'indice scritto in **routePath** è l'indice di accesso a questo array. Es. ["iditem", "iditem2"]
1337
- * @param {'ASC' | 'DESC' } dataOrder Ordinamento dei dati presentati in questa colonna
1338
- * @param {number} columnOrder Ordinamento di questa colonna
1339
- * @param {boolean} visible Visibilità o meno della colonna
1340
- * @param {string} clss Classe da applicare sia ai TD che ai TH relativi a questa colonna
1341
- * @param {boolean} orderable Indica se la colonna è ordinabile o no (nel senso ASC / DESC / NONE)
1342
- * @param {boolean} headerWraps Indica se il testo dell'header dev'essere wrappato all'interno del th. Di default no.
1542
+ * @param {'ASC' | 'DESC' } DataOrder Ordinamento dei dati presentati in questa colonna
1543
+ * @param {number} ColumnOrder Ordinamento di questa colonna
1544
+ * @param {boolean} Visible Visibilità o meno della colonna
1545
+ * @param {string} Clss Classe da applicare sia ai TD che ai TH relativi a questa colonna
1546
+ * @param {boolean} Orderable Indica se la colonna è ordinabile o no (nel senso ASC / DESC / NONE)
1547
+ * @param {boolean} HeaderWraps Indica se il testo dell'header dev'essere wrappato all'interno del th. Di default no.
1548
+ * @param {InputType | string} PropertyType Indica il tipo della proprietà identificata da **propertyName**.
1549
+ * @param {{id: string, description: string}[]} PropertySource Sorgente dati su cui autocompletare/scegliere il valore per la proprietà **propertyName**, ha senso solo per **propType** enum o autocomplete.
1550
+ * @param {string} EditorName Nome dell'editor da utilizzare per la modifica di questo campo
1551
+ * @param {string} RendererName Nome del renderer da utilizzare per visualizzare questo campo
1343
1552
  */
1344
- constructor(description, propertyName, routePath = null, routeParameterProperties = null, dataOrder = null, columnOrder = null, visible = true, clss = null, orderable = true, headerWraps = false) {
1345
- this.description = description;
1346
- this.propertyName = propertyName;
1347
- this.routePath = routePath;
1348
- this.routeParameterProperties = routeParameterProperties;
1349
- this.dataOrder = dataOrder;
1350
- this.columnOrder = columnOrder;
1351
- this.visible = visible;
1352
- this.clss = clss;
1353
- this.orderable = orderable;
1354
- this.headerWraps = headerWraps;
1553
+ constructor(Description, PropertyName, RoutePath = null, RouteParameterProperties = null, DataOrder = null, ColumnOrder = null, Visible = true, Clss = null, Orderable = true, HeaderWraps = false, PropertyType = null, PropertySource = [], EditorName = "", RendererName = "", EditorOptions = {}, Pinned = false, PinnedWidth = 150, Pinnable = true, Grouping = "", Shrink = false) {
1554
+ this.Description = Description;
1555
+ this.PropertyName = PropertyName;
1556
+ this.RoutePath = RoutePath;
1557
+ this.RouteParameterProperties = RouteParameterProperties;
1558
+ this.DataOrder = DataOrder;
1559
+ this.ColumnOrder = ColumnOrder;
1560
+ this.Visible = Visible;
1561
+ this.Clss = Clss;
1562
+ this.Orderable = Orderable;
1563
+ this.HeaderWraps = HeaderWraps;
1564
+ this.PropertyType = PropertyType;
1565
+ this.PropertySource = PropertySource;
1566
+ this.EditorName = EditorName;
1567
+ this.RendererName = RendererName;
1568
+ this.EditorOptions = EditorOptions;
1569
+ this.Pinned = Pinned;
1570
+ this.PinnedWidth = PinnedWidth;
1571
+ this.Pinnable = Pinnable;
1572
+ this.Grouping = Grouping;
1573
+ this.Shrink = Shrink;
1574
+ }
1575
+ static build(parsObj) {
1576
+ return new EsTableColumnsDefinition(parsObj.Description, parsObj.PropertyName, parsObj.RoutePath, parsObj.RouteParameterProperties, parsObj.DataOrder, parsObj.ColumnOrder, parsObj.Visible || true, parsObj.Clss, parsObj.Orderable || true, parsObj.HeaderWraps, parsObj.PropertyType, parsObj.PropertySource, parsObj.EditorName, parsObj.RendererName, parsObj.Pinned, parsObj.Grouping, parsObj.Shrink);
1355
1577
  }
1356
1578
  }
1357
1579
 
@@ -1361,42 +1583,6 @@ class DynamicModeHandler {
1361
1583
  constructor(est) {
1362
1584
  this.est = est;
1363
1585
  }
1364
- /**
1365
- * Metodo di supporto alla creazione di un router link parametrizzato all'oggetto corrente utilizzato nella modalità dinamica
1366
- *
1367
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1368
- * @param {string[]} parameterProps Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1369
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1370
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1371
- *
1372
- * @returns {any} Router link generato in base al parametri
1373
- */
1374
- generateRouterLink(path, parameterProps, item) {
1375
- if (this.est.DynamicTableRouterLinkCache[item._hash + path]) {
1376
- return this.est.DynamicTableRouterLinkCache[item._hash + path];
1377
- }
1378
- else {
1379
- let link = this.getRouterLink(path, parameterProps, item);
1380
- this.est.DynamicTableRouterLinkCache[item._hash + path] = link;
1381
- return link;
1382
- }
1383
- }
1384
- /**
1385
- * Crea un router link
1386
- *
1387
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1388
- * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1389
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1390
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1391
- *
1392
- * @returns {any} Router link generato in base al parametri
1393
- */
1394
- getRouterLink(path, pars, item) {
1395
- for (let i = 0; i < pars.length; i++)
1396
- path = path.replace('{' + i + '}', item.properties[pars[i]]);
1397
- path = path.replace(/'/g, '"').replace(/ /g, '');
1398
- return JSON.parse(path);
1399
- }
1400
1586
  /** Se non ho l'Input **DynamicRowColumnsDefinition** in modalità dinamica lo riempio con il default nome della colonna = testo della colonna */
1401
1587
  eventuallyReviewDynamicColumns() {
1402
1588
  // Senza oggetti esco
@@ -1415,6 +1601,82 @@ class DynamicModeHandler {
1415
1601
  else
1416
1602
  this.est.UserDefinedDynamicCols = true;
1417
1603
  }
1604
+ /** Genera partendo dalle **DynamicRowColumnsDefinition** la lista di **EsThDirective** e **EsTdDirective** che servono per la tabella */
1605
+ emitThsAndTdsBasedOnDynamicDefinition() {
1606
+ // Senza dynamic columns esco
1607
+ if (!this.est.DynamicRowColumnsDefinition || this.est.DynamicRowColumnsDefinition.length == 0)
1608
+ return null;
1609
+ let ths = [];
1610
+ let tds = [];
1611
+ for (let i = 0; i < this.est.DynamicOperations.length; i++) {
1612
+ let op = this.est.DynamicOperations[i];
1613
+ ths.push(this.getThFromOperation(op));
1614
+ tds.push(this.getTdFromOperation(op));
1615
+ }
1616
+ for (let i = 0; i < this.est.DynamicRowColumnsDefinition.length; i++) {
1617
+ let col = this.est.DynamicRowColumnsDefinition[i];
1618
+ ths.push(this.getThFromColumnDef(col));
1619
+ tds.push(this.getTdFromColumnDef(col));
1620
+ }
1621
+ return { ths, tds };
1622
+ }
1623
+ /** @ignore Helper */
1624
+ getThFromOperation(op) {
1625
+ let th = new EsThDirective(null);
1626
+ th.th = op.id;
1627
+ th.thStaticContent = "";
1628
+ return th;
1629
+ }
1630
+ getTdFromOperation(op) {
1631
+ let td = new EsTdDirective(null);
1632
+ td.td = op.id;
1633
+ td.tdIconClass = op.iconClass;
1634
+ td.tdConditionField = op.conditionField;
1635
+ td.tdConditionValue = op.conditionValue;
1636
+ td.tdTitle = op.title;
1637
+ td.tdContent = op.text;
1638
+ return td;
1639
+ }
1640
+ getThFromColumnDef(col) {
1641
+ var ret = new EsThDirective(null);
1642
+ ret.th = col.PropertyName;
1643
+ ret.thPinned = col.Pinned;
1644
+ ret.thPinnable = col.Pinnable;
1645
+ ret.thPinnedWidth = col.PinnedWidth;
1646
+ ret.thVisible = col.Visible;
1647
+ ret.thOrder = col.DataOrder;
1648
+ ret.thOrderable = col.Orderable;
1649
+ ret.thWrap = col.HeaderWraps;
1650
+ ret.thClass = col.Clss;
1651
+ ret.thProperty = col.PropertyName;
1652
+ ret.thType = col.PropertyType;
1653
+ ret.thSource = col.PropertySource;
1654
+ ret.thEditorName = col.EditorName;
1655
+ ret.thEditorOptions = col.EditorOptions;
1656
+ ret.thRendererName = col.RendererName;
1657
+ ret.thRoutePath = col.RoutePath;
1658
+ ret.thRouteParameterProperties = col.RouteParameterProperties;
1659
+ //ret.thFixed = col.Fixed;
1660
+ //ret.thResizable = col.Resizable;
1661
+ //ret.thGroupClass = col.GroupClass;
1662
+ //ret.thGroup = col.Group;
1663
+ //ret.thAggregation = col.Aggregation;
1664
+ //ret.thMulti = col.Multi;
1665
+ //ret.thStaticContent = col.StaticContent;
1666
+ //ret.thBackgroundColor = col.BackgroundColor;
1667
+ //ret.thAlignment = col.Alignment;
1668
+ //ret.thFormat = col.Format;
1669
+ return ret;
1670
+ }
1671
+ /** @ignore Helper */
1672
+ getTdFromColumnDef(col) {
1673
+ var ret = new EsTdDirective(null);
1674
+ ret.td = col.PropertyName;
1675
+ ret.tdClass = col.Clss;
1676
+ //ret.tdAlignment = col.Alignment;
1677
+ //ret.tdFormat = col.Format;
1678
+ return ret;
1679
+ }
1418
1680
  }
1419
1681
 
1420
1682
  /** Classe contenente la gestione della modalità gerarchica */
@@ -1649,17 +1911,25 @@ class ItemsHandler {
1649
1911
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.arraymodePage, this.est.arraymodePages);
1650
1912
  else
1651
1913
  return this.est.View;
1914
+ // Applico eventuali oridnamenti lato Array prima di tirare fuori la pagina selezionata
1915
+ let items = this.est.View;
1916
+ if (this.est)
1917
+ items = this.arrayModeReviewOrderings(items);
1652
1918
  // Poi per tutti i valori dopo compresi fra la pagina - 1 e la pagina
1653
1919
  for (let i = ((this.est.arraymodePage - 1) * this.est.ArraymodeItemsPerPage); i < this.est.arraymodePage * this.est.ArraymodeItemsPerPage; i++) {
1654
- if (i <= this.est.View.length - 1)
1655
- tmpItems.push(this.est.View[i]);
1920
+ if (i <= items.length - 1)
1921
+ tmpItems.push(items[i]);
1656
1922
  }
1657
1923
  return tmpItems;
1658
1924
  }
1659
1925
  /** Se in modalità array applica gli ordinamenti ASC-DESC delle colonne */
1660
- arrayModeReviewOrderings() {
1926
+ arrayModeReviewOrderings(items) {
1927
+ let tmp = items;
1661
1928
  if (this.est.arrayOrders.length > 0)
1662
- this.est.arrayOrders.forEach(t => { this.est.boundSource = this.est.boundSource.sort((a, b) => (a[t.id] > b[t.id] ? 1 : -1) * (t.order == 'DESC' ? -1 : 1)); });
1929
+ this.est.arrayOrders.forEach(t => {
1930
+ tmp = tmp.sort((a, b) => (a[t.id] > b[t.id] ? 1 : -1) * (t.order == 'DESC' ? -1 : 1));
1931
+ });
1932
+ return tmp;
1663
1933
  }
1664
1934
  }
1665
1935
 
@@ -1688,6 +1958,15 @@ class ReportModeHandler {
1688
1958
  this.est.View.pages = Math.ceil(count / ipp);
1689
1959
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.View.page, this.est.View.pages);
1690
1960
  }
1961
+ /**
1962
+ * Data una AppSearch questo metodo genera la lista di th e td che si possono collegare al giro standard.
1963
+ * Se non ci fosse questo passaggio intermedio la gestione della modalità report sarebbe 100% custom,
1964
+ * come poi lo era prima che la facessi passare dal giro che fanno tutte le altre modalità
1965
+ *
1966
+ * @param {AppSearch<any>} view View in modalità report contenente le informazioni sulle colonne
1967
+ *
1968
+ * @returns {{ ths: EsThDirective[], tds: EsTdDirective[] }} Lista di direttive per gli header e per il body
1969
+ */
1691
1970
  generateThsAndTdsFromView(view) {
1692
1971
  var ret = { ths: [], tds: [] };
1693
1972
  // Ordinamento per ora commentato... non vorrebbe mi fuckappasse tutto
@@ -1696,11 +1975,15 @@ class ReportModeHandler {
1696
1975
  let clm = view.report_columns[i];
1697
1976
  var th = new EsThDirective(null);
1698
1977
  th.th = clm.id;
1699
- th.thStaticContent = clm.description;
1978
+ th.thStaticContent = clm.description || null;
1700
1979
  th.thBackgroundColor = clm.color;
1980
+ th.thAlignment = clm.alignment;
1981
+ th.thFormat = clm.format;
1701
1982
  var td = new EsTdDirective(null);
1702
1983
  td.td = clm.id;
1703
1984
  td.tdPropertyAccessor = i.toString();
1985
+ td.tdAlignment = clm.alignment;
1986
+ td.tdFormat = clm.format;
1704
1987
  ret.ths.push(th);
1705
1988
  ret.tds.push(td);
1706
1989
  }
@@ -1762,8 +2045,9 @@ class GroupPager {
1762
2045
  /**
1763
2046
  * Costruttore
1764
2047
  *
1765
- * @param {number} groupLevel Livello del gruppo a cui questo separatore fa riferimento
1766
- * @param {string} parentKey Chiave del gruppo parent se esiste
2048
+ * @param {number} _grouplevel Livello del gruppo a cui questo separatore fa riferimento
2049
+ * @param {string} _thisRoute Route che identifica la gerarchia del gruppo e chi sono i parent
2050
+ * @param {string} _parent Chiave del gruppo parent se esiste
1767
2051
  * @param {AppSearch<any>} view Vista di ricerca collegata a questo elemento
1768
2052
  * @param {'groups' | 'items'} searches Indica che cosa cerca questo separatore, se sottogruppi o oggetti
1769
2053
  */
@@ -2332,6 +2616,120 @@ class SelectionHandler {
2332
2616
  return;
2333
2617
  this.handleSelectionEvaluation(items, selectionItem);
2334
2618
  }
2619
+ /**
2620
+ * Precompila le informazioni sullo stato di selezione tutto a false per le celle della tabella
2621
+ *
2622
+ * @param {any[]} items Oggetti attualmente bindati sulla tabella
2623
+ * @param {EsThDirective[]} ths Colonne su cui gli oggetti sono bindati
2624
+ */
2625
+ evaluateSingleCellSelection(items, ths, dyn) {
2626
+ for (let i = 0; i < items.length; i++) {
2627
+ // items[i]._ordinal dovrebbe essere uguale a "i" ma dato che lato HTML il ciclo è esterno e non ho l'indice per convenzione mi baso sull'_ordinal
2628
+ this.est.selectionStatus[items[i]._ordinal] = {};
2629
+ if (dyn && dyn.length > 0)
2630
+ this.fillSelectionStatusByDynamicColumns(items[i], dyn);
2631
+ else
2632
+ this.fillSelectionStatusByEsThs(items[i], ths);
2633
+ }
2634
+ }
2635
+ /** @ignore */
2636
+ fillSelectionStatusByDynamicColumns(item, dyn) {
2637
+ for (let k = 0; k < dyn.length; k++) {
2638
+ let th = dyn[k];
2639
+ let iper = { selected: false, value: th.PropertyName ? item.properties[th.PropertyName] : "Undefined Property", type: th.PropertyType, property: th.PropertyName, header: th.PropertyName, item: item };
2640
+ this.est.selectionStatus[item._ordinal][k] = iper;
2641
+ // Funzione assegnata dopo in modo da poterle fare anche aggiornare il valore del riferimento all'oggetto di selezione
2642
+ iper.val_setter = (value) => {
2643
+ if (!th.PropertyName) {
2644
+ item[th.PropertyName] = value;
2645
+ iper.value = value;
2646
+ return value;
2647
+ }
2648
+ let valToApply = "";
2649
+ switch (th.PropertyType) {
2650
+ case "string":
2651
+ if (value.startsWith && value.startsWith('"') && value.endsWith && value.endsWith('"'))
2652
+ valToApply = value.substring(1, value.length - 1);
2653
+ else
2654
+ valToApply = value;
2655
+ break;
2656
+ case "number":
2657
+ case "int":
2658
+ case "boolean":
2659
+ case "enum":
2660
+ case "autocomplete":
2661
+ case "float":
2662
+ case "currency":
2663
+ valToApply = value;
2664
+ break;
2665
+ case "date":
2666
+ case "datetime":
2667
+ valToApply = this.est.dateExts.getDateConvertion(value);
2668
+ break;
2669
+ case "time":
2670
+ let mydate = this.est.dateExts.getDateConvertion(value);
2671
+ valToApply = `${mydate.hour()}:${mydate.minute()}:${mydate.second()}`;
2672
+ break;
2673
+ // Per evitare di sbiancare senza senso
2674
+ default:
2675
+ valToApply = value;
2676
+ break;
2677
+ }
2678
+ item.properties[th.PropertyName] = valToApply;
2679
+ iper.value = valToApply;
2680
+ return valToApply;
2681
+ };
2682
+ }
2683
+ }
2684
+ /** @ignore */
2685
+ fillSelectionStatusByEsThs(item, ths) {
2686
+ for (let k = 0; k < ths.length; k++) {
2687
+ let th = ths[k];
2688
+ let iper = { selected: false, value: th.thProperty ? item[th.thProperty] : "Undefined Property", type: th.thType, property: th.thProperty, header: th.th, item: item };
2689
+ this.est.selectionStatus[item._ordinal][k] = iper;
2690
+ // Funzione assegnata dopo in modo da poterle fare anche aggiornare il valore del riferimento all'oggetto di selezione
2691
+ iper.val_setter = (value) => {
2692
+ if (!th.thProperty) {
2693
+ item[th.thProperty] = value;
2694
+ iper.value = value;
2695
+ return value;
2696
+ }
2697
+ let valToApply = "";
2698
+ switch (th.thType) {
2699
+ case "string":
2700
+ if (value.startsWith('"') && value.endsWith('"'))
2701
+ valToApply = value.substring(1, value.length - 1);
2702
+ else
2703
+ valToApply = value;
2704
+ break;
2705
+ case "number":
2706
+ case "int":
2707
+ case "boolean":
2708
+ case "enum":
2709
+ case "autocomplete":
2710
+ case "float":
2711
+ case "currency":
2712
+ valToApply = value;
2713
+ break;
2714
+ case "date":
2715
+ case "datetime":
2716
+ valToApply = this.est.dateExts.getDateConvertion(value);
2717
+ break;
2718
+ case "time":
2719
+ let mydate = this.est.dateExts.getDateConvertion(value);
2720
+ valToApply = `${mydate.hour()}:${mydate.minute()}:${mydate.second()}`;
2721
+ break;
2722
+ // Per evitare di sbiancare senza senso
2723
+ default:
2724
+ valToApply = value;
2725
+ break;
2726
+ }
2727
+ item[th.thProperty] = valToApply;
2728
+ iper.value = valToApply;
2729
+ return valToApply;
2730
+ };
2731
+ }
2732
+ }
2335
2733
  /**
2336
2734
  * Implementazione agnostica della valutazione delle selezioni degli oggetti. Richiede gli oggetti della vista attuale e l'itemSelector
2337
2735
  *
@@ -2808,6 +3206,158 @@ class SelectionHandler {
2808
3206
  // Dopo aver resettato direttamente il solo oggetto this.View.selection devo anche riallineare a tutti gli oggetti bindati
2809
3207
  this.evaluateSelection(this.est.boundSource, selectionItem);
2810
3208
  }
3209
+ /**
3210
+ * @TODO Spostare in SelectionHandler
3211
+ *
3212
+ * Registra la selezione singola su una cella sulla combo di comandi "CTRL + Click".
3213
+ * Se viene premuto anche il tasto Shift viene creato un range di selezione il cui status di "selezionato" viene salvato nella
3214
+ * matrice virtuale **selectionStatus**
3215
+ *
3216
+ * @param {any} event Evento Javascript di Click
3217
+ * @param {number} row Indice della riga. Non è l'indice vero e proprio ma è l'ordinale (.ordinal) dell'oggetto bindato su quella riga
3218
+ * @param {number} column Indice della colonna preso banalmente dall'ngIf sui thElement
3219
+ * @param {{ row: number, column: number }} firstSelectionOverride Permette di overridare il primo elemento selezionato
3220
+ */
3221
+ singleCellSelection(event, row, column, firstSelectionOverride) {
3222
+ // Recupero la selezione precedente se presente come punto di partenza
3223
+ var first = firstSelectionOverride || this.lastSingleSelection;
3224
+ //Il punto di arrivo, che diventerà il prossimo punto di partenza, è la selezione corrente
3225
+ this.lastSingleSelection = { row, column };
3226
+ this.clearTextSelection(event);
3227
+ this.clearSelectionStatusExcluding(this.lastSingleSelection);
3228
+ this.setSelectionStatusBorders(event.range && first ? first : this.lastSingleSelection, this.lastSingleSelection);
3229
+ // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
3230
+ this.est.cdr.markForCheck();
3231
+ }
3232
+ setSelectionStatusBorders(from, to) {
3233
+ let rowAddition = to.row < from.row ? -1 : +1;
3234
+ let columnAddition = to.column < from.column ? -1 : +1;
3235
+ let singleItem = from == to;
3236
+ for (let ir = from.row; ir != to.row + rowAddition; ir += rowAddition) {
3237
+ let firstRow = ir == from.row;
3238
+ let lastRow = ir == to.row;
3239
+ for (let ic = from.column; ic != to.column + columnAddition; ic += columnAddition) {
3240
+ let firstCol = ic == from.column;
3241
+ let lastCol = ic == to.column;
3242
+ let current = this.est.selectionStatus[ir][ic];
3243
+ let prevColumn = ic > 0 ? this.est.selectionStatus[ir][ic - 1] : null;
3244
+ let nextcolumn = this.est.selectionStatus[ir][ic + 1];
3245
+ let prevRow = ir > 0 ? this.est.selectionStatus[ir - 1][ic] : null;
3246
+ let nextRow = this.est.selectionStatus[ir + 1] ? this.est.selectionStatus[ir + 1][ic] : null;
3247
+ current.selected = singleItem ? !current.selected : true;
3248
+ current.lborder = !current.selected ? false : columnAddition > 0 ? firstCol : lastCol;
3249
+ current.tborder = !current.selected ? false : rowAddition > 0 ? firstRow : lastRow;
3250
+ current.rborder = !current.selected ? false : columnAddition > 0 ? lastCol : firstCol;
3251
+ current.bborder = !current.selected ? false : rowAddition > 0 ? lastRow : firstRow;
3252
+ if (prevRow)
3253
+ prevRow.boverlaps = current.tborder;
3254
+ if (nextRow)
3255
+ nextRow.toverlaps = current.bborder;
3256
+ if (prevColumn)
3257
+ prevColumn.roverlaps = current.lborder;
3258
+ if (nextcolumn)
3259
+ nextcolumn.loverlaps = current.rborder;
3260
+ }
3261
+ }
3262
+ }
3263
+ /**
3264
+ * Helper per ripulire lo stato di selezione delle singole celle della tabella, ad esclusione di una singola coordinata
3265
+ *
3266
+ * @param {{row: number, column: number}} exclusion Coordinata da escludere nella pulizia
3267
+ */
3268
+ clearSelectionStatusExcluding(exclusion) {
3269
+ for (let row in this.est.selectionStatus) {
3270
+ for (let column in this.est.selectionStatus[row]) {
3271
+ // Se è l'elemento che ho escluso dal cleanup, skippo
3272
+ if (exclusion && row == exclusion.row.toString() && column == exclusion.column.toString())
3273
+ continue;
3274
+ // Altrimenti pulisco
3275
+ let curr = this.est.selectionStatus[row][column];
3276
+ curr.selected = curr.lborder = curr.rborder = curr.tborder = curr.bborder = curr.loverlaps = curr.roverlaps = curr.toverlaps = curr.boverlaps = false;
3277
+ }
3278
+ }
3279
+ }
3280
+ /**
3281
+ * Helper che esamina la matrice **selectionStatus** e ne estrappola gli elementi selezionati in una comoda matrice
3282
+ *
3283
+ * @returns {{ value: string, type: InputType, val_setter: Function }[][]} Matrice di elementi selezionati con la loro informazione sul tipo
3284
+ */
3285
+ getSelectionStatusSelection() {
3286
+ let selection = [];
3287
+ for (let row in this.est.selectionStatus) {
3288
+ let rowValues = [];
3289
+ for (let column in this.est.selectionStatus[row]) {
3290
+ let ssItem = this.est.selectionStatus[row][column];
3291
+ if (ssItem.selected)
3292
+ rowValues.push(ssItem);
3293
+ }
3294
+ if (rowValues.length > 0)
3295
+ selection.push(rowValues);
3296
+ }
3297
+ return selection;
3298
+ }
3299
+ /**
3300
+ * Helper per ripulire la selezione lato HTML
3301
+ *
3302
+ * @param {any} event Evento nativo Javascript
3303
+ */
3304
+ clearTextSelection(event) {
3305
+ // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
3306
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.range)
3307
+ return false;
3308
+ // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
3309
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.range)
3310
+ this.est.utiExts.clearTextSelection();
3311
+ }
3312
+ /**
3313
+ * Data la matrice di selezione generata dal metodo **getSelectionStatusSelection** genera la strigna vera e propria da copiare nella Clipboard
3314
+ *
3315
+ * @param {{ value: string, type: InputType }[][]} sel Matrice di selezione con valori e tipi dei dati selezionati
3316
+ *
3317
+ * @returns {string} Stringa da copiare nella clipboard, le stringhe vengono wrappate fra doppi apici e fra un valore e l'altro viene messo un tab
3318
+ * in modo che siano compatibili anche con la copia su Excel
3319
+ */
3320
+ getClipbardTextFromSelection(sel) {
3321
+ var ret = "";
3322
+ for (let r = 0; r < sel.length; r++) {
3323
+ let row = sel[r];
3324
+ if (r > 0)
3325
+ ret += "\n";
3326
+ for (let c = 0; c < row.length; c++) {
3327
+ let col = row[c];
3328
+ ret += this.getValueByType(col) + (c < row.length - 1 ? "\t" : "");
3329
+ }
3330
+ }
3331
+ return ret;
3332
+ }
3333
+ /**
3334
+ * Ottiene la rappresentazione stringa di un valore dato un tipo
3335
+ *
3336
+ * @param {{ value: string, type: InputType }} valType Oggetto Valore - Tipo da cui estrapolare la rappresentazione del dato in stringa
3337
+ *
3338
+ * @returns {string} Valore convertito in stringa in base al tipo
3339
+ */
3340
+ getValueByType(valType) {
3341
+ switch (valType.type) {
3342
+ case 'string':
3343
+ return '"' + valType.value + '"';
3344
+ case 'number':
3345
+ case 'int':
3346
+ case 'boolean':
3347
+ case 'enum':
3348
+ case 'autocomplete':
3349
+ return valType.value;
3350
+ case 'float':
3351
+ case 'currency':
3352
+ return parseFloat(valType.value).toLocaleString(this.est.locale);
3353
+ case 'date':
3354
+ return dayjs(valType.value).format(this.est.lc.token("getSmallDateDisplayFormat"));
3355
+ case 'datetime':
3356
+ return dayjs(valType.value).format(this.est.lc.token("getFullDateDisplayFormat"));
3357
+ case 'time':
3358
+ return dayjs(valType.value).format("HH:mm:ss");
3359
+ }
3360
+ }
2811
3361
  }
2812
3362
 
2813
3363
  // Angular
@@ -2902,10 +3452,7 @@ class UtilitiesHandler {
2902
3452
  for (let i = min; i <= max; i++)
2903
3453
  if (i !== 1)
2904
3454
  result.push({ val: i, cssClass: (i === page ? 'btn-main app-white-text' : 'app-white-button') });
2905
- result.push({
2906
- val: lastPage,
2907
- cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button')
2908
- });
3455
+ result.push({ val: lastPage, cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button') });
2909
3456
  }
2910
3457
  return result;
2911
3458
  }
@@ -2926,9 +3473,11 @@ class UtilitiesHandler {
2926
3473
  delete tmp._selected;
2927
3474
  delete tmp._visible;
2928
3475
  delete tmp._hash;
3476
+ delete tmp._ordinal;
2929
3477
  let hash = this.hashExts.hashObject(tmp);
2930
3478
  usedHashesCache[hash] = usedHashesCache[hash] ? usedHashesCache[hash] + 1 : 1;
2931
3479
  item._hash = hash + (usedHashesCache[hash] > 1 ? "_" + usedHashesCache[hash] : "");
3480
+ item._ordinal = i;
2932
3481
  }
2933
3482
  }
2934
3483
  /**
@@ -2952,13 +3501,61 @@ class UtilitiesHandler {
2952
3501
  return null;
2953
3502
  }
2954
3503
  }
2955
- UtilitiesHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, deps: [{ token: i5.HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
2956
- UtilitiesHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, providedIn: 'root' });
2957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, decorators: [{
3504
+ UtilitiesHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, deps: [{ token: i5.HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
3505
+ UtilitiesHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, providedIn: 'root' });
3506
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, decorators: [{
2958
3507
  type: Injectable,
2959
3508
  args: [{ providedIn: 'root' }]
2960
3509
  }], ctorParameters: function () { return [{ type: i5.HashingService }]; } });
2961
3510
 
3511
+ /** Classe che fornisce dei metodi di estensione in grado di riconoscere e dispatchare l'evento copia e incolla lanciato su una pagina web */
3512
+ class CopyPasteDetector {
3513
+ /** @ignore */
3514
+ constructor() {
3515
+ /** Dispatcher del Copia */
3516
+ this.OnCopy = new Subject();
3517
+ /** Dispatcher dell' Incolla */
3518
+ this.OnPaste = new Subject();
3519
+ /** Riferimento all'estable attiva per evitare di spammare copia incolla dove non servono */
3520
+ this.ActiveEstReference = null;
3521
+ document.addEventListener("keydown", (event) => {
3522
+ if (event.key === "c" && event.ctrlKey)
3523
+ this.OnCopy.next();
3524
+ if (event.key === "v" && event.ctrlKey)
3525
+ this.OnPaste.next();
3526
+ });
3527
+ }
3528
+ }
3529
+ CopyPasteDetector.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3530
+ CopyPasteDetector.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, providedIn: "root" });
3531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, decorators: [{
3532
+ type: Injectable,
3533
+ args: [{ providedIn: "root" }]
3534
+ }], ctorParameters: function () { return []; } });
3535
+
3536
+ /** Classe che fornisce dei metodi di estensione in grado di riconoscere e dispatchare l'evento copia e incolla lanciato su una pagina web */
3537
+ class Logger {
3538
+ /** @ignore */
3539
+ constructor(debugMode) {
3540
+ this.debugMode = debugMode;
3541
+ }
3542
+ log(text) {
3543
+ if (this.debugMode)
3544
+ console.log("[@esfaenza/es-table @ " + (new Date()).toISOString() + "] " + text);
3545
+ }
3546
+ }
3547
+ Logger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: Logger, deps: [{ token: EST_DEBUG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
3548
+ Logger.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: Logger, providedIn: "root" });
3549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: Logger, decorators: [{
3550
+ type: Injectable,
3551
+ args: [{ providedIn: "root" }]
3552
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
3553
+ type: Optional
3554
+ }, {
3555
+ type: Inject,
3556
+ args: [EST_DEBUG]
3557
+ }] }]; } });
3558
+
2962
3559
  //Angular
2963
3560
  /** Componente rappresentante una Colonna della tabella */
2964
3561
  class EsTh {
@@ -3087,11 +3684,11 @@ class EsTh {
3087
3684
  $event.preventDefault();
3088
3685
  }
3089
3686
  }
3090
- EsTh.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTh, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3091
- EsTh.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: EsTh, selector: "[es-th]", inputs: { ID: ["es-th", "ID"], Order: "Order", Orderable: "Orderable", Display: "Display", Resizable: "Resizable", Pinned: "Pinned", SearchInProgress: "SearchInProgress", OrderBy: "OrderBy", Wrap: "Wrap", Fixed: "Fixed", Template: "Template", Visible: "Visible" }, outputs: { onOrderChange: "onOrderChange", onUnpinning: "onUnpinning" }, host: { listeners: { "window:mouseup.out-zone": "onMouseUp()", "window:mousemove.out-zone": "onMouseMove($event)" } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<span (click)=\"setupNextOrderAndNotify()\" [class.app-no-selection]=\"!!ID && Orderable\" [class.app-pointer]=\"!!ID && Orderable\">\r\n <span #content>\r\n <ng-container *ngIf=\"Template\">\r\n <ng-container *ngTemplateOutlet=\"Template\"></ng-container>\r\n </ng-container>\r\n <ng-content *ngIf=\"!Template\"></ng-content>\r\n </span>&nbsp;\r\n <span class=\"fa\" [class.fa-chevron-down]=\"Order == 'DESC'\" [class.fa-chevron-up]=\"Order == 'ASC'\"></span>\r\n</span>\r\n<span *ngIf=\"Pinned && !Fixed\" class=\"app-pointer fa fa-thumb-tack est-quick-unpin\" (click)=\"unpin()\"></span>\r\n<div [hidden]=\"!Resizable || Fixed || Pinned\" class=\"est-head-resizer\" (mousedown)=\"onResizeStart($event)\">\r\n <div class=\"est-head-resizer-internal\"></div>\r\n</div>", directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i11.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3092
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTh, decorators: [{
3687
+ EsTh.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTh, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3688
+ EsTh.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: EsTh, selector: "[es-th]", inputs: { ID: ["es-th", "ID"], Order: "Order", Orderable: "Orderable", Display: "Display", Resizable: "Resizable", Pinned: "Pinned", SearchInProgress: "SearchInProgress", OrderBy: "OrderBy", Wrap: "Wrap", Fixed: "Fixed", Template: "Template", Visible: "Visible" }, outputs: { onOrderChange: "onOrderChange", onUnpinning: "onUnpinning" }, host: { listeners: { "window:mouseup.out-zone": "onMouseUp()", "window:mousemove.out-zone": "onMouseMove($event)" } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<span (click)=\"setupNextOrderAndNotify()\" [class.app-no-selection]=\"!!ID && Orderable\" [class.app-pointer]=\"!!ID && Orderable\">\r\n <span #content>\r\n <ng-container *ngIf=\"!!Template\">\r\n <ng-container *ngTemplateOutlet=\"Template\"></ng-container>\r\n </ng-container>\r\n <ng-content *ngIf=\"!Template\"></ng-content>\r\n </span>&nbsp;\r\n <span class=\"fa\" [class.fa-chevron-down]=\"Order == 'DESC'\" [class.fa-chevron-up]=\"Order == 'ASC'\"></span>\r\n</span>\r\n<span *ngIf=\"Pinned && !Fixed\" class=\"app-pointer fa fa-thumb-tack est-quick-unpin\" (click)=\"unpin()\"></span>\r\n<div [hidden]=\"!Resizable || Fixed || Pinned\" class=\"est-head-resizer\" (mousedown)=\"onResizeStart($event)\">\r\n <div class=\"est-head-resizer-internal\"></div>\r\n</div>", directives: [{ type: i13.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i13.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTh, decorators: [{
3093
3690
  type: Component,
3094
- args: [{ selector: "[es-th]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span (click)=\"setupNextOrderAndNotify()\" [class.app-no-selection]=\"!!ID && Orderable\" [class.app-pointer]=\"!!ID && Orderable\">\r\n <span #content>\r\n <ng-container *ngIf=\"Template\">\r\n <ng-container *ngTemplateOutlet=\"Template\"></ng-container>\r\n </ng-container>\r\n <ng-content *ngIf=\"!Template\"></ng-content>\r\n </span>&nbsp;\r\n <span class=\"fa\" [class.fa-chevron-down]=\"Order == 'DESC'\" [class.fa-chevron-up]=\"Order == 'ASC'\"></span>\r\n</span>\r\n<span *ngIf=\"Pinned && !Fixed\" class=\"app-pointer fa fa-thumb-tack est-quick-unpin\" (click)=\"unpin()\"></span>\r\n<div [hidden]=\"!Resizable || Fixed || Pinned\" class=\"est-head-resizer\" (mousedown)=\"onResizeStart($event)\">\r\n <div class=\"est-head-resizer-internal\"></div>\r\n</div>" }]
3691
+ args: [{ selector: "[es-th]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span (click)=\"setupNextOrderAndNotify()\" [class.app-no-selection]=\"!!ID && Orderable\" [class.app-pointer]=\"!!ID && Orderable\">\r\n <span #content>\r\n <ng-container *ngIf=\"!!Template\">\r\n <ng-container *ngTemplateOutlet=\"Template\"></ng-container>\r\n </ng-container>\r\n <ng-content *ngIf=\"!Template\"></ng-content>\r\n </span>&nbsp;\r\n <span class=\"fa\" [class.fa-chevron-down]=\"Order == 'DESC'\" [class.fa-chevron-up]=\"Order == 'ASC'\"></span>\r\n</span>\r\n<span *ngIf=\"Pinned && !Fixed\" class=\"app-pointer fa fa-thumb-tack est-quick-unpin\" (click)=\"unpin()\"></span>\r\n<div [hidden]=\"!Resizable || Fixed || Pinned\" class=\"est-head-resizer\" (mousedown)=\"onResizeStart($event)\">\r\n <div class=\"est-head-resizer-internal\"></div>\r\n</div>" }]
3095
3692
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ID: [{
3096
3693
  type: Input,
3097
3694
  args: ['es-th']
@@ -3132,75 +3729,206 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
3132
3729
  args: ['window:mousemove.out-zone', ['$event']]
3133
3730
  }] } });
3134
3731
 
3135
- //Angular
3732
+ // Angular
3136
3733
  /** Componente rappresentante una singola cella del body della tabella */
3137
3734
  class EsTd {
3138
3735
  /** @ignore */
3139
- constructor(myself, renderer, _viewContainer, sanitizer) {
3140
- this.myself = myself;
3141
- this.renderer = renderer;
3142
- this._viewContainer = _viewContainer;
3143
- this.sanitizer = sanitizer;
3736
+ constructor(cdr) {
3737
+ this.cdr = cdr;
3144
3738
  /** Id della cella, dev'essere lo stesso della colonna **EsTh** relativa */
3145
3739
  this.ID = "";
3146
- /** Valore da mostrare all'interno della cella. Se omesso verrà proiettato il contenuto dal template in cui è stata usata */
3147
- this.Display = null;
3148
- /** Template Angular da istanziare per questo TD */
3149
- this.Template = null;
3150
- }
3151
- /**
3152
- * Imposta la visibilità o meno della cella, si traduce nell'applicazione o rimozione della classe **app-display-none**
3153
- *
3154
- * @param {boolean} expression Indicazione della visibilità
3155
- */
3156
- set Visible(expression) {
3157
- this._Visible = expression;
3158
- if (expression)
3159
- this.renderer.removeClass(this.myself.nativeElement, "app-display-none");
3160
- else
3161
- this.renderer.addClass(this.myself.nativeElement, "app-display-none");
3162
- }
3163
- /**
3164
- * Restituisce lo stato di Visibilità della cella in oggetto
3165
- *
3166
- * @returns {boolean} **true** se visibile, **false** altrimenti
3167
- */
3168
- get Visible() {
3169
- if (this._Visible == undefined)
3170
- this._Visible = true;
3171
- return this._Visible;
3740
+ /** Quando questa cella viene generata questo evento permette di dire "ehi, sono nato!" */
3741
+ this.onCellGeneration = new EventEmitter();
3742
+ /** Errore attualmente presente sulla cella */
3743
+ this.ValidationError = "";
3172
3744
  }
3173
3745
  /** @ignore */
3174
3746
  ngAfterViewInit() {
3175
- // Se è Internal significa che è gestita internamente da ES-TABLE quindi evito di fare sti due passaggi di lettura del DOM
3176
- if (this.Internal)
3177
- return;
3178
- this.Content = this.Display === null || this.Display === "" ? this.sanitizer.bypassSecurityTrustHtml(this.myself.nativeElement.innerHTML) : this.sanitizer.bypassSecurityTrustHtml(this.Display);
3179
- this.Class = this.myself.nativeElement.className.replace("app-display-none", "");
3747
+ this.onCellGeneration.emit({ id: this.ID, hash: this.Context, self: this });
3748
+ }
3749
+ /** Api per impostare un "errore" su questa cella in maniera programmatica */
3750
+ validationError(error) {
3751
+ this.ValidationError = error;
3752
+ this.cdr.markForCheck();
3180
3753
  }
3181
3754
  }
3182
- EsTd.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTd, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
3183
- EsTd.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: EsTd, selector: "[es-td]", inputs: { ID: ["es-td", "ID"], Internal: "Internal", RouterLink: "RouterLink", Display: "Display", Template: "Template", Context: "Context", Visible: "Visible" }, ngImport: i0, template: "<span>\r\n <ng-content></ng-content>\r\n</span>", changeDetection: i0.ChangeDetectionStrategy.OnPush });
3184
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTd, decorators: [{
3755
+ EsTd.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTd, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3756
+ EsTd.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: EsTd, selector: "[es-td]", inputs: { ID: ["es-td", "ID"], Context: "Context" }, outputs: { onCellGeneration: "onCellGeneration" }, ngImport: i0, template: "<div class=\"td-content\" [class.td-error]=\"!!ValidationError\" [matTooltip]=\"ValidationError\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".td-error{background-color:#f003;box-shadow:inset 0 0 0 1px red}.td-content{padding:.3rem;margin:-.3rem;box-sizing:border-box!important}\n"], directives: [{ type: i1$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTd, decorators: [{
3185
3758
  type: Component,
3186
- args: [{ selector: "[es-td]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>\r\n <ng-content></ng-content>\r\n</span>" }]
3187
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i1$1.DomSanitizer }]; }, propDecorators: { ID: [{
3759
+ args: [{ selector: "[es-td]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"td-content\" [class.td-error]=\"!!ValidationError\" [matTooltip]=\"ValidationError\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".td-error{background-color:#f003;box-shadow:inset 0 0 0 1px red}.td-content{padding:.3rem;margin:-.3rem;box-sizing:border-box!important}\n"] }]
3760
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { ID: [{
3188
3761
  type: Input,
3189
3762
  args: ['es-td']
3190
- }], Internal: [{
3191
- type: Input
3192
- }], RouterLink: [{
3193
- type: Input
3194
- }], Display: [{
3195
- type: Input
3196
- }], Template: [{
3197
- type: Input
3198
3763
  }], Context: [{
3199
3764
  type: Input
3200
- }], Visible: [{
3201
- type: Input
3765
+ }], onCellGeneration: [{
3766
+ type: Output
3202
3767
  }] } });
3203
3768
 
3769
+ // Angular
3770
+ class EstLookupPipe {
3771
+ transform(value, source) {
3772
+ for (let i = 0; i < source.length; i++) {
3773
+ if (source[i].id == value)
3774
+ return source[i];
3775
+ }
3776
+ return { id: "", description: "" };
3777
+ }
3778
+ }
3779
+ EstLookupPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3780
+ EstLookupPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, name: "est_lookup" });
3781
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, decorators: [{
3782
+ type: Pipe,
3783
+ args: [{ name: 'est_lookup' }]
3784
+ }] });
3785
+
3786
+ class EstRouterLinkPipe {
3787
+ constructor() {
3788
+ /** Cache per i routerLink generati nelle tabelle dinamiche */
3789
+ this.routerLinksCache = {};
3790
+ }
3791
+ transform(item, path, parameters) {
3792
+ if (this.routerLinksCache[item._hash + path]) {
3793
+ return this.routerLinksCache[item._hash + path];
3794
+ }
3795
+ else {
3796
+ let link = this.getRouterLink(path, parameters, item);
3797
+ this.routerLinksCache[item._hash + path] = link;
3798
+ return link;
3799
+ }
3800
+ }
3801
+ /**
3802
+ * Crea un router link
3803
+ *
3804
+ * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
3805
+ * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
3806
+ * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
3807
+ * @param {any} item Oggetto collegato a questo contesto. Può essere un oggetto generico (con "properties") o un oggetto ben definito
3808
+ *
3809
+ * @returns {any} Router link generato in base al parametri
3810
+ */
3811
+ getRouterLink(path, pars, item) {
3812
+ for (let i = 0; i < pars.length; i++)
3813
+ path = path.replace('{' + i + '}', item.properties ? item.properties[pars[i]] : item[pars[i]]);
3814
+ path = path.replace(/'/g, '"').replace(/ /g, '');
3815
+ return JSON.parse(path);
3816
+ }
3817
+ }
3818
+ EstRouterLinkPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3819
+ EstRouterLinkPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, name: "est_routerlink" });
3820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, decorators: [{
3821
+ type: Pipe,
3822
+ args: [{ name: 'est_routerlink' }]
3823
+ }] });
3824
+
3825
+ // Angular
3826
+ class EstFormatPipe {
3827
+ constructor(dates) {
3828
+ this.dates = dates;
3829
+ }
3830
+ transform(value, format) {
3831
+ if (!format) {
3832
+ // Se è un formato data mi assicuro di non stampare mai una data 00:00:00 altrimenti in esportazione viene uno schifo
3833
+ return value ? this.dates.trimSeconds(value.toString()) : "";
3834
+ }
3835
+ else {
3836
+ // Caso formato numerico
3837
+ if (format.startsWith("F")) {
3838
+ if (!value)
3839
+ return "";
3840
+ if (format.length != 2)
3841
+ return value.toString().replace(/,/, "").replace(".", ",");
3842
+ else {
3843
+ let tmp = parseFloat(value);
3844
+ let cifre = parseInt(format[1]);
3845
+ if (isNaN(tmp) || isNaN(cifre))
3846
+ return "";
3847
+ return (Math.trunc(tmp * Math.pow(10, cifre)) / Math.pow(10, cifre)).toString();
3848
+ }
3849
+ }
3850
+ else {
3851
+ // Se ho un formato data trasformo in dayjs, formatto ed esporto
3852
+ // Per la trasformazione in dayjs provo prima a passargli la stringa di netto, sperando la riconosca
3853
+ // Se non funziona provo a definirgli la formattazione standard del metering per quel linguaggio
3854
+ return this.dates.getFormatted(value, format.length <= 10, format.length > 16);
3855
+ }
3856
+ }
3857
+ }
3858
+ }
3859
+ EstFormatPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, deps: [{ token: i5.DateService }], target: i0.ɵɵFactoryTarget.Pipe });
3860
+ EstFormatPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, name: "est_format" });
3861
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, decorators: [{
3862
+ type: Pipe,
3863
+ args: [{ name: 'est_format' }]
3864
+ }], ctorParameters: function () { return [{ type: i5.DateService }]; } });
3865
+
3866
+ // Angular
3867
+ class EstRendererPipe {
3868
+ constructor(logger) {
3869
+ this.logger = logger;
3870
+ }
3871
+ transform(propName, params) {
3872
+ var EsTd = null;
3873
+ // Perf. Version di `params.src.find((item) => params.name ? item.td === params.name : item.tdForProperty === propName);`
3874
+ for (let i = 0; i < params.src.length; i++) {
3875
+ let item = params.src.get(i);
3876
+ if (params.name && item.td === params.name ||
3877
+ !params.name && item.tdForProperty === propName) {
3878
+ EsTd = item;
3879
+ break;
3880
+ }
3881
+ }
3882
+ // Name non trovato, fallback al nome della colonna
3883
+ if (propName && params.name && !EsTd) {
3884
+ this.logger.log(`Renderer retrieved in a non performant way`);
3885
+ EsTd = params.src.find((item) => item.tdForProperty === propName);
3886
+ }
3887
+ this.logger.log(`Renderer ${EsTd ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!EsTd ? '. Using fallback renderer' : ''}`);
3888
+ var ret = EsTd ? EsTd.Template : params.fallback;
3889
+ return ret;
3890
+ }
3891
+ }
3892
+ EstRendererPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, deps: [{ token: Logger }], target: i0.ɵɵFactoryTarget.Pipe });
3893
+ EstRendererPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, name: "est_renderer" });
3894
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, decorators: [{
3895
+ type: Pipe,
3896
+ args: [{ name: 'est_renderer' }]
3897
+ }], ctorParameters: function () { return [{ type: Logger }]; } });
3898
+
3899
+ // Angular
3900
+ class EstEditorPipe {
3901
+ constructor(logger) {
3902
+ this.logger = logger;
3903
+ }
3904
+ transform(propName, params) {
3905
+ var Editor = null;
3906
+ // Perf. Version di `params.src.find((item) => params.name ? item.editor === params.name : item.editorForProperty === propName);`
3907
+ for (let i = 0; i < params.src.length; i++) {
3908
+ let item = params.src.get(i);
3909
+ if (params.name && item.editor === params.name ||
3910
+ !params.name && item.editorForProperty === propName) {
3911
+ Editor = item;
3912
+ break;
3913
+ }
3914
+ }
3915
+ // Name non trovato, fallback al nome della colonna
3916
+ if (propName && params.name && !Editor) {
3917
+ this.logger.log(`Editor retrieved in a non performant way`);
3918
+ Editor = params.src.find((item) => item.editorForProperty === propName);
3919
+ }
3920
+ this.logger.log(`Editor ${Editor ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!Editor ? '. Using fallback editor' : ''}`);
3921
+ var ret = Editor ? Editor.Template : params.fallback;
3922
+ return ret;
3923
+ }
3924
+ }
3925
+ EstEditorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, deps: [{ token: Logger }], target: i0.ɵɵFactoryTarget.Pipe });
3926
+ EstEditorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, name: "est_editor" });
3927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, decorators: [{
3928
+ type: Pipe,
3929
+ args: [{ name: 'est_editor' }]
3930
+ }], ctorParameters: function () { return [{ type: Logger }]; } });
3931
+
3204
3932
  /** Raccolta di tutti gli Input dell'EsTable a cui può essere logicamente sensato assegnare default per progetto */
3205
3933
  class EsTableDefaultable {
3206
3934
  }
@@ -3209,7 +3937,7 @@ class EsTableDefaultable {
3209
3937
  /** Componente che permette di rappresentare una griglia di valori */
3210
3938
  class EsTableComponent {
3211
3939
  /** @ignore */
3212
- constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts) {
3940
+ constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts, copyPasteDetector, clipboardService, logger) {
3213
3941
  this.ngControl = ngControl;
3214
3942
  this.prefService = prefService;
3215
3943
  this.deafults = deafults;
@@ -3221,6 +3949,9 @@ class EsTableComponent {
3221
3949
  this.expExts = expExts;
3222
3950
  this.dateExts = dateExts;
3223
3951
  this.msgExts = msgExts;
3952
+ this.copyPasteDetector = copyPasteDetector;
3953
+ this.clipboardService = clipboardService;
3954
+ this.logger = logger;
3224
3955
  /** Subject utilizzato internamente lato EsTable per causare il Focus lato componente di Input */
3225
3956
  this.FocusSubject = new Subject();
3226
3957
  /** Se vengono effettuati 2 click a distanza inferiore a questi Millisecondi viene considerato un doppio click */
@@ -3246,9 +3977,9 @@ class EsTableComponent {
3246
3977
  this.boundSource = [];
3247
3978
  /** Stessa cosa della **boundSource**, utilizzata come appoggio temporaneo interno */
3248
3979
  this.TMPBoundSource = [];
3249
- /** "Fetta" di oggetti utilizzata nell'endless scroll, ogni elemento di questo array è un blocchetto di 100 elementi */
3980
+ /** @deprecated "Fetta" di oggetti utilizzata nell'endless scroll, ogni elemento di questo array è un blocchetto di 100 elementi */
3250
3981
  this.boundSubSources = [];
3251
- /** Questa funge da indicatore per gli slice inseriti, la lunghezza dovrebbe essere corrispondente a **boundSubSources** */
3982
+ /** @deprecated Questa funge da indicatore per gli slice inseriti, la lunghezza dovrebbe essere corrispondente a **boundSubSources** */
3252
3983
  this.addedSlices = [];
3253
3984
  /** Variabile che identifica il valore del "seleziona Tutto" nella paginazione */
3254
3985
  this.defaultAllPageOverride = 999999;
@@ -3258,20 +3989,20 @@ class EsTableComponent {
3258
3989
  this.seconds = '10';
3259
3990
  /** Impostata a true ogni volta che viene avviata una ricerca, e a false ogni volta che un nuovo valore viene ricevuto */
3260
3991
  this.researchInProgress = false;
3261
- /** Modello rappresentante un dizionario di righe della tabella, con chiave l'hash e valore la lista di celle */
3262
- this.RowTDs = null;
3263
3992
  /** Modello di appoggio temporaneo per i **RowTDs** */
3264
3993
  this.TMPRowTDs = null;
3265
- /** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
3266
- this.RowTHs = null;
3994
+ /** Modello rappresentante un dizionario di righe della tabella, con chiave l'hash e valore la lista di celle */
3995
+ this.RowTDs = null;
3996
+ /** Indica se **RowTDs** è un oggetto vuoto o meno */
3997
+ this.EmptyRowTds = true;
3267
3998
  /** Modello di appoggio temporaneo per i **RowTHs** */
3268
3999
  this.TMPRowTHs = null;
4000
+ /** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
4001
+ this.RowTHs = null;
3269
4002
  /** Modello di appoggio temporaneo per i **RowThGroups** */
3270
4003
  this.TMPRowThGroups = null;
3271
4004
  /** Modello rappresentante un singolo header group della tabella. Questa lista è già ordinata e pronta per essere utilizzata in ngFor */
3272
4005
  this.RowThGroups = null;
3273
- /** Cache per i routerLink generati nelle tabelle dinamiche */
3274
- this.DynamicTableRouterLinkCache = {};
3275
4006
  /**
3276
4007
  * Lista dei contesti. Un contesto non è altro che un hash particolare calcolato su un oggetto che identifica univocamente tale oggetto.
3277
4008
  *
@@ -3282,6 +4013,19 @@ class EsTableComponent {
3282
4013
  this.OrderDirectives = [];
3283
4014
  /** Codice dell'ultimo oggetto solezionato */
3284
4015
  this.lastSelectedItemID = null;
4016
+ /**
4017
+ * Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
4018
+ *
4019
+ * 1) Ordinamento e visibilità delle colonne
4020
+ *
4021
+ * 2) Ordinamento dei dati
4022
+ *
4023
+ * 3) Modalità Gerarchica
4024
+ *
4025
+ * ecc...
4026
+ * viene dedotto dal sistema in automatico
4027
+ */
4028
+ this.UseCustomCells = null;
3285
4029
  /**
3286
4030
  * Indica se oltre alle colonne dinamiche specifiche di un tipo di oggetto ci sono anche colonne dinamiche aggiunte dall'utente
3287
4031
  *
@@ -3304,18 +4048,12 @@ class EsTableComponent {
3304
4048
  this.ColumnsPinnable = null;
3305
4049
  /** Indica se dev'essere disponibile il sistema di aggiornamento automatico */
3306
4050
  this.AutoUpdate = null;
3307
- /**
3308
- * Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
3309
- *
3310
- * 1) Ordinamento e visibilità delle colonne
3311
- *
3312
- * 2) Ordinamento dei dati
3313
- *
3314
- * 3) Modalità Gerarchica
3315
- *
3316
- * ecc...
3317
- */
3318
- this.UseCustomCells = null;
4051
+ /** Indica l'altezza cablata che deve assumere la tabella. Es: "100px" | "100%" ... */
4052
+ this.Height = null;
4053
+ /** Indica il colore di sfondo dello spazio vuoto (non ricoperto da dati). Particolarmente utile da impostare in caso di **Height** diverso da null */
4054
+ this.EmptySpaceBackgroundColor = null;
4055
+ /** Indica se dev'essere l'estable a gestire la ricerca, anche la prima. **/
4056
+ this.EsTableHandledSearch = false;
3319
4057
  /** Permette di impostare l'altezza massima della tabella. Se null la dimensione si adatta al numero di elementi attualmente in visualizzazione */
3320
4058
  this.MaxHeight = null;
3321
4059
  /** Classi da applicare al contenitore della tabella */
@@ -3358,9 +4096,11 @@ class EsTableComponent {
3358
4096
  this.ExportFileName = 'Export.csv';
3359
4097
  /** Classe (HTML) di default della tabella */
3360
4098
  this.TableClass = null;
3361
- /** Indica la presenza di raggruppamenti a livello di header */
4099
+ /** Indica di esportare solo le colonne attualmente visibili della view */
4100
+ this.ExportOnlyVisibleColumns = false;
4101
+ /** @deprecated Indica la presenza di raggruppamenti a livello di header */
3362
4102
  this.HasHeaderGroup = null;
3363
- /** Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
4103
+ /** @deprecated Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
3364
4104
  this.HasSecondaryHeaderGroup = null;
3365
4105
  /** Indica se nascondere gli Header della tabella */
3366
4106
  this.HeaderHidden = null;
@@ -3386,7 +4126,7 @@ class EsTableComponent {
3386
4126
  this.HiddenColumns = null;
3387
4127
  /** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
3388
4128
  this.ColumnsOrdering = null;
3389
- /** Eventuale supporto alle ricerche applicate alla modalità Array */
4129
+ /** @deprecated Eventuale supporto alle ricerche applicate alla modalità Array */
3390
4130
  this.SearchView = null;
3391
4131
  /** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
3392
4132
  this.SelectAll = null;
@@ -3406,6 +4146,8 @@ class EsTableComponent {
3406
4146
  this.StartsExpanded = true;
3407
4147
  /** Indica se effettuare il salvataggio delle preferenze di ricerca */
3408
4148
  this.SavePreferences = null;
4149
+ /** Allineamento di default per celle e headers */
4150
+ this.DefaultAlignment = null;
3409
4151
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
3410
4152
  this.PagingStyle = null;
3411
4153
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
@@ -3417,7 +4159,11 @@ class EsTableComponent {
3417
4159
  /** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
3418
4160
  this.ShowItemGroupsColumns = null;
3419
4161
  /** Indica che tutti i campi che definiscono le modalità di modifica campo possono essere modificati in base alle impostazioni */
3420
- this.UserEdits = false;
4162
+ this.Editable = false;
4163
+ /** Indica se è possibile effettuare selezioni a range per poi farci eventualmente copia incolla */
4164
+ this.RangeSelection = false;
4165
+ /** Indica il numero di millisecondi per cui debouncare il writeValue per la modalità **EsTableHandledSearch** */
4166
+ this.SearchThrottle = 50;
3421
4167
  /** Evento che viene richiamato al cambio di oridnamento di una colonna */
3422
4168
  this.onOrderChanged = new EventEmitter();
3423
4169
  /**
@@ -3436,6 +4182,10 @@ class EsTableComponent {
3436
4182
  this.onRemoval = new EventEmitter();
3437
4183
  /** Evento richiamato all'annullamento di un'eliminazione */
3438
4184
  this.onAbortRemoval = new EventEmitter();
4185
+ /** Evento richiamato alla modifica dei modelli bindati */
4186
+ this.onModelChange = new EventEmitter();
4187
+ /** Evento richiamato all'apertura del menù contestuale */
4188
+ this.onOpenContextMenu = new EventEmitter();
3439
4189
  /** Evento richiamato quando si clicca su un opzione definita nelle **CornerMenuOptions** */
3440
4190
  this.onCornerAction = new EventEmitter();
3441
4191
  /** Evento richiamato quando si clicca su un opzione definita nelle **DynamicOperations** */
@@ -3486,12 +4236,47 @@ class EsTableComponent {
3486
4236
  this.ArrayGrouping = false;
3487
4237
  /** Indica che l'es-table è basata sulle direttive (nuova modalità) */
3488
4238
  this.DirectivesBased = false;
4239
+ /** Indica lo stato di selezione per singola cella */
4240
+ this.selectionStatus = {};
4241
+ /** Chiamata reale al writeValue dopo il passaggio di **SearchThrottle** millisecondi. Solo modalità EsTableHandledSearch */
4242
+ this.callTimeout = null;
4243
+ /** Cache dei th piuttosto che ricalcolarseli di continuo */
4244
+ this.thsCache = {};
4245
+ /** Indica quando la cache dei th è stata fillata almeno la prima volta */
4246
+ this.thsCacheSet = false;
4247
+ /**
4248
+ * Flag che, se **true**, per un giro di binding mantiene la visibilità impostata localmente, piuttosto che allineare alla View bindata.
4249
+ * Usata per modificare in maniera programmatica la visibilità delle colonne dal metodo **setHeaderVisibility**,
4250
+ *
4251
+ * Disclaimer: **NON MODIFICARE**
4252
+ **/
4253
+ this.useLocalVisibility = false;
3489
4254
  /** Opzioni di paginazione */
3490
- this.PagerOptions = { PagerCount: null, ShowCount: true, ShowPaging: true, ShowButtons: true, ShowPagingOptions: true, UsesView: true, View: null, Ready: false, Searches: 'items' };
4255
+ this.PagerOptions = new PagerInfos();
3491
4256
  /** @ignore */
3492
4257
  this.propagateChange = (_) => { };
3493
4258
  /** Funzione di trackby per il body che dovrebbe evitare il 90% delle change detection */
3494
- this.bodyTrackBy = (index, item) => item._hash;
4259
+ this.bodyTrackBy = (_, item) => item._hash;
4260
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo id */
4261
+ this.idTrackBy = (_, item) => item.id;
4262
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo PropertyName */
4263
+ this.PropertyNameTrackBy = (_, item) => item.PropertyName;
4264
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
4265
+ this.IDTrackBy = (_, item) => item.ID;
4266
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
4267
+ this.valTrackBy = (_, item) => item.val;
4268
+ // Range selection Experimentals
4269
+ this.mouseIsDown = false;
4270
+ this.rangeSelected = false;
4271
+ this.rangeStartWasIgnored = false;
4272
+ this.firstCoordinates = null;
4273
+ //* Piango
4274
+ this.EsTdsCache = {};
4275
+ // Copia e incolla si effettuano solo se la tabella attuale è univocamente selezionata
4276
+ this.copySubscription = this.copyPasteDetector.OnCopy.subscribe(() => { if (this.copyPasteDetector.ActiveEstReference == this)
4277
+ this.handleCopy(); });
4278
+ this.pasteSubscription = this.copyPasteDetector.OnPaste.subscribe(() => { if (this.copyPasteDetector.ActiveEstReference == this)
4279
+ this.handlePaste(); });
3495
4280
  this.export_H = new ExportHandler(this, this.expExts, this.msgExts, this.utiExts, this.dateExts);
3496
4281
  this.rowGrouping_H = new RowGroupingHandler(this, this.utilities_H, this.dateExts);
3497
4282
  this.columnMetadata_H = new ColumnMetadataHandler(this, this.utilities_H, this.utiExts, this.prefService, this.rowGrouping_H);
@@ -3520,6 +4305,7 @@ class EsTableComponent {
3520
4305
  this.ShowItemGroupsColumns = this.utilities_H.InputOrDefault(this.ShowItemGroupsColumns, this.deafults?.ShowItemGroupsColumns, false);
3521
4306
  this.ArraymodeItemsPerPage = this.utilities_H.InputOrDefault(this.ArraymodeItemsPerPage, this.deafults?.ArraymodeItemsPerPage, 15);
3522
4307
  this.ColumnsPinnable = this.utilities_H.InputOrDefault(this.ColumnsPinnable, this.deafults?.ColumnsPinnable, true);
4308
+ this.DefaultAlignment = this.utilities_H.InputOrDefault(this.DefaultAlignment, this.deafults?.DefaultAlignment, 'Left');
3523
4309
  }
3524
4310
  /** @ignore */
3525
4311
  ngOnInit() {
@@ -3530,6 +4316,7 @@ class EsTableComponent {
3530
4316
  return;
3531
4317
  let shouldEmit = !t.item._selected;
3532
4318
  t.item._selected = true;
4319
+ this.selection_H.clearSelectionStatusExcluding(null);
3533
4320
  var itemSelection = this.selection_H.handleItemsSelection([t.item]);
3534
4321
  this.changed();
3535
4322
  if (shouldEmit)
@@ -3540,7 +4327,9 @@ class EsTableComponent {
3540
4327
  ngAfterViewInit() {
3541
4328
  // Se utilizzo la new spicy mode deduco tutti i parametri di lavoro possibili al caricamento della tabella
3542
4329
  // Vengono sovrascritte solo le proprietà non impostate dall'utente
3543
- let usesThsAndTdsDirectives = this.EsTdsDirective && this.EsTdsDirective.length > 0 && this.EsThsDirective && this.EsThsDirective.length > 0;
4330
+ let tdsD = this.EsTdsDirective.length == 0 ? this.EsTableTemplate?.Template?.EsTdsDirective?.length > 0 ? this.EsTableTemplate?.Template?.EsTdsDirective : this.EsTdsDirective : this.EsTdsDirective;
4331
+ let thsD = this.EsThsDirective.length == 0 ? this.EsTableTemplate?.Template?.EsThsDirective?.length > 0 ? this.EsTableTemplate?.Template?.EsThsDirective : this.EsThsDirective : this.EsThsDirective;
4332
+ let usesThsAndTdsDirectives = tdsD && tdsD.length > 0 && thsD && thsD.length > 0;
3544
4333
  let hasNoContentProjection = !this.bodyRef && !this.headerRef && !this.headerGroupRef && !this.secondaryHeaderGroupRef;
3545
4334
  if (usesThsAndTdsDirectives || hasNoContentProjection) {
3546
4335
  if (this.UseCustomCells == null)
@@ -3564,24 +4353,40 @@ class EsTableComponent {
3564
4353
  }
3565
4354
  /** @ignore */
3566
4355
  ngOnDestroy() {
4356
+ if (this.copySubscription)
4357
+ this.copySubscription.unsubscribe();
4358
+ if (this.pasteSubscription)
4359
+ this.pasteSubscription.unsubscribe();
3567
4360
  if (this.ctxMenuSubscription)
3568
4361
  this.ctxMenuSubscription.unsubscribe();
4362
+ if (this.copyPasteDetector.ActiveEstReference == this)
4363
+ this.copyPasteDetector.ActiveEstReference = null;
3569
4364
  }
3570
4365
  /** @ignore */
3571
4366
  async ngOnChanges(changes) {
3572
4367
  let newSearchView = changes['SearchView'];
3573
4368
  if (newSearchView && this.SearchView)
3574
- this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
4369
+ this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.objectcount, this.SearchView.itemsperpageoverride);
3575
4370
  }
3576
4371
  /** @ignore */
3577
4372
  registerOnChange(fn) { this.propagateChange = fn; }
3578
4373
  /** @ignore */
3579
4374
  registerOnTouched(fn) { }
3580
4375
  /** @ignore */
3581
- changed() { this.propagateChange(this.View); }
4376
+ changed(clearItems = false) {
4377
+ if (clearItems && this.viewMode)
4378
+ this.View.items = [];
4379
+ this.propagateChange(this.View);
4380
+ }
3582
4381
  /** @ignore */
3583
- async writeValue(obj) {
4382
+ async writeValue(obj, throttle = true) {
3584
4383
  this.View = obj ? obj : null;
4384
+ if (this.EsTableHandledSearch && throttle) {
4385
+ if (this.callTimeout)
4386
+ clearTimeout(this.callTimeout);
4387
+ this.callTimeout = setTimeout(() => { this.writeValue(obj, false); }, this.SearchThrottle);
4388
+ return;
4389
+ }
3585
4390
  // Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
3586
4391
  this.researchInProgress = false;
3587
4392
  if (!this.View && !this.SearchView) {
@@ -3635,16 +4440,29 @@ class EsTableComponent {
3635
4440
  }
3636
4441
  // In modalità report devo controllare che tutte le colonne salvate facciano parte della vista
3637
4442
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3638
- // sto facendo riferimento a una versione vecchia dell'es-table, quindi non foccio operazioni
4443
+ // sto facendo riferimento a una versione vecchia dell'es-table, quindi non faccio operazioni
3639
4444
  for (let i = 0; i < source.length; i++) {
3640
4445
  if (repository.indexOf(source[i]) == -1) {
3641
4446
  updatedPrefs = false;
3642
4447
  break;
3643
4448
  }
3644
4449
  }
4450
+ // Se mi baso su direttive ma nelle preference è presente anche solo una colonna non presente nelle direttive
4451
+ // vuol dire che l'es-table è cambiata quindi non imposto preference
4452
+ if (this.EsThsDirective?.length > 0) {
4453
+ for (let i = 0; i < repository.length; i++) {
4454
+ if (this.thsCacheSet && !this.thsCache[repository[i]]) {
4455
+ updatedPrefs = false;
4456
+ break;
4457
+ }
4458
+ }
4459
+ }
3645
4460
  if (updatedPrefs) {
3646
4461
  this.View.columns = prefs?.columns || [];
3647
4462
  this.View.column_ordering = prefs?.column_ordering || [];
4463
+ // Se le pref sono nulle non sovrascrivo gli ordini dato che potrebbe servire mettere degli ordinamenti di default lato ts
4464
+ if (prefs)
4465
+ this.View.orders = prefs?.orders || [];
3648
4466
  }
3649
4467
  }
3650
4468
  }
@@ -3680,7 +4498,10 @@ class EsTableComponent {
3680
4498
  repository = cols;
3681
4499
  source = this.View.columns;
3682
4500
  }
3683
- // In modalità report devo controllare che tutte le colonne salvate facciano parte della vista
4501
+ // In modalità report aggiorno le preferenze solo se c'è almeno una colonna, altrimenti vuol dire che si parte da vuoti
4502
+ // con tutte le colonne disponibili
4503
+ if (this.View.report_columns && (source?.length || 0) == 0)
4504
+ updatedPrefs = false;
3684
4505
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3685
4506
  // sto facendo riferimento a una versione vecchia dell'es-table, quindi non foccio operazioni
3686
4507
  for (let i = 0; i < source.length; i++) {
@@ -3692,6 +4513,9 @@ class EsTableComponent {
3692
4513
  if (updatedPrefs) {
3693
4514
  this.View.columns = prefs?.columns || [];
3694
4515
  this.View.column_ordering = prefs?.column_ordering || [];
4516
+ // Se le pref sono nulle non sovrascrivo gli ordini dato che potrebbe servire mettere degli ordinamenti di default lato ts
4517
+ if (prefs)
4518
+ this.View.orders = prefs?.orders || [];
3695
4519
  }
3696
4520
  }
3697
4521
  }
@@ -3700,6 +4524,15 @@ class EsTableComponent {
3700
4524
  }
3701
4525
  this.finalizeContext();
3702
4526
  this.postBoundSourceCalculation();
4527
+ if (this.View && !this.View.selfsearch && this.EsTableHandledSearch) {
4528
+ this.View.selfsearch = true;
4529
+ this.changed(true);
4530
+ this.onSearchRequest.emit(false);
4531
+ }
4532
+ else if (this.View && this.View.selfsearch && this.EsTableHandledSearch) {
4533
+ this.View.selfsearch = false;
4534
+ this.changed();
4535
+ }
3703
4536
  }
3704
4537
  /**
3705
4538
  * Successivamente al bind del nuovo input questa funzione si occupa di finalizzare tutti i parametri di funzionamento dell'es-table
@@ -3707,7 +4540,7 @@ class EsTableComponent {
3707
4540
  */
3708
4541
  finalizeContext() {
3709
4542
  let viewCasted = this.View;
3710
- let hasRowGroups = (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
4543
+ let hasRowGroups = viewCasted && (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
3711
4544
  // Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
3712
4545
  if (this.arrayMode && hasRowGroups)
3713
4546
  this.UseArrayModePaging = false;
@@ -3751,7 +4584,7 @@ class EsTableComponent {
3751
4584
  this.PagerOptions.PagerCount = this.View.length || 0;
3752
4585
  this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && (this.View.length > 10 || (this.SearchView?.objectcount || 0) > 10);
3753
4586
  this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
3754
- this.PagerOptions.ShowPaging = this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount;
4587
+ this.PagerOptions.ShowPaging = this.PagerOptions.ShowPaging && (this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount);
3755
4588
  this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
3756
4589
  }
3757
4590
  else if (this.viewMode) {
@@ -3779,10 +4612,13 @@ class EsTableComponent {
3779
4612
  /** Per poter distinguere le chiamate a questo metodo: Dopo il setTimeout se uso gli EsTd/EsTh vecchi, senza il setTimeout se uso le nuove direttive */
3780
4613
  internalPostBoundSource() {
3781
4614
  let View = this.View;
3782
- let ths = this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
3783
- let tds = this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
4615
+ let tdsD = this.EsTdsDirective.length == 0 ? this.EsTableTemplate?.Template?.EsTdsDirective?.length > 0 ? this.EsTableTemplate?.Template?.EsTdsDirective : this.EsTdsDirective : this.EsTdsDirective;
4616
+ let thsD = this.EsThsDirective.length == 0 ? this.EsTableTemplate?.Template?.EsThsDirective?.length > 0 ? this.EsTableTemplate?.Template?.EsThsDirective : this.EsThsDirective : this.EsThsDirective;
4617
+ let ths = thsD && thsD.length > 0 ? thsD.toArray() : [];
4618
+ let tds = tdsD && tdsD.length > 0 ? tdsD.toArray() : [];
3784
4619
  // Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
3785
4620
  this.dynamicMode_H.eventuallyReviewDynamicColumns();
4621
+ // Gestisce la richiesta per gruppi o per singoli oggetti
3786
4622
  this.bindDisplayToLoadedItemsOrGroups(View);
3787
4623
  // Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
3788
4624
  this.setupPagingInformations();
@@ -3793,22 +4629,34 @@ class EsTableComponent {
3793
4629
  let si = this.viewMode ? view.selection : this.arraymodeSelection;
3794
4630
  // N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
3795
4631
  // ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
3796
- // Espando i th e i td multipli duplicandoli
3797
- let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
3798
- ths = ret.expThs;
3799
- tds = ret.expTds;
4632
+ // Se ho definizioni dinamiche, prima di qualsiasi altra cosa devo trasformarle in th/td in modo che poi il codice qui sotto faccia le sue magie
4633
+ if (this.DynamicRowColumnsDefinition?.length > 0) {
4634
+ this.logger.log("Generating ths and tds from Dynamic definition");
4635
+ let ret = this.dynamicMode_H.emitThsAndTdsBasedOnDynamicDefinition();
4636
+ ths = ret.ths;
4637
+ tds = ret.tds;
4638
+ }
3800
4639
  // Gestione delle view in modalità report, i th e i td vengono rigenerati dalle configurazioni della view
3801
4640
  if (!this.arrayMode && view.report_columns) {
4641
+ this.logger.log("Generating ths and tds from report results");
3802
4642
  let ret = this.reportMode_H.generateThsAndTdsFromView(view);
3803
4643
  ths = ret.ths;
3804
4644
  tds = ret.tds;
3805
4645
  }
4646
+ // Espando i th e i td multipli duplicandoli
4647
+ let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
4648
+ ths = ret.expThs;
4649
+ tds = ret.expTds;
4650
+ // Genero la cache dei th da usare da qui in poi, dopo avergli lasciato fare le sue cose in caso ci siano dei multi o dei report
4651
+ for (let i = 0; i < ths.length; i++) {
4652
+ let th = ths[i];
4653
+ this.thsCache[th.th] = th;
4654
+ }
4655
+ this.thsCacheSet = true;
3806
4656
  // Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
3807
4657
  let hI = this.columnMetadata_H.evaluateHeadersGroupingInfos(ths);
3808
- if (this.arrayMode) { // In modalità array non ho un backend...
3809
- this.items_H.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
4658
+ if (this.arrayMode) // In modalità array non ho un backend...
3810
4659
  this.rowGrouping_H.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
3811
- }
3812
4660
  this.columnMetadata_H.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
3813
4661
  this.columnMetadata_H.alignColumnsIfLoadedView(view); // Se sto caricando una View da hotpotato (quindi con savedstate = true) riallineo la visibilità delle colonne e il loro ordine.
3814
4662
  this.columnMetadata_H.moveFixedColumnsAtTheBeginning(hI.leafs, tds); // Sposto tutte le cose fixed all'inizio in modo che la creazione di th e td sia più snella (Utilizza le ColumnsList, quindi dev'essere richiamata PIRMA di reviewColumnsList)
@@ -3824,6 +4672,8 @@ class EsTableComponent {
3824
4672
  this.columnMetadata_H.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
3825
4673
  this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
3826
4674
  this.selection_H.evaluateSelection(itemsAndGroups, si); // Riallineo le info di selezione degli elementi della View
4675
+ // Valuta lo stato iniziale di selezione a range
4676
+ this.selection_H.evaluateSingleCellSelection(itemsAndGroups, hI.leafs, this.DynamicRowColumnsDefinition);
3827
4677
  if (this.ResearchNeeded) {
3828
4678
  this.changed();
3829
4679
  this.emitSearchRequest(false);
@@ -3940,7 +4790,13 @@ class EsTableComponent {
3940
4790
  viewOverride.internalsearchrequest = true;
3941
4791
  }
3942
4792
  this.researchInProgress = true;
3943
- this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
4793
+ if (this.View && !this.View.selfsearch && this.EsTableHandledSearch) {
4794
+ this.View.selfsearch = true;
4795
+ this.changed(true);
4796
+ this.onSearchRequest.emit(false);
4797
+ }
4798
+ else
4799
+ this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
3944
4800
  }
3945
4801
  /**
3946
4802
  * Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
@@ -3955,16 +4811,11 @@ class EsTableComponent {
3955
4811
  evaluateRowTds(ths, tds) {
3956
4812
  if (tds.length == 0)
3957
4813
  return;
3958
- let thsCache = {};
3959
4814
  let columnsCache = {};
3960
4815
  for (let coli = 0; coli < this.ColumnsList.length; coli++) {
3961
4816
  let col = this.ColumnsList[coli];
3962
4817
  columnsCache[col.id] = col;
3963
4818
  }
3964
- for (let i = 0; i < ths.length; i++) {
3965
- let th = ths[i];
3966
- thsCache[th.th] = th;
3967
- }
3968
4819
  this.TMPRowTDs = {};
3969
4820
  // Variabile d'appoggio per permettermi di inserire tutte le colonne "Fixed" davanti
3970
4821
  let contextFixeds = {};
@@ -3974,22 +4825,54 @@ class EsTableComponent {
3974
4825
  let item = this.boundSource[i];
3975
4826
  let ctx = item._hash;
3976
4827
  let key = td.td;
3977
- let th = thsCache[td.td];
3978
- let drcd = this.DynamicRowColumnsDefinition;
4828
+ let th = this.thsCache[td.td];
3979
4829
  if (!!th)
3980
4830
  th._referenced = true;
3981
- else if (!drcd || !drcd.find(t => t.propertyName == td.td)) {
3982
- let subject = drcd && drcd.length > 0 ? "le colonne dinamiche specificate" : "gli ID dicharati negli EsTh";
3983
- console.error(`ID dell'oggeto EsTd non compatibile con ${subject} ${td.td}`);
3984
- return;
3985
- }
3986
4831
  // Skippare senza th (casistica tabella dinamica)
3987
- if (th && (td.tdIf || th.thGroup)) {
4832
+ if (th && th.thIf && (td.tdIf || th.thGroup)) {
3988
4833
  let thCasted = th;
3989
4834
  let isFixed = th.thFixed || th.thGroup || th.thPinned;
3990
4835
  let itemToAdd = item._item ?
3991
- { LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: false, GroupAggregation: false, Visible: columnsCache[td.td].visible, Wraps: false, Class: td.tdClass, Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template, Multi: td._multi, MultiProp: td._multi ? td.td.split('_')[0] : null, MultiIndex: td._multi ? td.td.split('_')[1] : null, UserEdits: th.thUserEdits, PropAccessor: td.tdPropertyAccessor } :
3992
- { LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: thCasted.thGroup, GroupAggregation: !!thCasted.thAggregation, Visible: columnsCache[td.td].visible, Wraps: false, Class: thCasted.thGroupClass || '', Content: this.rowGrouping_H.getGroupCellDisplay(item, key, th) };
4836
+ {
4837
+ LeftBorder: thCasted._lbord,
4838
+ RightBorder: thCasted._rbord,
4839
+ ID: key,
4840
+ Pinned: columnsCache[td.td].pinned,
4841
+ PinnedWidth: thCasted.thPinnedWidth,
4842
+ GroupHeader: false,
4843
+ GroupAggregation: false,
4844
+ Visible: columnsCache[td.td].visible,
4845
+ Wraps: false,
4846
+ Class: td.tdClass,
4847
+ IconClass: td.tdIconClass,
4848
+ ConditionField: td.tdConditionField,
4849
+ ConditionValue: td.tdConditionValue,
4850
+ Title: td.tdTitle,
4851
+ Content: td.tdContent,
4852
+ Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template,
4853
+ Multi: td._multi,
4854
+ MultiProp: td._multi ? td.td.split('_')[0] : null,
4855
+ MultiIndex: td._multi ? td.td.split('_')[1] : null,
4856
+ Alignment: (td.tdAlignment || th.thAlignment || this.DefaultAlignment).toLowerCase(),
4857
+ Format: td.tdFormat || th.thFormat,
4858
+ PropertyName: th.thProperty,
4859
+ PropertyType: th.thType,
4860
+ PropertySource: th.thSource,
4861
+ PropAccessor: td.tdPropertyAccessor
4862
+ } :
4863
+ {
4864
+ LeftBorder: thCasted._lbord,
4865
+ RightBorder: thCasted._rbord,
4866
+ ID: key,
4867
+ Pinned: columnsCache[td.td].pinned,
4868
+ PinnedWidth: thCasted.thPinnedWidth,
4869
+ GroupHeader: thCasted.thGroup,
4870
+ GroupAggregation: !!thCasted.thAggregation,
4871
+ Visible: columnsCache[td.td].visible,
4872
+ Wraps: false,
4873
+ Class: thCasted.thGroupClass || '',
4874
+ Content: this.rowGrouping_H.getGroupCellDisplay(item, key, th)
4875
+ };
3993
4876
  if (this.TMPRowTDs[ctx]) {
3994
4877
  this.TMPRowTDs[ctx].push(itemToAdd);
3995
4878
  }
@@ -4039,8 +4922,26 @@ class EsTableComponent {
4039
4922
  let th = ths[i];
4040
4923
  let toAdd;
4041
4924
  if (th.thIf || th.thGroup) {
4042
- let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
4043
- toAdd = { Pinned: columnsListCache[th.th].pinned, Fixed: th.thFixed, PinnedWidth: th.thPinnedWidth, ID: th.th, Visible: th.thVisible, Class: thClass, Order: th.thOrder, Orderable: th.thOrderable, Template: th.Template, Content: th.thStaticContent, Wrap: th.thWrap, LeftBorder: th._lbord, RightBorder: th._rbord, Multi: th._multi, MultiContent: th._multi_content };
4925
+ let thClass = (th.thClass || "") + (th.thShrink ? " app-col-min" : "") + (th.thGroup ? " est-col-min" : "");
4926
+ toAdd = {
4927
+ Pinned: columnsListCache[th.th].pinned,
4928
+ Fixed: th.thFixed,
4929
+ PinnedWidth: th.thPinnedWidth,
4930
+ ID: th.th,
4931
+ Visible: th.thVisible,
4932
+ Class: thClass,
4933
+ Order: th.thOrder,
4934
+ Orderable: th.thOrderable,
4935
+ Template: th.Template,
4936
+ Alignment: (th.thAlignment || this.DefaultAlignment).toLowerCase(),
4937
+ // Se non è nessun contenuto né nessun template mostro semplicemente l'ID dell'header
4938
+ Content: th.thStaticContent != null ? th.thStaticContent : th.Template ? '' : th.th,
4939
+ Wrap: th.thWrap,
4940
+ LeftBorder: th._lbord,
4941
+ RightBorder: th._rbord,
4942
+ Multi: th._multi,
4943
+ MultiContent: th._multi_content
4944
+ };
4044
4945
  this.TMPRowTHs.push(toAdd);
4045
4946
  // Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
4046
4947
  // li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
@@ -4079,6 +4980,8 @@ class EsTableComponent {
4079
4980
  this.emitSearchRequest(false, appSearchElement);
4080
4981
  }
4081
4982
  /**
4983
+ * @TODO Spostare in SelectionHandler
4984
+ *
4082
4985
  * Gestisce i click sulla tabella solo per le righe a gruppo.
4083
4986
  * O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
4084
4987
  *
@@ -4135,6 +5038,7 @@ class EsTableComponent {
4135
5038
  * @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
4136
5039
  */
4137
5040
  globalCheckChanged(forcedVal = null) {
5041
+ this.selection_H.clearSelectionStatusExcluding(null);
4138
5042
  // Prendo tutti gli elementi presenti in questa vista. Se ho gruppi prendo solo i gruppi a livello 0, altrimenti prendo tutti gli oggetti per selezionarli
4139
5043
  let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
4140
5044
  var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
@@ -4142,6 +5046,8 @@ class EsTableComponent {
4142
5046
  this.onSelectionChanged.emit(itemSelection);
4143
5047
  }
4144
5048
  /**
5049
+ * @TODO Spostare in SelectionHandler
5050
+ *
4145
5051
  * Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
4146
5052
  *
4147
5053
  * @param {any} event Evento nativo HTML del click
@@ -4150,12 +5056,8 @@ class EsTableComponent {
4150
5056
  * @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
4151
5057
  */
4152
5058
  handleClick(event, item) {
4153
- // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
4154
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
4155
- return false;
4156
- // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
4157
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
4158
- this.utiExts.clearTextSelection();
5059
+ this.selection_H.clearTextSelection(event);
5060
+ this.selection_H.clearSelectionStatusExcluding(null);
4159
5061
  let selecteditems = [];
4160
5062
  if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
4161
5063
  let startSelecting = false;
@@ -4258,13 +5160,32 @@ class EsTableComponent {
4258
5160
  * Ottiene il contenuto dell'EsTd da utilizzare per la colonna specificata
4259
5161
  *
4260
5162
  * @param {string} column Colonna per cui cercare la cella
5163
+ * @param {string} name Nome diretto per cercare il TD con l'ID. Questa variabile ha priorità rispetto a **column**
4261
5164
  *
4262
5165
  * @returns {TemplateRef<any>} Template da usare per la colonna
4263
5166
  */
4264
- findEsTd(column) {
4265
- var EsTd = this.EsTdsDirective.find((item) => item.td === column);
5167
+ findEsTd(column, name = null) {
5168
+ var EsTd = this.EsTdsDirective.find((item) => name ? item.td === name : item.tdForProperty === column);
5169
+ // Name non trovato, fallback al nome della colonna
5170
+ if (name && column && !EsTd)
5171
+ EsTd = this.EsTdsDirective.find((item) => item.tdForProperty === column);
4266
5172
  return EsTd ? EsTd.Template : null;
4267
5173
  }
5174
+ /**
5175
+ * Ottiene il contenuto dell'editor EsTd da utilizzare per la colonna specificata
5176
+ *
5177
+ * @param {string} column Colonna per cui cercare l'editor
5178
+ * @param {string} name Nome diretto per cercare l'Editor con l'ID. Questa variabile ha priorità rispetto a **column**
5179
+ *
5180
+ * @returns {TemplateRef<any>} Template da usare per la colonna
5181
+ */
5182
+ findEditor(column, name = null) {
5183
+ var Editor = this.EsTdEditorDirectives.find((item) => name ? item.editor === name : item.editorForProperty === column);
5184
+ // Name non trovato, fallback al nome della colonna
5185
+ if (name && column && !Editor)
5186
+ Editor = this.EsTdEditorDirectives.find((item) => item.editorForProperty === column);
5187
+ return Editor ? Editor.Template : null;
5188
+ }
4268
5189
  /**
4269
5190
  * Equivalente del metodo **addToPage** riadattato per la modalità array
4270
5191
  *
@@ -4312,7 +5233,7 @@ class EsTableComponent {
4312
5233
  this.internalWriteCall = false;
4313
5234
  }
4314
5235
  /** Metodo eventualmente richiamabile anche dal componente esterno che permette di forzare un refresh della tabella */
4315
- forceRefresh() {
5236
+ forceRefresh(relaunchSearch = true) {
4316
5237
  // Se sono in modalità View viene mantenuto in automatico il numero di pagina, ma per la modalità array devo prendere le info di paginazione prima e riapplicarle dopo
4317
5238
  let arrayPage;
4318
5239
  let arrayIpp;
@@ -4320,6 +5241,8 @@ class EsTableComponent {
4320
5241
  arrayPage = this.arraymodePage;
4321
5242
  arrayIpp = this.ArraymodeItemsPerPage;
4322
5243
  }
5244
+ if (!relaunchSearch && this.viewMode)
5245
+ this.View.selfsearch = true;
4323
5246
  this.writeValue(this.View);
4324
5247
  this.cdr.detectChanges();
4325
5248
  if (this.arrayMode) {
@@ -4327,6 +5250,28 @@ class EsTableComponent {
4327
5250
  this.arrayGoToPage(arrayPage);
4328
5251
  }
4329
5252
  }
5253
+ /**
5254
+ * Imposta la visibilità di un header e di eventuali header collegati se questo header è un gruppo, dopodiché aggiorna l'es-table
5255
+ *
5256
+ * @param {string} groupOrHeader Header di cui settare la visibilità
5257
+ * @param {boolean} visibility Visibilità da impostare
5258
+ **/
5259
+ setHeaderVisibility(groupOrHeader, visibility, refresh = true, relaunchSearch = true) {
5260
+ let groupOrHead = this.thsCache[groupOrHeader];
5261
+ if (!groupOrHead)
5262
+ return;
5263
+ groupOrHead.thVisible = visibility;
5264
+ let thsArr = this.EsThsDirective.toArray();
5265
+ for (let i = 0; i < thsArr.length; i++) {
5266
+ let th = thsArr[i];
5267
+ if (th.thParent == groupOrHeader)
5268
+ this.setHeaderVisibility(th.th, visibility, false);
5269
+ }
5270
+ if (refresh) {
5271
+ this.useLocalVisibility = true;
5272
+ this.forceRefresh(relaunchSearch);
5273
+ }
5274
+ }
4330
5275
  /**
4331
5276
  * Funzione che in base ai click su una cella capisce se sto effettuando un'operazione di selezione o se sto entrando nell'edit di una cella con un doppio click
4332
5277
  *
@@ -4335,30 +5280,107 @@ class EsTableComponent {
4335
5280
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4336
5281
  */
4337
5282
  dbClickEditOrSingleClickRowSelection($event, rowItem, item) {
5283
+ // Prima cosa da fare è controllare se ci sono dei range lasciati da operazioni precedenti (se applicabile) e ripulirli
5284
+ if (this.rangeSelected && !$event.ctrlKey && this.Selection) {
5285
+ this.logger.log("clearing previously selected range");
5286
+ this.selection_H.clearSelectionStatusExcluding(null);
5287
+ this.rangeSelected = false;
5288
+ return;
5289
+ }
5290
+ // Modalità Editable, gestisco i doppi click senza però rallentare la modalità di selezione a range
5291
+ if (this.Editable) {
5292
+ // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
5293
+ if (this.cellDbClickTimer) {
5294
+ this.logger.log("handling doubleclick on editable cell: " + (rowItem.PropertyName ? 'edit mode for property ' + rowItem.PropertyName : 'no property set, fallback to simple click'));
5295
+ if (rowItem.PropertyName)
5296
+ this.setupUserEdit(rowItem, item);
5297
+ else
5298
+ this.handleRowClick($event, item, this.Selection, true);
5299
+ this.clearCellClickTimer();
5300
+ return;
5301
+ }
5302
+ // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
5303
+ this.cellDbClickTimer = setTimeout(() => {
5304
+ this.clearCellClickTimer();
5305
+ if (!this.RangeSelection || !this.mouseIsDown) {
5306
+ this.logger.log("time's up for second click, handling single click");
5307
+ this.handleRowClick($event, item, this.Selection, true);
5308
+ }
5309
+ }, this.doubleClickBufferMs);
5310
+ }
5311
+ // In modalità a range la creazione del range è gestita dai mousedown, move ed up...
5312
+ // La selezione delle righe invece è gestita dalle caselline a sinistra
5313
+ if (this.RangeSelection)
5314
+ return;
5315
+ // Se ho fatto click col control attaccato esco subito dato che deve solo permettere la navigazione dei link
5316
+ if ($event.ctrlKey)
5317
+ return;
4338
5318
  // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
4339
5319
  if (rowItem._editing)
4340
5320
  return;
4341
5321
  // Per evitare di rallentare a prescindere
4342
- if (!this.UserEdits) {
4343
- this.handleRowClick($event, item, this.Selection);
5322
+ if (!this.Editable) {
5323
+ this.handleRowClick($event, item, this.Selection, true);
4344
5324
  return;
4345
5325
  }
4346
- // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
4347
- if (this.cellDbClickTimer) {
4348
- if (this.UserEdits && rowItem.UserEdits)
4349
- this.setupUserEdit(rowItem);
4350
- this.clearCellClickTimer();
5326
+ }
5327
+ /** Evento che gestisce il comando "Copia" buttando i valori selezionati nella clipboard in base al loro tipo */
5328
+ handleCopy() {
5329
+ if (!this.RangeSelection)
4351
5330
  return;
5331
+ let sel = this.selection_H.getSelectionStatusSelection();
5332
+ if (sel.length > 0 && sel[0].length > 0) {
5333
+ var selectionText = this.selection_H.getClipbardTextFromSelection(sel);
5334
+ this.clipboardService.copyTextToClipboard(selectionText);
5335
+ this.msgExts.simpleInfo(this.lc.loc("Values copied in the clipboard"), "toastr", 1000);
4352
5336
  }
4353
- // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
4354
- this.cellDbClickTimer = setTimeout(() => {
4355
- this.clearCellClickTimer();
4356
- this.handleRowClick($event, item, this.Selection);
4357
- }, this.doubleClickBufferMs);
4358
5337
  }
4359
- /**
4360
- * Ripulisce il timer utilizzato per capire se è stato effettuato un doppio click o meno
4361
- */
5338
+ /** Evento che gestisce il comando "Incolla" prendendo i dati della clipboard e applicandoli al range di selezione attuale in base al tipo delle celle sotto */
5339
+ handlePaste() {
5340
+ if (!this.RangeSelection)
5341
+ return;
5342
+ let sel = this.selection_H.getSelectionStatusSelection();
5343
+ if (sel.length > 0 && sel[0].length > 0) {
5344
+ this.clipboardService.getClipboard("matrix", (values) => {
5345
+ // Fix clipboard service che pare un po' stronza, rimuovo l'ultimo array se mi accorgo che è un singolo array con un solo elemento vuoto
5346
+ if (values.length > 0 && values[values.length - 1].length == 1 && values[values.length - 1][0] == '')
5347
+ values.splice(values.length - 1, 1);
5348
+ if (values.length > 0 && values[0].length > 0) {
5349
+ // Check se la modifica è abilitata
5350
+ if (!this.Editable) {
5351
+ this.msgExts.simpleWarning(this.lc.loc("Data for this table cannot be edited"));
5352
+ return;
5353
+ }
5354
+ // Controllo che quello che sto copiando sia della stessa dimensione della selezione sull'es-table, tranne nel caso ho un singolo valore da copiare
5355
+ if ((sel.length != values.length || sel[0].length != values[0].length) && (values.length != 1 || values[0].length != 1)) {
5356
+ this.msgExts.simpleWarning(this.lc.loc("Size of copied data is different from the size of the selection"));
5357
+ return;
5358
+ }
5359
+ // Se le dimensioni coincidono copio da una parte all'altra
5360
+ let changes = [];
5361
+ for (let r = 0; r < sel.length; r++) {
5362
+ var row = sel[r];
5363
+ for (let c = 0; c < row.length; c++) {
5364
+ let cell = row[c];
5365
+ // Se ho un singolo valore lo applico a tutta la selezione
5366
+ let value = values.length == 1 && values[0].length == 1 ? values[0][0] : values[r][c];
5367
+ let old = cell.value;
5368
+ let niu = cell.val_setter(value);
5369
+ let olddate = this.dateExts.getDateConvertion(old);
5370
+ let niudate = this.dateExts.getDateConvertion(niu);
5371
+ if ((olddate && niudate && olddate.isSame && olddate.isSame(niudate)) || old === niu)
5372
+ continue;
5373
+ changes.push(new EsTableModelChange(cell.item, cell.header, cell.property, old, niu));
5374
+ }
5375
+ }
5376
+ this.cdr.markForCheck();
5377
+ if (changes.length > 0)
5378
+ this.onModelChange.emit(changes);
5379
+ }
5380
+ });
5381
+ }
5382
+ }
5383
+ /** Ripulisce il timer utilizzato per capire se è stato effettuato un doppio click o meno */
4362
5384
  clearCellClickTimer() {
4363
5385
  clearTimeout(this.cellDbClickTimer);
4364
5386
  this.cellDbClickTimer = null;
@@ -4369,9 +5391,15 @@ class EsTableComponent {
4369
5391
  * @param {any} $event Evento nativo javascript
4370
5392
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4371
5393
  * @param {boolean} selection Indica se la selezione è attiva
4372
- *
5394
+ * @param {boolean} internalCall Indica se la chiamata a questa funzione è interna: permette di skippare i check sulle CustomCells
4373
5395
  */
4374
- handleRowClick($event, item, selection) {
5396
+ handleRowClick($event, item, selection, internalCall = false) {
5397
+ // Se ho un ctrl premuto esco con true in modo da fare bubbling dell'evento e lasciarlo gestire al browser (link ecc...)
5398
+ // Stessa cosa se ho custom cell dato che la gestione dei click viene affidata ai singoli TD
5399
+ if ($event.ctrlKey || (this.UseCustomCells && !internalCall))
5400
+ return true;
5401
+ if (selection)
5402
+ this.selection_H.clearSelectionStatusExcluding(null);
4375
5403
  if (selection && !item.locked && !item._sep && !item._group)
4376
5404
  this.handleClick($event, item);
4377
5405
  else if (item._group)
@@ -4379,34 +5407,127 @@ class EsTableComponent {
4379
5407
  // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
4380
5408
  this.cdr.markForCheck();
4381
5409
  }
5410
+ /**
5411
+ * Gestione del click destro sull'es-table
5412
+ */
5413
+ onRightClick() {
5414
+ if (this.Selection)
5415
+ this.onOpenContextMenu.emit();
5416
+ }
4382
5417
  /**
4383
5418
  * La modifica dell'utente è iniziata. Si imposta la variabile relativa a "true" in modo da mostrare l'input di testo
4384
5419
  *
4385
5420
  * Dopo che l'input è apparso, dopo un ciclo di Change Detection viene attivato il Subject collegato all'input che servirà a effettuare il focus
4386
5421
  *
4387
5422
  * @param {TdElement} rowItem Elemento di riga su cui è stata attivata la modifica
5423
+ * @param {any} item Oggetto sopra il quale è stata attivata la modifica
4388
5424
  */
4389
- setupUserEdit(rowItem) {
4390
- if (this.UserEdits && rowItem.UserEdits)
5425
+ setupUserEdit(rowItem, item) {
5426
+ this.selection_H.clearSelectionStatusExcluding(null);
5427
+ if (this.Editable && rowItem.PropertyName) {
5428
+ let dynMode = this.DynamicRowColumnsDefinition?.length > 0;
4391
5429
  rowItem._editing = true;
5430
+ rowItem.old_value = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
5431
+ }
4392
5432
  this.cdr.detectChanges();
4393
5433
  setTimeout(() => { this.FocusSubject.next(); });
4394
5434
  }
4395
5435
  /**
4396
- * La modifica dell'utente è terminata. Si reimposta la variabile relativa a "false" in modo da nascondere l'input di testo
5436
+ * La modifica dell'utente è terminata. Si reimposta la variabile relativa a "false" in modo da nascondere l'input di testo e si emette la modifica del valore
4397
5437
  *
4398
5438
  * @param {TdElement} rowItem Elemento di riga su cui è stata attivata la modifica
4399
5439
  * @param {any} item Oggetto sopra il quale è stata attivata la modifica
5440
+ * @param {number} columnIndex Indice della colonna su cui è avvenuta la modifica
4400
5441
  */
4401
- finalizeUserEdit(rowItem, item) {
4402
- rowItem._editing = false;
5442
+ finalizeUserEdit(rowItem, item, columnIndex) {
5443
+ let dynMode = this.DynamicRowColumnsDefinition?.length > 0;
5444
+ let rowItm = rowItem;
5445
+ rowItm._editing = false;
5446
+ let old = rowItm.old_value;
5447
+ let niu = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
5448
+ let olddate = this.dateExts.getDateConvertion(old);
5449
+ let niudate = this.dateExts.getDateConvertion(niu);
5450
+ if ((olddate && niudate && olddate.isSame && olddate.isSame(niudate)) || old === niu)
5451
+ return;
5452
+ this.onModelChange.emit([new EsTableModelChange(item, rowItem.ID, rowItem.PropertyName, old, niu)]);
5453
+ this.selectionStatus[item._ordinal][columnIndex].val_setter(niu);
5454
+ }
5455
+ mousedown(event, rowItem, _) {
5456
+ // Tasto diverso dal click sinistro -> ciao è stato bello e intenso
5457
+ if (event.buttons != 1 || !this.RangeSelection)
5458
+ return;
5459
+ // Sto lavorando su QUESTA es-table
5460
+ this.copyPasteDetector.ActiveEstReference = this;
5461
+ // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
5462
+ if (rowItem._editing)
5463
+ return;
5464
+ this.mouseIsDown = true;
5465
+ let coords = event.currentTarget.id.split('_');
5466
+ let row = parseInt(coords[coords.length - 2]);
5467
+ let column = parseInt(coords[coords.length - 1]);
5468
+ this.firstCoordinates = { row, column };
5469
+ // Se ho già un range di selezione ignoro temporanemaente questa selezione in modo da capire bene cosa devo fare dopo (click sulla riga / altra selezione)
5470
+ // e gestire la grafica in maniera un po' più precisa
5471
+ if (!this.rangeSelected || (event.ctrlKey || !this.Selection))
5472
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
5473
+ else
5474
+ this.rangeStartWasIgnored = true;
5475
+ this.logger.log(`mouse down on ${row}:${column}`);
5476
+ }
5477
+ mouseenter(event) {
5478
+ if (!this.RangeSelection)
5479
+ return;
5480
+ if (event.buttons == 0)
5481
+ this.mouseIsDown = false;
5482
+ if (this.mouseIsDown && this.firstCoordinates) {
5483
+ let id = event.currentTarget.id;
5484
+ let coords = id.split('_');
5485
+ let row = parseInt(coords[coords.length - 2]);
5486
+ let column = parseInt(coords[coords.length - 1]);
5487
+ // Se ho ignorato l'inizio della selezione nel mousedown lo recupero qui
5488
+ if (this.rangeStartWasIgnored) {
5489
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, this.firstCoordinates.row, this.firstCoordinates.column);
5490
+ this.rangeStartWasIgnored = false;
5491
+ }
5492
+ this.selection_H.singleCellSelection({ view: event.view, range: true }, row, column, this.firstCoordinates);
5493
+ this.logger.log(`mouse move over ${row}:${column}`);
5494
+ this.rangeSelected = true;
5495
+ }
5496
+ }
5497
+ mouseup(event) {
5498
+ if (!this.RangeSelection)
5499
+ return;
5500
+ let id = event.currentTarget.id;
5501
+ let coords = id.split('_');
5502
+ let row = parseInt(coords[coords.length - 2]);
5503
+ let column = parseInt(coords[coords.length - 1]);
5504
+ // Se il mouseup viene effettuato sulla stessa cella del primo mousedown e siamo in modalità di selezione deseleziono la cella perché è un semplice click
5505
+ if (this.mouseIsDown && this.firstCoordinates) {
5506
+ if (this.firstCoordinates.row == row && this.firstCoordinates.column == column && !event.ctrlKey && !this.rangeStartWasIgnored && this.Selection)
5507
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
5508
+ else if (event.ctrlKey || !this.Selection)
5509
+ this.rangeSelected = true;
5510
+ }
5511
+ this.mouseIsDown = false;
5512
+ this.logger.log(`mouse lifted up`);
5513
+ }
5514
+ getCellReference(object, column) {
5515
+ let fkThisShitImOut = this.utiExts.deepClone(object);
5516
+ this.utilities_H.calculateHash([fkThisShitImOut]);
5517
+ let prop = column;
5518
+ let hash = fkThisShitImOut._hash;
5519
+ let toRet = this.EsTdsCache[`${prop}_${hash}`];
5520
+ return toRet;
5521
+ }
5522
+ registerCell(event) {
5523
+ this.EsTdsCache[`${event.id}_${event.hash}`] = event.self;
4403
5524
  }
4404
5525
  }
4405
- EsTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i2$1.PreferencesService, optional: true }, { token: EST_DEFAULTS, optional: true }, { token: EST_LOCALE, optional: true }, { token: i2.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: UtilitiesHandler }, { token: i5.UtilityService }, { token: i5.ExportService }, { token: i5.DateService }, { token: i5.MessageService }], target: i0.ɵɵFactoryTarget.Component });
4406
- EsTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: EsTableComponent, selector: "es-table", inputs: { CornerMenuOptions: "CornerMenuOptions", ColumnsResizable: "ColumnsResizable", ColumnsPinnable: "ColumnsPinnable", AutoUpdate: "AutoUpdate", UseCustomCells: "UseCustomCells", MaxHeight: "MaxHeight", ContainerClass: "ContainerClass", XLSXExport: "XLSXExport", CSVExport: "CSVExport", AllSearch: "AllSearch", HighCellDensity: "HighCellDensity", Selection: "Selection", ShowLoadingOnBootstrap: "ShowLoadingOnBootstrap", Removal: "Removal", RemovalCondition: "RemovalCondition", Export: "Export", ShiftClick: "ShiftClick", CountLabel: "CountLabel", HidePaging: "HidePaging", HidePagingCount: "HidePagingCount", HidePagingButtons: "HidePagingButtons", ContextMenu: "ContextMenu", ExportFileName: "ExportFileName", TableClass: "TableClass", ExportFunction: "ExportFunction", HasHeaderGroup: "HasHeaderGroup", HasSecondaryHeaderGroup: "HasSecondaryHeaderGroup", HeaderHidden: "HeaderHidden", BodyHidden: "BodyHidden", SelectionDisabled: "SelectionDisabled", SingleSelection: "SingleSelection", RowClassAssigner: "RowClassAssigner", OrderByColumn: "OrderByColumn", MultipleOrderingDirectives: "MultipleOrderingDirectives", HiddenColumns: "HiddenColumns", ColumnsOrdering: "ColumnsOrdering", SearchView: "SearchView", SelectAll: "SelectAll", UseArrayModePaging: "UseArrayModePaging", DynamicRowColumnsDefinition: "DynamicRowColumnsDefinition", DynamicOperations: "DynamicOperations", Hierarchy: "Hierarchy", ParentKey: "ParentKey", OwnKey: "OwnKey", StartsExpanded: "StartsExpanded", SavePreferences: "SavePreferences", PagingStyle: "PagingStyle", RowGroupingPagingStyle: "RowGroupingPagingStyle", ItemSourceProperty: "ItemSourceProperty", UseSelectionCache: "UseSelectionCache", ShowItemGroupsColumns: "ShowItemGroupsColumns", UserEdits: "UserEdits", ArraymodeItemsPerPage: "ArraymodeItemsPerPage" }, outputs: { onOrderChanged: "onOrderChanged", onSearchRequest: "onSearchRequest", onSelectionChanged: "onSelectionChanged", onRemoval: "onRemoval", onAbortRemoval: "onAbortRemoval", onCornerAction: "onCornerAction", onDynamicOperation: "onDynamicOperation" }, queries: [{ propertyName: "bodyRef", first: true, predicate: ["body"], descendants: true }, { propertyName: "headerRef", first: true, predicate: ["header"], descendants: true }, { propertyName: "headerGroupRef", first: true, predicate: ["headerGroup"], descendants: true }, { propertyName: "secondaryHeaderGroupRef", first: true, predicate: ["secondaryHeaderGroup"], descendants: true }, { propertyName: "EsTdsDirective", predicate: EsTdDirective }, { propertyName: "EsThsDirective", predicate: EsThDirective }], viewQueries: [{ propertyName: "inputField", first: true, predicate: ["input"], descendants: true }, { propertyName: "exportDownloader", first: true, predicate: ["exportDownloader"], descendants: true }, { propertyName: "tableEmptyMenu", first: true, predicate: ["emptyMenu"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs && RowTHs.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" [Fixed]=\"rowHeader.Fixed\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class || ''}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName.endsWith('.xlsx') ? ExportFileName.replace('.xlsx', '.csv') : ExportFileName.endsWith('.csv') ? ExportFileName : ExportFileName + '.csv'\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" >\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, true)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\"><div class=\"est-pinned-border est-cell-group-padding\"></div></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"dynamicMode_H.generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputChange)=\"finalizeUserEdit(rowItem, item)\" (inputFocus)=\"$event.stopPropagation();\" ></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\" >\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputFinalized)=\"finalizeUserEdit(rowItem, item)\"></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"], components: [{ type: EsTh, selector: "[es-th]", inputs: ["es-th", "Order", "Orderable", "Display", "Resizable", "Pinned", "SearchInProgress", "OrderBy", "Wrap", "Fixed", "Template", "Visible"], outputs: ["onOrderChange", "onUnpinning"] }, { type: TablePagerComponent, selector: "app-paging", inputs: ["CurrentPageSize", "View", "WarnOnAll", "AllSearch", "DefaultAll", "GroupMode", "GroupCount", "CountLabel", "ShowCount", "ShowPaging", "PagerCount", "Hidden"], outputs: ["pagingSelected"] }, { type: EsTd, selector: "[es-td]", inputs: ["es-td", "Internal", "RouterLink", "Display", "Template", "Context", "Visible"] }, { type: i9.FormAdaptiveComponent, selector: "form-adaptive", inputs: ["Type", "TypeMissingMessage", "Pattern", "AllowDownload", "Precision", "Alignment", "SearchFunction", "MinChars", "CaseSensitive"] }, { type: i10.ContextMenuComponent, selector: "context-menu", inputs: ["menuClass", "autoFocus", "useBootstrap4", "disabled"], outputs: ["close", "open"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i11.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i12.CsvDirective, selector: "[csvLink]", inputs: ["data", "headers", "delimiter", "filename", "uFEFF", "target"] }, { type: i13.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { type: i13.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { type: i13.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { type: i10.ContextMenuAttachDirective, selector: "[contextMenu]", inputs: ["contextMenuSubject", "contextMenu"] }, { type: i14.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i10.ContextMenuItemDirective, selector: "[contextMenuItem]", inputs: ["subMenu", "divider", "enabled", "passive", "visible"], outputs: ["execute"] }, { type: i15.ModalDirective, selector: "[bsModal]", inputs: ["config", "closeInterceptor"], outputs: ["onShow", "onShown", "onHide", "onHidden"], exportAs: ["bs-modal"] }, { type: i16.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i16.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i16.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"] }], pipes: { "localize": i2.LocalizePipe, "number": i11.DecimalPipe }, viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
4407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableComponent, decorators: [{
5526
+ EsTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i2$1.PreferencesService, optional: true }, { token: EST_DEFAULTS, optional: true }, { token: EST_LOCALE, optional: true }, { token: i2.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: UtilitiesHandler }, { token: i5.UtilityService }, { token: i5.ExportService }, { token: i5.DateService }, { token: i5.MessageService }, { token: CopyPasteDetector }, { token: i5.ClipboardService }, { token: Logger }], target: i0.ɵɵFactoryTarget.Component });
5527
+ EsTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: EsTableComponent, selector: "es-table", inputs: { EsTableTemplate: "EsTableTemplate", CornerMenuOptions: "CornerMenuOptions", ColumnsResizable: "ColumnsResizable", ColumnsPinnable: "ColumnsPinnable", AutoUpdate: "AutoUpdate", Height: "Height", EmptySpaceBackgroundColor: "EmptySpaceBackgroundColor", EsTableHandledSearch: "EsTableHandledSearch", MaxHeight: "MaxHeight", ContainerClass: "ContainerClass", XLSXExport: "XLSXExport", CSVExport: "CSVExport", AllSearch: "AllSearch", HighCellDensity: "HighCellDensity", Selection: "Selection", ShowLoadingOnBootstrap: "ShowLoadingOnBootstrap", Removal: "Removal", RemovalCondition: "RemovalCondition", Export: "Export", ShiftClick: "ShiftClick", CountLabel: "CountLabel", HidePaging: "HidePaging", HidePagingCount: "HidePagingCount", HidePagingButtons: "HidePagingButtons", ContextMenu: "ContextMenu", ExportFileName: "ExportFileName", TableClass: "TableClass", ExportFunction: "ExportFunction", ExportOnlyVisibleColumns: "ExportOnlyVisibleColumns", HasHeaderGroup: "HasHeaderGroup", HasSecondaryHeaderGroup: "HasSecondaryHeaderGroup", HeaderHidden: "HeaderHidden", BodyHidden: "BodyHidden", SelectionDisabled: "SelectionDisabled", SingleSelection: "SingleSelection", RowClassAssigner: "RowClassAssigner", OrderByColumn: "OrderByColumn", MultipleOrderingDirectives: "MultipleOrderingDirectives", HiddenColumns: "HiddenColumns", ColumnsOrdering: "ColumnsOrdering", SearchView: "SearchView", SelectAll: "SelectAll", UseArrayModePaging: "UseArrayModePaging", DynamicRowColumnsDefinition: "DynamicRowColumnsDefinition", DynamicOperations: "DynamicOperations", Hierarchy: "Hierarchy", ParentKey: "ParentKey", OwnKey: "OwnKey", StartsExpanded: "StartsExpanded", SavePreferences: "SavePreferences", DefaultAlignment: "DefaultAlignment", PagingStyle: "PagingStyle", RowGroupingPagingStyle: "RowGroupingPagingStyle", ItemSourceProperty: "ItemSourceProperty", UseSelectionCache: "UseSelectionCache", ShowItemGroupsColumns: "ShowItemGroupsColumns", Editable: "Editable", RangeSelection: "RangeSelection", SearchThrottle: "SearchThrottle", ArraymodeItemsPerPage: "ArraymodeItemsPerPage" }, outputs: { onOrderChanged: "onOrderChanged", onSearchRequest: "onSearchRequest", onSelectionChanged: "onSelectionChanged", onRemoval: "onRemoval", onAbortRemoval: "onAbortRemoval", onModelChange: "onModelChange", onOpenContextMenu: "onOpenContextMenu", onCornerAction: "onCornerAction", onDynamicOperation: "onDynamicOperation" }, queries: [{ propertyName: "bodyRef", first: true, predicate: ["body"], descendants: true }, { propertyName: "headerRef", first: true, predicate: ["header"], descendants: true }, { propertyName: "headerGroupRef", first: true, predicate: ["headerGroup"], descendants: true }, { propertyName: "secondaryHeaderGroupRef", first: true, predicate: ["secondaryHeaderGroup"], descendants: true }, { propertyName: "EsTdEditorDirectives", predicate: EsTdEditorDirective }, { propertyName: "EsTdsDirective", predicate: EsTdDirective }, { propertyName: "EsThsDirective", predicate: EsThDirective }], viewQueries: [{ propertyName: "inputField", first: true, predicate: ["input"], descendants: true }, { propertyName: "exportDownloader", first: true, predicate: ["exportDownloader"], descendants: true }, { propertyName: "tableEmptyMenu", first: true, predicate: ["emptyMenu"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" [ngModelOptions]=\"{'standalone': true}\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\" [style.height]=\"Height\" [style.background-color]=\"EmptySpaceBackgroundColor\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable est-full-height {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" style=\"background-color: white;\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups; trackBy: IDTrackBy\">\r\n <th *ngFor=\"let cell of level; trackBy: IDTrackBy\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations; trackBy: idTrackBy\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition; trackBy: PropertyNameTrackBy\">\r\n <ng-container *ngIf=\"rowHeader.Visible\">\r\n <th *ngIf=\"OrderByColumn\" id=\"esth_{{rowHeader.PropertyName}}\" es-th=\"{{rowHeader.PropertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.Clss || '') + (rowHeader.HeaderWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.DataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.PropertyName, $event)\">{{rowHeader.Description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" id=\"esth_{{rowHeader.PropertyName}}\" es-th=\"{{rowHeader.PropertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.Clss || '') + (rowHeader.HeaderWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.DataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.Description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs?.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs; trackBy: IDTrackBy\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" \r\n [style.width.px]=\"rowHeader.PinnedWidth\" \r\n es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" \r\n [Fixed]=\"rowHeader.Fixed\" \r\n [Order]=\"rowHeader.Order\" \r\n [Resizable]=\"ColumnsResizable\"\r\n [Orderable]=\"rowHeader.Orderable\" \r\n [OrderBy]=\"OrderByColumn\" \r\n [SearchInProgress]=\"!!researchInProgress\" \r\n (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" \r\n (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n \r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs; trackBy: IDTrackBy\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" \r\n es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [style.text-align]=\" rowHeader.Alignment || null\"\r\n [class.est-ltab-border]=\"rowHeader.LeftBorder\" \r\n [class.est-rtab-border]=\"rowHeader.RightBorder\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Order]=\"rowHeader.Order\" \r\n [Resizable]=\"ColumnsResizable\" \r\n [Orderable]=\"rowHeader.Orderable\" \r\n [OrderBy]=\"OrderByColumn\" \r\n [SearchInProgress]=\"!!researchInProgress\" \r\n (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions; trackBy: idTrackBy\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" [class.est-no-selection]=\"RangeSelection\">\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"PagerOptions.View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array; trackBy: valTrackBy\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!RangeSelection && handleRowClick($event, item, true)\"\r\n (contextmenu)=\"onRightClick();\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item, index: i }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, index: i, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item, index: i }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let i = index, let even = even; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item, index: i }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, index: i }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item, index: i }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item let-index=\"index\">\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item, index: index}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEditor let-ctx>\r\n <!-- Un po' triste ma questo \u00E8 il metodo pi\u00F9 semplice per gestire il cambio di modello -->\r\n <ng-container *ngIf=\"ctx.item.properties\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [Options]=\"ctx.definition.EditorOptions\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"ctx.item.properties[ctx.definition.PropertyName]\" name=\"{{ ctx.definition.PropertyName + '_' + ctx.item._hash }}\" [Type]=\"ctx.definition.PropertyType\" [Source]=\"ctx.definition.PropertySource\" (inputFinalized)=\"ctx.finalizer()\"></form-adaptive>\r\n </ng-container>\r\n <ng-container *ngIf=\"!ctx.item.properties\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [Options]=\"ctx.definition.EditorOptions\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"ctx.item[ctx.definition.PropertyName]\" name=\"{{ ctx.definition.PropertyName + '_' + ctx.item._hash }}\" [Type]=\"ctx.definition.PropertyType\" [Source]=\"ctx.definition.PropertySource\" (inputFinalized)=\"ctx.finalizer()\"></form-adaptive>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-ctx>\r\n <!-- TODO: Formattare il valore in base a valType.type -->\r\n <ng-container *ngIf=\"ctx.type == 'enum'\">\r\n {{ (ctx.value | est_lookup : ctx.definition.PropertySource).description }}\r\n </ng-container>\r\n <ng-container *ngIf=\"ctx.type != 'enum'\">\r\n {{ctx.value}}\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n <!-- Cella che aggrega tutte le colonne che devono essere pinnate -->\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let cell of RowTDs[item._hash]; let index = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"cell.Pinned; let pinned = true\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: { $implicit: item, index: index, cell: cell, pinned: pinned };;\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <!-- Body effettivo della riga -->\r\n <ng-container *ngFor=\"let cell of RowTDs[item._hash]; let index = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"!cell.Pinned; let pinned = false\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: { $implicit: item, index: index, cell: cell, pinned: pinned };\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Cella customizzata, elemento grafico base per la tabella -->\r\n<ng-template #customTd let-item let-cell=\"cell\" let-index=\"index\" let-pinned=\"pinned\">\r\n\r\n <!-- Customizzazione per celle con icona (sono essenzialmente operazioni semplici e basta) -->\r\n <ng-container *ngIf=\"cell.IconClass && cell.Visible\">\r\n <ng-container *ngIf=\"!cell.ConditionField || ((item.properties || item)[cell.ConditionField] == cell.ConditionValue)\">\r\n <td [class.est-no-right-padding]=\"index != DynamicOperations.length -1\" [class.est-no-left-padding]=\"index != 0\" class=\"est-col-min\"><span title=\"{{cell.Title}}\" class=\"{{cell.IconClass}} est-pointer\" (click)=\"dynamicOperation(item, cell.ID)\">{{cell.Content}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"cell.ConditionField && ((item.properties || item)[cell.ConditionField] != cell.ConditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-----------------------------------------------------------------------------------------------------------------------\r\n - ATTENZIONE: Gli spazi fra le propriet\u00E0 di questo mega td sono significativi e dividono la dichiarazione in sezioni: -\r\n - . Generiche -\r\n - . Gestione allineamento e colori per la modalit\u00E0 report -\r\n - . Gestioni grafiche particolari per il Pinned -\r\n - . Gestione della selezione a singola cella in assenza di pinned -\r\n - . Gestione click classico -\r\n ------------------------------------------------------------------------------------------------------------------------->\r\n\r\n <td *ngIf=\"!cell.IconClass && cell.Visible\" \r\n es-td=\"{{cell.Property || cell.ID}}\"\r\n id=\"estd_{{cell.Property || cell.ID}}_{{item._ordinal}}_{{index}}\" \r\n class=\"{{ cell.Class }} est-default-row-height\" \r\n [Context]=\"item._hash\" \r\n [class.est-no-selection]=\"Editable && cell.PropertyName\" \r\n [class.est-rg-hdr]=\"cell.GroupHeader\" \r\n [class.est-rg-agg]=\"cell.GroupAggregation\"\r\n [class.est-nowrap]=\"Hierarchy || !cell.Wraps\"\r\n \r\n [style.text-align]=\" (!pinned && cell.Alignment) ? cell.Alignment : null\"\r\n [style.color]=\"(!pinned && item.forecolors && cell.PropAccessor) ? item.forecolors[cell.PropAccessor] : null\"\r\n [style.background-color]=\"(!pinned && item.backcolors && cell.PropAccessor) ? item.backcolors[cell.PropAccessor] : null\"\r\n\r\n [style.width.px]=\"pinned ? cell.PinnedWidth : null\"\r\n [class.est-no-border]=\"pinned\"\r\n\r\n [class.est-ltab-border]=\"cell.LeftBorder && !selectionStatus[item._ordinal][index]?.lborder\" \r\n [class.est-rtab-border]=\"cell.RightBorder && !selectionStatus[item._ordinal][index]?.rborder\" \r\n\r\n [class.est-selected-cell]=\"selectionStatus[item._ordinal][index]?.selected\"\r\n [class.est-cell-lborder]=\"selectionStatus[item._ordinal][index]?.lborder\"\r\n [class.est-cell-rborder]=\"selectionStatus[item._ordinal][index]?.rborder\"\r\n [class.est-cell-tborder]=\"selectionStatus[item._ordinal][index]?.tborder\"\r\n [class.est-cell-bborder]=\"selectionStatus[item._ordinal][index]?.bborder\"\r\n\r\n [class.est-cell-lborder-tmp]=\"!cell.LeftBorder && !selectionStatus[item._ordinal][index]?.lborder && !selectionStatus[item._ordinal][index]?.loverlaps\"\r\n [class.est-cell-rborder-tmp]=\"!cell.RightBorder && !selectionStatus[item._ordinal][index]?.rborder && !selectionStatus[item._ordinal][index]?.roverlaps\"\r\n [class.est-cell-tborder-tmp]=\"!selectionStatus[item._ordinal][index]?.tborder && !selectionStatus[item._ordinal][index]?.toverlaps\"\r\n [class.est-cell-bborder-tmp]=\"!selectionStatus[item._ordinal][index]?.bborder && !selectionStatus[item._ordinal][index]?.boverlaps\"\r\n\r\n (mousedown)=\"mousedown($event, cell, item)\" \r\n (mouseenter)=\"mouseenter($event)\" \r\n (mouseup)=\"mouseup($event)\"\r\n (onCellGeneration)=\"registerCell($event)\"\r\n \r\n (click)=\"dbClickEditOrSingleClickRowSelection($event, cell, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"cell._editing\" [class.est-pre]=\"!(Hierarchy && index == 0)\">\r\n\r\n <ng-container #DEBUG>\r\n <!-- Debug box in caso la roba che viene scritta nelle celle non torni. Scirvere qui i propri binding per controllare cose -->\r\n </ng-container>\r\n\r\n <!-- 90% Template disponibile, quindi derivante da *td, controllo giusto che non sia un field particolare multi -->\r\n <ng-container *ngIf=\"cell.Template\">\r\n <ng-container *ngIf=\"!cell.Multi\"><ng-container *ngTemplateOutlet=\"cell.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"cell.Multi\"><ng-container *ngTemplateOutlet=\"cell.Template; context: { $implicit: (item[cell.MultiProp] ? item[cell.MultiProp][cell.MultiIndex] : {}) }\"></ng-container></span>\r\n </ng-container>\r\n \r\n <!-- 8%\r\n Template non disponibile, pu\u00F2 venire da \r\n RoutePath in caso sia un link di una tabella dinamica\r\n PropAccessor in caso di ReportRow (quindi oggetti con \"values\" dentro), \r\n o Renderer se modalit\u00E0 dinamica/standard (in qual caso il renderer \u00E8 il default)\r\n -->\r\n <ng-container *ngIf=\"!cell.Template && !cell.Multi && !cell.Content\">\r\n <a *ngIf=\"cell.RoutePath\" [routerLink]=\"item | est_routerlink : cell.RoutePath : cell.RouteParameterProperties\" class=\"est-link\" [innerHTML]=\"item.properties ? item.properties[cell.PropertyName] : item[cell.PropertyName]\"></a>\r\n \r\n <span *ngIf=\"cell.PropAccessor\">\r\n {{(item.values? item.values[cell.PropAccessor] : item[cell.PropAccessor]) | est_format: cell.Format }}\r\n </span>\r\n\r\n <ng-container *ngIf=\"!cell.PropAccessor && !cell.RoutePath\">\r\n <ng-container *ngTemplateOutlet=\"cell.PropertyName | est_renderer: { name: cell.RendererName, src: EsTdsDirective, fallback: defaultEsTd }; context: { $implicit: { definition: cell, value: item.properties ? item.properties[cell.PropertyName] : item[cell.PropertyName], type: cell.PropertyType} }\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- 1% Se in modalit\u00E0 gerarchica metto il td per navigare la gerarchia -->\r\n <ng-container *ngIf=\"Hierarchy && index == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <!-- 1% Content programmatico per le casistiche di Row Grouping ecc... -->\r\n <ng-container *ngIf=\"cell.Content\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"cell._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"cell.PropertyName | est_editor: { name: cell.EditorName, src: EsTdEditorDirectives, fallback: defaultEditor}; context: { $implicit: { definition: cell, columnIndex: index, item: item, finalizer: finalizeUserEdit.bind(this, cell, item, index) } }\"></ng-container>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Navigatore della gerarchia di una view gerarchica, con tasto per espandere e collassare -->\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem><span><em>{{'No operations available' | localize : lc}}...</em></span></ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last; trackBy: idTrackBy\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last; trackBy: idTrackBy\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-default-row-height{height:31px}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-full-height{height:100%}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:1px solid #bbb!important}.est-rtab-border{border-right:1px solid #bbb!important}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-selected-cell{background-color:#2196f333}.est-cell-lborder{border-left:1.02px solid #2196f3!important}.est-cell-tborder{border-top:1.02px solid #2196f3!important}.est-cell-rborder{border-right:1.02px solid #2196f3!important}.est-cell-bborder{border-bottom:1.02px solid #2196f3!important}.est-cell-lborder-tmp{border-left:1.02px solid transparent!important}.est-cell-tborder-tmp{border-top:1.02px solid transparent!important}.est-cell-rborder-tmp{border-right:1.02px solid transparent!important}.est-cell-bborder-tmp{border-bottom:1.02px solid transparent!important}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"], components: [{ type: EsTh, selector: "[es-th]", inputs: ["es-th", "Order", "Orderable", "Display", "Resizable", "Pinned", "SearchInProgress", "OrderBy", "Wrap", "Fixed", "Template", "Visible"], outputs: ["onOrderChange", "onUnpinning"] }, { type: TablePagerComponent, selector: "app-paging", inputs: ["CurrentPageSize", "View", "WarnOnAll", "AllSearch", "DefaultAll", "GroupMode", "GroupCount", "CountLabel", "ShowCount", "ShowPaging", "PagerCount", "Hidden"], outputs: ["pagingSelected"] }, { type: i10.FormAdaptiveComponent, selector: "form-adaptive", inputs: ["Type", "TypeMissingMessage", "Pattern", "AdjustNumber", "AllowDownload", "Precision", "Alignment", "SearchFunction", "MinChars", "CaseSensitive", "Options"] }, { type: EsTd, selector: "[es-td]", inputs: ["es-td", "Context"], outputs: ["onCellGeneration"] }, { type: i12.ContextMenuComponent, selector: "context-menu", inputs: ["menuClass", "autoFocus", "useBootstrap4", "disabled"], outputs: ["close", "open"] }], directives: [{ type: i13.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i13.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i13.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { type: i14.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { type: i14.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { type: i12.ContextMenuAttachDirective, selector: "[contextMenu]", inputs: ["contextMenuSubject", "contextMenu"] }, { type: i15.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i12.ContextMenuItemDirective, selector: "[contextMenuItem]", inputs: ["subMenu", "divider", "enabled", "passive", "visible"], outputs: ["execute"] }, { type: i16.ModalDirective, selector: "[bsModal]", inputs: ["config", "closeInterceptor"], outputs: ["onShow", "onShown", "onHide", "onHidden"], exportAs: ["bs-modal"] }, { type: i17.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i17.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i17.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"] }], pipes: { "localize": i2.LocalizePipe, "number": i13.DecimalPipe, "est_lookup": EstLookupPipe, "est_routerlink": EstRouterLinkPipe, "est_format": EstFormatPipe, "est_renderer": EstRendererPipe, "est_editor": EstEditorPipe }, viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableComponent, decorators: [{
4408
5529
  type: Component,
4409
- args: [{ selector: 'es-table', viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs && RowTHs.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" [Fixed]=\"rowHeader.Fixed\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class || ''}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName.endsWith('.xlsx') ? ExportFileName.replace('.xlsx', '.csv') : ExportFileName.endsWith('.csv') ? ExportFileName : ExportFileName + '.csv'\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" >\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, true)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\"><div class=\"est-pinned-border est-cell-group-padding\"></div></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"dynamicMode_H.generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputChange)=\"finalizeUserEdit(rowItem, item)\" (inputFocus)=\"$event.stopPropagation();\" ></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\" >\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputFinalized)=\"finalizeUserEdit(rowItem, item)\"></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"] }]
5530
+ args: [{ selector: 'es-table', viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" [ngModelOptions]=\"{'standalone': true}\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\" [style.height]=\"Height\" [style.background-color]=\"EmptySpaceBackgroundColor\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable est-full-height {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" style=\"background-color: white;\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups; trackBy: IDTrackBy\">\r\n <th *ngFor=\"let cell of level; trackBy: IDTrackBy\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations; trackBy: idTrackBy\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition; trackBy: PropertyNameTrackBy\">\r\n <ng-container *ngIf=\"rowHeader.Visible\">\r\n <th *ngIf=\"OrderByColumn\" id=\"esth_{{rowHeader.PropertyName}}\" es-th=\"{{rowHeader.PropertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.Clss || '') + (rowHeader.HeaderWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.DataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.PropertyName, $event)\">{{rowHeader.Description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" id=\"esth_{{rowHeader.PropertyName}}\" es-th=\"{{rowHeader.PropertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.Clss || '') + (rowHeader.HeaderWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.DataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.Description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs?.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs; trackBy: IDTrackBy\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" \r\n [style.width.px]=\"rowHeader.PinnedWidth\" \r\n es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" \r\n [Fixed]=\"rowHeader.Fixed\" \r\n [Order]=\"rowHeader.Order\" \r\n [Resizable]=\"ColumnsResizable\"\r\n [Orderable]=\"rowHeader.Orderable\" \r\n [OrderBy]=\"OrderByColumn\" \r\n [SearchInProgress]=\"!!researchInProgress\" \r\n (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" \r\n (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n \r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs; trackBy: IDTrackBy\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" \r\n es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [style.text-align]=\" rowHeader.Alignment || null\"\r\n [class.est-ltab-border]=\"rowHeader.LeftBorder\" \r\n [class.est-rtab-border]=\"rowHeader.RightBorder\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Order]=\"rowHeader.Order\" \r\n [Resizable]=\"ColumnsResizable\" \r\n [Orderable]=\"rowHeader.Orderable\" \r\n [OrderBy]=\"OrderByColumn\" \r\n [SearchInProgress]=\"!!researchInProgress\" \r\n (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions; trackBy: idTrackBy\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" [class.est-no-selection]=\"RangeSelection\">\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"PagerOptions.View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array; trackBy: valTrackBy\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!RangeSelection && handleRowClick($event, item, true)\"\r\n (contextmenu)=\"onRightClick();\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item, index: i }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, index: i, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item, index: i }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let i = index, let even = even; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item, index: i }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, index: i }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item, index: i }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item let-index=\"index\">\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item, index: index}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEditor let-ctx>\r\n <!-- Un po' triste ma questo \u00E8 il metodo pi\u00F9 semplice per gestire il cambio di modello -->\r\n <ng-container *ngIf=\"ctx.item.properties\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [Options]=\"ctx.definition.EditorOptions\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"ctx.item.properties[ctx.definition.PropertyName]\" name=\"{{ ctx.definition.PropertyName + '_' + ctx.item._hash }}\" [Type]=\"ctx.definition.PropertyType\" [Source]=\"ctx.definition.PropertySource\" (inputFinalized)=\"ctx.finalizer()\"></form-adaptive>\r\n </ng-container>\r\n <ng-container *ngIf=\"!ctx.item.properties\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [Options]=\"ctx.definition.EditorOptions\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"ctx.item[ctx.definition.PropertyName]\" name=\"{{ ctx.definition.PropertyName + '_' + ctx.item._hash }}\" [Type]=\"ctx.definition.PropertyType\" [Source]=\"ctx.definition.PropertySource\" (inputFinalized)=\"ctx.finalizer()\"></form-adaptive>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-ctx>\r\n <!-- TODO: Formattare il valore in base a valType.type -->\r\n <ng-container *ngIf=\"ctx.type == 'enum'\">\r\n {{ (ctx.value | est_lookup : ctx.definition.PropertySource).description }}\r\n </ng-container>\r\n <ng-container *ngIf=\"ctx.type != 'enum'\">\r\n {{ctx.value}}\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n <!-- Cella che aggrega tutte le colonne che devono essere pinnate -->\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let cell of RowTDs[item._hash]; let index = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"cell.Pinned; let pinned = true\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: { $implicit: item, index: index, cell: cell, pinned: pinned };;\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <!-- Body effettivo della riga -->\r\n <ng-container *ngFor=\"let cell of RowTDs[item._hash]; let index = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"!cell.Pinned; let pinned = false\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: { $implicit: item, index: index, cell: cell, pinned: pinned };\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Cella customizzata, elemento grafico base per la tabella -->\r\n<ng-template #customTd let-item let-cell=\"cell\" let-index=\"index\" let-pinned=\"pinned\">\r\n\r\n <!-- Customizzazione per celle con icona (sono essenzialmente operazioni semplici e basta) -->\r\n <ng-container *ngIf=\"cell.IconClass && cell.Visible\">\r\n <ng-container *ngIf=\"!cell.ConditionField || ((item.properties || item)[cell.ConditionField] == cell.ConditionValue)\">\r\n <td [class.est-no-right-padding]=\"index != DynamicOperations.length -1\" [class.est-no-left-padding]=\"index != 0\" class=\"est-col-min\"><span title=\"{{cell.Title}}\" class=\"{{cell.IconClass}} est-pointer\" (click)=\"dynamicOperation(item, cell.ID)\">{{cell.Content}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"cell.ConditionField && ((item.properties || item)[cell.ConditionField] != cell.ConditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-----------------------------------------------------------------------------------------------------------------------\r\n - ATTENZIONE: Gli spazi fra le propriet\u00E0 di questo mega td sono significativi e dividono la dichiarazione in sezioni: -\r\n - . Generiche -\r\n - . Gestione allineamento e colori per la modalit\u00E0 report -\r\n - . Gestioni grafiche particolari per il Pinned -\r\n - . Gestione della selezione a singola cella in assenza di pinned -\r\n - . Gestione click classico -\r\n ------------------------------------------------------------------------------------------------------------------------->\r\n\r\n <td *ngIf=\"!cell.IconClass && cell.Visible\" \r\n es-td=\"{{cell.Property || cell.ID}}\"\r\n id=\"estd_{{cell.Property || cell.ID}}_{{item._ordinal}}_{{index}}\" \r\n class=\"{{ cell.Class }} est-default-row-height\" \r\n [Context]=\"item._hash\" \r\n [class.est-no-selection]=\"Editable && cell.PropertyName\" \r\n [class.est-rg-hdr]=\"cell.GroupHeader\" \r\n [class.est-rg-agg]=\"cell.GroupAggregation\"\r\n [class.est-nowrap]=\"Hierarchy || !cell.Wraps\"\r\n \r\n [style.text-align]=\" (!pinned && cell.Alignment) ? cell.Alignment : null\"\r\n [style.color]=\"(!pinned && item.forecolors && cell.PropAccessor) ? item.forecolors[cell.PropAccessor] : null\"\r\n [style.background-color]=\"(!pinned && item.backcolors && cell.PropAccessor) ? item.backcolors[cell.PropAccessor] : null\"\r\n\r\n [style.width.px]=\"pinned ? cell.PinnedWidth : null\"\r\n [class.est-no-border]=\"pinned\"\r\n\r\n [class.est-ltab-border]=\"cell.LeftBorder && !selectionStatus[item._ordinal][index]?.lborder\" \r\n [class.est-rtab-border]=\"cell.RightBorder && !selectionStatus[item._ordinal][index]?.rborder\" \r\n\r\n [class.est-selected-cell]=\"selectionStatus[item._ordinal][index]?.selected\"\r\n [class.est-cell-lborder]=\"selectionStatus[item._ordinal][index]?.lborder\"\r\n [class.est-cell-rborder]=\"selectionStatus[item._ordinal][index]?.rborder\"\r\n [class.est-cell-tborder]=\"selectionStatus[item._ordinal][index]?.tborder\"\r\n [class.est-cell-bborder]=\"selectionStatus[item._ordinal][index]?.bborder\"\r\n\r\n [class.est-cell-lborder-tmp]=\"!cell.LeftBorder && !selectionStatus[item._ordinal][index]?.lborder && !selectionStatus[item._ordinal][index]?.loverlaps\"\r\n [class.est-cell-rborder-tmp]=\"!cell.RightBorder && !selectionStatus[item._ordinal][index]?.rborder && !selectionStatus[item._ordinal][index]?.roverlaps\"\r\n [class.est-cell-tborder-tmp]=\"!selectionStatus[item._ordinal][index]?.tborder && !selectionStatus[item._ordinal][index]?.toverlaps\"\r\n [class.est-cell-bborder-tmp]=\"!selectionStatus[item._ordinal][index]?.bborder && !selectionStatus[item._ordinal][index]?.boverlaps\"\r\n\r\n (mousedown)=\"mousedown($event, cell, item)\" \r\n (mouseenter)=\"mouseenter($event)\" \r\n (mouseup)=\"mouseup($event)\"\r\n (onCellGeneration)=\"registerCell($event)\"\r\n \r\n (click)=\"dbClickEditOrSingleClickRowSelection($event, cell, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"cell._editing\" [class.est-pre]=\"!(Hierarchy && index == 0)\">\r\n\r\n <ng-container #DEBUG>\r\n <!-- Debug box in caso la roba che viene scritta nelle celle non torni. Scirvere qui i propri binding per controllare cose -->\r\n </ng-container>\r\n\r\n <!-- 90% Template disponibile, quindi derivante da *td, controllo giusto che non sia un field particolare multi -->\r\n <ng-container *ngIf=\"cell.Template\">\r\n <ng-container *ngIf=\"!cell.Multi\"><ng-container *ngTemplateOutlet=\"cell.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"cell.Multi\"><ng-container *ngTemplateOutlet=\"cell.Template; context: { $implicit: (item[cell.MultiProp] ? item[cell.MultiProp][cell.MultiIndex] : {}) }\"></ng-container></span>\r\n </ng-container>\r\n \r\n <!-- 8%\r\n Template non disponibile, pu\u00F2 venire da \r\n RoutePath in caso sia un link di una tabella dinamica\r\n PropAccessor in caso di ReportRow (quindi oggetti con \"values\" dentro), \r\n o Renderer se modalit\u00E0 dinamica/standard (in qual caso il renderer \u00E8 il default)\r\n -->\r\n <ng-container *ngIf=\"!cell.Template && !cell.Multi && !cell.Content\">\r\n <a *ngIf=\"cell.RoutePath\" [routerLink]=\"item | est_routerlink : cell.RoutePath : cell.RouteParameterProperties\" class=\"est-link\" [innerHTML]=\"item.properties ? item.properties[cell.PropertyName] : item[cell.PropertyName]\"></a>\r\n \r\n <span *ngIf=\"cell.PropAccessor\">\r\n {{(item.values? item.values[cell.PropAccessor] : item[cell.PropAccessor]) | est_format: cell.Format }}\r\n </span>\r\n\r\n <ng-container *ngIf=\"!cell.PropAccessor && !cell.RoutePath\">\r\n <ng-container *ngTemplateOutlet=\"cell.PropertyName | est_renderer: { name: cell.RendererName, src: EsTdsDirective, fallback: defaultEsTd }; context: { $implicit: { definition: cell, value: item.properties ? item.properties[cell.PropertyName] : item[cell.PropertyName], type: cell.PropertyType} }\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- 1% Se in modalit\u00E0 gerarchica metto il td per navigare la gerarchia -->\r\n <ng-container *ngIf=\"Hierarchy && index == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <!-- 1% Content programmatico per le casistiche di Row Grouping ecc... -->\r\n <ng-container *ngIf=\"cell.Content\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"cell._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"cell.PropertyName | est_editor: { name: cell.EditorName, src: EsTdEditorDirectives, fallback: defaultEditor}; context: { $implicit: { definition: cell, columnIndex: index, item: item, finalizer: finalizeUserEdit.bind(this, cell, item, index) } }\"></ng-container>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Navigatore della gerarchia di una view gerarchica, con tasto per espandere e collassare -->\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem><span><em>{{'No operations available' | localize : lc}}...</em></span></ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last; trackBy: idTrackBy\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last; trackBy: idTrackBy\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-default-row-height{height:31px}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-full-height{height:100%}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:1px solid #bbb!important}.est-rtab-border{border-right:1px solid #bbb!important}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-selected-cell{background-color:#2196f333}.est-cell-lborder{border-left:1.02px solid #2196f3!important}.est-cell-tborder{border-top:1.02px solid #2196f3!important}.est-cell-rborder{border-right:1.02px solid #2196f3!important}.est-cell-bborder{border-bottom:1.02px solid #2196f3!important}.est-cell-lborder-tmp{border-left:1.02px solid transparent!important}.est-cell-tborder-tmp{border-top:1.02px solid transparent!important}.est-cell-rborder-tmp{border-right:1.02px solid transparent!important}.est-cell-bborder-tmp{border-bottom:1.02px solid transparent!important}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"] }]
4410
5531
  }], ctorParameters: function () { return [{ type: i1.NgControl, decorators: [{
4411
5532
  type: Self
4412
5533
  }, {
@@ -4423,12 +5544,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4423
5544
  }, {
4424
5545
  type: Inject,
4425
5546
  args: [EST_LOCALE]
4426
- }] }, { type: i2.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: UtilitiesHandler }, { type: i5.UtilityService }, { type: i5.ExportService }, { type: i5.DateService }, { type: i5.MessageService }]; }, propDecorators: { EsTdsDirective: [{
5547
+ }] }, { type: i2.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: UtilitiesHandler }, { type: i5.UtilityService }, { type: i5.ExportService }, { type: i5.DateService }, { type: i5.MessageService }, { type: CopyPasteDetector }, { type: i5.ClipboardService }, { type: Logger }]; }, propDecorators: { EsTdEditorDirectives: [{
5548
+ type: ContentChildren,
5549
+ args: [EsTdEditorDirective]
5550
+ }], EsTdsDirective: [{
4427
5551
  type: ContentChildren,
4428
5552
  args: [EsTdDirective]
4429
5553
  }], EsThsDirective: [{
4430
5554
  type: ContentChildren,
4431
5555
  args: [EsThDirective]
5556
+ }], EsTableTemplate: [{
5557
+ type: Input
4432
5558
  }], bodyRef: [{
4433
5559
  type: ContentChild,
4434
5560
  args: ['body', { static: false }]
@@ -4452,7 +5578,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4452
5578
  type: Input
4453
5579
  }], AutoUpdate: [{
4454
5580
  type: Input
4455
- }], UseCustomCells: [{
5581
+ }], Height: [{
5582
+ type: Input
5583
+ }], EmptySpaceBackgroundColor: [{
5584
+ type: Input
5585
+ }], EsTableHandledSearch: [{
4456
5586
  type: Input
4457
5587
  }], MaxHeight: [{
4458
5588
  type: Input
@@ -4494,6 +5624,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4494
5624
  type: Input
4495
5625
  }], ExportFunction: [{
4496
5626
  type: Input
5627
+ }], ExportOnlyVisibleColumns: [{
5628
+ type: Input
4497
5629
  }], HasHeaderGroup: [{
4498
5630
  type: Input
4499
5631
  }], HasSecondaryHeaderGroup: [{
@@ -4536,6 +5668,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4536
5668
  type: Input
4537
5669
  }], SavePreferences: [{
4538
5670
  type: Input
5671
+ }], DefaultAlignment: [{
5672
+ type: Input
4539
5673
  }], PagingStyle: [{
4540
5674
  type: Input
4541
5675
  }], RowGroupingPagingStyle: [{
@@ -4546,7 +5680,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4546
5680
  type: Input
4547
5681
  }], ShowItemGroupsColumns: [{
4548
5682
  type: Input
4549
- }], UserEdits: [{
5683
+ }], Editable: [{
5684
+ type: Input
5685
+ }], RangeSelection: [{
5686
+ type: Input
5687
+ }], SearchThrottle: [{
4550
5688
  type: Input
4551
5689
  }], onOrderChanged: [{
4552
5690
  type: Output
@@ -4558,6 +5696,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4558
5696
  type: Output
4559
5697
  }], onAbortRemoval: [{
4560
5698
  type: Output
5699
+ }], onModelChange: [{
5700
+ type: Output
5701
+ }], onOpenContextMenu: [{
5702
+ type: Output
4561
5703
  }], onCornerAction: [{
4562
5704
  type: Output
4563
5705
  }], onDynamicOperation: [{
@@ -4570,12 +5712,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4570
5712
  args: ['emptyMenu', { static: true }]
4571
5713
  }], ArraymodeItemsPerPage: [{
4572
5714
  type: Input
5715
+ }] } });
5716
+ class EsTdReference {
5717
+ }
5718
+
5719
+ //Angular
5720
+ /** Componente rappresentante un template di th coi loro relativi td da poter riutilizzare quandomminchia si vuole */
5721
+ class EsTableTemplate {
5722
+ }
5723
+ EsTableTemplate.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
5724
+ EsTableTemplate.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: EsTableTemplate, selector: "es-table-template", queries: [{ propertyName: "EsTdsDirective", predicate: EsTdDirective }, { propertyName: "EsThsDirective", predicate: EsThDirective }], ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush });
5725
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableTemplate, decorators: [{
5726
+ type: Component,
5727
+ args: [{ selector: "es-table-template", changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
5728
+ }], propDecorators: { EsTdsDirective: [{
5729
+ type: ContentChildren,
5730
+ args: [EsTdDirective]
5731
+ }], EsThsDirective: [{
5732
+ type: ContentChildren,
5733
+ args: [EsThDirective]
4573
5734
  }] } });
4574
5735
 
4575
5736
  /** Modello di configurazione per L'EsTable */
4576
5737
  class EsTableModuleConfig {
4577
5738
  }
4578
5739
 
5740
+ const MODULES = [
5741
+ CommonModule,
5742
+ FormsModule,
5743
+ RouterModule,
5744
+ LocalizationModule,
5745
+ ModalModule,
5746
+ BsDropdownModule,
5747
+ ContextMenuModule,
5748
+ MatSelectModule,
5749
+ MatInputModule,
5750
+ MatTooltipModule,
5751
+ DragDropModule,
5752
+ FormsAndValidationsModule
5753
+ ];
5754
+ const PUBLIC_ELEMENTS = [
5755
+ // Direttive
5756
+ EsTdDirective,
5757
+ EsThDirective,
5758
+ EsTdEditorDirective,
5759
+ // Componenti
5760
+ EsTableComponent,
5761
+ TablePagerComponent,
5762
+ EsTableTemplate
5763
+ ];
5764
+ const PRIVATE_ELEMENTS = [
5765
+ // Componenti
5766
+ EsTh,
5767
+ EsTd,
5768
+ // Pipes
5769
+ EstFormatPipe,
5770
+ EstLookupPipe,
5771
+ EstRouterLinkPipe,
5772
+ EstRendererPipe,
5773
+ EstEditorPipe
5774
+ ];
4579
5775
  class EsTableModule {
4580
5776
  static forRoot(config) {
4581
5777
  return {
@@ -4588,53 +5784,52 @@ class EsTableModule {
4588
5784
  };
4589
5785
  }
4590
5786
  }
4591
- EsTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4592
- EsTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, declarations: [EsTh, EsTd, EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent], imports: [CommonModule,
5787
+ EsTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5788
+ EsTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, declarations: [
5789
+ // Direttive
5790
+ EsTdDirective,
5791
+ EsThDirective,
5792
+ EsTdEditorDirective,
5793
+ // Componenti
5794
+ EsTableComponent,
5795
+ TablePagerComponent,
5796
+ EsTableTemplate,
5797
+ // Componenti
5798
+ EsTh,
5799
+ EsTd,
5800
+ // Pipes
5801
+ EstFormatPipe,
5802
+ EstLookupPipe,
5803
+ EstRouterLinkPipe,
5804
+ EstRendererPipe,
5805
+ EstEditorPipe], imports: [CommonModule,
4593
5806
  FormsModule,
4594
5807
  RouterModule,
4595
5808
  LocalizationModule,
4596
5809
  ModalModule,
4597
5810
  BsDropdownModule,
4598
- CsvModule,
4599
5811
  ContextMenuModule,
4600
5812
  MatSelectModule,
4601
5813
  MatInputModule,
5814
+ MatTooltipModule,
4602
5815
  DragDropModule,
4603
- FormsAndValidationsModule], exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent] });
4604
- EsTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, providers: [UtilityService, ExportService, HashingService, MessageService], imports: [[
4605
- CommonModule,
4606
- FormsModule,
4607
- RouterModule,
4608
- LocalizationModule,
4609
- ModalModule,
4610
- BsDropdownModule,
4611
- CsvModule,
4612
- ContextMenuModule,
4613
- MatSelectModule,
4614
- MatInputModule,
4615
- DragDropModule,
4616
- FormsAndValidationsModule
4617
- ]] });
4618
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, decorators: [{
5816
+ FormsAndValidationsModule], exports: [
5817
+ // Direttive
5818
+ EsTdDirective,
5819
+ EsThDirective,
5820
+ EsTdEditorDirective,
5821
+ // Componenti
5822
+ EsTableComponent,
5823
+ TablePagerComponent,
5824
+ EsTableTemplate] });
5825
+ EsTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, providers: [UtilityService, ExportService, HashingService, MessageService], imports: [[MODULES]] });
5826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, decorators: [{
4619
5827
  type: NgModule,
4620
5828
  args: [{
4621
- imports: [
4622
- CommonModule,
4623
- FormsModule,
4624
- RouterModule,
4625
- LocalizationModule,
4626
- ModalModule,
4627
- BsDropdownModule,
4628
- CsvModule,
4629
- ContextMenuModule,
4630
- MatSelectModule,
4631
- MatInputModule,
4632
- DragDropModule,
4633
- FormsAndValidationsModule
4634
- ],
4635
- declarations: [EsTh, EsTd, EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent],
5829
+ imports: [MODULES],
5830
+ declarations: [...PUBLIC_ELEMENTS, ...PRIVATE_ELEMENTS],
4636
5831
  providers: [UtilityService, ExportService, HashingService, MessageService],
4637
- exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent]
5832
+ exports: [...PUBLIC_ELEMENTS]
4638
5833
  }]
4639
5834
  }] });
4640
5835
 
@@ -4712,9 +5907,13 @@ class ReportParam {
4712
5907
  class ReportRow {
4713
5908
  }
4714
5909
 
5910
+ /** Classe che rappresenta il riferimento ad una proprietà di un oggetto bindato sulla tabella */
5911
+ class ItemPropEditableReference {
5912
+ }
5913
+
4715
5914
  /**
4716
5915
  * Generated bundle index. Do not edit.
4717
5916
  */
4718
5917
 
4719
- export { AppOrdering, AppSearch, CornerMenuOption, EsTableColumnsDefinition, EsTableComponent, EsTableDefaultable, EsTableModule, EsTableModuleConfig, EsTableMultiValue, EsTableOperationDefinition, EsTdDirective, EsThDirective, GenericItem, Group, GroupAggregation, GroupFilter, GroupOrAggregation, ItemsSelection, ReportColumn, ReportParam, ReportRow, TablePagerComponent };
5918
+ export { AppOrdering, AppSearch, CornerMenuOption, EsTableColumnsDefinition, EsTableComponent, EsTableDefaultable, EsTableModelChange, EsTableModule, EsTableModuleConfig, EsTableMultiValue, EsTableOperationDefinition, EsTableTemplate, EsTdDirective, EsTdEditorDirective, EsTdReference, EsThDirective, GenericItem, Group, GroupAggregation, GroupFilter, GroupOrAggregation, ItemPropEditableReference, ItemsSelection, ReportColumn, ReportParam, ReportRow, TablePagerComponent };
4720
5919
  //# sourceMappingURL=esfaenza-es-table.mjs.map