@esfaenza/es-table 13.3.2 → 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 -5
  2. package/esm2020/lib/components/es-table/es_table.component.mjs +547 -117
  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 +1581 -361
  42. package/fesm2015/esfaenza-es-table.mjs.map +1 -1
  43. package/fesm2020/esfaenza-es-table.mjs +1560 -358
  44. package/fesm2020/esfaenza-es-table.mjs.map +1 -1
  45. package/lib/components/es-table/es_table.component.d.ts +173 -80
  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\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -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\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -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,12 +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"]);
395
- super.set("en->it", "Paging options are not available for this report", ["Le opzioni di paginazione non sono disponibili per questo report"]);
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"]);
396
520
  }
397
521
  }
398
- 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 });
399
- EsTableLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc });
400
- 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: [{
401
525
  type: Injectable
402
526
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
403
527
  type: Optional
@@ -434,8 +558,7 @@ class ExportHandler {
434
558
  }
435
559
  this.setupExport(data);
436
560
  if (format == "CSV") {
437
- this.est.cdr.detectChanges();
438
- setTimeout(() => { this.est.exportDownloader.nativeElement.click(); });
561
+ this.exportCSV();
439
562
  }
440
563
  else if (format == "XLSX") {
441
564
  if (this.ExcelJS != null) {
@@ -454,6 +577,33 @@ class ExportHandler {
454
577
  throw "Formato di esportazione non riconosciuto";
455
578
  }, format);
456
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
+ }
457
607
  /** Effettua l'esportazione del file Excel basandosi sul modulo **ExcelJS**, sugli header **this.est.headers** e sui dati **this.est.data** */
458
608
  async exportExcel() {
459
609
  let iFix = 1;
@@ -475,17 +625,28 @@ class ExportHandler {
475
625
  let h = this.est.headers[i];
476
626
  let cell = row.getCell(i + 1);
477
627
  let val = item[h.key];
478
- if (val == null || val == undefined)
628
+ if (!val) {
479
629
  cell.value = "";
480
- else {
481
- switch (h.type) {
482
- case 'date':
483
- cell.value = this.dateExts.getDateConvertion(val).toDate();
484
- case 'number':
485
- cell.value = parseFloat(val.replace(',', '.'));
486
- default:
487
- cell.value = val;
488
- }
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;
489
650
  }
490
651
  }
491
652
  }
@@ -502,7 +663,9 @@ class ExportHandler {
502
663
  */
503
664
  setupExport(items) {
504
665
  let drcd = this.est.DynamicRowColumnsDefinition;
505
- 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);
506
669
  this.est.data = items;
507
670
  }
508
671
  }
@@ -532,10 +695,11 @@ class EsTableColumn {
532
695
  * @param {string} description Descrizione (Header)
533
696
  * @param {boolean} visible Indica se di default mostrarla o meno
534
697
  * @param {boolean} fixed Indica se è una colonna fixed
698
+ * @param {boolean} pinnable Indica se una colonna può essere pinnata
535
699
  * @param {boolean} pinned Indica se è una colonna pinnata
536
700
  * @param {number} pinnedWidth Indica la dimensione da assegnare a questa colonna quando è pinnata
537
701
  * @param {TemplateRef<any>} template Indica il template da usare per mostrare il testo dell'Header
538
- * @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**)
539
703
  * @param {boolean} multi Indica che la colonna deriva da una direttiva **Multi**
540
704
  * @param {string} multiContent Indica il contenuto della direttiva **Multi** per questa colonna
541
705
  */
@@ -604,6 +768,12 @@ class ColumnMetadataHandler {
604
768
  this.est.arrayOrders = [new AppOrdering(id, order)];
605
769
  }
606
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
+ }
607
777
  this.est.onOrderChanged.emit({ id, order });
608
778
  if (this.est.viewMode) {
609
779
  if (this.est.groupSearchRequestsCache.length > 0)
@@ -614,6 +784,30 @@ class ColumnMetadataHandler {
614
784
  else if (this.est.arrayMode)
615
785
  this.est.internalWriteValue();
616
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
+ }
617
811
  /**
618
812
  * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
619
813
  *
@@ -645,6 +839,7 @@ class ColumnMetadataHandler {
645
839
  this.est.ColumnsList = [];
646
840
  this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
647
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 */
648
843
  expandMultiThsAndTds(ths, tds, items) {
649
844
  // Registro le info sui multiprovider
650
845
  let multiDefs = {};
@@ -696,6 +891,7 @@ class ColumnMetadataHandler {
696
891
  newtH._multi_content = headerValue;
697
892
  newtH.th = `${prop}_${ii}`;
698
893
  newtH.thClass = refth.thClass;
894
+ newtH.thShrink = refth.thShrink;
699
895
  newtH.thIf = refth.thIf;
700
896
  newtH.thVisible = refth.thVisible;
701
897
  newtH.thWrap = refth.thWrap;
@@ -753,7 +949,6 @@ class ColumnMetadataHandler {
753
949
  * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
754
950
  */
755
951
  moveFixedColumnsAtTheBeginning(ths, tds) {
756
- let thsCache = {};
757
952
  let fixeds = 0, pinneds = 0;
758
953
  let columnsCache = {};
759
954
  let columnsIndexCache = {};
@@ -778,7 +973,6 @@ class ColumnMetadataHandler {
778
973
  // Sposto tutti gli header fixed o pinned all'inizio
779
974
  for (let i = 0; i < ths.length; i++) {
780
975
  let th = ths[i];
781
- thsCache[th.th] = th;
782
976
  // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
783
977
  th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
784
978
  if (th.thPinned) {
@@ -821,6 +1015,7 @@ class ColumnMetadataHandler {
821
1015
  * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
822
1016
  *
823
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
824
1019
  */
825
1020
  alignColumnsIfLoadedView(view) {
826
1021
  let emitChanged = this.est.viewMode && view.savedstate;
@@ -838,10 +1033,10 @@ class ColumnMetadataHandler {
838
1033
  if (c.visible && columns.length == 0)
839
1034
  newColset.push(c.id);
840
1035
  // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
841
- else if (exCl.length == 1 && !c.visible)
1036
+ else if (exCl.length == 1 && !c.visible && !this.est.useLocalVisibility)
842
1037
  c.visible = true;
843
1038
  // Allineamento sull'AppSearch per casistiche inverse al di sopra
844
- else if (exCl.length == 0 && c.visible)
1039
+ else if (exCl.length == 0 && c.visible && !this.est.useLocalVisibility)
845
1040
  c.visible = false;
846
1041
  });
847
1042
  // Non ho colonne nella appsearch, vuol dire che sono al primo binding
@@ -870,6 +1065,9 @@ class ColumnMetadataHandler {
870
1065
  // In ogni caso questo non mi serve più, lo resetto **
871
1066
  if (this.est.viewMode)
872
1067
  view.savedstate = false;
1068
+ // Reset di questa variabile usata one-bind
1069
+ if (this.est.useLocalVisibility)
1070
+ this.est.useLocalVisibility = false;
873
1071
  if (emitChanged)
874
1072
  this.est.changed();
875
1073
  }
@@ -973,22 +1171,22 @@ class ColumnMetadataHandler {
973
1171
  evaluateHeaderGroups(infos) {
974
1172
  if (infos.groupingLevel == 0)
975
1173
  return;
976
- // 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 ******/
977
1175
  let expandedGroups = [];
978
- let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
1176
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
979
1177
  for (let l = 0; l < infos.groupingLevel; l++) {
980
1178
  expandedGroups.push([]);
981
1179
  for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
982
1180
  expandedGroups[l].push("");
983
1181
  }
984
- // Ordino le foglie in base agli ordinamenti delle colonne
1182
+ /****** STEP 2: Ordino le foglie in base agli ordinamenti delle colonne ******/
985
1183
  let orderedLeafs = [];
986
1184
  for (let i = 0; i < this.est.OrderDirectives.length; i++) {
987
1185
  let leaf = infos.thsCache[this.est.OrderDirectives[i]];
988
- if (leaf.thVisible && !leaf.thPinned)
1186
+ if (leaf.thVisible && leaf.thIf && !leaf.thPinned)
989
1187
  orderedLeafs.push(leaf);
990
1188
  }
991
- // 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 ******/
992
1190
  let currentParent = "";
993
1191
  for (let i = 0; i < orderedLeafs.length; i++) {
994
1192
  let refTh = orderedLeafs[i];
@@ -1009,35 +1207,51 @@ class ColumnMetadataHandler {
1009
1207
  }
1010
1208
  }
1011
1209
  }
1012
- // 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 ******/
1013
1211
  currentParent = "";
1014
1212
  let currentSpan = 0;
1015
- this.est.TMPRowThGroups = [];
1213
+ let finalHeaders = [];
1016
1214
  for (let l = 0; l < expandedGroups.length; l++) {
1017
1215
  let levelArray = [];
1018
- this.est.TMPRowThGroups.push(levelArray);
1216
+ finalHeaders.push(levelArray);
1019
1217
  if (this.est.Selection || this.est.HasPinnedColumns)
1020
- 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 });
1021
1219
  for (let h = 0; h < expandedGroups[l].length; h++) {
1022
1220
  let item = expandedGroups[l][h];
1023
1221
  if (item == currentParent)
1024
1222
  currentSpan++;
1025
1223
  else {
1026
1224
  if (currentSpan > 0)
1027
- 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 });
1028
1226
  currentSpan = 1;
1029
1227
  currentParent = item;
1030
1228
  }
1031
1229
  }
1032
1230
  // Ultima aggiunta che altrimenti mi rimarrebbe in cache
1033
- 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
1034
1233
  if (this.est.Removal)
1035
- levelArray.push({ Span: 1, Template: null });
1234
+ levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
1036
1235
  if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
1037
- levelArray.push({ Span: 1, Template: null });
1236
+ levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
1038
1237
  currentSpan = 0;
1039
1238
  currentParent = "";
1040
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
+ }
1041
1255
  }
1042
1256
  /**
1043
1257
  * Calcola il numero di salti da un header foglia all'ultimo parent della catena
@@ -1055,9 +1269,9 @@ class ColumnMetadataHandler {
1055
1269
  if (parent) {
1056
1270
  th = thsCache[parent];
1057
1271
  if (!th.thEmpty && !th._multi_content)
1058
- parentsPrepend.unshift({ tmpl: th.Template });
1272
+ parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
1059
1273
  else if (!th.thEmpty && th._multi_content)
1060
- parentsPrepend.unshift({ content: th._multi_content });
1274
+ parentsPrepend.unshift({ id: th.th, content: th._multi_content });
1061
1275
  jumps++;
1062
1276
  }
1063
1277
  } while (parent);
@@ -1118,7 +1332,9 @@ class ColumnMetadataHandler {
1118
1332
  let newContext = [];
1119
1333
  this.est.OrderDirectives.forEach(o => {
1120
1334
  let contextItem = context.filter(t => t.ID == o)[0];
1121
- newContext.push(contextItem);
1335
+ // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
1336
+ if (contextItem)
1337
+ newContext.push(contextItem);
1122
1338
  });
1123
1339
  this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
1124
1340
  }
@@ -1270,20 +1486,8 @@ class ColumnMetadataHandler {
1270
1486
  this.refreshColumnsVisibility(null, null, castedView);
1271
1487
  //Salvo le preferences di questa view
1272
1488
  //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
1273
- if (this.est.SavePreferences) {
1274
- if (!this.est.ngControl.name) {
1275
- console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
1276
- return false;
1277
- }
1278
- if (!this.prefService) {
1279
- console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
1280
- return false;
1281
- }
1282
- let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
1283
- let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
1284
- var toStore = { columns: JSON.parse(JSON.stringify(columns)), column_ordering: JSON.parse(JSON.stringify(columnsOrderings)) };
1285
- this.prefService.setItem(this.est.ngControl.name, toStore, 'preference').subscribe();
1286
- }
1489
+ if (this.est.SavePreferences)
1490
+ this.registerViewPreferences(castedView);
1287
1491
  // Rieseguo l'ultima ricerca bindata alla tabella
1288
1492
  // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
1289
1493
  if (this.est.viewMode)
@@ -1330,29 +1534,46 @@ class EsTableColumnsDefinition {
1330
1534
  /**
1331
1535
  * Costruttore
1332
1536
  *
1333
- * @param {string} description Descrizione della colonna
1334
- * @param {string} propertyName Nome della proprietà del modello in cui sono contenuti i dati da visualizzare per questa colonna
1335
- * @param {string} routePath Route di navigazione. Es. "['/pages/mod/mod_detail', { 'idItem': '{0}', 'idItem2' : '{1}' }]"
1336
- * @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.
1337
1541
  * L'indice scritto in **routePath** è l'indice di accesso a questo array. Es. ["iditem", "iditem2"]
1338
- * @param {'ASC' | 'DESC' } dataOrder Ordinamento dei dati presentati in questa colonna
1339
- * @param {number} columnOrder Ordinamento di questa colonna
1340
- * @param {boolean} visible Visibilità o meno della colonna
1341
- * @param {string} clss Classe da applicare sia ai TD che ai TH relativi a questa colonna
1342
- * @param {boolean} orderable Indica se la colonna è ordinabile o no (nel senso ASC / DESC / NONE)
1343
- * @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
1344
1552
  */
1345
- constructor(description, propertyName, routePath = null, routeParameterProperties = null, dataOrder = null, columnOrder = null, visible = true, clss = null, orderable = true, headerWraps = false) {
1346
- this.description = description;
1347
- this.propertyName = propertyName;
1348
- this.routePath = routePath;
1349
- this.routeParameterProperties = routeParameterProperties;
1350
- this.dataOrder = dataOrder;
1351
- this.columnOrder = columnOrder;
1352
- this.visible = visible;
1353
- this.clss = clss;
1354
- this.orderable = orderable;
1355
- 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);
1356
1577
  }
1357
1578
  }
1358
1579
 
@@ -1362,42 +1583,6 @@ class DynamicModeHandler {
1362
1583
  constructor(est) {
1363
1584
  this.est = est;
1364
1585
  }
1365
- /**
1366
- * Metodo di supporto alla creazione di un router link parametrizzato all'oggetto corrente utilizzato nella modalità dinamica
1367
- *
1368
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1369
- * @param {string[]} parameterProps Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1370
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1371
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1372
- *
1373
- * @returns {any} Router link generato in base al parametri
1374
- */
1375
- generateRouterLink(path, parameterProps, item) {
1376
- if (this.est.DynamicTableRouterLinkCache[item._hash + path]) {
1377
- return this.est.DynamicTableRouterLinkCache[item._hash + path];
1378
- }
1379
- else {
1380
- let link = this.getRouterLink(path, parameterProps, item);
1381
- this.est.DynamicTableRouterLinkCache[item._hash + path] = link;
1382
- return link;
1383
- }
1384
- }
1385
- /**
1386
- * Crea un router link
1387
- *
1388
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1389
- * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1390
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1391
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1392
- *
1393
- * @returns {any} Router link generato in base al parametri
1394
- */
1395
- getRouterLink(path, pars, item) {
1396
- for (let i = 0; i < pars.length; i++)
1397
- path = path.replace('{' + i + '}', item.properties[pars[i]]);
1398
- path = path.replace(/'/g, '"').replace(/ /g, '');
1399
- return JSON.parse(path);
1400
- }
1401
1586
  /** Se non ho l'Input **DynamicRowColumnsDefinition** in modalità dinamica lo riempio con il default nome della colonna = testo della colonna */
1402
1587
  eventuallyReviewDynamicColumns() {
1403
1588
  // Senza oggetti esco
@@ -1416,6 +1601,82 @@ class DynamicModeHandler {
1416
1601
  else
1417
1602
  this.est.UserDefinedDynamicCols = true;
1418
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
+ }
1419
1680
  }
1420
1681
 
1421
1682
  /** Classe contenente la gestione della modalità gerarchica */
@@ -1650,17 +1911,25 @@ class ItemsHandler {
1650
1911
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.arraymodePage, this.est.arraymodePages);
1651
1912
  else
1652
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);
1653
1918
  // Poi per tutti i valori dopo compresi fra la pagina - 1 e la pagina
1654
1919
  for (let i = ((this.est.arraymodePage - 1) * this.est.ArraymodeItemsPerPage); i < this.est.arraymodePage * this.est.ArraymodeItemsPerPage; i++) {
1655
- if (i <= this.est.View.length - 1)
1656
- tmpItems.push(this.est.View[i]);
1920
+ if (i <= items.length - 1)
1921
+ tmpItems.push(items[i]);
1657
1922
  }
1658
1923
  return tmpItems;
1659
1924
  }
1660
1925
  /** Se in modalità array applica gli ordinamenti ASC-DESC delle colonne */
1661
- arrayModeReviewOrderings() {
1926
+ arrayModeReviewOrderings(items) {
1927
+ let tmp = items;
1662
1928
  if (this.est.arrayOrders.length > 0)
1663
- 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;
1664
1933
  }
1665
1934
  }
1666
1935
 
@@ -1689,6 +1958,15 @@ class ReportModeHandler {
1689
1958
  this.est.View.pages = Math.ceil(count / ipp);
1690
1959
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.View.page, this.est.View.pages);
1691
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
+ */
1692
1970
  generateThsAndTdsFromView(view) {
1693
1971
  var ret = { ths: [], tds: [] };
1694
1972
  // Ordinamento per ora commentato... non vorrebbe mi fuckappasse tutto
@@ -1697,11 +1975,15 @@ class ReportModeHandler {
1697
1975
  let clm = view.report_columns[i];
1698
1976
  var th = new EsThDirective(null);
1699
1977
  th.th = clm.id;
1700
- th.thStaticContent = clm.description;
1978
+ th.thStaticContent = clm.description || null;
1701
1979
  th.thBackgroundColor = clm.color;
1980
+ th.thAlignment = clm.alignment;
1981
+ th.thFormat = clm.format;
1702
1982
  var td = new EsTdDirective(null);
1703
1983
  td.td = clm.id;
1704
1984
  td.tdPropertyAccessor = i.toString();
1985
+ td.tdAlignment = clm.alignment;
1986
+ td.tdFormat = clm.format;
1705
1987
  ret.ths.push(th);
1706
1988
  ret.tds.push(td);
1707
1989
  }
@@ -1763,8 +2045,9 @@ class GroupPager {
1763
2045
  /**
1764
2046
  * Costruttore
1765
2047
  *
1766
- * @param {number} groupLevel Livello del gruppo a cui questo separatore fa riferimento
1767
- * @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
1768
2051
  * @param {AppSearch<any>} view Vista di ricerca collegata a questo elemento
1769
2052
  * @param {'groups' | 'items'} searches Indica che cosa cerca questo separatore, se sottogruppi o oggetti
1770
2053
  */
@@ -2333,6 +2616,120 @@ class SelectionHandler {
2333
2616
  return;
2334
2617
  this.handleSelectionEvaluation(items, selectionItem);
2335
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
+ }
2336
2733
  /**
2337
2734
  * Implementazione agnostica della valutazione delle selezioni degli oggetti. Richiede gli oggetti della vista attuale e l'itemSelector
2338
2735
  *
@@ -2809,6 +3206,158 @@ class SelectionHandler {
2809
3206
  // Dopo aver resettato direttamente il solo oggetto this.View.selection devo anche riallineare a tutti gli oggetti bindati
2810
3207
  this.evaluateSelection(this.est.boundSource, selectionItem);
2811
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
+ }
2812
3361
  }
2813
3362
 
2814
3363
  // Angular
@@ -2903,10 +3452,7 @@ class UtilitiesHandler {
2903
3452
  for (let i = min; i <= max; i++)
2904
3453
  if (i !== 1)
2905
3454
  result.push({ val: i, cssClass: (i === page ? 'btn-main app-white-text' : 'app-white-button') });
2906
- result.push({
2907
- val: lastPage,
2908
- cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button')
2909
- });
3455
+ result.push({ val: lastPage, cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button') });
2910
3456
  }
2911
3457
  return result;
2912
3458
  }
@@ -2927,9 +3473,11 @@ class UtilitiesHandler {
2927
3473
  delete tmp._selected;
2928
3474
  delete tmp._visible;
2929
3475
  delete tmp._hash;
3476
+ delete tmp._ordinal;
2930
3477
  let hash = this.hashExts.hashObject(tmp);
2931
3478
  usedHashesCache[hash] = usedHashesCache[hash] ? usedHashesCache[hash] + 1 : 1;
2932
3479
  item._hash = hash + (usedHashesCache[hash] > 1 ? "_" + usedHashesCache[hash] : "");
3480
+ item._ordinal = i;
2933
3481
  }
2934
3482
  }
2935
3483
  /**
@@ -2953,13 +3501,61 @@ class UtilitiesHandler {
2953
3501
  return null;
2954
3502
  }
2955
3503
  }
2956
- UtilitiesHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, deps: [{ token: i5.HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
2957
- UtilitiesHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, providedIn: 'root' });
2958
- 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: [{
2959
3507
  type: Injectable,
2960
3508
  args: [{ providedIn: 'root' }]
2961
3509
  }], ctorParameters: function () { return [{ type: i5.HashingService }]; } });
2962
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
+
2963
3559
  //Angular
2964
3560
  /** Componente rappresentante una Colonna della tabella */
2965
3561
  class EsTh {
@@ -3088,11 +3684,11 @@ class EsTh {
3088
3684
  $event.preventDefault();
3089
3685
  }
3090
3686
  }
3091
- 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 });
3092
- 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 });
3093
- 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: [{
3094
3690
  type: Component,
3095
- 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>" }]
3096
3692
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ID: [{
3097
3693
  type: Input,
3098
3694
  args: ['es-th']
@@ -3133,75 +3729,206 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
3133
3729
  args: ['window:mousemove.out-zone', ['$event']]
3134
3730
  }] } });
3135
3731
 
3136
- //Angular
3732
+ // Angular
3137
3733
  /** Componente rappresentante una singola cella del body della tabella */
3138
3734
  class EsTd {
3139
3735
  /** @ignore */
3140
- constructor(myself, renderer, _viewContainer, sanitizer) {
3141
- this.myself = myself;
3142
- this.renderer = renderer;
3143
- this._viewContainer = _viewContainer;
3144
- this.sanitizer = sanitizer;
3736
+ constructor(cdr) {
3737
+ this.cdr = cdr;
3145
3738
  /** Id della cella, dev'essere lo stesso della colonna **EsTh** relativa */
3146
3739
  this.ID = "";
3147
- /** Valore da mostrare all'interno della cella. Se omesso verrà proiettato il contenuto dal template in cui è stata usata */
3148
- this.Display = null;
3149
- /** Template Angular da istanziare per questo TD */
3150
- this.Template = null;
3151
- }
3152
- /**
3153
- * Imposta la visibilità o meno della cella, si traduce nell'applicazione o rimozione della classe **app-display-none**
3154
- *
3155
- * @param {boolean} expression Indicazione della visibilità
3156
- */
3157
- set Visible(expression) {
3158
- this._Visible = expression;
3159
- if (expression)
3160
- this.renderer.removeClass(this.myself.nativeElement, "app-display-none");
3161
- else
3162
- this.renderer.addClass(this.myself.nativeElement, "app-display-none");
3163
- }
3164
- /**
3165
- * Restituisce lo stato di Visibilità della cella in oggetto
3166
- *
3167
- * @returns {boolean} **true** se visibile, **false** altrimenti
3168
- */
3169
- get Visible() {
3170
- if (this._Visible == undefined)
3171
- this._Visible = true;
3172
- 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 = "";
3173
3744
  }
3174
3745
  /** @ignore */
3175
3746
  ngAfterViewInit() {
3176
- // Se è Internal significa che è gestita internamente da ES-TABLE quindi evito di fare sti due passaggi di lettura del DOM
3177
- if (this.Internal)
3178
- return;
3179
- this.Content = this.Display === null || this.Display === "" ? this.sanitizer.bypassSecurityTrustHtml(this.myself.nativeElement.innerHTML) : this.sanitizer.bypassSecurityTrustHtml(this.Display);
3180
- 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();
3181
3753
  }
3182
3754
  }
3183
- 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 });
3184
- 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 });
3185
- 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: [{
3186
3758
  type: Component,
3187
- args: [{ selector: "[es-td]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>\r\n <ng-content></ng-content>\r\n</span>" }]
3188
- }], 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: [{
3189
3761
  type: Input,
3190
3762
  args: ['es-td']
3191
- }], Internal: [{
3192
- type: Input
3193
- }], RouterLink: [{
3194
- type: Input
3195
- }], Display: [{
3196
- type: Input
3197
- }], Template: [{
3198
- type: Input
3199
3763
  }], Context: [{
3200
3764
  type: Input
3201
- }], Visible: [{
3202
- type: Input
3765
+ }], onCellGeneration: [{
3766
+ type: Output
3203
3767
  }] } });
3204
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
+
3205
3932
  /** Raccolta di tutti gli Input dell'EsTable a cui può essere logicamente sensato assegnare default per progetto */
3206
3933
  class EsTableDefaultable {
3207
3934
  }
@@ -3210,7 +3937,7 @@ class EsTableDefaultable {
3210
3937
  /** Componente che permette di rappresentare una griglia di valori */
3211
3938
  class EsTableComponent {
3212
3939
  /** @ignore */
3213
- 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) {
3214
3941
  this.ngControl = ngControl;
3215
3942
  this.prefService = prefService;
3216
3943
  this.deafults = deafults;
@@ -3222,11 +3949,14 @@ class EsTableComponent {
3222
3949
  this.expExts = expExts;
3223
3950
  this.dateExts = dateExts;
3224
3951
  this.msgExts = msgExts;
3952
+ this.copyPasteDetector = copyPasteDetector;
3953
+ this.clipboardService = clipboardService;
3954
+ this.logger = logger;
3225
3955
  /** Subject utilizzato internamente lato EsTable per causare il Focus lato componente di Input */
3226
3956
  this.FocusSubject = new Subject();
3227
3957
  /** Se vengono effettuati 2 click a distanza inferiore a questi Millisecondi viene considerato un doppio click */
3228
3958
  this.doubleClickBufferMs = 200;
3229
- /** View finale su cui bindarsi lato Frontend, il tipo può essere IAppSearch<any> (per la **viewMode**), any[] (per l'**arrayMode**) e ReportDefinition per la **reportMode** */
3959
+ /** View finale su cui bindarsi lato Frontend, il tipo può essere IAppSearch<any> (per la **viewMode**), any[] (per l'**arrayMode**) */
3230
3960
  this.View = null;
3231
3961
  /** Indica se l'es-table deve mostrare il check globale nell'header per fare il "seleziona tutto" */
3232
3962
  this.globalCheck = false;
@@ -3247,9 +3977,9 @@ class EsTableComponent {
3247
3977
  this.boundSource = [];
3248
3978
  /** Stessa cosa della **boundSource**, utilizzata come appoggio temporaneo interno */
3249
3979
  this.TMPBoundSource = [];
3250
- /** "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 */
3251
3981
  this.boundSubSources = [];
3252
- /** 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** */
3253
3983
  this.addedSlices = [];
3254
3984
  /** Variabile che identifica il valore del "seleziona Tutto" nella paginazione */
3255
3985
  this.defaultAllPageOverride = 999999;
@@ -3259,20 +3989,20 @@ class EsTableComponent {
3259
3989
  this.seconds = '10';
3260
3990
  /** Impostata a true ogni volta che viene avviata una ricerca, e a false ogni volta che un nuovo valore viene ricevuto */
3261
3991
  this.researchInProgress = false;
3262
- /** Modello rappresentante un dizionario di righe della tabella, con chiave l'hash e valore la lista di celle */
3263
- this.RowTDs = null;
3264
3992
  /** Modello di appoggio temporaneo per i **RowTDs** */
3265
3993
  this.TMPRowTDs = null;
3266
- /** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
3267
- 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;
3268
3998
  /** Modello di appoggio temporaneo per i **RowTHs** */
3269
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;
3270
4002
  /** Modello di appoggio temporaneo per i **RowThGroups** */
3271
4003
  this.TMPRowThGroups = null;
3272
4004
  /** Modello rappresentante un singolo header group della tabella. Questa lista è già ordinata e pronta per essere utilizzata in ngFor */
3273
4005
  this.RowThGroups = null;
3274
- /** Cache per i routerLink generati nelle tabelle dinamiche */
3275
- this.DynamicTableRouterLinkCache = {};
3276
4006
  /**
3277
4007
  * Lista dei contesti. Un contesto non è altro che un hash particolare calcolato su un oggetto che identifica univocamente tale oggetto.
3278
4008
  *
@@ -3283,6 +4013,19 @@ class EsTableComponent {
3283
4013
  this.OrderDirectives = [];
3284
4014
  /** Codice dell'ultimo oggetto solezionato */
3285
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;
3286
4029
  /**
3287
4030
  * Indica se oltre alle colonne dinamiche specifiche di un tipo di oggetto ci sono anche colonne dinamiche aggiunte dall'utente
3288
4031
  *
@@ -3305,18 +4048,12 @@ class EsTableComponent {
3305
4048
  this.ColumnsPinnable = null;
3306
4049
  /** Indica se dev'essere disponibile il sistema di aggiornamento automatico */
3307
4050
  this.AutoUpdate = null;
3308
- /**
3309
- * Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
3310
- *
3311
- * 1) Ordinamento e visibilità delle colonne
3312
- *
3313
- * 2) Ordinamento dei dati
3314
- *
3315
- * 3) Modalità Gerarchica
3316
- *
3317
- * ecc...
3318
- */
3319
- 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;
3320
4057
  /** Permette di impostare l'altezza massima della tabella. Se null la dimensione si adatta al numero di elementi attualmente in visualizzazione */
3321
4058
  this.MaxHeight = null;
3322
4059
  /** Classi da applicare al contenitore della tabella */
@@ -3359,9 +4096,11 @@ class EsTableComponent {
3359
4096
  this.ExportFileName = 'Export.csv';
3360
4097
  /** Classe (HTML) di default della tabella */
3361
4098
  this.TableClass = null;
3362
- /** 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 */
3363
4102
  this.HasHeaderGroup = null;
3364
- /** 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** */
3365
4104
  this.HasSecondaryHeaderGroup = null;
3366
4105
  /** Indica se nascondere gli Header della tabella */
3367
4106
  this.HeaderHidden = null;
@@ -3387,7 +4126,7 @@ class EsTableComponent {
3387
4126
  this.HiddenColumns = null;
3388
4127
  /** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
3389
4128
  this.ColumnsOrdering = null;
3390
- /** Eventuale supporto alle ricerche applicate alla modalità Array */
4129
+ /** @deprecated Eventuale supporto alle ricerche applicate alla modalità Array */
3391
4130
  this.SearchView = null;
3392
4131
  /** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
3393
4132
  this.SelectAll = null;
@@ -3407,6 +4146,8 @@ class EsTableComponent {
3407
4146
  this.StartsExpanded = true;
3408
4147
  /** Indica se effettuare il salvataggio delle preferenze di ricerca */
3409
4148
  this.SavePreferences = null;
4149
+ /** Allineamento di default per celle e headers */
4150
+ this.DefaultAlignment = null;
3410
4151
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
3411
4152
  this.PagingStyle = null;
3412
4153
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
@@ -3418,7 +4159,11 @@ class EsTableComponent {
3418
4159
  /** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
3419
4160
  this.ShowItemGroupsColumns = null;
3420
4161
  /** Indica che tutti i campi che definiscono le modalità di modifica campo possono essere modificati in base alle impostazioni */
3421
- 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;
3422
4167
  /** Evento che viene richiamato al cambio di oridnamento di una colonna */
3423
4168
  this.onOrderChanged = new EventEmitter();
3424
4169
  /**
@@ -3437,6 +4182,10 @@ class EsTableComponent {
3437
4182
  this.onRemoval = new EventEmitter();
3438
4183
  /** Evento richiamato all'annullamento di un'eliminazione */
3439
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();
3440
4189
  /** Evento richiamato quando si clicca su un opzione definita nelle **CornerMenuOptions** */
3441
4190
  this.onCornerAction = new EventEmitter();
3442
4191
  /** Evento richiamato quando si clicca su un opzione definita nelle **DynamicOperations** */
@@ -3487,12 +4236,47 @@ class EsTableComponent {
3487
4236
  this.ArrayGrouping = false;
3488
4237
  /** Indica che l'es-table è basata sulle direttive (nuova modalità) */
3489
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;
3490
4254
  /** Opzioni di paginazione */
3491
- 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();
3492
4256
  /** @ignore */
3493
4257
  this.propagateChange = (_) => { };
3494
4258
  /** Funzione di trackby per il body che dovrebbe evitare il 90% delle change detection */
3495
- 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(); });
3496
4280
  this.export_H = new ExportHandler(this, this.expExts, this.msgExts, this.utiExts, this.dateExts);
3497
4281
  this.rowGrouping_H = new RowGroupingHandler(this, this.utilities_H, this.dateExts);
3498
4282
  this.columnMetadata_H = new ColumnMetadataHandler(this, this.utilities_H, this.utiExts, this.prefService, this.rowGrouping_H);
@@ -3521,6 +4305,7 @@ class EsTableComponent {
3521
4305
  this.ShowItemGroupsColumns = this.utilities_H.InputOrDefault(this.ShowItemGroupsColumns, this.deafults?.ShowItemGroupsColumns, false);
3522
4306
  this.ArraymodeItemsPerPage = this.utilities_H.InputOrDefault(this.ArraymodeItemsPerPage, this.deafults?.ArraymodeItemsPerPage, 15);
3523
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');
3524
4309
  }
3525
4310
  /** @ignore */
3526
4311
  ngOnInit() {
@@ -3531,6 +4316,7 @@ class EsTableComponent {
3531
4316
  return;
3532
4317
  let shouldEmit = !t.item._selected;
3533
4318
  t.item._selected = true;
4319
+ this.selection_H.clearSelectionStatusExcluding(null);
3534
4320
  var itemSelection = this.selection_H.handleItemsSelection([t.item]);
3535
4321
  this.changed();
3536
4322
  if (shouldEmit)
@@ -3541,7 +4327,9 @@ class EsTableComponent {
3541
4327
  ngAfterViewInit() {
3542
4328
  // Se utilizzo la new spicy mode deduco tutti i parametri di lavoro possibili al caricamento della tabella
3543
4329
  // Vengono sovrascritte solo le proprietà non impostate dall'utente
3544
- 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;
3545
4333
  let hasNoContentProjection = !this.bodyRef && !this.headerRef && !this.headerGroupRef && !this.secondaryHeaderGroupRef;
3546
4334
  if (usesThsAndTdsDirectives || hasNoContentProjection) {
3547
4335
  if (this.UseCustomCells == null)
@@ -3565,24 +4353,40 @@ class EsTableComponent {
3565
4353
  }
3566
4354
  /** @ignore */
3567
4355
  ngOnDestroy() {
4356
+ if (this.copySubscription)
4357
+ this.copySubscription.unsubscribe();
4358
+ if (this.pasteSubscription)
4359
+ this.pasteSubscription.unsubscribe();
3568
4360
  if (this.ctxMenuSubscription)
3569
4361
  this.ctxMenuSubscription.unsubscribe();
4362
+ if (this.copyPasteDetector.ActiveEstReference == this)
4363
+ this.copyPasteDetector.ActiveEstReference = null;
3570
4364
  }
3571
4365
  /** @ignore */
3572
4366
  async ngOnChanges(changes) {
3573
4367
  let newSearchView = changes['SearchView'];
3574
4368
  if (newSearchView && this.SearchView)
3575
- 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);
3576
4370
  }
3577
4371
  /** @ignore */
3578
4372
  registerOnChange(fn) { this.propagateChange = fn; }
3579
4373
  /** @ignore */
3580
4374
  registerOnTouched(fn) { }
3581
4375
  /** @ignore */
3582
- changed() { this.propagateChange(this.View); }
4376
+ changed(clearItems = false) {
4377
+ if (clearItems && this.viewMode)
4378
+ this.View.items = [];
4379
+ this.propagateChange(this.View);
4380
+ }
3583
4381
  /** @ignore */
3584
- async writeValue(obj) {
4382
+ async writeValue(obj, throttle = true) {
3585
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
+ }
3586
4390
  // Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
3587
4391
  this.researchInProgress = false;
3588
4392
  if (!this.View && !this.SearchView) {
@@ -3636,16 +4440,29 @@ class EsTableComponent {
3636
4440
  }
3637
4441
  // In modalità report devo controllare che tutte le colonne salvate facciano parte della vista
3638
4442
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3639
- // 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
3640
4444
  for (let i = 0; i < source.length; i++) {
3641
4445
  if (repository.indexOf(source[i]) == -1) {
3642
4446
  updatedPrefs = false;
3643
4447
  break;
3644
4448
  }
3645
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
+ }
3646
4460
  if (updatedPrefs) {
3647
4461
  this.View.columns = prefs?.columns || [];
3648
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 || [];
3649
4466
  }
3650
4467
  }
3651
4468
  }
@@ -3681,7 +4498,10 @@ class EsTableComponent {
3681
4498
  repository = cols;
3682
4499
  source = this.View.columns;
3683
4500
  }
3684
- // 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;
3685
4505
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3686
4506
  // sto facendo riferimento a una versione vecchia dell'es-table, quindi non foccio operazioni
3687
4507
  for (let i = 0; i < source.length; i++) {
@@ -3693,6 +4513,9 @@ class EsTableComponent {
3693
4513
  if (updatedPrefs) {
3694
4514
  this.View.columns = prefs?.columns || [];
3695
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 || [];
3696
4519
  }
3697
4520
  }
3698
4521
  }
@@ -3701,6 +4524,15 @@ class EsTableComponent {
3701
4524
  }
3702
4525
  this.finalizeContext();
3703
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
+ }
3704
4536
  }
3705
4537
  /**
3706
4538
  * Successivamente al bind del nuovo input questa funzione si occupa di finalizzare tutti i parametri di funzionamento dell'es-table
@@ -3708,7 +4540,7 @@ class EsTableComponent {
3708
4540
  */
3709
4541
  finalizeContext() {
3710
4542
  let viewCasted = this.View;
3711
- 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));
3712
4544
  // Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
3713
4545
  if (this.arrayMode && hasRowGroups)
3714
4546
  this.UseArrayModePaging = false;
@@ -3752,7 +4584,7 @@ class EsTableComponent {
3752
4584
  this.PagerOptions.PagerCount = this.View.length || 0;
3753
4585
  this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && (this.View.length > 10 || (this.SearchView?.objectcount || 0) > 10);
3754
4586
  this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
3755
- this.PagerOptions.ShowPaging = this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount;
4587
+ this.PagerOptions.ShowPaging = this.PagerOptions.ShowPaging && (this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount);
3756
4588
  this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
3757
4589
  }
3758
4590
  else if (this.viewMode) {
@@ -3780,10 +4612,13 @@ class EsTableComponent {
3780
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 */
3781
4613
  internalPostBoundSource() {
3782
4614
  let View = this.View;
3783
- let ths = this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
3784
- 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() : [];
3785
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
3786
4620
  this.dynamicMode_H.eventuallyReviewDynamicColumns();
4621
+ // Gestisce la richiesta per gruppi o per singoli oggetti
3787
4622
  this.bindDisplayToLoadedItemsOrGroups(View);
3788
4623
  // Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
3789
4624
  this.setupPagingInformations();
@@ -3794,22 +4629,34 @@ class EsTableComponent {
3794
4629
  let si = this.viewMode ? view.selection : this.arraymodeSelection;
3795
4630
  // N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
3796
4631
  // ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
3797
- // Espando i th e i td multipli duplicandoli
3798
- let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
3799
- ths = ret.expThs;
3800
- 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
+ }
3801
4639
  // Gestione delle view in modalità report, i th e i td vengono rigenerati dalle configurazioni della view
3802
4640
  if (!this.arrayMode && view.report_columns) {
4641
+ this.logger.log("Generating ths and tds from report results");
3803
4642
  let ret = this.reportMode_H.generateThsAndTdsFromView(view);
3804
4643
  ths = ret.ths;
3805
4644
  tds = ret.tds;
3806
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;
3807
4656
  // Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
3808
4657
  let hI = this.columnMetadata_H.evaluateHeadersGroupingInfos(ths);
3809
- if (this.arrayMode) { // In modalità array non ho un backend...
3810
- this.items_H.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
4658
+ if (this.arrayMode) // In modalità array non ho un backend...
3811
4659
  this.rowGrouping_H.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
3812
- }
3813
4660
  this.columnMetadata_H.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
3814
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.
3815
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)
@@ -3825,6 +4672,8 @@ class EsTableComponent {
3825
4672
  this.columnMetadata_H.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
3826
4673
  this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
3827
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);
3828
4677
  if (this.ResearchNeeded) {
3829
4678
  this.changed();
3830
4679
  this.emitSearchRequest(false);
@@ -3896,6 +4745,10 @@ class EsTableComponent {
3896
4745
  */
3897
4746
  setSelectionStatus(items, all, select) {
3898
4747
  if (all) {
4748
+ if (!this.SelectAll) {
4749
+ console.error("Impossibile impostare la selezione con l'all selection quando l'Input SelectAll è false");
4750
+ return;
4751
+ }
3899
4752
  let si = this.View?.selection || this.arraymodeSelection;
3900
4753
  //se deseleziono con attuale selezione ad all o se seleziono con attuale selezione manuale devo richiamare la **selectAllOrResetSelection**
3901
4754
  if ((si.all && !select) || (!si.all && select))
@@ -3937,7 +4790,13 @@ class EsTableComponent {
3937
4790
  viewOverride.internalsearchrequest = true;
3938
4791
  }
3939
4792
  this.researchInProgress = true;
3940
- 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);
3941
4800
  }
3942
4801
  /**
3943
4802
  * Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
@@ -3952,16 +4811,11 @@ class EsTableComponent {
3952
4811
  evaluateRowTds(ths, tds) {
3953
4812
  if (tds.length == 0)
3954
4813
  return;
3955
- let thsCache = {};
3956
4814
  let columnsCache = {};
3957
4815
  for (let coli = 0; coli < this.ColumnsList.length; coli++) {
3958
4816
  let col = this.ColumnsList[coli];
3959
4817
  columnsCache[col.id] = col;
3960
4818
  }
3961
- for (let i = 0; i < ths.length; i++) {
3962
- let th = ths[i];
3963
- thsCache[th.th] = th;
3964
- }
3965
4819
  this.TMPRowTDs = {};
3966
4820
  // Variabile d'appoggio per permettermi di inserire tutte le colonne "Fixed" davanti
3967
4821
  let contextFixeds = {};
@@ -3971,22 +4825,54 @@ class EsTableComponent {
3971
4825
  let item = this.boundSource[i];
3972
4826
  let ctx = item._hash;
3973
4827
  let key = td.td;
3974
- let th = thsCache[td.td];
3975
- let drcd = this.DynamicRowColumnsDefinition;
4828
+ let th = this.thsCache[td.td];
3976
4829
  if (!!th)
3977
4830
  th._referenced = true;
3978
- else if (!drcd || !drcd.find(t => t.propertyName == td.td)) {
3979
- let subject = drcd && drcd.length > 0 ? "le colonne dinamiche specificate" : "gli ID dicharati negli EsTh";
3980
- console.error(`ID dell'oggeto EsTd non compatibile con ${subject} ${td.td}`);
3981
- return;
3982
- }
3983
4831
  // Skippare senza th (casistica tabella dinamica)
3984
- if (th && (td.tdIf || th.thGroup)) {
4832
+ if (th && th.thIf && (td.tdIf || th.thGroup)) {
3985
4833
  let thCasted = th;
3986
4834
  let isFixed = th.thFixed || th.thGroup || th.thPinned;
3987
4835
  let itemToAdd = item._item ?
3988
- { 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 } :
3989
- { 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
+ };
3990
4876
  if (this.TMPRowTDs[ctx]) {
3991
4877
  this.TMPRowTDs[ctx].push(itemToAdd);
3992
4878
  }
@@ -4036,8 +4922,26 @@ class EsTableComponent {
4036
4922
  let th = ths[i];
4037
4923
  let toAdd;
4038
4924
  if (th.thIf || th.thGroup) {
4039
- let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
4040
- 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
+ };
4041
4945
  this.TMPRowTHs.push(toAdd);
4042
4946
  // Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
4043
4947
  // li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
@@ -4076,6 +4980,8 @@ class EsTableComponent {
4076
4980
  this.emitSearchRequest(false, appSearchElement);
4077
4981
  }
4078
4982
  /**
4983
+ * @TODO Spostare in SelectionHandler
4984
+ *
4079
4985
  * Gestisce i click sulla tabella solo per le righe a gruppo.
4080
4986
  * O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
4081
4987
  *
@@ -4132,6 +5038,7 @@ class EsTableComponent {
4132
5038
  * @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
4133
5039
  */
4134
5040
  globalCheckChanged(forcedVal = null) {
5041
+ this.selection_H.clearSelectionStatusExcluding(null);
4135
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
4136
5043
  let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
4137
5044
  var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
@@ -4139,6 +5046,8 @@ class EsTableComponent {
4139
5046
  this.onSelectionChanged.emit(itemSelection);
4140
5047
  }
4141
5048
  /**
5049
+ * @TODO Spostare in SelectionHandler
5050
+ *
4142
5051
  * Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
4143
5052
  *
4144
5053
  * @param {any} event Evento nativo HTML del click
@@ -4147,12 +5056,8 @@ class EsTableComponent {
4147
5056
  * @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
4148
5057
  */
4149
5058
  handleClick(event, item) {
4150
- // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
4151
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
4152
- return false;
4153
- // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
4154
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
4155
- this.utiExts.clearTextSelection();
5059
+ this.selection_H.clearTextSelection(event);
5060
+ this.selection_H.clearSelectionStatusExcluding(null);
4156
5061
  let selecteditems = [];
4157
5062
  if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
4158
5063
  let startSelecting = false;
@@ -4255,13 +5160,32 @@ class EsTableComponent {
4255
5160
  * Ottiene il contenuto dell'EsTd da utilizzare per la colonna specificata
4256
5161
  *
4257
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**
4258
5164
  *
4259
5165
  * @returns {TemplateRef<any>} Template da usare per la colonna
4260
5166
  */
4261
- findEsTd(column) {
4262
- 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);
4263
5172
  return EsTd ? EsTd.Template : null;
4264
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
+ }
4265
5189
  /**
4266
5190
  * Equivalente del metodo **addToPage** riadattato per la modalità array
4267
5191
  *
@@ -4309,7 +5233,7 @@ class EsTableComponent {
4309
5233
  this.internalWriteCall = false;
4310
5234
  }
4311
5235
  /** Metodo eventualmente richiamabile anche dal componente esterno che permette di forzare un refresh della tabella */
4312
- forceRefresh() {
5236
+ forceRefresh(relaunchSearch = true) {
4313
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
4314
5238
  let arrayPage;
4315
5239
  let arrayIpp;
@@ -4317,6 +5241,8 @@ class EsTableComponent {
4317
5241
  arrayPage = this.arraymodePage;
4318
5242
  arrayIpp = this.ArraymodeItemsPerPage;
4319
5243
  }
5244
+ if (!relaunchSearch && this.viewMode)
5245
+ this.View.selfsearch = true;
4320
5246
  this.writeValue(this.View);
4321
5247
  this.cdr.detectChanges();
4322
5248
  if (this.arrayMode) {
@@ -4324,6 +5250,28 @@ class EsTableComponent {
4324
5250
  this.arrayGoToPage(arrayPage);
4325
5251
  }
4326
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
+ }
4327
5275
  /**
4328
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
4329
5277
  *
@@ -4332,30 +5280,107 @@ class EsTableComponent {
4332
5280
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4333
5281
  */
4334
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;
4335
5318
  // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
4336
5319
  if (rowItem._editing)
4337
5320
  return;
4338
5321
  // Per evitare di rallentare a prescindere
4339
- if (!this.UserEdits) {
4340
- this.handleRowClick($event, item, this.Selection);
5322
+ if (!this.Editable) {
5323
+ this.handleRowClick($event, item, this.Selection, true);
4341
5324
  return;
4342
5325
  }
4343
- // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
4344
- if (this.cellDbClickTimer) {
4345
- if (this.UserEdits && rowItem.UserEdits)
4346
- this.setupUserEdit(rowItem);
4347
- 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)
4348
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);
4349
5336
  }
4350
- // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
4351
- this.cellDbClickTimer = setTimeout(() => {
4352
- this.clearCellClickTimer();
4353
- this.handleRowClick($event, item, this.Selection);
4354
- }, this.doubleClickBufferMs);
4355
5337
  }
4356
- /**
4357
- * Ripulisce il timer utilizzato per capire se è stato effettuato un doppio click o meno
4358
- */
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 */
4359
5384
  clearCellClickTimer() {
4360
5385
  clearTimeout(this.cellDbClickTimer);
4361
5386
  this.cellDbClickTimer = null;
@@ -4366,9 +5391,15 @@ class EsTableComponent {
4366
5391
  * @param {any} $event Evento nativo javascript
4367
5392
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4368
5393
  * @param {boolean} selection Indica se la selezione è attiva
4369
- *
5394
+ * @param {boolean} internalCall Indica se la chiamata a questa funzione è interna: permette di skippare i check sulle CustomCells
4370
5395
  */
4371
- 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);
4372
5403
  if (selection && !item.locked && !item._sep && !item._group)
4373
5404
  this.handleClick($event, item);
4374
5405
  else if (item._group)
@@ -4376,34 +5407,127 @@ class EsTableComponent {
4376
5407
  // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
4377
5408
  this.cdr.markForCheck();
4378
5409
  }
5410
+ /**
5411
+ * Gestione del click destro sull'es-table
5412
+ */
5413
+ onRightClick() {
5414
+ if (this.Selection)
5415
+ this.onOpenContextMenu.emit();
5416
+ }
4379
5417
  /**
4380
5418
  * La modifica dell'utente è iniziata. Si imposta la variabile relativa a "true" in modo da mostrare l'input di testo
4381
5419
  *
4382
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
4383
5421
  *
4384
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
4385
5424
  */
4386
- setupUserEdit(rowItem) {
4387
- 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;
4388
5429
  rowItem._editing = true;
5430
+ rowItem.old_value = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
5431
+ }
4389
5432
  this.cdr.detectChanges();
4390
5433
  setTimeout(() => { this.FocusSubject.next(); });
4391
5434
  }
4392
5435
  /**
4393
- * 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
4394
5437
  *
4395
5438
  * @param {TdElement} rowItem Elemento di riga su cui è stata attivata la modifica
4396
5439
  * @param {any} item Oggetto sopra il quale è stata attivata la modifica
5440
+ * @param {number} columnIndex Indice della colonna su cui è avvenuta la modifica
4397
5441
  */
4398
- finalizeUserEdit(rowItem, item) {
4399
- 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;
4400
5524
  }
4401
5525
  }
4402
- 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 });
4403
- 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 *ngIf=\"!PagerOptions.ShowPaging\"><em>{{'Paging options are not available for this report' | localize: lc}}</em></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 });
4404
- 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: [{
4405
5529
  type: Component,
4406
- 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 *ngIf=\"!PagerOptions.ShowPaging\"><em>{{'Paging options are not available for this report' | localize: lc}}</em></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"] }]
4407
5531
  }], ctorParameters: function () { return [{ type: i1.NgControl, decorators: [{
4408
5532
  type: Self
4409
5533
  }, {
@@ -4420,12 +5544,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4420
5544
  }, {
4421
5545
  type: Inject,
4422
5546
  args: [EST_LOCALE]
4423
- }] }, { 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: [{
4424
5551
  type: ContentChildren,
4425
5552
  args: [EsTdDirective]
4426
5553
  }], EsThsDirective: [{
4427
5554
  type: ContentChildren,
4428
5555
  args: [EsThDirective]
5556
+ }], EsTableTemplate: [{
5557
+ type: Input
4429
5558
  }], bodyRef: [{
4430
5559
  type: ContentChild,
4431
5560
  args: ['body', { static: false }]
@@ -4449,7 +5578,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4449
5578
  type: Input
4450
5579
  }], AutoUpdate: [{
4451
5580
  type: Input
4452
- }], UseCustomCells: [{
5581
+ }], Height: [{
5582
+ type: Input
5583
+ }], EmptySpaceBackgroundColor: [{
5584
+ type: Input
5585
+ }], EsTableHandledSearch: [{
4453
5586
  type: Input
4454
5587
  }], MaxHeight: [{
4455
5588
  type: Input
@@ -4491,6 +5624,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4491
5624
  type: Input
4492
5625
  }], ExportFunction: [{
4493
5626
  type: Input
5627
+ }], ExportOnlyVisibleColumns: [{
5628
+ type: Input
4494
5629
  }], HasHeaderGroup: [{
4495
5630
  type: Input
4496
5631
  }], HasSecondaryHeaderGroup: [{
@@ -4533,6 +5668,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4533
5668
  type: Input
4534
5669
  }], SavePreferences: [{
4535
5670
  type: Input
5671
+ }], DefaultAlignment: [{
5672
+ type: Input
4536
5673
  }], PagingStyle: [{
4537
5674
  type: Input
4538
5675
  }], RowGroupingPagingStyle: [{
@@ -4543,7 +5680,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4543
5680
  type: Input
4544
5681
  }], ShowItemGroupsColumns: [{
4545
5682
  type: Input
4546
- }], UserEdits: [{
5683
+ }], Editable: [{
5684
+ type: Input
5685
+ }], RangeSelection: [{
5686
+ type: Input
5687
+ }], SearchThrottle: [{
4547
5688
  type: Input
4548
5689
  }], onOrderChanged: [{
4549
5690
  type: Output
@@ -4555,6 +5696,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4555
5696
  type: Output
4556
5697
  }], onAbortRemoval: [{
4557
5698
  type: Output
5699
+ }], onModelChange: [{
5700
+ type: Output
5701
+ }], onOpenContextMenu: [{
5702
+ type: Output
4558
5703
  }], onCornerAction: [{
4559
5704
  type: Output
4560
5705
  }], onDynamicOperation: [{
@@ -4567,12 +5712,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4567
5712
  args: ['emptyMenu', { static: true }]
4568
5713
  }], ArraymodeItemsPerPage: [{
4569
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]
4570
5734
  }] } });
4571
5735
 
4572
5736
  /** Modello di configurazione per L'EsTable */
4573
5737
  class EsTableModuleConfig {
4574
5738
  }
4575
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
+ ];
4576
5775
  class EsTableModule {
4577
5776
  static forRoot(config) {
4578
5777
  return {
@@ -4585,53 +5784,52 @@ class EsTableModule {
4585
5784
  };
4586
5785
  }
4587
5786
  }
4588
- EsTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4589
- 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,
4590
5806
  FormsModule,
4591
5807
  RouterModule,
4592
5808
  LocalizationModule,
4593
5809
  ModalModule,
4594
5810
  BsDropdownModule,
4595
- CsvModule,
4596
5811
  ContextMenuModule,
4597
5812
  MatSelectModule,
4598
5813
  MatInputModule,
5814
+ MatTooltipModule,
4599
5815
  DragDropModule,
4600
- FormsAndValidationsModule], exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent] });
4601
- EsTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, providers: [UtilityService, ExportService, HashingService, MessageService], imports: [[
4602
- CommonModule,
4603
- FormsModule,
4604
- RouterModule,
4605
- LocalizationModule,
4606
- ModalModule,
4607
- BsDropdownModule,
4608
- CsvModule,
4609
- ContextMenuModule,
4610
- MatSelectModule,
4611
- MatInputModule,
4612
- DragDropModule,
4613
- FormsAndValidationsModule
4614
- ]] });
4615
- 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: [{
4616
5827
  type: NgModule,
4617
5828
  args: [{
4618
- imports: [
4619
- CommonModule,
4620
- FormsModule,
4621
- RouterModule,
4622
- LocalizationModule,
4623
- ModalModule,
4624
- BsDropdownModule,
4625
- CsvModule,
4626
- ContextMenuModule,
4627
- MatSelectModule,
4628
- MatInputModule,
4629
- DragDropModule,
4630
- FormsAndValidationsModule
4631
- ],
4632
- declarations: [EsTh, EsTd, EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent],
5829
+ imports: [MODULES],
5830
+ declarations: [...PUBLIC_ELEMENTS, ...PRIVATE_ELEMENTS],
4633
5831
  providers: [UtilityService, ExportService, HashingService, MessageService],
4634
- exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent]
5832
+ exports: [...PUBLIC_ELEMENTS]
4635
5833
  }]
4636
5834
  }] });
4637
5835
 
@@ -4709,9 +5907,13 @@ class ReportParam {
4709
5907
  class ReportRow {
4710
5908
  }
4711
5909
 
5910
+ /** Classe che rappresenta il riferimento ad una proprietà di un oggetto bindato sulla tabella */
5911
+ class ItemPropEditableReference {
5912
+ }
5913
+
4712
5914
  /**
4713
5915
  * Generated bundle index. Do not edit.
4714
5916
  */
4715
5917
 
4716
- 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 };
4717
5919
  //# sourceMappingURL=esfaenza-es-table.mjs.map