@esfaenza/es-table 13.3.3 → 13.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/esm2020/lib/components/es-table/es_table.component.loc.mjs +7 -4
  2. package/esm2020/lib/components/es-table/es_table.component.mjs +542 -116
  3. package/esm2020/lib/components/es-table-template/es_table_template.component.mjs +21 -0
  4. package/esm2020/lib/components/es-td/es_td.component.mjs +23 -55
  5. package/esm2020/lib/components/es-th/es_th.component.mjs +5 -5
  6. package/esm2020/lib/components/pager/table_pager.component.loc.mjs +3 -3
  7. package/esm2020/lib/components/pager/table_pager.component.mjs +5 -5
  8. package/esm2020/lib/components/pipes/est-format.pipe.mjs +44 -0
  9. package/esm2020/lib/components/pipes/est-lookup.pipe.mjs +19 -0
  10. package/esm2020/lib/components/pipes/est-renderer.pipe.mjs +36 -0
  11. package/esm2020/lib/components/pipes/est-routerlink.pipe.mjs +41 -0
  12. package/esm2020/lib/components/pipes/est_editor.pipe.mjs +36 -0
  13. package/esm2020/lib/core/CopyPasteDetector.mjs +28 -0
  14. package/esm2020/lib/core/Logger.mjs +26 -0
  15. package/esm2020/lib/core/handlers/ColumnMetadataHandler.mjs +75 -35
  16. package/esm2020/lib/core/handlers/DynamicModeHandler.mjs +80 -37
  17. package/esm2020/lib/core/handlers/ExportHandler.mjs +53 -14
  18. package/esm2020/lib/core/handlers/ItemsHandler.mjs +13 -5
  19. package/esm2020/lib/core/handlers/ReportModeHandler.mjs +15 -2
  20. package/esm2020/lib/core/handlers/SelectionHandler.mjs +267 -1
  21. package/esm2020/lib/core/handlers/UtilitiesHandler.mjs +7 -8
  22. package/esm2020/lib/directives/es_td.directive.mjs +24 -6
  23. package/esm2020/lib/directives/es_td_editor.directive.mjs +24 -0
  24. package/esm2020/lib/directives/es_th.directive.mjs +39 -9
  25. package/esm2020/lib/domain/configuration/EsTableDefaultable.mjs +1 -1
  26. package/esm2020/lib/domain/externals/EsTableColumnsDefinition.mjs +39 -22
  27. package/esm2020/lib/domain/externals/EsTableModelChange.mjs +19 -0
  28. package/esm2020/lib/domain/externals/ItemPropEditableReference.mjs +4 -0
  29. package/esm2020/lib/domain/externals/appsearch/AppSearch.mjs +33 -14
  30. package/esm2020/lib/domain/externals/report/ReportColumn.mjs +1 -1
  31. package/esm2020/lib/domain/externals/report/ReportRow.mjs +1 -1
  32. package/esm2020/lib/domain/internals/EsTableColumn.mjs +3 -2
  33. package/esm2020/lib/domain/internals/GroupPager.mjs +4 -3
  34. package/esm2020/lib/domain/internals/PagerInfos.mjs +15 -0
  35. package/esm2020/lib/domain/internals/TdElement.mjs +1 -1
  36. package/esm2020/lib/domain/internals/ThElement.mjs +1 -1
  37. package/esm2020/lib/domain/internals/ThGroup.mjs +2 -0
  38. package/esm2020/lib/domain/types.mjs +2 -0
  39. package/esm2020/lib/es-table.module.mjs +78 -37
  40. package/esm2020/public-api.mjs +6 -1
  41. package/fesm2015/esfaenza-es-table.mjs +1576 -359
  42. package/fesm2015/esfaenza-es-table.mjs.map +1 -1
  43. package/fesm2020/esfaenza-es-table.mjs +1555 -356
  44. package/fesm2020/esfaenza-es-table.mjs.map +1 -1
  45. package/lib/components/es-table/es_table.component.d.ts +172 -79
  46. package/lib/components/es-table-template/es_table_template.component.d.ts +18 -0
  47. package/lib/components/es-td/es_td.component.d.ts +14 -34
  48. package/lib/components/pipes/est-format.pipe.d.ts +10 -0
  49. package/lib/components/pipes/est-lookup.pipe.d.ts +13 -0
  50. package/lib/components/pipes/est-renderer.pipe.d.ts +15 -0
  51. package/lib/components/pipes/est-routerlink.pipe.d.ts +20 -0
  52. package/lib/components/pipes/est_editor.pipe.d.ts +15 -0
  53. package/lib/core/CopyPasteDetector.d.ts +15 -0
  54. package/lib/core/Logger.d.ts +10 -0
  55. package/lib/core/handlers/ColumnMetadataHandler.d.ts +8 -0
  56. package/lib/core/handlers/DynamicModeHandler.d.ts +13 -23
  57. package/lib/core/handlers/ExportHandler.d.ts +4 -0
  58. package/lib/core/handlers/ItemsHandler.d.ts +1 -1
  59. package/lib/core/handlers/ReportModeHandler.d.ts +9 -0
  60. package/lib/core/handlers/SelectionHandler.d.ts +90 -0
  61. package/lib/core/handlers/UtilitiesHandler.d.ts +4 -1
  62. package/lib/directives/es_td.directive.d.ts +18 -2
  63. package/lib/directives/es_td_editor.directive.d.ts +14 -0
  64. package/lib/directives/es_th.directive.d.ts +43 -11
  65. package/lib/domain/configuration/EsTableDefaultable.d.ts +1 -0
  66. package/lib/domain/externals/EsTableColumnsDefinition.d.ts +48 -23
  67. package/lib/domain/externals/EsTableModelChange.d.ts +17 -0
  68. package/lib/domain/externals/ItemPropEditableReference.d.ts +34 -0
  69. package/lib/domain/externals/appsearch/AppSearch.d.ts +15 -2
  70. package/lib/domain/externals/report/ReportColumn.d.ts +4 -0
  71. package/lib/domain/externals/report/ReportRow.d.ts +4 -0
  72. package/lib/domain/internals/EsTableColumn.d.ts +4 -1
  73. package/lib/domain/internals/GroupPager.d.ts +3 -2
  74. package/lib/domain/internals/PagerInfos.d.ts +13 -0
  75. package/lib/domain/internals/TdElement.d.ts +18 -5
  76. package/lib/domain/internals/ThElement.d.ts +6 -0
  77. package/lib/domain/internals/ThGroup.d.ts +10 -0
  78. package/lib/domain/types.d.ts +2 -0
  79. package/lib/es-table.module.d.ts +26 -19
  80. package/package.json +9 -10
  81. package/public-api.d.ts +5 -0
@@ -1,33 +1,32 @@
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
14
  import { __awaiter } from 'tslib';
15
- import * as i16 from '@angular/cdk/drag-drop';
15
+ import * as i17 from '@angular/cdk/drag-drop';
16
16
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
17
17
  import { Subject } from 'rxjs';
18
18
  import * as i2$1 from '@esfaenza/preferences';
19
- import * as i1$1 from '@angular/platform-browser';
20
- import * as i9 from '@esfaenza/forms-and-validations';
19
+ import * as i10 from '@esfaenza/forms-and-validations';
21
20
  import { FormsAndValidationsModule } from '@esfaenza/forms-and-validations';
22
- import * as i10 from '@esfaenza/ngx-contextmenu';
21
+ import * as i1$1 from '@angular/material/tooltip';
22
+ import { MatTooltipModule } from '@angular/material/tooltip';
23
+ import * as i12 from '@esfaenza/ngx-contextmenu';
23
24
  import { ContextMenuModule } from '@esfaenza/ngx-contextmenu';
24
- import * as i12 from '@ctrl/ngx-csv';
25
- import { CsvModule } from '@ctrl/ngx-csv';
26
- import * as i13 from 'ngx-bootstrap/dropdown';
25
+ import * as i14 from 'ngx-bootstrap/dropdown';
27
26
  import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
28
- import * as i14 from '@angular/router';
27
+ import * as i15 from '@angular/router';
29
28
  import { RouterModule } from '@angular/router';
30
- import * as i15 from 'ngx-bootstrap/modal';
29
+ import * as i16 from 'ngx-bootstrap/modal';
31
30
  import { ModalModule } from 'ngx-bootstrap/modal';
32
31
  import { MatSelectModule } from '@angular/material/select';
33
32
 
@@ -50,9 +49,9 @@ class TablePagerLoc extends LocalizationService {
50
49
  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"]);
51
50
  }
52
51
  }
53
- 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 });
54
- TablePagerLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerLoc });
55
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerLoc, decorators: [{
52
+ 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 });
53
+ TablePagerLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerLoc });
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerLoc, decorators: [{
56
55
  type: Injectable
57
56
  }], ctorParameters: function () {
58
57
  return [{ type: undefined, decorators: [{
@@ -130,11 +129,11 @@ class TablePagerComponent {
130
129
  }
131
130
  }
132
131
  }
133
- 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 });
134
- TablePagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: TablePagerComponent, selector: "app-paging", inputs: { CurrentPageSize: "CurrentPageSize", View: "View", WarnOnAll: "WarnOnAll", AllSearch: "AllSearch", DefaultAll: "DefaultAll", GroupMode: "GroupMode", GroupCount: "GroupCount", CountLabel: "CountLabel", ShowCount: "ShowCount", ShowPaging: "ShowPaging", PagerCount: "PagerCount", Hidden: "Hidden" }, outputs: { pagingSelected: "pagingSelected" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && (Model == DefaultAll || PagerCount >= Model || PagerCount == -1)\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"], components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], pipes: { "localize": i2.LocalizePipe, "number": i11.DecimalPipe }, viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: TablePagerComponent, decorators: [{
132
+ 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 });
133
+ 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 });
134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TablePagerComponent, decorators: [{
136
135
  type: Component,
137
- args: [{ selector: "app-paging", viewProviders: [{ provide: LocalizationService, useClass: TablePagerLoc }], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!Hidden\">\r\n <span class=\"est-fs-14\"> {{CountLabel && !GroupMode ? CountLabel : ((GroupMode ? 'Shown Groups' : 'Shown Elements') | localize : lc)}}:&nbsp;</span>\r\n <ng-container *ngIf=\"ShowPaging && Model && (Model == DefaultAll || PagerCount >= Model || PagerCount == -1)\">\r\n <mat-form-field [appearance]=\"'legacy'\" class=\"mat-paginator-page-size-select est-fs-14 est-ipp-bold\">\r\n <select matNativeControl [ngModel]=\"Model\" name=\"input\" (ngModelChange)=\"choice($event)\">\r\n <ng-container *ngFor=\"let pOpt of PagingOptions; let i = index\">\r\n <option *ngIf=\"pOpt == DefaultAll || PagerCount >= pOpt || PagerCount == -1 || (i > 0 && PagerCount >= PagingOptions[i-1])\" [value]=\"pOpt\">{{ pOpt == DefaultAll ? ('All' | localize : lc) : pOpt.toString()}}</option>\r\n </ng-container>\r\n </select>\r\n </mat-form-field>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">&nbsp;/&nbsp;</span>\r\n </ng-container>\r\n <span class=\"est-fs-14 est-ipp-bold\" *ngIf=\"ShowCount && PagerCount != -1\">{{PagerCount | number : '0.0-0' : locale}}</span>\r\n</ng-container>", styles: [".est-rg-ipp-sel-all,.est-rg-ipp-sel,.est-ipp-sel-all,.est-ipp-sel{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block;display:inline}.est-ipp-bold{font-weight:700}.mat-paginator-page-size-select{margin:6px 4px 0;width:50px}.mat-paginator-page-size-select .mat-form-field-wrapper{height:52px!important;margin-top:-15px!important;padding:0!important}.mat-form-field-type-mat-native-select .mat-form-field-infix:after{margin-top:-5.5px!important}\n"] }]
136
+ 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"] }]
138
137
  }], ctorParameters: function () {
139
138
  return [{ type: i5.MessageService }, { type: i2.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
140
139
  type: Optional
@@ -188,20 +187,54 @@ class AppSearch {
188
187
  this.firstsearch = true;
189
188
  }
190
189
  /**
191
- * Permette di resettare questo oggetto ai valori di default
190
+ * Permette di resettare un AppSearch ai valori di default.
191
+ * Reso statico perché fra una deserializzazione e l'altra si potrebbe perdere il prototype del costruttore
192
+ *
193
+ * @param {AppSearch<any>} aps AppSearch da resettare
192
194
  */
193
- reset() {
194
- this.pages = 1;
195
- this.objectcount = 0;
196
- this.searchinprogress = false;
197
- this.firstsearch = false;
198
- this.page = 1;
199
- this.itemsperpageoverride = 15;
200
- this.items = [];
201
- this.orders = [];
202
- this.columns = [];
203
- this.column_ordering = [];
204
- this.savedstate = false;
195
+ static reset(aps) {
196
+ aps.pages = 1;
197
+ aps.objectcount = 0;
198
+ aps.searchinprogress = false;
199
+ aps.firstsearch = false;
200
+ aps.page = 1;
201
+ aps.itemsperpageoverride = 15;
202
+ aps.items = [];
203
+ aps.orders = [];
204
+ aps.columns = [];
205
+ aps.column_ordering = [];
206
+ aps.savedstate = false;
207
+ aps.selfsearch = false;
208
+ }
209
+ /**
210
+ * Permette di ottenere un nuovo riferimento all'AppSearch passata come parametro.
211
+ * Internamente utilizza il JSON.parse(JSON.stringify(X)) con la differenza che prima stacca il riferimento agli items per evitare di
212
+ * reserializzare potenzialmente centinaia di elementi. Il riferimento viene poi ricollegato alla nuova appsearch generata
213
+ *
214
+ * @param {AppSearch<any>} aps AppSearch di cui estrarre un nuovo riferimento equivalente
215
+ */
216
+ static newref(aps) {
217
+ var items = aps.items;
218
+ aps.items = [];
219
+ var newref = JSON.parse(JSON.stringify(aps));
220
+ newref.items = items;
221
+ newref.page = 1;
222
+ return newref;
223
+ }
224
+ }
225
+
226
+ /** Classe che rappresenta le informazioni di paginazione della tabella attuale */
227
+ class PagerInfos {
228
+ constructor() {
229
+ this.PagerCount = null;
230
+ this.ShowCount = true;
231
+ this.ShowPaging = true;
232
+ this.ShowButtons = true;
233
+ this.ShowPagingOptions = true;
234
+ this.UsesView = true;
235
+ this.View = null;
236
+ this.Ready = false;
237
+ this.Searches = 'items';
205
238
  }
206
239
  }
207
240
 
@@ -242,6 +275,25 @@ class GroupFilter {
242
275
  }
243
276
  }
244
277
 
278
+ /** Classe che rappresenta la modifica ad un singolo oggetto in una singola proprietà */
279
+ class EsTableModelChange {
280
+ /**
281
+ * Costruttore
282
+ * @param {any} item Oggetto modificato
283
+ * @param {string} header Nome dell'Header che è stato modificato
284
+ * @param {string} property Nome della proprietà modificata
285
+ * @param {string} old_value Vecchio valore della proprietà **property** dell'oggetto **item**
286
+ * @param {string} new_value Nuovo valore della proprietà **property** dell'oggetto **item**
287
+ */
288
+ constructor(item, header, property, old_value, new_value) {
289
+ this.item = item;
290
+ this.header = header;
291
+ this.property = property;
292
+ this.old_value = old_value;
293
+ this.new_value = new_value;
294
+ }
295
+ }
296
+
245
297
  /** Direttiva per la dichiarazione snella di un EsTd da emettere per ogni elemento, data una colonna */
246
298
  class EsTdDirective {
247
299
  /**
@@ -259,21 +311,41 @@ class EsTdDirective {
259
311
  this.tdIf = true;
260
312
  }
261
313
  }
262
- EsTdDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTdDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
263
- 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 });
264
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTdDirective, decorators: [{
314
+ 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 });
315
+ 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 });
316
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdDirective, decorators: [{
265
317
  type: Directive,
266
318
  args: [{ selector: '[td]' }]
267
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { tdVisible: [{
319
+ }], ctorParameters: function () {
320
+ return [{ type: i0.TemplateRef, decorators: [{
321
+ type: Self
322
+ }] }];
323
+ }, propDecorators: { tdVisible: [{
268
324
  type: Input
269
325
  }], td: [{
270
326
  type: Input
327
+ }], tdForProperty: [{
328
+ type: Input
271
329
  }], tdIf: [{
272
330
  type: Input
273
331
  }], tdClass: [{
274
332
  type: Input
275
333
  }], tdPropertyAccessor: [{
276
334
  type: Input
335
+ }], tdAlignment: [{
336
+ type: Input
337
+ }], tdFormat: [{
338
+ type: Input
339
+ }], tdIconClass: [{
340
+ type: Input
341
+ }], tdConditionField: [{
342
+ type: Input
343
+ }], tdConditionValue: [{
344
+ type: Input
345
+ }], tdTitle: [{
346
+ type: Input
347
+ }], tdContent: [{
348
+ type: Input
277
349
  }] } });
278
350
 
279
351
  /** Direttiva per la dichiarazione snella di un EsTh da emettere come header */
@@ -321,16 +393,28 @@ class EsThDirective {
321
393
  this.thGroup = false;
322
394
  /** Indica che bisogna fare una aggregazione su questa colonna, a fronte di almeno un altra con un raggruppamento */
323
395
  this.thAggregation = null;
324
- /** Impostazioni per la modifica inline di questo campo: la **Property** di riferimento e il **Type** (a scelta fra quelli supportati dal form-adaptive) */
325
- this.thUserEdits = null;
396
+ /** Proprietà JS a cui si riferisce questa cella */
397
+ this.thProperty = null;
398
+ /** Tipo della proprietà JS a cui si riferisce questa cella. Se valorizzato l'utente la potrà modificare facendo doppio click */
399
+ this.thType = null;
400
+ /** Sorgente dei valori disponibili per questa cella se il **Type** è di tipo 'enum' */
401
+ this.thSource = null;
402
+ /** Indica un contenuto statico da mostrare piuttosto che utilizzare il **Template**. Serve in caso questo oggetto venga generato programmaticamente */
403
+ this.thStaticContent = null;
404
+ /** Opzioni da applicare all'editor di questa colonna */
405
+ this.thEditorOptions = {};
326
406
  }
327
407
  }
328
- EsThDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsThDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
329
- 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 });
330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsThDirective, decorators: [{
408
+ 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 });
409
+ 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 });
410
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsThDirective, decorators: [{
331
411
  type: Directive,
332
412
  args: [{ selector: '[th]' }]
333
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { th: [{
413
+ }], ctorParameters: function () {
414
+ return [{ type: i0.TemplateRef, decorators: [{
415
+ type: Self
416
+ }] }];
417
+ }, propDecorators: { th: [{
334
418
  type: Input
335
419
  }], thPinned: [{
336
420
  type: Input
@@ -354,6 +438,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
354
438
  type: Input
355
439
  }], thClass: [{
356
440
  type: Input
441
+ }], thShrink: [{
442
+ type: Input
357
443
  }], thGroupClass: [{
358
444
  type: Input
359
445
  }], thIf: [{
@@ -364,7 +450,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
364
450
  type: Input
365
451
  }], thAggregation: [{
366
452
  type: Input
367
- }], thUserEdits: [{
453
+ }], thProperty: [{
454
+ type: Input
455
+ }], thType: [{
456
+ type: Input
457
+ }], thSource: [{
368
458
  type: Input
369
459
  }], thMulti: [{
370
460
  type: Input
@@ -372,6 +462,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
372
462
  type: Input
373
463
  }], thBackgroundColor: [{
374
464
  type: Input
465
+ }], thAlignment: [{
466
+ type: Input
467
+ }], thFormat: [{
468
+ type: Input
469
+ }], thEditorName: [{
470
+ type: Input
471
+ }], thEditorOptions: [{
472
+ type: Input
473
+ }], thRendererName: [{
474
+ type: Input
475
+ }], thRoutePath: [{
476
+ type: Input
477
+ }], thRouteParameterProperties: [{
478
+ type: Input
479
+ }] } });
480
+
481
+ /** Direttiva che rappresenta il template dell'editor di una cella all'interno della tabella */
482
+ class EsTdEditorDirective {
483
+ /** @ignore */
484
+ constructor(Template) {
485
+ this.Template = Template;
486
+ }
487
+ }
488
+ 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 });
489
+ EsTdEditorDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: EsTdEditorDirective, selector: "[editor]", inputs: { editor: "editor", editorForProperty: "editorForProperty" }, ngImport: i0 });
490
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTdEditorDirective, decorators: [{
491
+ type: Directive,
492
+ args: [{ selector: '[editor]' }]
493
+ }], ctorParameters: function () {
494
+ return [{ type: i0.TemplateRef, decorators: [{
495
+ type: Self
496
+ }, {
497
+ type: Optional
498
+ }] }];
499
+ }, propDecorators: { editor: [{
500
+ type: Input
501
+ }], editorForProperty: [{
502
+ type: Input
375
503
  }] } });
376
504
 
377
505
  /** Classe di localizzazione per il componente **EsTableComponent** */
@@ -397,11 +525,14 @@ class EsTableLoc extends LocalizationService {
397
525
  super.set("en->it", "Select Everything", ["Seleziona Tutto"]);
398
526
  super.set("en->it", "Reset Selection", ["Resetta Selezione"]);
399
527
  super.set("en->it", "No operations available", ["Nessuna operazione disponibile"]);
528
+ super.set("en->it", "Values copied in the clipboard", ["Valori copiati nella clipboard"]);
529
+ 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"]);
530
+ super.set("en->it", "Data for this table cannot be edited", ["I dati di questa tabella non possono essere modificati"]);
400
531
  }
401
532
  }
402
- 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 });
403
- EsTableLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc });
404
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableLoc, decorators: [{
533
+ 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 });
534
+ EsTableLoc.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableLoc });
535
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableLoc, decorators: [{
405
536
  type: Injectable
406
537
  }], ctorParameters: function () {
407
538
  return [{ type: undefined, decorators: [{
@@ -440,8 +571,7 @@ class ExportHandler {
440
571
  }
441
572
  this.setupExport(data);
442
573
  if (format == "CSV") {
443
- this.est.cdr.detectChanges();
444
- setTimeout(() => { this.est.exportDownloader.nativeElement.click(); });
574
+ this.exportCSV();
445
575
  }
446
576
  else if (format == "XLSX") {
447
577
  if (this.ExcelJS != null) {
@@ -460,6 +590,33 @@ class ExportHandler {
460
590
  throw "Formato di esportazione non riconosciuto";
461
591
  }), format);
462
592
  }
593
+ /** Effettua l'esportazione in file CSV, va a sostituire quel coso inutile di @ctrl/ngx-csv */
594
+ exportCSV() {
595
+ var csvData = this.convertToCSV();
596
+ var blob = new Blob([csvData], { type: 'text/csv' });
597
+ var objectUrl = window.URL.createObjectURL(blob);
598
+ let fn = this.est.ExportFileName;
599
+ this.utiExts.fileDownload(objectUrl, fn.endsWith('.xlsx') ? fn.replace('.xlsx', '.csv') : fn.endsWith('.csv') ? fn : fn + ".csv");
600
+ }
601
+ /** Generazione specifica del CSV */
602
+ convertToCSV() {
603
+ let csv = '', row = '', sep = ';';
604
+ for (let i = 0; i < this.est.headers.length; i++) {
605
+ let h = this.est.headers[i];
606
+ row += `${row != '' ? sep : ''}"${h.label}"`;
607
+ }
608
+ csv += row + '\r\n';
609
+ for (let i = 0; i < this.est.data.length; i++) {
610
+ row = '';
611
+ let item = this.est.data[i];
612
+ for (let j = 0; j < this.est.headers.length; j++) {
613
+ let val = item[this.est.headers[j].key];
614
+ row += `${row != '' ? sep : ''}"${val}"`;
615
+ }
616
+ csv += row + '\r\n';
617
+ }
618
+ return csv;
619
+ }
463
620
  /** Effettua l'esportazione del file Excel basandosi sul modulo **ExcelJS**, sugli header **this.est.headers** e sui dati **this.est.data** */
464
621
  exportExcel() {
465
622
  return __awaiter(this, void 0, void 0, function* () {
@@ -482,17 +639,28 @@ class ExportHandler {
482
639
  let h = this.est.headers[i];
483
640
  let cell = row.getCell(i + 1);
484
641
  let val = item[h.key];
485
- if (val == null || val == undefined)
642
+ if (!val) {
486
643
  cell.value = "";
487
- else {
488
- switch (h.type) {
489
- case 'date':
490
- cell.value = this.dateExts.getDateConvertion(val).toDate();
491
- case 'number':
492
- cell.value = parseFloat(val.replace(',', '.'));
493
- default:
494
- cell.value = val;
495
- }
644
+ continue;
645
+ }
646
+ switch (h.type) {
647
+ case 'date':
648
+ // ExcelJS va di default in UTC quindi rischierebbe di tirare giù 2 ore ad ogni esportazione
649
+ // Bisogna aggiungere l'utc offset alla data attuale
650
+ let date = this.dateExts.getDateConvertion(val);
651
+ if (date) {
652
+ let correctedDate = date.add(date.utcOffset(), 'minute');
653
+ cell.value = correctedDate.toDate();
654
+ cell.numFmt = val.length > 10 ? 'dd/mm/yyyy h:m:s' : '';
655
+ }
656
+ break;
657
+ case 'number':
658
+ let converted = parseFloat(val.replace(',', '.'));
659
+ cell.value = isNaN(converted) ? "" : converted;
660
+ break;
661
+ default:
662
+ cell.value = val;
663
+ break;
496
664
  }
497
665
  }
498
666
  }
@@ -510,7 +678,9 @@ class ExportHandler {
510
678
  */
511
679
  setupExport(items) {
512
680
  let drcd = this.est.DynamicRowColumnsDefinition;
513
- 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);
681
+ this.est.headers = drcd && drcd.length > 0 ?
682
+ this.expExts.setupForGenericExport(items, drcd.map(t => { return { label: t.Description, key: t.PropertyName, propKey: t.PropertyName, order: t.ColumnOrder, type: 'string' }; })) :
683
+ this.expExts.setupForExport(items, this.est.ExportOnlyVisibleColumns ? this.est.ColumnsList.filter(t => t.visible).map(t => t.id) : null);
514
684
  this.est.data = items;
515
685
  }
516
686
  }
@@ -540,10 +710,11 @@ class EsTableColumn {
540
710
  * @param {string} description Descrizione (Header)
541
711
  * @param {boolean} visible Indica se di default mostrarla o meno
542
712
  * @param {boolean} fixed Indica se è una colonna fixed
713
+ * @param {boolean} pinnable Indica se una colonna può essere pinnata
543
714
  * @param {boolean} pinned Indica se è una colonna pinnata
544
715
  * @param {number} pinnedWidth Indica la dimensione da assegnare a questa colonna quando è pinnata
545
716
  * @param {TemplateRef<any>} template Indica il template da usare per mostrare il testo dell'Header
546
- * @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**)
717
+ * @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**)
547
718
  * @param {boolean} multi Indica che la colonna deriva da una direttiva **Multi**
548
719
  * @param {string} multiContent Indica il contenuto della direttiva **Multi** per questa colonna
549
720
  */
@@ -612,6 +783,12 @@ class ColumnMetadataHandler {
612
783
  this.est.arrayOrders = [new AppOrdering(id, order)];
613
784
  }
614
785
  }
786
+ //Salvo le preferences di questa view
787
+ //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
788
+ if (this.est.SavePreferences) {
789
+ let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
790
+ this.registerViewPreferences(castedView);
791
+ }
615
792
  this.est.onOrderChanged.emit({ id, order });
616
793
  if (this.est.viewMode) {
617
794
  if (this.est.groupSearchRequestsCache.length > 0)
@@ -622,6 +799,30 @@ class ColumnMetadataHandler {
622
799
  else if (this.est.arrayMode)
623
800
  this.est.internalWriteValue();
624
801
  }
802
+ /**
803
+ * Registra le preference relative alla view passata come parametro
804
+ *
805
+ * @param {any} castedView View di cui salvare colonne e ordinamento colonne
806
+ */
807
+ registerViewPreferences(castedView) {
808
+ if (!this.est.ngControl.name) {
809
+ console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
810
+ return false;
811
+ }
812
+ if (!this.prefService) {
813
+ console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
814
+ return false;
815
+ }
816
+ let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
817
+ let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
818
+ let columnOrders = this.est.arrayMode ? [] : castedView.orders;
819
+ var toStore = {
820
+ columns: this.utiExts.deepClone(columns),
821
+ column_ordering: this.utiExts.deepClone(columnsOrderings),
822
+ orders: this.utiExts.deepClone(columnOrders)
823
+ };
824
+ this.prefService.setItem(this.est.ngControl.name, toStore).subscribe();
825
+ }
625
826
  /**
626
827
  * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
627
828
  *
@@ -653,6 +854,7 @@ class ColumnMetadataHandler {
653
854
  this.est.ColumnsList = [];
654
855
  this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
655
856
  }
857
+ /** 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 */
656
858
  expandMultiThsAndTds(ths, tds, items) {
657
859
  // Registro le info sui multiprovider
658
860
  let multiDefs = {};
@@ -704,6 +906,7 @@ class ColumnMetadataHandler {
704
906
  newtH._multi_content = headerValue;
705
907
  newtH.th = `${prop}_${ii}`;
706
908
  newtH.thClass = refth.thClass;
909
+ newtH.thShrink = refth.thShrink;
707
910
  newtH.thIf = refth.thIf;
708
911
  newtH.thVisible = refth.thVisible;
709
912
  newtH.thWrap = refth.thWrap;
@@ -761,7 +964,6 @@ class ColumnMetadataHandler {
761
964
  * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
762
965
  */
763
966
  moveFixedColumnsAtTheBeginning(ths, tds) {
764
- let thsCache = {};
765
967
  let fixeds = 0, pinneds = 0;
766
968
  let columnsCache = {};
767
969
  let columnsIndexCache = {};
@@ -786,7 +988,6 @@ class ColumnMetadataHandler {
786
988
  // Sposto tutti gli header fixed o pinned all'inizio
787
989
  for (let i = 0; i < ths.length; i++) {
788
990
  let th = ths[i];
789
- thsCache[th.th] = th;
790
991
  // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
791
992
  th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
792
993
  if (th.thPinned) {
@@ -829,6 +1030,7 @@ class ColumnMetadataHandler {
829
1030
  * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
830
1031
  *
831
1032
  * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
1033
+ * @param {boolean} useLocalVisibility Indica di utilizzare le impostazioni di visibilità locali senza allinearle alla view
832
1034
  */
833
1035
  alignColumnsIfLoadedView(view) {
834
1036
  let emitChanged = this.est.viewMode && view.savedstate;
@@ -846,10 +1048,10 @@ class ColumnMetadataHandler {
846
1048
  if (c.visible && columns.length == 0)
847
1049
  newColset.push(c.id);
848
1050
  // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
849
- else if (exCl.length == 1 && !c.visible)
1051
+ else if (exCl.length == 1 && !c.visible && !this.est.useLocalVisibility)
850
1052
  c.visible = true;
851
1053
  // Allineamento sull'AppSearch per casistiche inverse al di sopra
852
- else if (exCl.length == 0 && c.visible)
1054
+ else if (exCl.length == 0 && c.visible && !this.est.useLocalVisibility)
853
1055
  c.visible = false;
854
1056
  });
855
1057
  // Non ho colonne nella appsearch, vuol dire che sono al primo binding
@@ -878,6 +1080,9 @@ class ColumnMetadataHandler {
878
1080
  // In ogni caso questo non mi serve più, lo resetto **
879
1081
  if (this.est.viewMode)
880
1082
  view.savedstate = false;
1083
+ // Reset di questa variabile usata one-bind
1084
+ if (this.est.useLocalVisibility)
1085
+ this.est.useLocalVisibility = false;
881
1086
  if (emitChanged)
882
1087
  this.est.changed();
883
1088
  }
@@ -981,22 +1186,22 @@ class ColumnMetadataHandler {
981
1186
  evaluateHeaderGroups(infos) {
982
1187
  if (infos.groupingLevel == 0)
983
1188
  return;
984
- // Giro 2.5, creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate
1189
+ /****** STEP 1: Creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate ******/
985
1190
  let expandedGroups = [];
986
- let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
1191
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
987
1192
  for (let l = 0; l < infos.groupingLevel; l++) {
988
1193
  expandedGroups.push([]);
989
1194
  for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
990
1195
  expandedGroups[l].push("");
991
1196
  }
992
- // Ordino le foglie in base agli ordinamenti delle colonne
1197
+ /****** STEP 2: Ordino le foglie in base agli ordinamenti delle colonne ******/
993
1198
  let orderedLeafs = [];
994
1199
  for (let i = 0; i < this.est.OrderDirectives.length; i++) {
995
1200
  let leaf = infos.thsCache[this.est.OrderDirectives[i]];
996
- if (leaf.thVisible && !leaf.thPinned)
1201
+ if (leaf.thVisible && leaf.thIf && !leaf.thPinned)
997
1202
  orderedLeafs.push(leaf);
998
1203
  }
999
- // Terzo giro per creare l'array group con tutti i riferimenti del caso
1204
+ /****** STEP 3: Creo l'array group con tutti i riferimenti del caso ******/
1000
1205
  let currentParent = "";
1001
1206
  for (let i = 0; i < orderedLeafs.length; i++) {
1002
1207
  let refTh = orderedLeafs[i];
@@ -1017,35 +1222,51 @@ class ColumnMetadataHandler {
1017
1222
  }
1018
1223
  }
1019
1224
  }
1020
- // Quarto giro per compattarlo nell'elemento finale su cui bindarmi
1225
+ /****** STEP 4: Compatto nell'elemento finale su cui bindarmi. L'ID assegnato è SOLO per ottimizzare gli ngFor ******/
1021
1226
  currentParent = "";
1022
1227
  let currentSpan = 0;
1023
- this.est.TMPRowThGroups = [];
1228
+ let finalHeaders = [];
1024
1229
  for (let l = 0; l < expandedGroups.length; l++) {
1025
1230
  let levelArray = [];
1026
- this.est.TMPRowThGroups.push(levelArray);
1231
+ finalHeaders.push(levelArray);
1027
1232
  if (this.est.Selection || this.est.HasPinnedColumns)
1028
- levelArray.push({ Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1233
+ levelArray.push({ ID: "_base_sel_pinned", Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1029
1234
  for (let h = 0; h < expandedGroups[l].length; h++) {
1030
1235
  let item = expandedGroups[l][h];
1031
1236
  if (item == currentParent)
1032
1237
  currentSpan++;
1033
1238
  else {
1034
1239
  if (currentSpan > 0)
1035
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1240
+ 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 });
1036
1241
  currentSpan = 1;
1037
1242
  currentParent = item;
1038
1243
  }
1039
1244
  }
1040
1245
  // Ultima aggiunta che altrimenti mi rimarrebbe in cache
1041
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1246
+ 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 });
1247
+ // Aggiungo i pezzettini per la rimozione e gli export, se presenti
1042
1248
  if (this.est.Removal)
1043
- levelArray.push({ Span: 1, Template: null });
1249
+ levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
1044
1250
  if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
1045
- levelArray.push({ Span: 1, Template: null });
1251
+ levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
1046
1252
  currentSpan = 0;
1047
1253
  currentParent = "";
1048
1254
  }
1255
+ /****** STEP 5: Secco le righe in cui non c'è nulla ******/
1256
+ this.est.TMPRowThGroups = [];
1257
+ for (let i = 0; i < finalHeaders.length; i++) {
1258
+ let level = finalHeaders[i];
1259
+ let empty = true;
1260
+ for (let j = 0; j < level.length; j++) {
1261
+ let item = level[j];
1262
+ if (item.Template || item.Content) {
1263
+ empty = false;
1264
+ break;
1265
+ }
1266
+ }
1267
+ if (!empty)
1268
+ this.est.TMPRowThGroups.push(level);
1269
+ }
1049
1270
  }
1050
1271
  /**
1051
1272
  * Calcola il numero di salti da un header foglia all'ultimo parent della catena
@@ -1063,9 +1284,9 @@ class ColumnMetadataHandler {
1063
1284
  if (parent) {
1064
1285
  th = thsCache[parent];
1065
1286
  if (!th.thEmpty && !th._multi_content)
1066
- parentsPrepend.unshift({ tmpl: th.Template });
1287
+ parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
1067
1288
  else if (!th.thEmpty && th._multi_content)
1068
- parentsPrepend.unshift({ content: th._multi_content });
1289
+ parentsPrepend.unshift({ id: th.th, content: th._multi_content });
1069
1290
  jumps++;
1070
1291
  }
1071
1292
  } while (parent);
@@ -1126,7 +1347,9 @@ class ColumnMetadataHandler {
1126
1347
  let newContext = [];
1127
1348
  this.est.OrderDirectives.forEach(o => {
1128
1349
  let contextItem = context.filter(t => t.ID == o)[0];
1129
- newContext.push(contextItem);
1350
+ // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
1351
+ if (contextItem)
1352
+ newContext.push(contextItem);
1130
1353
  });
1131
1354
  this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
1132
1355
  }
@@ -1278,20 +1501,8 @@ class ColumnMetadataHandler {
1278
1501
  this.refreshColumnsVisibility(null, null, castedView);
1279
1502
  //Salvo le preferences di questa view
1280
1503
  //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
1281
- if (this.est.SavePreferences) {
1282
- if (!this.est.ngControl.name) {
1283
- console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
1284
- return false;
1285
- }
1286
- if (!this.prefService) {
1287
- console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
1288
- return false;
1289
- }
1290
- let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
1291
- let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
1292
- var toStore = { columns: JSON.parse(JSON.stringify(columns)), column_ordering: JSON.parse(JSON.stringify(columnsOrderings)) };
1293
- this.prefService.setItem(this.est.ngControl.name, toStore, 'preference').subscribe();
1294
- }
1504
+ if (this.est.SavePreferences)
1505
+ this.registerViewPreferences(castedView);
1295
1506
  // Rieseguo l'ultima ricerca bindata alla tabella
1296
1507
  // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
1297
1508
  if (this.est.viewMode)
@@ -1338,29 +1549,46 @@ class EsTableColumnsDefinition {
1338
1549
  /**
1339
1550
  * Costruttore
1340
1551
  *
1341
- * @param {string} description Descrizione della colonna
1342
- * @param {string} propertyName Nome della proprietà del modello in cui sono contenuti i dati da visualizzare per questa colonna
1343
- * @param {string} routePath Route di navigazione. Es. "['/pages/mod/mod_detail', { 'idItem': '{0}', 'idItem2' : '{1}' }]"
1344
- * @param {string[]} routeParameterProperties Proprietà da bindare a **routePath** per generare la route completa.
1552
+ * @param {string} Description Descrizione della colonna
1553
+ * @param {string} PropertyName Nome della proprietà del modello in cui sono contenuti i dati da visualizzare per questa colonna
1554
+ * @param {string} RoutePath Route di navigazione. Es. "['/pages/mod/mod_detail', { 'idItem': '{0}', 'idItem2' : '{1}' }]"
1555
+ * @param {string[]} RouteParameterProperties Proprietà da bindare a **routePath** per generare la route completa.
1345
1556
  * L'indice scritto in **routePath** è l'indice di accesso a questo array. Es. ["iditem", "iditem2"]
1346
- * @param {'ASC' | 'DESC' } dataOrder Ordinamento dei dati presentati in questa colonna
1347
- * @param {number} columnOrder Ordinamento di questa colonna
1348
- * @param {boolean} visible Visibilità o meno della colonna
1349
- * @param {string} clss Classe da applicare sia ai TD che ai TH relativi a questa colonna
1350
- * @param {boolean} orderable Indica se la colonna è ordinabile o no (nel senso ASC / DESC / NONE)
1351
- * @param {boolean} headerWraps Indica se il testo dell'header dev'essere wrappato all'interno del th. Di default no.
1557
+ * @param {'ASC' | 'DESC' } DataOrder Ordinamento dei dati presentati in questa colonna
1558
+ * @param {number} ColumnOrder Ordinamento di questa colonna
1559
+ * @param {boolean} Visible Visibilità o meno della colonna
1560
+ * @param {string} Clss Classe da applicare sia ai TD che ai TH relativi a questa colonna
1561
+ * @param {boolean} Orderable Indica se la colonna è ordinabile o no (nel senso ASC / DESC / NONE)
1562
+ * @param {boolean} HeaderWraps Indica se il testo dell'header dev'essere wrappato all'interno del th. Di default no.
1563
+ * @param {InputType | string} PropertyType Indica il tipo della proprietà identificata da **propertyName**.
1564
+ * @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.
1565
+ * @param {string} EditorName Nome dell'editor da utilizzare per la modifica di questo campo
1566
+ * @param {string} RendererName Nome del renderer da utilizzare per visualizzare questo campo
1352
1567
  */
1353
- constructor(description, propertyName, routePath = null, routeParameterProperties = null, dataOrder = null, columnOrder = null, visible = true, clss = null, orderable = true, headerWraps = false) {
1354
- this.description = description;
1355
- this.propertyName = propertyName;
1356
- this.routePath = routePath;
1357
- this.routeParameterProperties = routeParameterProperties;
1358
- this.dataOrder = dataOrder;
1359
- this.columnOrder = columnOrder;
1360
- this.visible = visible;
1361
- this.clss = clss;
1362
- this.orderable = orderable;
1363
- this.headerWraps = headerWraps;
1568
+ 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) {
1569
+ this.Description = Description;
1570
+ this.PropertyName = PropertyName;
1571
+ this.RoutePath = RoutePath;
1572
+ this.RouteParameterProperties = RouteParameterProperties;
1573
+ this.DataOrder = DataOrder;
1574
+ this.ColumnOrder = ColumnOrder;
1575
+ this.Visible = Visible;
1576
+ this.Clss = Clss;
1577
+ this.Orderable = Orderable;
1578
+ this.HeaderWraps = HeaderWraps;
1579
+ this.PropertyType = PropertyType;
1580
+ this.PropertySource = PropertySource;
1581
+ this.EditorName = EditorName;
1582
+ this.RendererName = RendererName;
1583
+ this.EditorOptions = EditorOptions;
1584
+ this.Pinned = Pinned;
1585
+ this.PinnedWidth = PinnedWidth;
1586
+ this.Pinnable = Pinnable;
1587
+ this.Grouping = Grouping;
1588
+ this.Shrink = Shrink;
1589
+ }
1590
+ static build(parsObj) {
1591
+ 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);
1364
1592
  }
1365
1593
  }
1366
1594
 
@@ -1370,42 +1598,6 @@ class DynamicModeHandler {
1370
1598
  constructor(est) {
1371
1599
  this.est = est;
1372
1600
  }
1373
- /**
1374
- * Metodo di supporto alla creazione di un router link parametrizzato all'oggetto corrente utilizzato nella modalità dinamica
1375
- *
1376
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1377
- * @param {string[]} parameterProps Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1378
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1379
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1380
- *
1381
- * @returns {any} Router link generato in base al parametri
1382
- */
1383
- generateRouterLink(path, parameterProps, item) {
1384
- if (this.est.DynamicTableRouterLinkCache[item._hash + path]) {
1385
- return this.est.DynamicTableRouterLinkCache[item._hash + path];
1386
- }
1387
- else {
1388
- let link = this.getRouterLink(path, parameterProps, item);
1389
- this.est.DynamicTableRouterLinkCache[item._hash + path] = link;
1390
- return link;
1391
- }
1392
- }
1393
- /**
1394
- * Crea un router link
1395
- *
1396
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1397
- * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1398
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1399
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1400
- *
1401
- * @returns {any} Router link generato in base al parametri
1402
- */
1403
- getRouterLink(path, pars, item) {
1404
- for (let i = 0; i < pars.length; i++)
1405
- path = path.replace('{' + i + '}', item.properties[pars[i]]);
1406
- path = path.replace(/'/g, '"').replace(/ /g, '');
1407
- return JSON.parse(path);
1408
- }
1409
1601
  /** Se non ho l'Input **DynamicRowColumnsDefinition** in modalità dinamica lo riempio con il default nome della colonna = testo della colonna */
1410
1602
  eventuallyReviewDynamicColumns() {
1411
1603
  // Senza oggetti esco
@@ -1424,6 +1616,82 @@ class DynamicModeHandler {
1424
1616
  else
1425
1617
  this.est.UserDefinedDynamicCols = true;
1426
1618
  }
1619
+ /** Genera partendo dalle **DynamicRowColumnsDefinition** la lista di **EsThDirective** e **EsTdDirective** che servono per la tabella */
1620
+ emitThsAndTdsBasedOnDynamicDefinition() {
1621
+ // Senza dynamic columns esco
1622
+ if (!this.est.DynamicRowColumnsDefinition || this.est.DynamicRowColumnsDefinition.length == 0)
1623
+ return null;
1624
+ let ths = [];
1625
+ let tds = [];
1626
+ for (let i = 0; i < this.est.DynamicOperations.length; i++) {
1627
+ let op = this.est.DynamicOperations[i];
1628
+ ths.push(this.getThFromOperation(op));
1629
+ tds.push(this.getTdFromOperation(op));
1630
+ }
1631
+ for (let i = 0; i < this.est.DynamicRowColumnsDefinition.length; i++) {
1632
+ let col = this.est.DynamicRowColumnsDefinition[i];
1633
+ ths.push(this.getThFromColumnDef(col));
1634
+ tds.push(this.getTdFromColumnDef(col));
1635
+ }
1636
+ return { ths, tds };
1637
+ }
1638
+ /** @ignore Helper */
1639
+ getThFromOperation(op) {
1640
+ let th = new EsThDirective(null);
1641
+ th.th = op.id;
1642
+ th.thStaticContent = "";
1643
+ return th;
1644
+ }
1645
+ getTdFromOperation(op) {
1646
+ let td = new EsTdDirective(null);
1647
+ td.td = op.id;
1648
+ td.tdIconClass = op.iconClass;
1649
+ td.tdConditionField = op.conditionField;
1650
+ td.tdConditionValue = op.conditionValue;
1651
+ td.tdTitle = op.title;
1652
+ td.tdContent = op.text;
1653
+ return td;
1654
+ }
1655
+ getThFromColumnDef(col) {
1656
+ var ret = new EsThDirective(null);
1657
+ ret.th = col.PropertyName;
1658
+ ret.thPinned = col.Pinned;
1659
+ ret.thPinnable = col.Pinnable;
1660
+ ret.thPinnedWidth = col.PinnedWidth;
1661
+ ret.thVisible = col.Visible;
1662
+ ret.thOrder = col.DataOrder;
1663
+ ret.thOrderable = col.Orderable;
1664
+ ret.thWrap = col.HeaderWraps;
1665
+ ret.thClass = col.Clss;
1666
+ ret.thProperty = col.PropertyName;
1667
+ ret.thType = col.PropertyType;
1668
+ ret.thSource = col.PropertySource;
1669
+ ret.thEditorName = col.EditorName;
1670
+ ret.thEditorOptions = col.EditorOptions;
1671
+ ret.thRendererName = col.RendererName;
1672
+ ret.thRoutePath = col.RoutePath;
1673
+ ret.thRouteParameterProperties = col.RouteParameterProperties;
1674
+ //ret.thFixed = col.Fixed;
1675
+ //ret.thResizable = col.Resizable;
1676
+ //ret.thGroupClass = col.GroupClass;
1677
+ //ret.thGroup = col.Group;
1678
+ //ret.thAggregation = col.Aggregation;
1679
+ //ret.thMulti = col.Multi;
1680
+ //ret.thStaticContent = col.StaticContent;
1681
+ //ret.thBackgroundColor = col.BackgroundColor;
1682
+ //ret.thAlignment = col.Alignment;
1683
+ //ret.thFormat = col.Format;
1684
+ return ret;
1685
+ }
1686
+ /** @ignore Helper */
1687
+ getTdFromColumnDef(col) {
1688
+ var ret = new EsTdDirective(null);
1689
+ ret.td = col.PropertyName;
1690
+ ret.tdClass = col.Clss;
1691
+ //ret.tdAlignment = col.Alignment;
1692
+ //ret.tdFormat = col.Format;
1693
+ return ret;
1694
+ }
1427
1695
  }
1428
1696
 
1429
1697
  /** Classe contenente la gestione della modalità gerarchica */
@@ -1659,17 +1927,25 @@ class ItemsHandler {
1659
1927
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.arraymodePage, this.est.arraymodePages);
1660
1928
  else
1661
1929
  return this.est.View;
1930
+ // Applico eventuali oridnamenti lato Array prima di tirare fuori la pagina selezionata
1931
+ let items = this.est.View;
1932
+ if (this.est)
1933
+ items = this.arrayModeReviewOrderings(items);
1662
1934
  // Poi per tutti i valori dopo compresi fra la pagina - 1 e la pagina
1663
1935
  for (let i = ((this.est.arraymodePage - 1) * this.est.ArraymodeItemsPerPage); i < this.est.arraymodePage * this.est.ArraymodeItemsPerPage; i++) {
1664
- if (i <= this.est.View.length - 1)
1665
- tmpItems.push(this.est.View[i]);
1936
+ if (i <= items.length - 1)
1937
+ tmpItems.push(items[i]);
1666
1938
  }
1667
1939
  return tmpItems;
1668
1940
  }
1669
1941
  /** Se in modalità array applica gli ordinamenti ASC-DESC delle colonne */
1670
- arrayModeReviewOrderings() {
1942
+ arrayModeReviewOrderings(items) {
1943
+ let tmp = items;
1671
1944
  if (this.est.arrayOrders.length > 0)
1672
- 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)); });
1945
+ this.est.arrayOrders.forEach(t => {
1946
+ tmp = tmp.sort((a, b) => (a[t.id] > b[t.id] ? 1 : -1) * (t.order == 'DESC' ? -1 : 1));
1947
+ });
1948
+ return tmp;
1673
1949
  }
1674
1950
  }
1675
1951
 
@@ -1698,6 +1974,15 @@ class ReportModeHandler {
1698
1974
  this.est.View.pages = Math.ceil(count / ipp);
1699
1975
  this.est.arrayPulsanti = this.utilities.getPagesArray(6, this.est.View.page, this.est.View.pages);
1700
1976
  }
1977
+ /**
1978
+ * Data una AppSearch questo metodo genera la lista di th e td che si possono collegare al giro standard.
1979
+ * Se non ci fosse questo passaggio intermedio la gestione della modalità report sarebbe 100% custom,
1980
+ * come poi lo era prima che la facessi passare dal giro che fanno tutte le altre modalità
1981
+ *
1982
+ * @param {AppSearch<any>} view View in modalità report contenente le informazioni sulle colonne
1983
+ *
1984
+ * @returns {{ ths: EsThDirective[], tds: EsTdDirective[] }} Lista di direttive per gli header e per il body
1985
+ */
1701
1986
  generateThsAndTdsFromView(view) {
1702
1987
  var ret = { ths: [], tds: [] };
1703
1988
  // Ordinamento per ora commentato... non vorrebbe mi fuckappasse tutto
@@ -1706,11 +1991,15 @@ class ReportModeHandler {
1706
1991
  let clm = view.report_columns[i];
1707
1992
  var th = new EsThDirective(null);
1708
1993
  th.th = clm.id;
1709
- th.thStaticContent = clm.description;
1994
+ th.thStaticContent = clm.description || null;
1710
1995
  th.thBackgroundColor = clm.color;
1996
+ th.thAlignment = clm.alignment;
1997
+ th.thFormat = clm.format;
1711
1998
  var td = new EsTdDirective(null);
1712
1999
  td.td = clm.id;
1713
2000
  td.tdPropertyAccessor = i.toString();
2001
+ td.tdAlignment = clm.alignment;
2002
+ td.tdFormat = clm.format;
1714
2003
  ret.ths.push(th);
1715
2004
  ret.tds.push(td);
1716
2005
  }
@@ -1772,8 +2061,9 @@ class GroupPager {
1772
2061
  /**
1773
2062
  * Costruttore
1774
2063
  *
1775
- * @param {number} groupLevel Livello del gruppo a cui questo separatore fa riferimento
1776
- * @param {string} parentKey Chiave del gruppo parent se esiste
2064
+ * @param {number} _grouplevel Livello del gruppo a cui questo separatore fa riferimento
2065
+ * @param {string} _thisRoute Route che identifica la gerarchia del gruppo e chi sono i parent
2066
+ * @param {string} _parent Chiave del gruppo parent se esiste
1777
2067
  * @param {AppSearch<any>} view Vista di ricerca collegata a questo elemento
1778
2068
  * @param {'groups' | 'items'} searches Indica che cosa cerca questo separatore, se sottogruppi o oggetti
1779
2069
  */
@@ -2343,6 +2633,120 @@ class SelectionHandler {
2343
2633
  return;
2344
2634
  this.handleSelectionEvaluation(items, selectionItem);
2345
2635
  }
2636
+ /**
2637
+ * Precompila le informazioni sullo stato di selezione tutto a false per le celle della tabella
2638
+ *
2639
+ * @param {any[]} items Oggetti attualmente bindati sulla tabella
2640
+ * @param {EsThDirective[]} ths Colonne su cui gli oggetti sono bindati
2641
+ */
2642
+ evaluateSingleCellSelection(items, ths, dyn) {
2643
+ for (let i = 0; i < items.length; i++) {
2644
+ // 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
2645
+ this.est.selectionStatus[items[i]._ordinal] = {};
2646
+ if (dyn && dyn.length > 0)
2647
+ this.fillSelectionStatusByDynamicColumns(items[i], dyn);
2648
+ else
2649
+ this.fillSelectionStatusByEsThs(items[i], ths);
2650
+ }
2651
+ }
2652
+ /** @ignore */
2653
+ fillSelectionStatusByDynamicColumns(item, dyn) {
2654
+ for (let k = 0; k < dyn.length; k++) {
2655
+ let th = dyn[k];
2656
+ let iper = { selected: false, value: th.PropertyName ? item.properties[th.PropertyName] : "Undefined Property", type: th.PropertyType, property: th.PropertyName, header: th.PropertyName, item: item };
2657
+ this.est.selectionStatus[item._ordinal][k] = iper;
2658
+ // Funzione assegnata dopo in modo da poterle fare anche aggiornare il valore del riferimento all'oggetto di selezione
2659
+ iper.val_setter = (value) => {
2660
+ if (!th.PropertyName) {
2661
+ item[th.PropertyName] = value;
2662
+ iper.value = value;
2663
+ return value;
2664
+ }
2665
+ let valToApply = "";
2666
+ switch (th.PropertyType) {
2667
+ case "string":
2668
+ if (value.startsWith && value.startsWith('"') && value.endsWith && value.endsWith('"'))
2669
+ valToApply = value.substring(1, value.length - 1);
2670
+ else
2671
+ valToApply = value;
2672
+ break;
2673
+ case "number":
2674
+ case "int":
2675
+ case "boolean":
2676
+ case "enum":
2677
+ case "autocomplete":
2678
+ case "float":
2679
+ case "currency":
2680
+ valToApply = value;
2681
+ break;
2682
+ case "date":
2683
+ case "datetime":
2684
+ valToApply = this.est.dateExts.getDateConvertion(value);
2685
+ break;
2686
+ case "time":
2687
+ let mydate = this.est.dateExts.getDateConvertion(value);
2688
+ valToApply = `${mydate.hour()}:${mydate.minute()}:${mydate.second()}`;
2689
+ break;
2690
+ // Per evitare di sbiancare senza senso
2691
+ default:
2692
+ valToApply = value;
2693
+ break;
2694
+ }
2695
+ item.properties[th.PropertyName] = valToApply;
2696
+ iper.value = valToApply;
2697
+ return valToApply;
2698
+ };
2699
+ }
2700
+ }
2701
+ /** @ignore */
2702
+ fillSelectionStatusByEsThs(item, ths) {
2703
+ for (let k = 0; k < ths.length; k++) {
2704
+ let th = ths[k];
2705
+ let iper = { selected: false, value: th.thProperty ? item[th.thProperty] : "Undefined Property", type: th.thType, property: th.thProperty, header: th.th, item: item };
2706
+ this.est.selectionStatus[item._ordinal][k] = iper;
2707
+ // Funzione assegnata dopo in modo da poterle fare anche aggiornare il valore del riferimento all'oggetto di selezione
2708
+ iper.val_setter = (value) => {
2709
+ if (!th.thProperty) {
2710
+ item[th.thProperty] = value;
2711
+ iper.value = value;
2712
+ return value;
2713
+ }
2714
+ let valToApply = "";
2715
+ switch (th.thType) {
2716
+ case "string":
2717
+ if (value.startsWith('"') && value.endsWith('"'))
2718
+ valToApply = value.substring(1, value.length - 1);
2719
+ else
2720
+ valToApply = value;
2721
+ break;
2722
+ case "number":
2723
+ case "int":
2724
+ case "boolean":
2725
+ case "enum":
2726
+ case "autocomplete":
2727
+ case "float":
2728
+ case "currency":
2729
+ valToApply = value;
2730
+ break;
2731
+ case "date":
2732
+ case "datetime":
2733
+ valToApply = this.est.dateExts.getDateConvertion(value);
2734
+ break;
2735
+ case "time":
2736
+ let mydate = this.est.dateExts.getDateConvertion(value);
2737
+ valToApply = `${mydate.hour()}:${mydate.minute()}:${mydate.second()}`;
2738
+ break;
2739
+ // Per evitare di sbiancare senza senso
2740
+ default:
2741
+ valToApply = value;
2742
+ break;
2743
+ }
2744
+ item[th.thProperty] = valToApply;
2745
+ iper.value = valToApply;
2746
+ return valToApply;
2747
+ };
2748
+ }
2749
+ }
2346
2750
  /**
2347
2751
  * Implementazione agnostica della valutazione delle selezioni degli oggetti. Richiede gli oggetti della vista attuale e l'itemSelector
2348
2752
  *
@@ -2821,6 +3225,158 @@ class SelectionHandler {
2821
3225
  // Dopo aver resettato direttamente il solo oggetto this.View.selection devo anche riallineare a tutti gli oggetti bindati
2822
3226
  this.evaluateSelection(this.est.boundSource, selectionItem);
2823
3227
  }
3228
+ /**
3229
+ * @TODO Spostare in SelectionHandler
3230
+ *
3231
+ * Registra la selezione singola su una cella sulla combo di comandi "CTRL + Click".
3232
+ * Se viene premuto anche il tasto Shift viene creato un range di selezione il cui status di "selezionato" viene salvato nella
3233
+ * matrice virtuale **selectionStatus**
3234
+ *
3235
+ * @param {any} event Evento Javascript di Click
3236
+ * @param {number} row Indice della riga. Non è l'indice vero e proprio ma è l'ordinale (.ordinal) dell'oggetto bindato su quella riga
3237
+ * @param {number} column Indice della colonna preso banalmente dall'ngIf sui thElement
3238
+ * @param {{ row: number, column: number }} firstSelectionOverride Permette di overridare il primo elemento selezionato
3239
+ */
3240
+ singleCellSelection(event, row, column, firstSelectionOverride) {
3241
+ // Recupero la selezione precedente se presente come punto di partenza
3242
+ var first = firstSelectionOverride || this.lastSingleSelection;
3243
+ //Il punto di arrivo, che diventerà il prossimo punto di partenza, è la selezione corrente
3244
+ this.lastSingleSelection = { row, column };
3245
+ this.clearTextSelection(event);
3246
+ this.clearSelectionStatusExcluding(this.lastSingleSelection);
3247
+ this.setSelectionStatusBorders(event.range && first ? first : this.lastSingleSelection, this.lastSingleSelection);
3248
+ // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
3249
+ this.est.cdr.markForCheck();
3250
+ }
3251
+ setSelectionStatusBorders(from, to) {
3252
+ let rowAddition = to.row < from.row ? -1 : +1;
3253
+ let columnAddition = to.column < from.column ? -1 : +1;
3254
+ let singleItem = from == to;
3255
+ for (let ir = from.row; ir != to.row + rowAddition; ir += rowAddition) {
3256
+ let firstRow = ir == from.row;
3257
+ let lastRow = ir == to.row;
3258
+ for (let ic = from.column; ic != to.column + columnAddition; ic += columnAddition) {
3259
+ let firstCol = ic == from.column;
3260
+ let lastCol = ic == to.column;
3261
+ let current = this.est.selectionStatus[ir][ic];
3262
+ let prevColumn = ic > 0 ? this.est.selectionStatus[ir][ic - 1] : null;
3263
+ let nextcolumn = this.est.selectionStatus[ir][ic + 1];
3264
+ let prevRow = ir > 0 ? this.est.selectionStatus[ir - 1][ic] : null;
3265
+ let nextRow = this.est.selectionStatus[ir + 1] ? this.est.selectionStatus[ir + 1][ic] : null;
3266
+ current.selected = singleItem ? !current.selected : true;
3267
+ current.lborder = !current.selected ? false : columnAddition > 0 ? firstCol : lastCol;
3268
+ current.tborder = !current.selected ? false : rowAddition > 0 ? firstRow : lastRow;
3269
+ current.rborder = !current.selected ? false : columnAddition > 0 ? lastCol : firstCol;
3270
+ current.bborder = !current.selected ? false : rowAddition > 0 ? lastRow : firstRow;
3271
+ if (prevRow)
3272
+ prevRow.boverlaps = current.tborder;
3273
+ if (nextRow)
3274
+ nextRow.toverlaps = current.bborder;
3275
+ if (prevColumn)
3276
+ prevColumn.roverlaps = current.lborder;
3277
+ if (nextcolumn)
3278
+ nextcolumn.loverlaps = current.rborder;
3279
+ }
3280
+ }
3281
+ }
3282
+ /**
3283
+ * Helper per ripulire lo stato di selezione delle singole celle della tabella, ad esclusione di una singola coordinata
3284
+ *
3285
+ * @param {{row: number, column: number}} exclusion Coordinata da escludere nella pulizia
3286
+ */
3287
+ clearSelectionStatusExcluding(exclusion) {
3288
+ for (let row in this.est.selectionStatus) {
3289
+ for (let column in this.est.selectionStatus[row]) {
3290
+ // Se è l'elemento che ho escluso dal cleanup, skippo
3291
+ if (exclusion && row == exclusion.row.toString() && column == exclusion.column.toString())
3292
+ continue;
3293
+ // Altrimenti pulisco
3294
+ let curr = this.est.selectionStatus[row][column];
3295
+ curr.selected = curr.lborder = curr.rborder = curr.tborder = curr.bborder = curr.loverlaps = curr.roverlaps = curr.toverlaps = curr.boverlaps = false;
3296
+ }
3297
+ }
3298
+ }
3299
+ /**
3300
+ * Helper che esamina la matrice **selectionStatus** e ne estrappola gli elementi selezionati in una comoda matrice
3301
+ *
3302
+ * @returns {{ value: string, type: InputType, val_setter: Function }[][]} Matrice di elementi selezionati con la loro informazione sul tipo
3303
+ */
3304
+ getSelectionStatusSelection() {
3305
+ let selection = [];
3306
+ for (let row in this.est.selectionStatus) {
3307
+ let rowValues = [];
3308
+ for (let column in this.est.selectionStatus[row]) {
3309
+ let ssItem = this.est.selectionStatus[row][column];
3310
+ if (ssItem.selected)
3311
+ rowValues.push(ssItem);
3312
+ }
3313
+ if (rowValues.length > 0)
3314
+ selection.push(rowValues);
3315
+ }
3316
+ return selection;
3317
+ }
3318
+ /**
3319
+ * Helper per ripulire la selezione lato HTML
3320
+ *
3321
+ * @param {any} event Evento nativo Javascript
3322
+ */
3323
+ clearTextSelection(event) {
3324
+ // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
3325
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.range)
3326
+ return false;
3327
+ // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
3328
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.range)
3329
+ this.est.utiExts.clearTextSelection();
3330
+ }
3331
+ /**
3332
+ * Data la matrice di selezione generata dal metodo **getSelectionStatusSelection** genera la strigna vera e propria da copiare nella Clipboard
3333
+ *
3334
+ * @param {{ value: string, type: InputType }[][]} sel Matrice di selezione con valori e tipi dei dati selezionati
3335
+ *
3336
+ * @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
3337
+ * in modo che siano compatibili anche con la copia su Excel
3338
+ */
3339
+ getClipbardTextFromSelection(sel) {
3340
+ var ret = "";
3341
+ for (let r = 0; r < sel.length; r++) {
3342
+ let row = sel[r];
3343
+ if (r > 0)
3344
+ ret += "\n";
3345
+ for (let c = 0; c < row.length; c++) {
3346
+ let col = row[c];
3347
+ ret += this.getValueByType(col) + (c < row.length - 1 ? "\t" : "");
3348
+ }
3349
+ }
3350
+ return ret;
3351
+ }
3352
+ /**
3353
+ * Ottiene la rappresentazione stringa di un valore dato un tipo
3354
+ *
3355
+ * @param {{ value: string, type: InputType }} valType Oggetto Valore - Tipo da cui estrapolare la rappresentazione del dato in stringa
3356
+ *
3357
+ * @returns {string} Valore convertito in stringa in base al tipo
3358
+ */
3359
+ getValueByType(valType) {
3360
+ switch (valType.type) {
3361
+ case 'string':
3362
+ return '"' + valType.value + '"';
3363
+ case 'number':
3364
+ case 'int':
3365
+ case 'boolean':
3366
+ case 'enum':
3367
+ case 'autocomplete':
3368
+ return valType.value;
3369
+ case 'float':
3370
+ case 'currency':
3371
+ return parseFloat(valType.value).toLocaleString(this.est.locale);
3372
+ case 'date':
3373
+ return dayjs(valType.value).format(this.est.lc.token("getSmallDateDisplayFormat"));
3374
+ case 'datetime':
3375
+ return dayjs(valType.value).format(this.est.lc.token("getFullDateDisplayFormat"));
3376
+ case 'time':
3377
+ return dayjs(valType.value).format("HH:mm:ss");
3378
+ }
3379
+ }
2824
3380
  }
2825
3381
 
2826
3382
  // Angular
@@ -2915,10 +3471,7 @@ class UtilitiesHandler {
2915
3471
  for (let i = min; i <= max; i++)
2916
3472
  if (i !== 1)
2917
3473
  result.push({ val: i, cssClass: (i === page ? 'btn-main app-white-text' : 'app-white-button') });
2918
- result.push({
2919
- val: lastPage,
2920
- cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button')
2921
- });
3474
+ result.push({ val: lastPage, cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button') });
2922
3475
  }
2923
3476
  return result;
2924
3477
  }
@@ -2939,9 +3492,11 @@ class UtilitiesHandler {
2939
3492
  delete tmp._selected;
2940
3493
  delete tmp._visible;
2941
3494
  delete tmp._hash;
3495
+ delete tmp._ordinal;
2942
3496
  let hash = this.hashExts.hashObject(tmp);
2943
3497
  usedHashesCache[hash] = usedHashesCache[hash] ? usedHashesCache[hash] + 1 : 1;
2944
3498
  item._hash = hash + (usedHashesCache[hash] > 1 ? "_" + usedHashesCache[hash] : "");
3499
+ item._ordinal = i;
2945
3500
  }
2946
3501
  }
2947
3502
  /**
@@ -2965,13 +3520,63 @@ class UtilitiesHandler {
2965
3520
  return null;
2966
3521
  }
2967
3522
  }
2968
- UtilitiesHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, deps: [{ token: i5.HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
2969
- UtilitiesHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, providedIn: 'root' });
2970
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: UtilitiesHandler, decorators: [{
3523
+ UtilitiesHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, deps: [{ token: i5.HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
3524
+ UtilitiesHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, providedIn: 'root' });
3525
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UtilitiesHandler, decorators: [{
2971
3526
  type: Injectable,
2972
3527
  args: [{ providedIn: 'root' }]
2973
3528
  }], ctorParameters: function () { return [{ type: i5.HashingService }]; } });
2974
3529
 
3530
+ /** Classe che fornisce dei metodi di estensione in grado di riconoscere e dispatchare l'evento copia e incolla lanciato su una pagina web */
3531
+ class CopyPasteDetector {
3532
+ /** @ignore */
3533
+ constructor() {
3534
+ /** Dispatcher del Copia */
3535
+ this.OnCopy = new Subject();
3536
+ /** Dispatcher dell' Incolla */
3537
+ this.OnPaste = new Subject();
3538
+ /** Riferimento all'estable attiva per evitare di spammare copia incolla dove non servono */
3539
+ this.ActiveEstReference = null;
3540
+ document.addEventListener("keydown", (event) => {
3541
+ if (event.key === "c" && event.ctrlKey)
3542
+ this.OnCopy.next();
3543
+ if (event.key === "v" && event.ctrlKey)
3544
+ this.OnPaste.next();
3545
+ });
3546
+ }
3547
+ }
3548
+ CopyPasteDetector.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3549
+ CopyPasteDetector.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, providedIn: "root" });
3550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CopyPasteDetector, decorators: [{
3551
+ type: Injectable,
3552
+ args: [{ providedIn: "root" }]
3553
+ }], ctorParameters: function () { return []; } });
3554
+
3555
+ /** Classe che fornisce dei metodi di estensione in grado di riconoscere e dispatchare l'evento copia e incolla lanciato su una pagina web */
3556
+ class Logger {
3557
+ /** @ignore */
3558
+ constructor(debugMode) {
3559
+ this.debugMode = debugMode;
3560
+ }
3561
+ log(text) {
3562
+ if (this.debugMode)
3563
+ console.log("[@esfaenza/es-table @ " + (new Date()).toISOString() + "] " + text);
3564
+ }
3565
+ }
3566
+ 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 });
3567
+ Logger.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: Logger, providedIn: "root" });
3568
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: Logger, decorators: [{
3569
+ type: Injectable,
3570
+ args: [{ providedIn: "root" }]
3571
+ }], ctorParameters: function () {
3572
+ return [{ type: undefined, decorators: [{
3573
+ type: Optional
3574
+ }, {
3575
+ type: Inject,
3576
+ args: [EST_DEBUG]
3577
+ }] }];
3578
+ } });
3579
+
2975
3580
  //Angular
2976
3581
  /** Componente rappresentante una Colonna della tabella */
2977
3582
  class EsTh {
@@ -3100,11 +3705,11 @@ class EsTh {
3100
3705
  $event.preventDefault();
3101
3706
  }
3102
3707
  }
3103
- 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 });
3104
- 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 });
3105
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTh, decorators: [{
3708
+ 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 });
3709
+ 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 });
3710
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTh, decorators: [{
3106
3711
  type: Component,
3107
- 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>" }]
3712
+ 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>" }]
3108
3713
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ID: [{
3109
3714
  type: Input,
3110
3715
  args: ['es-th']
@@ -3145,75 +3750,206 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
3145
3750
  args: ['window:mousemove.out-zone', ['$event']]
3146
3751
  }] } });
3147
3752
 
3148
- //Angular
3753
+ // Angular
3149
3754
  /** Componente rappresentante una singola cella del body della tabella */
3150
3755
  class EsTd {
3151
3756
  /** @ignore */
3152
- constructor(myself, renderer, _viewContainer, sanitizer) {
3153
- this.myself = myself;
3154
- this.renderer = renderer;
3155
- this._viewContainer = _viewContainer;
3156
- this.sanitizer = sanitizer;
3757
+ constructor(cdr) {
3758
+ this.cdr = cdr;
3157
3759
  /** Id della cella, dev'essere lo stesso della colonna **EsTh** relativa */
3158
3760
  this.ID = "";
3159
- /** Valore da mostrare all'interno della cella. Se omesso verrà proiettato il contenuto dal template in cui è stata usata */
3160
- this.Display = null;
3161
- /** Template Angular da istanziare per questo TD */
3162
- this.Template = null;
3163
- }
3164
- /**
3165
- * Imposta la visibilità o meno della cella, si traduce nell'applicazione o rimozione della classe **app-display-none**
3166
- *
3167
- * @param {boolean} expression Indicazione della visibilità
3168
- */
3169
- set Visible(expression) {
3170
- this._Visible = expression;
3171
- if (expression)
3172
- this.renderer.removeClass(this.myself.nativeElement, "app-display-none");
3173
- else
3174
- this.renderer.addClass(this.myself.nativeElement, "app-display-none");
3175
- }
3176
- /**
3177
- * Restituisce lo stato di Visibilità della cella in oggetto
3178
- *
3179
- * @returns {boolean} **true** se visibile, **false** altrimenti
3180
- */
3181
- get Visible() {
3182
- if (this._Visible == undefined)
3183
- this._Visible = true;
3184
- return this._Visible;
3761
+ /** Quando questa cella viene generata questo evento permette di dire "ehi, sono nato!" */
3762
+ this.onCellGeneration = new EventEmitter();
3763
+ /** Errore attualmente presente sulla cella */
3764
+ this.ValidationError = "";
3185
3765
  }
3186
3766
  /** @ignore */
3187
3767
  ngAfterViewInit() {
3188
- // Se è Internal significa che è gestita internamente da ES-TABLE quindi evito di fare sti due passaggi di lettura del DOM
3189
- if (this.Internal)
3190
- return;
3191
- this.Content = this.Display === null || this.Display === "" ? this.sanitizer.bypassSecurityTrustHtml(this.myself.nativeElement.innerHTML) : this.sanitizer.bypassSecurityTrustHtml(this.Display);
3192
- this.Class = this.myself.nativeElement.className.replace("app-display-none", "");
3768
+ this.onCellGeneration.emit({ id: this.ID, hash: this.Context, self: this });
3769
+ }
3770
+ /** Api per impostare un "errore" su questa cella in maniera programmatica */
3771
+ validationError(error) {
3772
+ this.ValidationError = error;
3773
+ this.cdr.markForCheck();
3193
3774
  }
3194
3775
  }
3195
- 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 });
3196
- 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 });
3197
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTd, decorators: [{
3776
+ EsTd.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTd, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3777
+ 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 });
3778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTd, decorators: [{
3198
3779
  type: Component,
3199
- args: [{ selector: "[es-td]", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>\r\n <ng-content></ng-content>\r\n</span>" }]
3200
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i1$1.DomSanitizer }]; }, propDecorators: { ID: [{
3780
+ 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"] }]
3781
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { ID: [{
3201
3782
  type: Input,
3202
3783
  args: ['es-td']
3203
- }], Internal: [{
3204
- type: Input
3205
- }], RouterLink: [{
3206
- type: Input
3207
- }], Display: [{
3208
- type: Input
3209
- }], Template: [{
3210
- type: Input
3211
3784
  }], Context: [{
3212
3785
  type: Input
3213
- }], Visible: [{
3214
- type: Input
3786
+ }], onCellGeneration: [{
3787
+ type: Output
3215
3788
  }] } });
3216
3789
 
3790
+ // Angular
3791
+ class EstLookupPipe {
3792
+ transform(value, source) {
3793
+ for (let i = 0; i < source.length; i++) {
3794
+ if (source[i].id == value)
3795
+ return source[i];
3796
+ }
3797
+ return { id: "", description: "" };
3798
+ }
3799
+ }
3800
+ EstLookupPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3801
+ EstLookupPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, name: "est_lookup" });
3802
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstLookupPipe, decorators: [{
3803
+ type: Pipe,
3804
+ args: [{ name: 'est_lookup' }]
3805
+ }] });
3806
+
3807
+ class EstRouterLinkPipe {
3808
+ constructor() {
3809
+ /** Cache per i routerLink generati nelle tabelle dinamiche */
3810
+ this.routerLinksCache = {};
3811
+ }
3812
+ transform(item, path, parameters) {
3813
+ if (this.routerLinksCache[item._hash + path]) {
3814
+ return this.routerLinksCache[item._hash + path];
3815
+ }
3816
+ else {
3817
+ let link = this.getRouterLink(path, parameters, item);
3818
+ this.routerLinksCache[item._hash + path] = link;
3819
+ return link;
3820
+ }
3821
+ }
3822
+ /**
3823
+ * Crea un router link
3824
+ *
3825
+ * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
3826
+ * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
3827
+ * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
3828
+ * @param {any} item Oggetto collegato a questo contesto. Può essere un oggetto generico (con "properties") o un oggetto ben definito
3829
+ *
3830
+ * @returns {any} Router link generato in base al parametri
3831
+ */
3832
+ getRouterLink(path, pars, item) {
3833
+ for (let i = 0; i < pars.length; i++)
3834
+ path = path.replace('{' + i + '}', item.properties ? item.properties[pars[i]] : item[pars[i]]);
3835
+ path = path.replace(/'/g, '"').replace(/ /g, '');
3836
+ return JSON.parse(path);
3837
+ }
3838
+ }
3839
+ EstRouterLinkPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3840
+ EstRouterLinkPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, name: "est_routerlink" });
3841
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRouterLinkPipe, decorators: [{
3842
+ type: Pipe,
3843
+ args: [{ name: 'est_routerlink' }]
3844
+ }] });
3845
+
3846
+ // Angular
3847
+ class EstFormatPipe {
3848
+ constructor(dates) {
3849
+ this.dates = dates;
3850
+ }
3851
+ transform(value, format) {
3852
+ if (!format) {
3853
+ // Se è un formato data mi assicuro di non stampare mai una data 00:00:00 altrimenti in esportazione viene uno schifo
3854
+ return value ? this.dates.trimSeconds(value.toString()) : "";
3855
+ }
3856
+ else {
3857
+ // Caso formato numerico
3858
+ if (format.startsWith("F")) {
3859
+ if (!value)
3860
+ return "";
3861
+ if (format.length != 2)
3862
+ return value.toString().replace(/,/, "").replace(".", ",");
3863
+ else {
3864
+ let tmp = parseFloat(value);
3865
+ let cifre = parseInt(format[1]);
3866
+ if (isNaN(tmp) || isNaN(cifre))
3867
+ return "";
3868
+ return (Math.trunc(tmp * Math.pow(10, cifre)) / Math.pow(10, cifre)).toString();
3869
+ }
3870
+ }
3871
+ else {
3872
+ // Se ho un formato data trasformo in dayjs, formatto ed esporto
3873
+ // Per la trasformazione in dayjs provo prima a passargli la stringa di netto, sperando la riconosca
3874
+ // Se non funziona provo a definirgli la formattazione standard del metering per quel linguaggio
3875
+ return this.dates.getFormatted(value, format.length <= 10, format.length > 16);
3876
+ }
3877
+ }
3878
+ }
3879
+ }
3880
+ EstFormatPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, deps: [{ token: i5.DateService }], target: i0.ɵɵFactoryTarget.Pipe });
3881
+ EstFormatPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, name: "est_format" });
3882
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstFormatPipe, decorators: [{
3883
+ type: Pipe,
3884
+ args: [{ name: 'est_format' }]
3885
+ }], ctorParameters: function () { return [{ type: i5.DateService }]; } });
3886
+
3887
+ // Angular
3888
+ class EstRendererPipe {
3889
+ constructor(logger) {
3890
+ this.logger = logger;
3891
+ }
3892
+ transform(propName, params) {
3893
+ var EsTd = null;
3894
+ // Perf. Version di `params.src.find((item) => params.name ? item.td === params.name : item.tdForProperty === propName);`
3895
+ for (let i = 0; i < params.src.length; i++) {
3896
+ let item = params.src.get(i);
3897
+ if (params.name && item.td === params.name ||
3898
+ !params.name && item.tdForProperty === propName) {
3899
+ EsTd = item;
3900
+ break;
3901
+ }
3902
+ }
3903
+ // Name non trovato, fallback al nome della colonna
3904
+ if (propName && params.name && !EsTd) {
3905
+ this.logger.log(`Renderer retrieved in a non performant way`);
3906
+ EsTd = params.src.find((item) => item.tdForProperty === propName);
3907
+ }
3908
+ this.logger.log(`Renderer ${EsTd ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!EsTd ? '. Using fallback renderer' : ''}`);
3909
+ var ret = EsTd ? EsTd.Template : params.fallback;
3910
+ return ret;
3911
+ }
3912
+ }
3913
+ EstRendererPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, deps: [{ token: Logger }], target: i0.ɵɵFactoryTarget.Pipe });
3914
+ EstRendererPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, name: "est_renderer" });
3915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstRendererPipe, decorators: [{
3916
+ type: Pipe,
3917
+ args: [{ name: 'est_renderer' }]
3918
+ }], ctorParameters: function () { return [{ type: Logger }]; } });
3919
+
3920
+ // Angular
3921
+ class EstEditorPipe {
3922
+ constructor(logger) {
3923
+ this.logger = logger;
3924
+ }
3925
+ transform(propName, params) {
3926
+ var Editor = null;
3927
+ // Perf. Version di `params.src.find((item) => params.name ? item.editor === params.name : item.editorForProperty === propName);`
3928
+ for (let i = 0; i < params.src.length; i++) {
3929
+ let item = params.src.get(i);
3930
+ if (params.name && item.editor === params.name ||
3931
+ !params.name && item.editorForProperty === propName) {
3932
+ Editor = item;
3933
+ break;
3934
+ }
3935
+ }
3936
+ // Name non trovato, fallback al nome della colonna
3937
+ if (propName && params.name && !Editor) {
3938
+ this.logger.log(`Editor retrieved in a non performant way`);
3939
+ Editor = params.src.find((item) => item.editorForProperty === propName);
3940
+ }
3941
+ this.logger.log(`Editor ${Editor ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!Editor ? '. Using fallback editor' : ''}`);
3942
+ var ret = Editor ? Editor.Template : params.fallback;
3943
+ return ret;
3944
+ }
3945
+ }
3946
+ EstEditorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, deps: [{ token: Logger }], target: i0.ɵɵFactoryTarget.Pipe });
3947
+ EstEditorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, name: "est_editor" });
3948
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EstEditorPipe, decorators: [{
3949
+ type: Pipe,
3950
+ args: [{ name: 'est_editor' }]
3951
+ }], ctorParameters: function () { return [{ type: Logger }]; } });
3952
+
3217
3953
  /** Raccolta di tutti gli Input dell'EsTable a cui può essere logicamente sensato assegnare default per progetto */
3218
3954
  class EsTableDefaultable {
3219
3955
  }
@@ -3221,8 +3957,8 @@ class EsTableDefaultable {
3221
3957
  /** Componente che permette di rappresentare una griglia di valori */
3222
3958
  class EsTableComponent {
3223
3959
  /** @ignore */
3224
- constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts) {
3225
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
3960
+ constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts, copyPasteDetector, clipboardService, logger) {
3961
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
3226
3962
  this.ngControl = ngControl;
3227
3963
  this.prefService = prefService;
3228
3964
  this.deafults = deafults;
@@ -3234,6 +3970,9 @@ class EsTableComponent {
3234
3970
  this.expExts = expExts;
3235
3971
  this.dateExts = dateExts;
3236
3972
  this.msgExts = msgExts;
3973
+ this.copyPasteDetector = copyPasteDetector;
3974
+ this.clipboardService = clipboardService;
3975
+ this.logger = logger;
3237
3976
  /** Subject utilizzato internamente lato EsTable per causare il Focus lato componente di Input */
3238
3977
  this.FocusSubject = new Subject();
3239
3978
  /** Se vengono effettuati 2 click a distanza inferiore a questi Millisecondi viene considerato un doppio click */
@@ -3259,9 +3998,9 @@ class EsTableComponent {
3259
3998
  this.boundSource = [];
3260
3999
  /** Stessa cosa della **boundSource**, utilizzata come appoggio temporaneo interno */
3261
4000
  this.TMPBoundSource = [];
3262
- /** "Fetta" di oggetti utilizzata nell'endless scroll, ogni elemento di questo array è un blocchetto di 100 elementi */
4001
+ /** @deprecated "Fetta" di oggetti utilizzata nell'endless scroll, ogni elemento di questo array è un blocchetto di 100 elementi */
3263
4002
  this.boundSubSources = [];
3264
- /** Questa funge da indicatore per gli slice inseriti, la lunghezza dovrebbe essere corrispondente a **boundSubSources** */
4003
+ /** @deprecated Questa funge da indicatore per gli slice inseriti, la lunghezza dovrebbe essere corrispondente a **boundSubSources** */
3265
4004
  this.addedSlices = [];
3266
4005
  /** Variabile che identifica il valore del "seleziona Tutto" nella paginazione */
3267
4006
  this.defaultAllPageOverride = 999999;
@@ -3271,20 +4010,20 @@ class EsTableComponent {
3271
4010
  this.seconds = '10';
3272
4011
  /** Impostata a true ogni volta che viene avviata una ricerca, e a false ogni volta che un nuovo valore viene ricevuto */
3273
4012
  this.researchInProgress = false;
3274
- /** Modello rappresentante un dizionario di righe della tabella, con chiave l'hash e valore la lista di celle */
3275
- this.RowTDs = null;
3276
4013
  /** Modello di appoggio temporaneo per i **RowTDs** */
3277
4014
  this.TMPRowTDs = null;
3278
- /** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
3279
- this.RowTHs = null;
4015
+ /** Modello rappresentante un dizionario di righe della tabella, con chiave l'hash e valore la lista di celle */
4016
+ this.RowTDs = null;
4017
+ /** Indica se **RowTDs** è un oggetto vuoto o meno */
4018
+ this.EmptyRowTds = true;
3280
4019
  /** Modello di appoggio temporaneo per i **RowTHs** */
3281
4020
  this.TMPRowTHs = null;
4021
+ /** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
4022
+ this.RowTHs = null;
3282
4023
  /** Modello di appoggio temporaneo per i **RowThGroups** */
3283
4024
  this.TMPRowThGroups = null;
3284
4025
  /** Modello rappresentante un singolo header group della tabella. Questa lista è già ordinata e pronta per essere utilizzata in ngFor */
3285
4026
  this.RowThGroups = null;
3286
- /** Cache per i routerLink generati nelle tabelle dinamiche */
3287
- this.DynamicTableRouterLinkCache = {};
3288
4027
  /**
3289
4028
  * Lista dei contesti. Un contesto non è altro che un hash particolare calcolato su un oggetto che identifica univocamente tale oggetto.
3290
4029
  *
@@ -3295,6 +4034,19 @@ class EsTableComponent {
3295
4034
  this.OrderDirectives = [];
3296
4035
  /** Codice dell'ultimo oggetto solezionato */
3297
4036
  this.lastSelectedItemID = null;
4037
+ /**
4038
+ * Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
4039
+ *
4040
+ * 1) Ordinamento e visibilità delle colonne
4041
+ *
4042
+ * 2) Ordinamento dei dati
4043
+ *
4044
+ * 3) Modalità Gerarchica
4045
+ *
4046
+ * ecc...
4047
+ * viene dedotto dal sistema in automatico
4048
+ */
4049
+ this.UseCustomCells = null;
3298
4050
  /**
3299
4051
  * Indica se oltre alle colonne dinamiche specifiche di un tipo di oggetto ci sono anche colonne dinamiche aggiunte dall'utente
3300
4052
  *
@@ -3317,18 +4069,12 @@ class EsTableComponent {
3317
4069
  this.ColumnsPinnable = null;
3318
4070
  /** Indica se dev'essere disponibile il sistema di aggiornamento automatico */
3319
4071
  this.AutoUpdate = null;
3320
- /**
3321
- * Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
3322
- *
3323
- * 1) Ordinamento e visibilità delle colonne
3324
- *
3325
- * 2) Ordinamento dei dati
3326
- *
3327
- * 3) Modalità Gerarchica
3328
- *
3329
- * ecc...
3330
- */
3331
- this.UseCustomCells = null;
4072
+ /** Indica l'altezza cablata che deve assumere la tabella. Es: "100px" | "100%" ... */
4073
+ this.Height = null;
4074
+ /** Indica il colore di sfondo dello spazio vuoto (non ricoperto da dati). Particolarmente utile da impostare in caso di **Height** diverso da null */
4075
+ this.EmptySpaceBackgroundColor = null;
4076
+ /** Indica se dev'essere l'estable a gestire la ricerca, anche la prima. **/
4077
+ this.EsTableHandledSearch = false;
3332
4078
  /** Permette di impostare l'altezza massima della tabella. Se null la dimensione si adatta al numero di elementi attualmente in visualizzazione */
3333
4079
  this.MaxHeight = null;
3334
4080
  /** Classi da applicare al contenitore della tabella */
@@ -3371,9 +4117,11 @@ class EsTableComponent {
3371
4117
  this.ExportFileName = 'Export.csv';
3372
4118
  /** Classe (HTML) di default della tabella */
3373
4119
  this.TableClass = null;
3374
- /** Indica la presenza di raggruppamenti a livello di header */
4120
+ /** Indica di esportare solo le colonne attualmente visibili della view */
4121
+ this.ExportOnlyVisibleColumns = false;
4122
+ /** @deprecated Indica la presenza di raggruppamenti a livello di header */
3375
4123
  this.HasHeaderGroup = null;
3376
- /** Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
4124
+ /** @deprecated Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
3377
4125
  this.HasSecondaryHeaderGroup = null;
3378
4126
  /** Indica se nascondere gli Header della tabella */
3379
4127
  this.HeaderHidden = null;
@@ -3399,7 +4147,7 @@ class EsTableComponent {
3399
4147
  this.HiddenColumns = null;
3400
4148
  /** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
3401
4149
  this.ColumnsOrdering = null;
3402
- /** Eventuale supporto alle ricerche applicate alla modalità Array */
4150
+ /** @deprecated Eventuale supporto alle ricerche applicate alla modalità Array */
3403
4151
  this.SearchView = null;
3404
4152
  /** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
3405
4153
  this.SelectAll = null;
@@ -3419,6 +4167,8 @@ class EsTableComponent {
3419
4167
  this.StartsExpanded = true;
3420
4168
  /** Indica se effettuare il salvataggio delle preferenze di ricerca */
3421
4169
  this.SavePreferences = null;
4170
+ /** Allineamento di default per celle e headers */
4171
+ this.DefaultAlignment = null;
3422
4172
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
3423
4173
  this.PagingStyle = null;
3424
4174
  /** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
@@ -3430,7 +4180,11 @@ class EsTableComponent {
3430
4180
  /** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
3431
4181
  this.ShowItemGroupsColumns = null;
3432
4182
  /** Indica che tutti i campi che definiscono le modalità di modifica campo possono essere modificati in base alle impostazioni */
3433
- this.UserEdits = false;
4183
+ this.Editable = false;
4184
+ /** Indica se è possibile effettuare selezioni a range per poi farci eventualmente copia incolla */
4185
+ this.RangeSelection = false;
4186
+ /** Indica il numero di millisecondi per cui debouncare il writeValue per la modalità **EsTableHandledSearch** */
4187
+ this.SearchThrottle = 50;
3434
4188
  /** Evento che viene richiamato al cambio di oridnamento di una colonna */
3435
4189
  this.onOrderChanged = new EventEmitter();
3436
4190
  /**
@@ -3449,6 +4203,10 @@ class EsTableComponent {
3449
4203
  this.onRemoval = new EventEmitter();
3450
4204
  /** Evento richiamato all'annullamento di un'eliminazione */
3451
4205
  this.onAbortRemoval = new EventEmitter();
4206
+ /** Evento richiamato alla modifica dei modelli bindati */
4207
+ this.onModelChange = new EventEmitter();
4208
+ /** Evento richiamato all'apertura del menù contestuale */
4209
+ this.onOpenContextMenu = new EventEmitter();
3452
4210
  /** Evento richiamato quando si clicca su un opzione definita nelle **CornerMenuOptions** */
3453
4211
  this.onCornerAction = new EventEmitter();
3454
4212
  /** Evento richiamato quando si clicca su un opzione definita nelle **DynamicOperations** */
@@ -3499,12 +4257,51 @@ class EsTableComponent {
3499
4257
  this.ArrayGrouping = false;
3500
4258
  /** Indica che l'es-table è basata sulle direttive (nuova modalità) */
3501
4259
  this.DirectivesBased = false;
4260
+ /** Indica lo stato di selezione per singola cella */
4261
+ this.selectionStatus = {};
4262
+ /** Chiamata reale al writeValue dopo il passaggio di **SearchThrottle** millisecondi. Solo modalità EsTableHandledSearch */
4263
+ this.callTimeout = null;
4264
+ /** Cache dei th piuttosto che ricalcolarseli di continuo */
4265
+ this.thsCache = {};
4266
+ /** Indica quando la cache dei th è stata fillata almeno la prima volta */
4267
+ this.thsCacheSet = false;
4268
+ /**
4269
+ * Flag che, se **true**, per un giro di binding mantiene la visibilità impostata localmente, piuttosto che allineare alla View bindata.
4270
+ * Usata per modificare in maniera programmatica la visibilità delle colonne dal metodo **setHeaderVisibility**,
4271
+ *
4272
+ * Disclaimer: **NON MODIFICARE**
4273
+ **/
4274
+ this.useLocalVisibility = false;
3502
4275
  /** Opzioni di paginazione */
3503
- this.PagerOptions = { PagerCount: null, ShowCount: true, ShowPaging: true, ShowButtons: true, ShowPagingOptions: true, UsesView: true, View: null, Ready: false, Searches: 'items' };
4276
+ this.PagerOptions = new PagerInfos();
3504
4277
  /** @ignore */
3505
4278
  this.propagateChange = (_) => { };
3506
4279
  /** Funzione di trackby per il body che dovrebbe evitare il 90% delle change detection */
3507
- this.bodyTrackBy = (index, item) => item._hash;
4280
+ this.bodyTrackBy = (_, item) => item._hash;
4281
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo id */
4282
+ this.idTrackBy = (_, item) => item.id;
4283
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo PropertyName */
4284
+ this.PropertyNameTrackBy = (_, item) => item.PropertyName;
4285
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
4286
+ this.IDTrackBy = (_, item) => item.ID;
4287
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
4288
+ this.valTrackBy = (_, item) => item.val;
4289
+ // Range selection Experimentals
4290
+ this.mouseIsDown = false;
4291
+ this.rangeSelected = false;
4292
+ this.rangeStartWasIgnored = false;
4293
+ this.firstCoordinates = null;
4294
+ //* Piango
4295
+ this.EsTdsCache = {};
4296
+ // Copia e incolla si effettuano solo se la tabella attuale è univocamente selezionata
4297
+ this.copySubscription = this.copyPasteDetector.OnCopy.subscribe(() => {
4298
+ if (this.copyPasteDetector.ActiveEstReference == this)
4299
+ this.handleCopy();
4300
+ });
4301
+ this.pasteSubscription = this.copyPasteDetector.OnPaste.subscribe(() => {
4302
+ if (this.copyPasteDetector.ActiveEstReference == this)
4303
+ this.handlePaste();
4304
+ });
3508
4305
  this.export_H = new ExportHandler(this, this.expExts, this.msgExts, this.utiExts, this.dateExts);
3509
4306
  this.rowGrouping_H = new RowGroupingHandler(this, this.utilities_H, this.dateExts);
3510
4307
  this.columnMetadata_H = new ColumnMetadataHandler(this, this.utilities_H, this.utiExts, this.prefService, this.rowGrouping_H);
@@ -3533,6 +4330,7 @@ class EsTableComponent {
3533
4330
  this.ShowItemGroupsColumns = this.utilities_H.InputOrDefault(this.ShowItemGroupsColumns, (_q = this.deafults) === null || _q === void 0 ? void 0 : _q.ShowItemGroupsColumns, false);
3534
4331
  this.ArraymodeItemsPerPage = this.utilities_H.InputOrDefault(this.ArraymodeItemsPerPage, (_r = this.deafults) === null || _r === void 0 ? void 0 : _r.ArraymodeItemsPerPage, 15);
3535
4332
  this.ColumnsPinnable = this.utilities_H.InputOrDefault(this.ColumnsPinnable, (_s = this.deafults) === null || _s === void 0 ? void 0 : _s.ColumnsPinnable, true);
4333
+ this.DefaultAlignment = this.utilities_H.InputOrDefault(this.DefaultAlignment, (_t = this.deafults) === null || _t === void 0 ? void 0 : _t.DefaultAlignment, 'Left');
3536
4334
  }
3537
4335
  /** @ignore */
3538
4336
  ngOnInit() {
@@ -3543,6 +4341,7 @@ class EsTableComponent {
3543
4341
  return;
3544
4342
  let shouldEmit = !t.item._selected;
3545
4343
  t.item._selected = true;
4344
+ this.selection_H.clearSelectionStatusExcluding(null);
3546
4345
  var itemSelection = this.selection_H.handleItemsSelection([t.item]);
3547
4346
  this.changed();
3548
4347
  if (shouldEmit)
@@ -3551,9 +4350,12 @@ class EsTableComponent {
3551
4350
  }
3552
4351
  /** @ignore */
3553
4352
  ngAfterViewInit() {
4353
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3554
4354
  // Se utilizzo la new spicy mode deduco tutti i parametri di lavoro possibili al caricamento della tabella
3555
4355
  // Vengono sovrascritte solo le proprietà non impostate dall'utente
3556
- let usesThsAndTdsDirectives = this.EsTdsDirective && this.EsTdsDirective.length > 0 && this.EsThsDirective && this.EsThsDirective.length > 0;
4356
+ let tdsD = this.EsTdsDirective.length == 0 ? ((_c = (_b = (_a = this.EsTableTemplate) === null || _a === void 0 ? void 0 : _a.Template) === null || _b === void 0 ? void 0 : _b.EsTdsDirective) === null || _c === void 0 ? void 0 : _c.length) > 0 ? (_e = (_d = this.EsTableTemplate) === null || _d === void 0 ? void 0 : _d.Template) === null || _e === void 0 ? void 0 : _e.EsTdsDirective : this.EsTdsDirective : this.EsTdsDirective;
4357
+ let thsD = this.EsThsDirective.length == 0 ? ((_h = (_g = (_f = this.EsTableTemplate) === null || _f === void 0 ? void 0 : _f.Template) === null || _g === void 0 ? void 0 : _g.EsThsDirective) === null || _h === void 0 ? void 0 : _h.length) > 0 ? (_k = (_j = this.EsTableTemplate) === null || _j === void 0 ? void 0 : _j.Template) === null || _k === void 0 ? void 0 : _k.EsThsDirective : this.EsThsDirective : this.EsThsDirective;
4358
+ let usesThsAndTdsDirectives = tdsD && tdsD.length > 0 && thsD && thsD.length > 0;
3557
4359
  let hasNoContentProjection = !this.bodyRef && !this.headerRef && !this.headerGroupRef && !this.secondaryHeaderGroupRef;
3558
4360
  if (usesThsAndTdsDirectives || hasNoContentProjection) {
3559
4361
  if (this.UseCustomCells == null)
@@ -3577,15 +4379,21 @@ class EsTableComponent {
3577
4379
  }
3578
4380
  /** @ignore */
3579
4381
  ngOnDestroy() {
4382
+ if (this.copySubscription)
4383
+ this.copySubscription.unsubscribe();
4384
+ if (this.pasteSubscription)
4385
+ this.pasteSubscription.unsubscribe();
3580
4386
  if (this.ctxMenuSubscription)
3581
4387
  this.ctxMenuSubscription.unsubscribe();
4388
+ if (this.copyPasteDetector.ActiveEstReference == this)
4389
+ this.copyPasteDetector.ActiveEstReference = null;
3582
4390
  }
3583
4391
  /** @ignore */
3584
4392
  ngOnChanges(changes) {
3585
4393
  return __awaiter(this, void 0, void 0, function* () {
3586
4394
  let newSearchView = changes['SearchView'];
3587
4395
  if (newSearchView && this.SearchView)
3588
- this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
4396
+ this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.objectcount, this.SearchView.itemsperpageoverride);
3589
4397
  });
3590
4398
  }
3591
4399
  /** @ignore */
@@ -3593,12 +4401,22 @@ class EsTableComponent {
3593
4401
  /** @ignore */
3594
4402
  registerOnTouched(fn) { }
3595
4403
  /** @ignore */
3596
- changed() { this.propagateChange(this.View); }
4404
+ changed(clearItems = false) {
4405
+ if (clearItems && this.viewMode)
4406
+ this.View.items = [];
4407
+ this.propagateChange(this.View);
4408
+ }
3597
4409
  /** @ignore */
3598
- writeValue(obj) {
3599
- var _a;
4410
+ writeValue(obj, throttle = true) {
4411
+ var _a, _b;
3600
4412
  return __awaiter(this, void 0, void 0, function* () {
3601
4413
  this.View = obj ? obj : null;
4414
+ if (this.EsTableHandledSearch && throttle) {
4415
+ if (this.callTimeout)
4416
+ clearTimeout(this.callTimeout);
4417
+ this.callTimeout = setTimeout(() => { this.writeValue(obj, false); }, this.SearchThrottle);
4418
+ return;
4419
+ }
3602
4420
  // Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
3603
4421
  this.researchInProgress = false;
3604
4422
  if (!this.View && !this.SearchView) {
@@ -3652,16 +4470,29 @@ class EsTableComponent {
3652
4470
  }
3653
4471
  // In modalità report devo controllare che tutte le colonne salvate facciano parte della vista
3654
4472
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3655
- // sto facendo riferimento a una versione vecchia dell'es-table, quindi non foccio operazioni
4473
+ // sto facendo riferimento a una versione vecchia dell'es-table, quindi non faccio operazioni
3656
4474
  for (let i = 0; i < source.length; i++) {
3657
4475
  if (repository.indexOf(source[i]) == -1) {
3658
4476
  updatedPrefs = false;
3659
4477
  break;
3660
4478
  }
3661
4479
  }
4480
+ // Se mi baso su direttive ma nelle preference è presente anche solo una colonna non presente nelle direttive
4481
+ // vuol dire che l'es-table è cambiata quindi non imposto preference
4482
+ if (((_b = this.EsThsDirective) === null || _b === void 0 ? void 0 : _b.length) > 0) {
4483
+ for (let i = 0; i < repository.length; i++) {
4484
+ if (this.thsCacheSet && !this.thsCache[repository[i]]) {
4485
+ updatedPrefs = false;
4486
+ break;
4487
+ }
4488
+ }
4489
+ }
3662
4490
  if (updatedPrefs) {
3663
4491
  this.View.columns = (prefs === null || prefs === void 0 ? void 0 : prefs.columns) || [];
3664
4492
  this.View.column_ordering = (prefs === null || prefs === void 0 ? void 0 : prefs.column_ordering) || [];
4493
+ // Se le pref sono nulle non sovrascrivo gli ordini dato che potrebbe servire mettere degli ordinamenti di default lato ts
4494
+ if (prefs)
4495
+ this.View.orders = (prefs === null || prefs === void 0 ? void 0 : prefs.orders) || [];
3665
4496
  }
3666
4497
  }
3667
4498
  }
@@ -3697,7 +4528,10 @@ class EsTableComponent {
3697
4528
  repository = cols;
3698
4529
  source = this.View.columns;
3699
4530
  }
3700
- // In modalità report devo controllare che tutte le colonne salvate facciano parte della vista
4531
+ // In modalità report aggiorno le preferenze solo se c'è almeno una colonna, altrimenti vuol dire che si parte da vuoti
4532
+ // con tutte le colonne disponibili
4533
+ if (this.View.report_columns && ((source === null || source === void 0 ? void 0 : source.length) || 0) == 0)
4534
+ updatedPrefs = false;
3701
4535
  // In modalità normale invece se le preferenze fanno riferimento a delle colonne che io non ho nella View attuale significa che
3702
4536
  // sto facendo riferimento a una versione vecchia dell'es-table, quindi non foccio operazioni
3703
4537
  for (let i = 0; i < source.length; i++) {
@@ -3709,6 +4543,9 @@ class EsTableComponent {
3709
4543
  if (updatedPrefs) {
3710
4544
  this.View.columns = (prefs === null || prefs === void 0 ? void 0 : prefs.columns) || [];
3711
4545
  this.View.column_ordering = (prefs === null || prefs === void 0 ? void 0 : prefs.column_ordering) || [];
4546
+ // Se le pref sono nulle non sovrascrivo gli ordini dato che potrebbe servire mettere degli ordinamenti di default lato ts
4547
+ if (prefs)
4548
+ this.View.orders = (prefs === null || prefs === void 0 ? void 0 : prefs.orders) || [];
3712
4549
  }
3713
4550
  }
3714
4551
  }
@@ -3717,6 +4554,15 @@ class EsTableComponent {
3717
4554
  }
3718
4555
  this.finalizeContext();
3719
4556
  this.postBoundSourceCalculation();
4557
+ if (this.View && !this.View.selfsearch && this.EsTableHandledSearch) {
4558
+ this.View.selfsearch = true;
4559
+ this.changed(true);
4560
+ this.onSearchRequest.emit(false);
4561
+ }
4562
+ else if (this.View && this.View.selfsearch && this.EsTableHandledSearch) {
4563
+ this.View.selfsearch = false;
4564
+ this.changed();
4565
+ }
3720
4566
  });
3721
4567
  }
3722
4568
  /**
@@ -3725,7 +4571,7 @@ class EsTableComponent {
3725
4571
  */
3726
4572
  finalizeContext() {
3727
4573
  let viewCasted = this.View;
3728
- let hasRowGroups = (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
4574
+ let hasRowGroups = viewCasted && (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
3729
4575
  // Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
3730
4576
  if (this.arrayMode && hasRowGroups)
3731
4577
  this.UseArrayModePaging = false;
@@ -3770,7 +4616,7 @@ class EsTableComponent {
3770
4616
  this.PagerOptions.PagerCount = this.View.length || 0;
3771
4617
  this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && (this.View.length > 10 || (((_a = this.SearchView) === null || _a === void 0 ? void 0 : _a.objectcount) || 0) > 10);
3772
4618
  this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
3773
- this.PagerOptions.ShowPaging = this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount;
4619
+ this.PagerOptions.ShowPaging = this.PagerOptions.ShowPaging && (this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount);
3774
4620
  this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
3775
4621
  }
3776
4622
  else if (this.viewMode) {
@@ -3797,11 +4643,15 @@ class EsTableComponent {
3797
4643
  }
3798
4644
  /** 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 */
3799
4645
  internalPostBoundSource() {
4646
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
3800
4647
  let View = this.View;
3801
- let ths = this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
3802
- let tds = this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
4648
+ let tdsD = this.EsTdsDirective.length == 0 ? ((_c = (_b = (_a = this.EsTableTemplate) === null || _a === void 0 ? void 0 : _a.Template) === null || _b === void 0 ? void 0 : _b.EsTdsDirective) === null || _c === void 0 ? void 0 : _c.length) > 0 ? (_e = (_d = this.EsTableTemplate) === null || _d === void 0 ? void 0 : _d.Template) === null || _e === void 0 ? void 0 : _e.EsTdsDirective : this.EsTdsDirective : this.EsTdsDirective;
4649
+ let thsD = this.EsThsDirective.length == 0 ? ((_h = (_g = (_f = this.EsTableTemplate) === null || _f === void 0 ? void 0 : _f.Template) === null || _g === void 0 ? void 0 : _g.EsThsDirective) === null || _h === void 0 ? void 0 : _h.length) > 0 ? (_k = (_j = this.EsTableTemplate) === null || _j === void 0 ? void 0 : _j.Template) === null || _k === void 0 ? void 0 : _k.EsThsDirective : this.EsThsDirective : this.EsThsDirective;
4650
+ let ths = thsD && thsD.length > 0 ? thsD.toArray() : [];
4651
+ let tds = tdsD && tdsD.length > 0 ? tdsD.toArray() : [];
3803
4652
  // Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
3804
4653
  this.dynamicMode_H.eventuallyReviewDynamicColumns();
4654
+ // Gestisce la richiesta per gruppi o per singoli oggetti
3805
4655
  this.bindDisplayToLoadedItemsOrGroups(View);
3806
4656
  // Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
3807
4657
  this.setupPagingInformations();
@@ -3812,22 +4662,34 @@ class EsTableComponent {
3812
4662
  let si = this.viewMode ? view.selection : this.arraymodeSelection;
3813
4663
  // N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
3814
4664
  // ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
3815
- // Espando i th e i td multipli duplicandoli
3816
- let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
3817
- ths = ret.expThs;
3818
- tds = ret.expTds;
4665
+ // 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
4666
+ if (((_l = this.DynamicRowColumnsDefinition) === null || _l === void 0 ? void 0 : _l.length) > 0) {
4667
+ this.logger.log("Generating ths and tds from Dynamic definition");
4668
+ let ret = this.dynamicMode_H.emitThsAndTdsBasedOnDynamicDefinition();
4669
+ ths = ret.ths;
4670
+ tds = ret.tds;
4671
+ }
3819
4672
  // Gestione delle view in modalità report, i th e i td vengono rigenerati dalle configurazioni della view
3820
4673
  if (!this.arrayMode && view.report_columns) {
4674
+ this.logger.log("Generating ths and tds from report results");
3821
4675
  let ret = this.reportMode_H.generateThsAndTdsFromView(view);
3822
4676
  ths = ret.ths;
3823
4677
  tds = ret.tds;
3824
4678
  }
4679
+ // Espando i th e i td multipli duplicandoli
4680
+ let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
4681
+ ths = ret.expThs;
4682
+ tds = ret.expTds;
4683
+ // 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
4684
+ for (let i = 0; i < ths.length; i++) {
4685
+ let th = ths[i];
4686
+ this.thsCache[th.th] = th;
4687
+ }
4688
+ this.thsCacheSet = true;
3825
4689
  // Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
3826
4690
  let hI = this.columnMetadata_H.evaluateHeadersGroupingInfos(ths);
3827
- if (this.arrayMode) { // In modalità array non ho un backend...
3828
- this.items_H.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
4691
+ if (this.arrayMode) // In modalità array non ho un backend...
3829
4692
  this.rowGrouping_H.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
3830
- }
3831
4693
  this.columnMetadata_H.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
3832
4694
  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.
3833
4695
  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)
@@ -3843,6 +4705,8 @@ class EsTableComponent {
3843
4705
  this.columnMetadata_H.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
3844
4706
  this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
3845
4707
  this.selection_H.evaluateSelection(itemsAndGroups, si); // Riallineo le info di selezione degli elementi della View
4708
+ // Valuta lo stato iniziale di selezione a range
4709
+ this.selection_H.evaluateSingleCellSelection(itemsAndGroups, hI.leafs, this.DynamicRowColumnsDefinition);
3846
4710
  if (this.ResearchNeeded) {
3847
4711
  this.changed();
3848
4712
  this.emitSearchRequest(false);
@@ -3961,7 +4825,13 @@ class EsTableComponent {
3961
4825
  viewOverride.internalsearchrequest = true;
3962
4826
  }
3963
4827
  this.researchInProgress = true;
3964
- this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
4828
+ if (this.View && !this.View.selfsearch && this.EsTableHandledSearch) {
4829
+ this.View.selfsearch = true;
4830
+ this.changed(true);
4831
+ this.onSearchRequest.emit(false);
4832
+ }
4833
+ else
4834
+ this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
3965
4835
  }
3966
4836
  /**
3967
4837
  * Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
@@ -3976,16 +4846,11 @@ class EsTableComponent {
3976
4846
  evaluateRowTds(ths, tds) {
3977
4847
  if (tds.length == 0)
3978
4848
  return;
3979
- let thsCache = {};
3980
4849
  let columnsCache = {};
3981
4850
  for (let coli = 0; coli < this.ColumnsList.length; coli++) {
3982
4851
  let col = this.ColumnsList[coli];
3983
4852
  columnsCache[col.id] = col;
3984
4853
  }
3985
- for (let i = 0; i < ths.length; i++) {
3986
- let th = ths[i];
3987
- thsCache[th.th] = th;
3988
- }
3989
4854
  this.TMPRowTDs = {};
3990
4855
  // Variabile d'appoggio per permettermi di inserire tutte le colonne "Fixed" davanti
3991
4856
  let contextFixeds = {};
@@ -3995,22 +4860,54 @@ class EsTableComponent {
3995
4860
  let item = this.boundSource[i];
3996
4861
  let ctx = item._hash;
3997
4862
  let key = td.td;
3998
- let th = thsCache[td.td];
3999
- let drcd = this.DynamicRowColumnsDefinition;
4863
+ let th = this.thsCache[td.td];
4000
4864
  if (!!th)
4001
4865
  th._referenced = true;
4002
- else if (!drcd || !drcd.find(t => t.propertyName == td.td)) {
4003
- let subject = drcd && drcd.length > 0 ? "le colonne dinamiche specificate" : "gli ID dicharati negli EsTh";
4004
- console.error(`ID dell'oggeto EsTd non compatibile con ${subject} ${td.td}`);
4005
- return;
4006
- }
4007
4866
  // Skippare senza th (casistica tabella dinamica)
4008
- if (th && (td.tdIf || th.thGroup)) {
4867
+ if (th && th.thIf && (td.tdIf || th.thGroup)) {
4009
4868
  let thCasted = th;
4010
4869
  let isFixed = th.thFixed || th.thGroup || th.thPinned;
4011
4870
  let itemToAdd = item._item ?
4012
- { 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 } :
4013
- { 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) };
4871
+ {
4872
+ LeftBorder: thCasted._lbord,
4873
+ RightBorder: thCasted._rbord,
4874
+ ID: key,
4875
+ Pinned: columnsCache[td.td].pinned,
4876
+ PinnedWidth: thCasted.thPinnedWidth,
4877
+ GroupHeader: false,
4878
+ GroupAggregation: false,
4879
+ Visible: columnsCache[td.td].visible,
4880
+ Wraps: false,
4881
+ Class: td.tdClass,
4882
+ IconClass: td.tdIconClass,
4883
+ ConditionField: td.tdConditionField,
4884
+ ConditionValue: td.tdConditionValue,
4885
+ Title: td.tdTitle,
4886
+ Content: td.tdContent,
4887
+ Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template,
4888
+ Multi: td._multi,
4889
+ MultiProp: td._multi ? td.td.split('_')[0] : null,
4890
+ MultiIndex: td._multi ? td.td.split('_')[1] : null,
4891
+ Alignment: (td.tdAlignment || th.thAlignment || this.DefaultAlignment).toLowerCase(),
4892
+ Format: td.tdFormat || th.thFormat,
4893
+ PropertyName: th.thProperty,
4894
+ PropertyType: th.thType,
4895
+ PropertySource: th.thSource,
4896
+ PropAccessor: td.tdPropertyAccessor
4897
+ } :
4898
+ {
4899
+ LeftBorder: thCasted._lbord,
4900
+ RightBorder: thCasted._rbord,
4901
+ ID: key,
4902
+ Pinned: columnsCache[td.td].pinned,
4903
+ PinnedWidth: thCasted.thPinnedWidth,
4904
+ GroupHeader: thCasted.thGroup,
4905
+ GroupAggregation: !!thCasted.thAggregation,
4906
+ Visible: columnsCache[td.td].visible,
4907
+ Wraps: false,
4908
+ Class: thCasted.thGroupClass || '',
4909
+ Content: this.rowGrouping_H.getGroupCellDisplay(item, key, th)
4910
+ };
4014
4911
  if (this.TMPRowTDs[ctx]) {
4015
4912
  this.TMPRowTDs[ctx].push(itemToAdd);
4016
4913
  }
@@ -4060,8 +4957,26 @@ class EsTableComponent {
4060
4957
  let th = ths[i];
4061
4958
  let toAdd;
4062
4959
  if (th.thIf || th.thGroup) {
4063
- let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
4064
- 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 };
4960
+ let thClass = (th.thClass || "") + (th.thShrink ? " app-col-min" : "") + (th.thGroup ? " est-col-min" : "");
4961
+ toAdd = {
4962
+ Pinned: columnsListCache[th.th].pinned,
4963
+ Fixed: th.thFixed,
4964
+ PinnedWidth: th.thPinnedWidth,
4965
+ ID: th.th,
4966
+ Visible: th.thVisible,
4967
+ Class: thClass,
4968
+ Order: th.thOrder,
4969
+ Orderable: th.thOrderable,
4970
+ Template: th.Template,
4971
+ Alignment: (th.thAlignment || this.DefaultAlignment).toLowerCase(),
4972
+ // Se non è nessun contenuto né nessun template mostro semplicemente l'ID dell'header
4973
+ Content: th.thStaticContent != null ? th.thStaticContent : th.Template ? '' : th.th,
4974
+ Wrap: th.thWrap,
4975
+ LeftBorder: th._lbord,
4976
+ RightBorder: th._rbord,
4977
+ Multi: th._multi,
4978
+ MultiContent: th._multi_content
4979
+ };
4065
4980
  this.TMPRowTHs.push(toAdd);
4066
4981
  // Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
4067
4982
  // li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
@@ -4100,6 +5015,8 @@ class EsTableComponent {
4100
5015
  this.emitSearchRequest(false, appSearchElement);
4101
5016
  }
4102
5017
  /**
5018
+ * @TODO Spostare in SelectionHandler
5019
+ *
4103
5020
  * Gestisce i click sulla tabella solo per le righe a gruppo.
4104
5021
  * O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
4105
5022
  *
@@ -4159,6 +5076,7 @@ class EsTableComponent {
4159
5076
  * @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
4160
5077
  */
4161
5078
  globalCheckChanged(forcedVal = null) {
5079
+ this.selection_H.clearSelectionStatusExcluding(null);
4162
5080
  // 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
4163
5081
  let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
4164
5082
  var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
@@ -4166,6 +5084,8 @@ class EsTableComponent {
4166
5084
  this.onSelectionChanged.emit(itemSelection);
4167
5085
  }
4168
5086
  /**
5087
+ * @TODO Spostare in SelectionHandler
5088
+ *
4169
5089
  * Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
4170
5090
  *
4171
5091
  * @param {any} event Evento nativo HTML del click
@@ -4174,12 +5094,8 @@ class EsTableComponent {
4174
5094
  * @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
4175
5095
  */
4176
5096
  handleClick(event, item) {
4177
- // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
4178
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
4179
- return false;
4180
- // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
4181
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
4182
- this.utiExts.clearTextSelection();
5097
+ this.selection_H.clearTextSelection(event);
5098
+ this.selection_H.clearSelectionStatusExcluding(null);
4183
5099
  let selecteditems = [];
4184
5100
  if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
4185
5101
  let startSelecting = false;
@@ -4284,13 +5200,32 @@ class EsTableComponent {
4284
5200
  * Ottiene il contenuto dell'EsTd da utilizzare per la colonna specificata
4285
5201
  *
4286
5202
  * @param {string} column Colonna per cui cercare la cella
5203
+ * @param {string} name Nome diretto per cercare il TD con l'ID. Questa variabile ha priorità rispetto a **column**
4287
5204
  *
4288
5205
  * @returns {TemplateRef<any>} Template da usare per la colonna
4289
5206
  */
4290
- findEsTd(column) {
4291
- var EsTd = this.EsTdsDirective.find((item) => item.td === column);
5207
+ findEsTd(column, name = null) {
5208
+ var EsTd = this.EsTdsDirective.find((item) => name ? item.td === name : item.tdForProperty === column);
5209
+ // Name non trovato, fallback al nome della colonna
5210
+ if (name && column && !EsTd)
5211
+ EsTd = this.EsTdsDirective.find((item) => item.tdForProperty === column);
4292
5212
  return EsTd ? EsTd.Template : null;
4293
5213
  }
5214
+ /**
5215
+ * Ottiene il contenuto dell'editor EsTd da utilizzare per la colonna specificata
5216
+ *
5217
+ * @param {string} column Colonna per cui cercare l'editor
5218
+ * @param {string} name Nome diretto per cercare l'Editor con l'ID. Questa variabile ha priorità rispetto a **column**
5219
+ *
5220
+ * @returns {TemplateRef<any>} Template da usare per la colonna
5221
+ */
5222
+ findEditor(column, name = null) {
5223
+ var Editor = this.EsTdEditorDirectives.find((item) => name ? item.editor === name : item.editorForProperty === column);
5224
+ // Name non trovato, fallback al nome della colonna
5225
+ if (name && column && !Editor)
5226
+ Editor = this.EsTdEditorDirectives.find((item) => item.editorForProperty === column);
5227
+ return Editor ? Editor.Template : null;
5228
+ }
4294
5229
  /**
4295
5230
  * Equivalente del metodo **addToPage** riadattato per la modalità array
4296
5231
  *
@@ -4338,7 +5273,7 @@ class EsTableComponent {
4338
5273
  this.internalWriteCall = false;
4339
5274
  }
4340
5275
  /** Metodo eventualmente richiamabile anche dal componente esterno che permette di forzare un refresh della tabella */
4341
- forceRefresh() {
5276
+ forceRefresh(relaunchSearch = true) {
4342
5277
  // 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
4343
5278
  let arrayPage;
4344
5279
  let arrayIpp;
@@ -4346,6 +5281,8 @@ class EsTableComponent {
4346
5281
  arrayPage = this.arraymodePage;
4347
5282
  arrayIpp = this.ArraymodeItemsPerPage;
4348
5283
  }
5284
+ if (!relaunchSearch && this.viewMode)
5285
+ this.View.selfsearch = true;
4349
5286
  this.writeValue(this.View);
4350
5287
  this.cdr.detectChanges();
4351
5288
  if (this.arrayMode) {
@@ -4353,6 +5290,28 @@ class EsTableComponent {
4353
5290
  this.arrayGoToPage(arrayPage);
4354
5291
  }
4355
5292
  }
5293
+ /**
5294
+ * Imposta la visibilità di un header e di eventuali header collegati se questo header è un gruppo, dopodiché aggiorna l'es-table
5295
+ *
5296
+ * @param {string} groupOrHeader Header di cui settare la visibilità
5297
+ * @param {boolean} visibility Visibilità da impostare
5298
+ **/
5299
+ setHeaderVisibility(groupOrHeader, visibility, refresh = true, relaunchSearch = true) {
5300
+ let groupOrHead = this.thsCache[groupOrHeader];
5301
+ if (!groupOrHead)
5302
+ return;
5303
+ groupOrHead.thVisible = visibility;
5304
+ let thsArr = this.EsThsDirective.toArray();
5305
+ for (let i = 0; i < thsArr.length; i++) {
5306
+ let th = thsArr[i];
5307
+ if (th.thParent == groupOrHeader)
5308
+ this.setHeaderVisibility(th.th, visibility, false);
5309
+ }
5310
+ if (refresh) {
5311
+ this.useLocalVisibility = true;
5312
+ this.forceRefresh(relaunchSearch);
5313
+ }
5314
+ }
4356
5315
  /**
4357
5316
  * 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
4358
5317
  *
@@ -4361,30 +5320,107 @@ class EsTableComponent {
4361
5320
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4362
5321
  */
4363
5322
  dbClickEditOrSingleClickRowSelection($event, rowItem, item) {
5323
+ // Prima cosa da fare è controllare se ci sono dei range lasciati da operazioni precedenti (se applicabile) e ripulirli
5324
+ if (this.rangeSelected && !$event.ctrlKey && this.Selection) {
5325
+ this.logger.log("clearing previously selected range");
5326
+ this.selection_H.clearSelectionStatusExcluding(null);
5327
+ this.rangeSelected = false;
5328
+ return;
5329
+ }
5330
+ // Modalità Editable, gestisco i doppi click senza però rallentare la modalità di selezione a range
5331
+ if (this.Editable) {
5332
+ // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
5333
+ if (this.cellDbClickTimer) {
5334
+ this.logger.log("handling doubleclick on editable cell: " + (rowItem.PropertyName ? 'edit mode for property ' + rowItem.PropertyName : 'no property set, fallback to simple click'));
5335
+ if (rowItem.PropertyName)
5336
+ this.setupUserEdit(rowItem, item);
5337
+ else
5338
+ this.handleRowClick($event, item, this.Selection, true);
5339
+ this.clearCellClickTimer();
5340
+ return;
5341
+ }
5342
+ // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
5343
+ this.cellDbClickTimer = setTimeout(() => {
5344
+ this.clearCellClickTimer();
5345
+ if (!this.RangeSelection || !this.mouseIsDown) {
5346
+ this.logger.log("time's up for second click, handling single click");
5347
+ this.handleRowClick($event, item, this.Selection, true);
5348
+ }
5349
+ }, this.doubleClickBufferMs);
5350
+ }
5351
+ // In modalità a range la creazione del range è gestita dai mousedown, move ed up...
5352
+ // La selezione delle righe invece è gestita dalle caselline a sinistra
5353
+ if (this.RangeSelection)
5354
+ return;
5355
+ // Se ho fatto click col control attaccato esco subito dato che deve solo permettere la navigazione dei link
5356
+ if ($event.ctrlKey)
5357
+ return;
4364
5358
  // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
4365
5359
  if (rowItem._editing)
4366
5360
  return;
4367
5361
  // Per evitare di rallentare a prescindere
4368
- if (!this.UserEdits) {
4369
- this.handleRowClick($event, item, this.Selection);
5362
+ if (!this.Editable) {
5363
+ this.handleRowClick($event, item, this.Selection, true);
5364
+ return;
5365
+ }
5366
+ }
5367
+ /** Evento che gestisce il comando "Copia" buttando i valori selezionati nella clipboard in base al loro tipo */
5368
+ handleCopy() {
5369
+ if (!this.RangeSelection)
4370
5370
  return;
5371
+ let sel = this.selection_H.getSelectionStatusSelection();
5372
+ if (sel.length > 0 && sel[0].length > 0) {
5373
+ var selectionText = this.selection_H.getClipbardTextFromSelection(sel);
5374
+ this.clipboardService.copyTextToClipboard(selectionText);
5375
+ this.msgExts.simpleInfo(this.lc.loc("Values copied in the clipboard"), "toastr", 1000);
4371
5376
  }
4372
- // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
4373
- if (this.cellDbClickTimer) {
4374
- if (this.UserEdits && rowItem.UserEdits)
4375
- this.setupUserEdit(rowItem);
4376
- this.clearCellClickTimer();
5377
+ }
5378
+ /** 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 */
5379
+ handlePaste() {
5380
+ if (!this.RangeSelection)
4377
5381
  return;
5382
+ let sel = this.selection_H.getSelectionStatusSelection();
5383
+ if (sel.length > 0 && sel[0].length > 0) {
5384
+ this.clipboardService.getClipboard("matrix", (values) => {
5385
+ // Fix clipboard service che pare un po' stronza, rimuovo l'ultimo array se mi accorgo che è un singolo array con un solo elemento vuoto
5386
+ if (values.length > 0 && values[values.length - 1].length == 1 && values[values.length - 1][0] == '')
5387
+ values.splice(values.length - 1, 1);
5388
+ if (values.length > 0 && values[0].length > 0) {
5389
+ // Check se la modifica è abilitata
5390
+ if (!this.Editable) {
5391
+ this.msgExts.simpleWarning(this.lc.loc("Data for this table cannot be edited"));
5392
+ return;
5393
+ }
5394
+ // Controllo che quello che sto copiando sia della stessa dimensione della selezione sull'es-table, tranne nel caso ho un singolo valore da copiare
5395
+ if ((sel.length != values.length || sel[0].length != values[0].length) && (values.length != 1 || values[0].length != 1)) {
5396
+ this.msgExts.simpleWarning(this.lc.loc("Size of copied data is different from the size of the selection"));
5397
+ return;
5398
+ }
5399
+ // Se le dimensioni coincidono copio da una parte all'altra
5400
+ let changes = [];
5401
+ for (let r = 0; r < sel.length; r++) {
5402
+ var row = sel[r];
5403
+ for (let c = 0; c < row.length; c++) {
5404
+ let cell = row[c];
5405
+ // Se ho un singolo valore lo applico a tutta la selezione
5406
+ let value = values.length == 1 && values[0].length == 1 ? values[0][0] : values[r][c];
5407
+ let old = cell.value;
5408
+ let niu = cell.val_setter(value);
5409
+ let olddate = this.dateExts.getDateConvertion(old);
5410
+ let niudate = this.dateExts.getDateConvertion(niu);
5411
+ if ((olddate && niudate && olddate.isSame && olddate.isSame(niudate)) || old === niu)
5412
+ continue;
5413
+ changes.push(new EsTableModelChange(cell.item, cell.header, cell.property, old, niu));
5414
+ }
5415
+ }
5416
+ this.cdr.markForCheck();
5417
+ if (changes.length > 0)
5418
+ this.onModelChange.emit(changes);
5419
+ }
5420
+ });
4378
5421
  }
4379
- // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
4380
- this.cellDbClickTimer = setTimeout(() => {
4381
- this.clearCellClickTimer();
4382
- this.handleRowClick($event, item, this.Selection);
4383
- }, this.doubleClickBufferMs);
4384
5422
  }
4385
- /**
4386
- * Ripulisce il timer utilizzato per capire se è stato effettuato un doppio click o meno
4387
- */
5423
+ /** Ripulisce il timer utilizzato per capire se è stato effettuato un doppio click o meno */
4388
5424
  clearCellClickTimer() {
4389
5425
  clearTimeout(this.cellDbClickTimer);
4390
5426
  this.cellDbClickTimer = null;
@@ -4395,9 +5431,15 @@ class EsTableComponent {
4395
5431
  * @param {any} $event Evento nativo javascript
4396
5432
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4397
5433
  * @param {boolean} selection Indica se la selezione è attiva
4398
- *
5434
+ * @param {boolean} internalCall Indica se la chiamata a questa funzione è interna: permette di skippare i check sulle CustomCells
4399
5435
  */
4400
- handleRowClick($event, item, selection) {
5436
+ handleRowClick($event, item, selection, internalCall = false) {
5437
+ // Se ho un ctrl premuto esco con true in modo da fare bubbling dell'evento e lasciarlo gestire al browser (link ecc...)
5438
+ // Stessa cosa se ho custom cell dato che la gestione dei click viene affidata ai singoli TD
5439
+ if ($event.ctrlKey || (this.UseCustomCells && !internalCall))
5440
+ return true;
5441
+ if (selection)
5442
+ this.selection_H.clearSelectionStatusExcluding(null);
4401
5443
  if (selection && !item.locked && !item._sep && !item._group)
4402
5444
  this.handleClick($event, item);
4403
5445
  else if (item._group)
@@ -4405,34 +5447,129 @@ class EsTableComponent {
4405
5447
  // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
4406
5448
  this.cdr.markForCheck();
4407
5449
  }
5450
+ /**
5451
+ * Gestione del click destro sull'es-table
5452
+ */
5453
+ onRightClick() {
5454
+ if (this.Selection)
5455
+ this.onOpenContextMenu.emit();
5456
+ }
4408
5457
  /**
4409
5458
  * La modifica dell'utente è iniziata. Si imposta la variabile relativa a "true" in modo da mostrare l'input di testo
4410
5459
  *
4411
5460
  * Dopo che l'input è apparso, dopo un ciclo di Change Detection viene attivato il Subject collegato all'input che servirà a effettuare il focus
4412
5461
  *
4413
5462
  * @param {TdElement} rowItem Elemento di riga su cui è stata attivata la modifica
5463
+ * @param {any} item Oggetto sopra il quale è stata attivata la modifica
4414
5464
  */
4415
- setupUserEdit(rowItem) {
4416
- if (this.UserEdits && rowItem.UserEdits)
5465
+ setupUserEdit(rowItem, item) {
5466
+ var _a;
5467
+ this.selection_H.clearSelectionStatusExcluding(null);
5468
+ if (this.Editable && rowItem.PropertyName) {
5469
+ let dynMode = ((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0;
4417
5470
  rowItem._editing = true;
5471
+ rowItem.old_value = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
5472
+ }
4418
5473
  this.cdr.detectChanges();
4419
5474
  setTimeout(() => { this.FocusSubject.next(); });
4420
5475
  }
4421
5476
  /**
4422
- * La modifica dell'utente è terminata. Si reimposta la variabile relativa a "false" in modo da nascondere l'input di testo
5477
+ * 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
4423
5478
  *
4424
5479
  * @param {TdElement} rowItem Elemento di riga su cui è stata attivata la modifica
4425
5480
  * @param {any} item Oggetto sopra il quale è stata attivata la modifica
5481
+ * @param {number} columnIndex Indice della colonna su cui è avvenuta la modifica
4426
5482
  */
4427
- finalizeUserEdit(rowItem, item) {
4428
- rowItem._editing = false;
5483
+ finalizeUserEdit(rowItem, item, columnIndex) {
5484
+ var _a;
5485
+ let dynMode = ((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0;
5486
+ let rowItm = rowItem;
5487
+ rowItm._editing = false;
5488
+ let old = rowItm.old_value;
5489
+ let niu = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
5490
+ let olddate = this.dateExts.getDateConvertion(old);
5491
+ let niudate = this.dateExts.getDateConvertion(niu);
5492
+ if ((olddate && niudate && olddate.isSame && olddate.isSame(niudate)) || old === niu)
5493
+ return;
5494
+ this.onModelChange.emit([new EsTableModelChange(item, rowItem.ID, rowItem.PropertyName, old, niu)]);
5495
+ this.selectionStatus[item._ordinal][columnIndex].val_setter(niu);
5496
+ }
5497
+ mousedown(event, rowItem, _) {
5498
+ // Tasto diverso dal click sinistro -> ciao è stato bello e intenso
5499
+ if (event.buttons != 1 || !this.RangeSelection)
5500
+ return;
5501
+ // Sto lavorando su QUESTA es-table
5502
+ this.copyPasteDetector.ActiveEstReference = this;
5503
+ // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
5504
+ if (rowItem._editing)
5505
+ return;
5506
+ this.mouseIsDown = true;
5507
+ let coords = event.currentTarget.id.split('_');
5508
+ let row = parseInt(coords[coords.length - 2]);
5509
+ let column = parseInt(coords[coords.length - 1]);
5510
+ this.firstCoordinates = { row, column };
5511
+ // 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)
5512
+ // e gestire la grafica in maniera un po' più precisa
5513
+ if (!this.rangeSelected || (event.ctrlKey || !this.Selection))
5514
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
5515
+ else
5516
+ this.rangeStartWasIgnored = true;
5517
+ this.logger.log(`mouse down on ${row}:${column}`);
5518
+ }
5519
+ mouseenter(event) {
5520
+ if (!this.RangeSelection)
5521
+ return;
5522
+ if (event.buttons == 0)
5523
+ this.mouseIsDown = false;
5524
+ if (this.mouseIsDown && this.firstCoordinates) {
5525
+ let id = event.currentTarget.id;
5526
+ let coords = id.split('_');
5527
+ let row = parseInt(coords[coords.length - 2]);
5528
+ let column = parseInt(coords[coords.length - 1]);
5529
+ // Se ho ignorato l'inizio della selezione nel mousedown lo recupero qui
5530
+ if (this.rangeStartWasIgnored) {
5531
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, this.firstCoordinates.row, this.firstCoordinates.column);
5532
+ this.rangeStartWasIgnored = false;
5533
+ }
5534
+ this.selection_H.singleCellSelection({ view: event.view, range: true }, row, column, this.firstCoordinates);
5535
+ this.logger.log(`mouse move over ${row}:${column}`);
5536
+ this.rangeSelected = true;
5537
+ }
5538
+ }
5539
+ mouseup(event) {
5540
+ if (!this.RangeSelection)
5541
+ return;
5542
+ let id = event.currentTarget.id;
5543
+ let coords = id.split('_');
5544
+ let row = parseInt(coords[coords.length - 2]);
5545
+ let column = parseInt(coords[coords.length - 1]);
5546
+ // Se il mouseup viene effettuato sulla stessa cella del primo mousedown e siamo in modalità di selezione deseleziono la cella perché è un semplice click
5547
+ if (this.mouseIsDown && this.firstCoordinates) {
5548
+ if (this.firstCoordinates.row == row && this.firstCoordinates.column == column && !event.ctrlKey && !this.rangeStartWasIgnored && this.Selection)
5549
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
5550
+ else if (event.ctrlKey || !this.Selection)
5551
+ this.rangeSelected = true;
5552
+ }
5553
+ this.mouseIsDown = false;
5554
+ this.logger.log(`mouse lifted up`);
5555
+ }
5556
+ getCellReference(object, column) {
5557
+ let fkThisShitImOut = this.utiExts.deepClone(object);
5558
+ this.utilities_H.calculateHash([fkThisShitImOut]);
5559
+ let prop = column;
5560
+ let hash = fkThisShitImOut._hash;
5561
+ let toRet = this.EsTdsCache[`${prop}_${hash}`];
5562
+ return toRet;
5563
+ }
5564
+ registerCell(event) {
5565
+ this.EsTdsCache[`${event.id}_${event.hash}`] = event.self;
4429
5566
  }
4430
5567
  }
4431
- 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 });
4432
- EsTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.9", type: EsTableComponent, selector: "es-table", inputs: { CornerMenuOptions: "CornerMenuOptions", ColumnsResizable: "ColumnsResizable", ColumnsPinnable: "ColumnsPinnable", AutoUpdate: "AutoUpdate", UseCustomCells: "UseCustomCells", MaxHeight: "MaxHeight", ContainerClass: "ContainerClass", XLSXExport: "XLSXExport", CSVExport: "CSVExport", AllSearch: "AllSearch", HighCellDensity: "HighCellDensity", Selection: "Selection", ShowLoadingOnBootstrap: "ShowLoadingOnBootstrap", Removal: "Removal", RemovalCondition: "RemovalCondition", Export: "Export", ShiftClick: "ShiftClick", CountLabel: "CountLabel", HidePaging: "HidePaging", HidePagingCount: "HidePagingCount", HidePagingButtons: "HidePagingButtons", ContextMenu: "ContextMenu", ExportFileName: "ExportFileName", TableClass: "TableClass", ExportFunction: "ExportFunction", HasHeaderGroup: "HasHeaderGroup", HasSecondaryHeaderGroup: "HasSecondaryHeaderGroup", HeaderHidden: "HeaderHidden", BodyHidden: "BodyHidden", SelectionDisabled: "SelectionDisabled", SingleSelection: "SingleSelection", RowClassAssigner: "RowClassAssigner", OrderByColumn: "OrderByColumn", MultipleOrderingDirectives: "MultipleOrderingDirectives", HiddenColumns: "HiddenColumns", ColumnsOrdering: "ColumnsOrdering", SearchView: "SearchView", SelectAll: "SelectAll", UseArrayModePaging: "UseArrayModePaging", DynamicRowColumnsDefinition: "DynamicRowColumnsDefinition", DynamicOperations: "DynamicOperations", Hierarchy: "Hierarchy", ParentKey: "ParentKey", OwnKey: "OwnKey", StartsExpanded: "StartsExpanded", SavePreferences: "SavePreferences", PagingStyle: "PagingStyle", RowGroupingPagingStyle: "RowGroupingPagingStyle", ItemSourceProperty: "ItemSourceProperty", UseSelectionCache: "UseSelectionCache", ShowItemGroupsColumns: "ShowItemGroupsColumns", UserEdits: "UserEdits", ArraymodeItemsPerPage: "ArraymodeItemsPerPage" }, outputs: { onOrderChanged: "onOrderChanged", onSearchRequest: "onSearchRequest", onSelectionChanged: "onSelectionChanged", onRemoval: "onRemoval", onAbortRemoval: "onAbortRemoval", onCornerAction: "onCornerAction", onDynamicOperation: "onDynamicOperation" }, queries: [{ propertyName: "bodyRef", first: true, predicate: ["body"], descendants: true }, { propertyName: "headerRef", first: true, predicate: ["header"], descendants: true }, { propertyName: "headerGroupRef", first: true, predicate: ["headerGroup"], descendants: true }, { propertyName: "secondaryHeaderGroupRef", first: true, predicate: ["secondaryHeaderGroup"], descendants: true }, { propertyName: "EsTdsDirective", predicate: EsTdDirective }, { propertyName: "EsThsDirective", predicate: EsThDirective }], viewQueries: [{ propertyName: "inputField", first: true, predicate: ["input"], descendants: true }, { propertyName: "exportDownloader", first: true, predicate: ["exportDownloader"], descendants: true }, { propertyName: "tableEmptyMenu", first: true, predicate: ["emptyMenu"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs && RowTHs.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" [Fixed]=\"rowHeader.Fixed\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class || ''}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName.endsWith('.xlsx') ? ExportFileName.replace('.xlsx', '.csv') : ExportFileName.endsWith('.csv') ? ExportFileName : ExportFileName + '.csv'\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" >\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, true)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\"><div class=\"est-pinned-border est-cell-group-padding\"></div></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"dynamicMode_H.generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputChange)=\"finalizeUserEdit(rowItem, item)\" (inputFocus)=\"$event.stopPropagation();\" ></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\" >\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputFinalized)=\"finalizeUserEdit(rowItem, item)\"></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"], components: [{ type: EsTh, selector: "[es-th]", inputs: ["es-th", "Order", "Orderable", "Display", "Resizable", "Pinned", "SearchInProgress", "OrderBy", "Wrap", "Fixed", "Template", "Visible"], outputs: ["onOrderChange", "onUnpinning"] }, { type: TablePagerComponent, selector: "app-paging", inputs: ["CurrentPageSize", "View", "WarnOnAll", "AllSearch", "DefaultAll", "GroupMode", "GroupCount", "CountLabel", "ShowCount", "ShowPaging", "PagerCount", "Hidden"], outputs: ["pagingSelected"] }, { type: EsTd, selector: "[es-td]", inputs: ["es-td", "Internal", "RouterLink", "Display", "Template", "Context", "Visible"] }, { type: i9.FormAdaptiveComponent, selector: "form-adaptive", inputs: ["Type", "TypeMissingMessage", "Pattern", "AllowDownload", "Precision", "Alignment", "SearchFunction", "MinChars", "CaseSensitive"] }, { type: i10.ContextMenuComponent, selector: "context-menu", inputs: ["menuClass", "autoFocus", "useBootstrap4", "disabled"], outputs: ["close", "open"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i11.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i12.CsvDirective, selector: "[csvLink]", inputs: ["data", "headers", "delimiter", "filename", "uFEFF", "target"] }, { type: i13.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { type: i13.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { type: i13.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { type: i10.ContextMenuAttachDirective, selector: "[contextMenu]", inputs: ["contextMenuSubject", "contextMenu"] }, { type: i14.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i10.ContextMenuItemDirective, selector: "[contextMenuItem]", inputs: ["subMenu", "divider", "enabled", "passive", "visible"], outputs: ["execute"] }, { type: i15.ModalDirective, selector: "[bsModal]", inputs: ["config", "closeInterceptor"], outputs: ["onShow", "onShown", "onHide", "onHidden"], exportAs: ["bs-modal"] }, { type: i16.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i16.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i16.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }], pipes: { "localize": i2.LocalizePipe, "number": i11.DecimalPipe }, viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
4433
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableComponent, decorators: [{
5568
+ 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 });
5569
+ 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 });
5570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableComponent, decorators: [{
4434
5571
  type: Component,
4435
- args: [{ selector: 'es-table', viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}}&nbsp;<input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" />&nbsp;{{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span>&nbsp;{{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (View?.selection || arraymodeSelection)?.all\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span>&nbsp;\r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection)?.all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10 est\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"(SelectAll && !SingleSelection) || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && !(View?.selection || arraymodeSelection)?.all && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned;\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cell.Pinned && cell.Content; Else: cell.Template\">\r\n {{cell.Content}}\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"arrayMode || viewMode\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs || RowTHs.length == 0) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs && RowTHs.length > 0\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\" [style.width.px]=\"20\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" \r\n class=\"{{rowHeader.Class || ''}}\" \r\n [class.est-pinned-internal-header]=\"true\" \r\n [class.est-no-border]=\"true\" \r\n [class.est-nowrap]=\"!rowHeader.Wrap\" \r\n [Pinned]=\"true\" [Fixed]=\"rowHeader.Fixed\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null } \"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class || ''}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template; context: { $implicit: rowHeader.Multi ? rowHeader.MultiContent : null }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName.endsWith('.xlsx') ? ExportFileName.replace('.xlsx', '.csv') : ExportFileName.endsWith('.csv') ? ExportFileName : ExportFileName + '.csv'\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" >\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"View?.pagingavailable || viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, true)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"!UseCustomCells && handleRowClick($event, item, false)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\"><div class=\"est-pinned-border est-cell-group-padding\"></div></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || EmptyRowTds) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"dynamicMode_H.generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && !EmptyRowTds\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\" [style.width.px]=\"20\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\" [style.width.px]=\"20\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: rowItem.Multi ? (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) : item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputChange)=\"finalizeUserEdit(rowItem, item)\" (inputFocus)=\"$event.stopPropagation();\" ></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-no-selection]=\"!!rowItem.UserEdits\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\" (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\" >\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"!rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"rowItem.Multi && rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: (item[rowItem.MultiProp] ? item[rowItem.MultiProp][rowItem.MultiIndex] : {}) }\"></ng-container></span>\r\n <ng-container *ngIf=\"!rowItem.Template && !rowItem.Multi\">\r\n <span *ngIf=\"rowItem.Content && !rowItem.PropAccessor\">{{rowItem.Content}}</span>\r\n <span *ngIf=\"!rowItem.Content && rowItem.PropAccessor\">{{item.values? item.values[rowItem.PropAccessor] : item[rowItem.PropAccessor]}}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <form-adaptive [FormLayout]=\"false\" [Validation]=\"false\" [FocusSubject]=\"FocusSubject\" [(ngModel)]=\"item[rowItem.UserEdits.Property]\" name=\"{{ rowItem.UserEdits.Property + '_' + item._hash }}\" [Type]=\"rowItem.UserEdits.Type\" [Source]=\"rowItem.UserEdits.Source\" (inputFinalized)=\"finalizeUserEdit(rowItem, item)\"></form-adaptive>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n &nbsp;\r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\" cdkDrag>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header est-pointer\" cdkDragHandle>\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <!-- <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th> -->\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th *ngIf=\"DirectivesBased\" class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody \r\n cdkDropList \r\n [cdkDropListData]=\"TMPColumnsList\" \r\n (cdkDropListDropped)=\"columnMetadata_H.columnReordered($event)\" \r\n [cdkDropListSortPredicate]=\"columnMetadata_H.sortPredicate.bind(this.columnMetadata_H)\"\r\n class=\"est-dropbox\">\r\n\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" \r\n class=\"est-pointer est-droplist\" \r\n [class.est-white-selected]=\"lastSelectedItemID == item.id\" \r\n [class.est-no-selection]=\"!item.visible\"\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!ColumnsOrdering || item.fixed || item.pinned\">\r\n\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap drag-visible\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <!-- Padri -->\r\n <span *ngIf=\"item.parentTemplates && item.parentTemplates.length > 0\" class=\"est-fw-bold est-fs-13\">\r\n (&nbsp;\r\n <ng-container *ngFor=\"let parent of item.parentTemplates; let last=last\">\r\n <ng-container *ngIf=\"parent.tmpl\"><ng-container *ngTemplateOutlet=\"parent.tmpl\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"parent.content\">{{parent.content}}</ng-container>\r\n <span *ngIf=\"!last\">&nbsp;-&nbsp;</span>\r\n </ng-container>\r\n &nbsp;)\r\n </span>\r\n <!-- Template header originale -->\r\n <ng-container *ngTemplateOutlet=\"item.template; context: { $implicit: item.multi ? item.multiContent : null }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td *ngIf=\"DirectivesBased && ColumnsPinnable\"><span *ngIf=\"!item.fixed && item.pinnable\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-head-resizer{top:0;right:0;bottom:0;width:7px;position:absolute;cursor:col-resize}.est-head-resizer-internal{top:0;right:0px;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density th,.est-high-density td{padding:0;padding-left:.2rem;padding-right:.2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-edit-hidden{visibility:hidden;height:1px!important}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14,.est-fs-13{font-size:14px}.est-fw-bold{font-weight:700}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}.est-slider:before{position:absolute;content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff;transition:.4s}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translate(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-prev,.est-page-next{color:#000;padding:2px 0 0;font-size:inherit}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0px solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:#7777!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:#bbbb!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}.est-droplist.cdk-drag-placeholder{opacity:0}.est-droplist.cdk-drag-preview{z-index:999999999!important;opacity:1;box-sizing:border-box;border-radius:4px;background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.est-droplist.cdk-drag-preview td:not(.drag-visible){visibility:hidden}.est-droplist.cdk-drag-preview td.drag-visible{padding-top:3px}.est-droplist.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.est-droplist.cdk-drop-list-dragging .est-dropbox:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.est-pre{white-space:pre}.est val-datetime .mat-form-field-appearance-outline .mat-form-field-infix input{margin-bottom:3px!important;min-width:130px!important}.est .mat-form-field-flex{height:29px!important;padding:0!important}.est .mat-form-field-flex .mat-form-field-outline{color:#00f}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-start{border-left:none;border-top:none;border-radius:0}.est .mat-form-field-flex .mat-form-field-outline .mat-form-field-outline-end{border-top:none;border-radius:0;border-right:none}.est .mat-form-field-wrapper{height:20px;min-height:20px!important;margin-top:0!important}.est .mat-form-field-infix{width:100%!important;min-width:50px!important}.est .mat-form-field-infix select.mat-input-element{margin-top:-5px!important}.est .mat-datepicker-input{margin-bottom:3px!important}.est input{height:20px;padding-top:0!important}\n"] }]
5572
+ 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"] }]
4436
5573
  }], ctorParameters: function () {
4437
5574
  return [{ type: i1.NgControl, decorators: [{
4438
5575
  type: Self
@@ -4450,13 +5587,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4450
5587
  }, {
4451
5588
  type: Inject,
4452
5589
  args: [EST_LOCALE]
4453
- }] }, { type: i2.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: UtilitiesHandler }, { type: i5.UtilityService }, { type: i5.ExportService }, { type: i5.DateService }, { type: i5.MessageService }];
4454
- }, propDecorators: { EsTdsDirective: [{
5590
+ }] }, { 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 }];
5591
+ }, propDecorators: { EsTdEditorDirectives: [{
5592
+ type: ContentChildren,
5593
+ args: [EsTdEditorDirective]
5594
+ }], EsTdsDirective: [{
4455
5595
  type: ContentChildren,
4456
5596
  args: [EsTdDirective]
4457
5597
  }], EsThsDirective: [{
4458
5598
  type: ContentChildren,
4459
5599
  args: [EsThDirective]
5600
+ }], EsTableTemplate: [{
5601
+ type: Input
4460
5602
  }], bodyRef: [{
4461
5603
  type: ContentChild,
4462
5604
  args: ['body', { static: false }]
@@ -4480,7 +5622,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4480
5622
  type: Input
4481
5623
  }], AutoUpdate: [{
4482
5624
  type: Input
4483
- }], UseCustomCells: [{
5625
+ }], Height: [{
5626
+ type: Input
5627
+ }], EmptySpaceBackgroundColor: [{
5628
+ type: Input
5629
+ }], EsTableHandledSearch: [{
4484
5630
  type: Input
4485
5631
  }], MaxHeight: [{
4486
5632
  type: Input
@@ -4522,6 +5668,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4522
5668
  type: Input
4523
5669
  }], ExportFunction: [{
4524
5670
  type: Input
5671
+ }], ExportOnlyVisibleColumns: [{
5672
+ type: Input
4525
5673
  }], HasHeaderGroup: [{
4526
5674
  type: Input
4527
5675
  }], HasSecondaryHeaderGroup: [{
@@ -4564,6 +5712,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4564
5712
  type: Input
4565
5713
  }], SavePreferences: [{
4566
5714
  type: Input
5715
+ }], DefaultAlignment: [{
5716
+ type: Input
4567
5717
  }], PagingStyle: [{
4568
5718
  type: Input
4569
5719
  }], RowGroupingPagingStyle: [{
@@ -4574,7 +5724,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4574
5724
  type: Input
4575
5725
  }], ShowItemGroupsColumns: [{
4576
5726
  type: Input
4577
- }], UserEdits: [{
5727
+ }], Editable: [{
5728
+ type: Input
5729
+ }], RangeSelection: [{
5730
+ type: Input
5731
+ }], SearchThrottle: [{
4578
5732
  type: Input
4579
5733
  }], onOrderChanged: [{
4580
5734
  type: Output
@@ -4586,6 +5740,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4586
5740
  type: Output
4587
5741
  }], onAbortRemoval: [{
4588
5742
  type: Output
5743
+ }], onModelChange: [{
5744
+ type: Output
5745
+ }], onOpenContextMenu: [{
5746
+ type: Output
4589
5747
  }], onCornerAction: [{
4590
5748
  type: Output
4591
5749
  }], onDynamicOperation: [{
@@ -4598,12 +5756,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImpor
4598
5756
  args: ['emptyMenu', { static: true }]
4599
5757
  }], ArraymodeItemsPerPage: [{
4600
5758
  type: Input
5759
+ }] } });
5760
+ class EsTdReference {
5761
+ }
5762
+
5763
+ //Angular
5764
+ /** Componente rappresentante un template di th coi loro relativi td da poter riutilizzare quandomminchia si vuole */
5765
+ class EsTableTemplate {
5766
+ }
5767
+ EsTableTemplate.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
5768
+ 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 });
5769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableTemplate, decorators: [{
5770
+ type: Component,
5771
+ args: [{ selector: "es-table-template", changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
5772
+ }], propDecorators: { EsTdsDirective: [{
5773
+ type: ContentChildren,
5774
+ args: [EsTdDirective]
5775
+ }], EsThsDirective: [{
5776
+ type: ContentChildren,
5777
+ args: [EsThDirective]
4601
5778
  }] } });
4602
5779
 
4603
5780
  /** Modello di configurazione per L'EsTable */
4604
5781
  class EsTableModuleConfig {
4605
5782
  }
4606
5783
 
5784
+ const MODULES = [
5785
+ CommonModule,
5786
+ FormsModule,
5787
+ RouterModule,
5788
+ LocalizationModule,
5789
+ ModalModule,
5790
+ BsDropdownModule,
5791
+ ContextMenuModule,
5792
+ MatSelectModule,
5793
+ MatInputModule,
5794
+ MatTooltipModule,
5795
+ DragDropModule,
5796
+ FormsAndValidationsModule
5797
+ ];
5798
+ const PUBLIC_ELEMENTS = [
5799
+ // Direttive
5800
+ EsTdDirective,
5801
+ EsThDirective,
5802
+ EsTdEditorDirective,
5803
+ // Componenti
5804
+ EsTableComponent,
5805
+ TablePagerComponent,
5806
+ EsTableTemplate
5807
+ ];
5808
+ const PRIVATE_ELEMENTS = [
5809
+ // Componenti
5810
+ EsTh,
5811
+ EsTd,
5812
+ // Pipes
5813
+ EstFormatPipe,
5814
+ EstLookupPipe,
5815
+ EstRouterLinkPipe,
5816
+ EstRendererPipe,
5817
+ EstEditorPipe
5818
+ ];
4607
5819
  class EsTableModule {
4608
5820
  static forRoot(config) {
4609
5821
  return {
@@ -4616,53 +5828,54 @@ class EsTableModule {
4616
5828
  };
4617
5829
  }
4618
5830
  }
4619
- EsTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4620
- 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,
5831
+ EsTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5832
+ EsTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, declarations: [
5833
+ // Direttive
5834
+ EsTdDirective,
5835
+ EsThDirective,
5836
+ EsTdEditorDirective,
5837
+ // Componenti
5838
+ EsTableComponent,
5839
+ TablePagerComponent,
5840
+ EsTableTemplate,
5841
+ // Componenti
5842
+ EsTh,
5843
+ EsTd,
5844
+ // Pipes
5845
+ EstFormatPipe,
5846
+ EstLookupPipe,
5847
+ EstRouterLinkPipe,
5848
+ EstRendererPipe,
5849
+ EstEditorPipe
5850
+ ], imports: [CommonModule,
4621
5851
  FormsModule,
4622
5852
  RouterModule,
4623
5853
  LocalizationModule,
4624
5854
  ModalModule,
4625
5855
  BsDropdownModule,
4626
- CsvModule,
4627
5856
  ContextMenuModule,
4628
5857
  MatSelectModule,
4629
5858
  MatInputModule,
5859
+ MatTooltipModule,
4630
5860
  DragDropModule,
4631
- FormsAndValidationsModule], exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent] });
4632
- EsTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, providers: [UtilityService, ExportService, HashingService, MessageService], imports: [[
4633
- CommonModule,
4634
- FormsModule,
4635
- RouterModule,
4636
- LocalizationModule,
4637
- ModalModule,
4638
- BsDropdownModule,
4639
- CsvModule,
4640
- ContextMenuModule,
4641
- MatSelectModule,
4642
- MatInputModule,
4643
- DragDropModule,
4644
- FormsAndValidationsModule
4645
- ]] });
4646
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.9", ngImport: i0, type: EsTableModule, decorators: [{
5861
+ FormsAndValidationsModule], exports: [
5862
+ // Direttive
5863
+ EsTdDirective,
5864
+ EsThDirective,
5865
+ EsTdEditorDirective,
5866
+ // Componenti
5867
+ EsTableComponent,
5868
+ TablePagerComponent,
5869
+ EsTableTemplate
5870
+ ] });
5871
+ EsTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, providers: [UtilityService, ExportService, HashingService, MessageService], imports: [[MODULES]] });
5872
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: EsTableModule, decorators: [{
4647
5873
  type: NgModule,
4648
5874
  args: [{
4649
- imports: [
4650
- CommonModule,
4651
- FormsModule,
4652
- RouterModule,
4653
- LocalizationModule,
4654
- ModalModule,
4655
- BsDropdownModule,
4656
- CsvModule,
4657
- ContextMenuModule,
4658
- MatSelectModule,
4659
- MatInputModule,
4660
- DragDropModule,
4661
- FormsAndValidationsModule
4662
- ],
4663
- declarations: [EsTh, EsTd, EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent],
5875
+ imports: [MODULES],
5876
+ declarations: [...PUBLIC_ELEMENTS, ...PRIVATE_ELEMENTS],
4664
5877
  providers: [UtilityService, ExportService, HashingService, MessageService],
4665
- exports: [EsTableComponent, EsTdDirective, EsThDirective, TablePagerComponent]
5878
+ exports: [...PUBLIC_ELEMENTS]
4666
5879
  }]
4667
5880
  }] });
4668
5881
 
@@ -4740,9 +5953,13 @@ class ReportParam {
4740
5953
  class ReportRow {
4741
5954
  }
4742
5955
 
5956
+ /** Classe che rappresenta il riferimento ad una proprietà di un oggetto bindato sulla tabella */
5957
+ class ItemPropEditableReference {
5958
+ }
5959
+
4743
5960
  /**
4744
5961
  * Generated bundle index. Do not edit.
4745
5962
  */
4746
5963
 
4747
- export { AppOrdering, AppSearch, CornerMenuOption, EsTableColumnsDefinition, EsTableComponent, EsTableDefaultable, EsTableModule, EsTableModuleConfig, EsTableMultiValue, EsTableOperationDefinition, EsTdDirective, EsThDirective, GenericItem, Group, GroupAggregation, GroupFilter, GroupOrAggregation, ItemsSelection, ReportColumn, ReportParam, ReportRow, TablePagerComponent };
5964
+ 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 };
4748
5965
  //# sourceMappingURL=esfaenza-es-table.mjs.map