@esfaenza/es-table 11.2.121 → 11.2.123-beta1

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 (41) hide show
  1. package/bundles/esfaenza-es-table.umd.js +443 -235
  2. package/bundles/esfaenza-es-table.umd.js.map +1 -1
  3. package/bundles/esfaenza-es-table.umd.min.js +1 -1
  4. package/bundles/esfaenza-es-table.umd.min.js.map +1 -1
  5. package/esfaenza-es-table.d.ts +8 -4
  6. package/esfaenza-es-table.metadata.json +1 -1
  7. package/esm2015/esfaenza-es-table.js +9 -5
  8. package/esm2015/lib/components/es-table/es_table.component.js +126 -49
  9. package/esm2015/lib/components/es-td/es_td.component.js +10 -52
  10. package/esm2015/lib/components/es-th/es_th.component.js +2 -2
  11. package/esm2015/lib/components/pipes/est-renderer.pipe.js +36 -0
  12. package/esm2015/lib/components/pipes/est-routerlink.pipe.js +37 -0
  13. package/esm2015/lib/components/pipes/est_editor.pipe.js +36 -0
  14. package/esm2015/lib/core/CopyPasteDetector.js +4 -2
  15. package/esm2015/lib/core/Logger.js +23 -0
  16. package/esm2015/lib/core/handlers/ColumnMetadataHandler.js +14 -12
  17. package/esm2015/lib/core/handlers/DynamicModeHandler.js +59 -37
  18. package/esm2015/lib/core/handlers/ExportHandler.js +2 -2
  19. package/esm2015/lib/core/handlers/SelectionHandler.js +46 -50
  20. package/esm2015/lib/core/handlers/UtilitiesHandler.js +2 -5
  21. package/esm2015/lib/directives/es_th.directive.js +9 -2
  22. package/esm2015/lib/domain/externals/EsTableColumnsDefinition.js +7 -4
  23. package/esm2015/lib/domain/externals/ItemPropEditableReference.js +1 -1
  24. package/esm2015/lib/domain/internals/EsTableColumn.js +2 -2
  25. package/esm2015/lib/es-table.module.js +42 -19
  26. package/fesm2015/esfaenza-es-table.js +422 -223
  27. package/fesm2015/esfaenza-es-table.js.map +1 -1
  28. package/lib/components/es-table/es_table.component.d.ts +28 -8
  29. package/lib/components/es-td/es_td.component.d.ts +6 -34
  30. package/lib/components/pipes/est-renderer.pipe.d.ts +12 -0
  31. package/lib/components/pipes/est-routerlink.pipe.d.ts +17 -0
  32. package/lib/components/pipes/est_editor.pipe.d.ts +12 -0
  33. package/lib/core/Logger.d.ts +7 -0
  34. package/lib/core/handlers/DynamicModeHandler.d.ts +11 -23
  35. package/lib/core/handlers/SelectionHandler.d.ts +16 -3
  36. package/lib/core/handlers/UtilitiesHandler.d.ts +4 -1
  37. package/lib/directives/es_th.directive.d.ts +25 -0
  38. package/lib/domain/externals/EsTableColumnsDefinition.d.ts +5 -9
  39. package/lib/domain/externals/ItemPropEditableReference.d.ts +4 -0
  40. package/lib/domain/internals/EsTableColumn.d.ts +3 -1
  41. package/package.json +2 -2
@@ -12,7 +12,6 @@ import { MatSelectModule } from '@angular/material/select';
12
12
  import { MatInputModule } from '@angular/material/input';
13
13
  import { MatTooltipModule } from '@angular/material/tooltip';
14
14
  import { FormsAndValidationsModule } from '@esfaenza/forms-and-validations';
15
- import { DomSanitizer } from '@angular/platform-browser';
16
15
  import { ModalModule } from 'ngx-bootstrap/modal';
17
16
  import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
18
17
  import { ContextMenuModule } from '@esfaenza/ngx-contextmenu';
@@ -340,6 +339,8 @@ class EsThDirective {
340
339
  this.thType = null;
341
340
  /** Sorgente dei valori disponibili per questa cella se il **Type** è di tipo 'enum' */
342
341
  this.thSource = null;
342
+ /** Opzioni da applicare all'editor di questa colonna */
343
+ this.thEditorOptions = {};
343
344
  }
344
345
  }
345
346
  EsThDirective.decorators = [
@@ -373,7 +374,12 @@ EsThDirective.propDecorators = {
373
374
  thStaticContent: [{ type: Input }],
374
375
  thBackgroundColor: [{ type: Input }],
375
376
  thAlignment: [{ type: Input }],
376
- thFormat: [{ type: Input }]
377
+ thFormat: [{ type: Input }],
378
+ thEditorName: [{ type: Input }],
379
+ thEditorOptions: [{ type: Input }],
380
+ thRendererName: [{ type: Input }],
381
+ thRoutePath: [{ type: Input }],
382
+ thRouteParameterProperties: [{ type: Input }]
377
383
  };
378
384
 
379
385
  /** Direttiva che rappresenta il template dell'editor di una cella all'interno della tabella */
@@ -565,7 +571,7 @@ class ExportHandler {
565
571
  setupExport(items) {
566
572
  let drcd = this.est.DynamicRowColumnsDefinition;
567
573
  this.est.headers = drcd && drcd.length > 0 ?
568
- this.expExts.setupForGenericExport(items, drcd.map(t => { return { label: t.Description, key: t.PropertyName, order: t.ColumnOrder, type: 'string' }; })) :
574
+ this.expExts.setupForGenericExport(items, drcd.map(t => { return { label: t.Description, key: t.PropertyName, propKey: t.PropertyName, order: t.ColumnOrder, type: 'string' }; })) :
569
575
  this.expExts.setupForExport(items, this.est.ExportOnlyVisibleColumns ? this.est.ColumnsList.filter(t => t.visible).map(t => t.id) : null);
570
576
  this.est.data = items;
571
577
  }
@@ -600,7 +606,7 @@ class EsTableColumn {
600
606
  * @param {boolean} pinned Indica se è una colonna pinnata
601
607
  * @param {number} pinnedWidth Indica la dimensione da assegnare a questa colonna quando è pinnata
602
608
  * @param {TemplateRef<any>} template Indica il template da usare per mostrare il testo dell'Header
603
- * @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**)
609
+ * @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**)
604
610
  * @param {boolean} multi Indica che la colonna deriva da una direttiva **Multi**
605
611
  * @param {string} multiContent Indica il contenuto della direttiva **Multi** per questa colonna
606
612
  */
@@ -1073,7 +1079,7 @@ class ColumnMetadataHandler {
1073
1079
  return;
1074
1080
  /****** STEP 1: Creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate ******/
1075
1081
  let expandedGroups = [];
1076
- let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
1082
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
1077
1083
  for (let l = 0; l < infos.groupingLevel; l++) {
1078
1084
  expandedGroups.push([]);
1079
1085
  for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
@@ -1083,7 +1089,7 @@ class ColumnMetadataHandler {
1083
1089
  let orderedLeafs = [];
1084
1090
  for (let i = 0; i < this.est.OrderDirectives.length; i++) {
1085
1091
  let leaf = infos.thsCache[this.est.OrderDirectives[i]];
1086
- if (leaf.thVisible && !leaf.thPinned)
1092
+ if (leaf.thVisible && leaf.thIf && !leaf.thPinned)
1087
1093
  orderedLeafs.push(leaf);
1088
1094
  }
1089
1095
  /****** STEP 3: Creo l'array group con tutti i riferimenti del caso ******/
@@ -1107,7 +1113,7 @@ class ColumnMetadataHandler {
1107
1113
  }
1108
1114
  }
1109
1115
  }
1110
- /****** STEP 4: Compatto nell'elemento finale su cui bindarmi ******/
1116
+ /****** STEP 4: Compatto nell'elemento finale su cui bindarmi. L'ID assegnato è SOLO per ottimizzare gli ngFor ******/
1111
1117
  currentParent = "";
1112
1118
  let currentSpan = 0;
1113
1119
  let finalHeaders = [];
@@ -1115,25 +1121,25 @@ class ColumnMetadataHandler {
1115
1121
  let levelArray = [];
1116
1122
  finalHeaders.push(levelArray);
1117
1123
  if (this.est.Selection || this.est.HasPinnedColumns)
1118
- levelArray.push({ Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1124
+ levelArray.push({ ID: "_base_sel_pinned", Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
1119
1125
  for (let h = 0; h < expandedGroups[l].length; h++) {
1120
1126
  let item = expandedGroups[l][h];
1121
1127
  if (item == currentParent)
1122
1128
  currentSpan++;
1123
1129
  else {
1124
1130
  if (currentSpan > 0)
1125
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1131
+ 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 });
1126
1132
  currentSpan = 1;
1127
1133
  currentParent = item;
1128
1134
  }
1129
1135
  }
1130
1136
  // Ultima aggiunta che altrimenti mi rimarrebbe in cache
1131
- levelArray.push({ Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
1137
+ 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 });
1132
1138
  // Aggiungo i pezzettini per la rimozione e gli export, se presenti
1133
1139
  if (this.est.Removal)
1134
- levelArray.push({ Span: 1, Template: null });
1140
+ levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
1135
1141
  if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
1136
- levelArray.push({ Span: 1, Template: null });
1142
+ levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
1137
1143
  currentSpan = 0;
1138
1144
  currentParent = "";
1139
1145
  }
@@ -1169,9 +1175,9 @@ class ColumnMetadataHandler {
1169
1175
  if (parent) {
1170
1176
  th = thsCache[parent];
1171
1177
  if (!th.thEmpty && !th._multi_content)
1172
- parentsPrepend.unshift({ tmpl: th.Template });
1178
+ parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
1173
1179
  else if (!th.thEmpty && th._multi_content)
1174
- parentsPrepend.unshift({ content: th._multi_content });
1180
+ parentsPrepend.unshift({ id: th.th, content: th._multi_content });
1175
1181
  jumps++;
1176
1182
  }
1177
1183
  } while (parent);
@@ -1232,7 +1238,9 @@ class ColumnMetadataHandler {
1232
1238
  let newContext = [];
1233
1239
  this.est.OrderDirectives.forEach(o => {
1234
1240
  let contextItem = context.filter(t => t.ID == o)[0];
1235
- newContext.push(contextItem);
1241
+ // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
1242
+ if (contextItem)
1243
+ newContext.push(contextItem);
1236
1244
  });
1237
1245
  this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
1238
1246
  }
@@ -1448,7 +1456,7 @@ class EsTableColumnsDefinition {
1448
1456
  * @param {string} EditorName Nome dell'editor da utilizzare per la modifica di questo campo
1449
1457
  * @param {string} RendererName Nome del renderer da utilizzare per visualizzare questo campo
1450
1458
  */
1451
- 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 = {}) {
1459
+ 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 = "") {
1452
1460
  this.Description = Description;
1453
1461
  this.PropertyName = PropertyName;
1454
1462
  this.RoutePath = RoutePath;
@@ -1464,10 +1472,13 @@ class EsTableColumnsDefinition {
1464
1472
  this.EditorName = EditorName;
1465
1473
  this.RendererName = RendererName;
1466
1474
  this.EditorOptions = EditorOptions;
1467
- this.edits = {};
1475
+ this.Pinned = Pinned;
1476
+ this.PinnedWidth = PinnedWidth;
1477
+ this.Pinnable = Pinnable;
1478
+ this.Grouping = Grouping;
1468
1479
  }
1469
1480
  static build(parsObj) {
1470
- 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);
1481
+ 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);
1471
1482
  }
1472
1483
  }
1473
1484
 
@@ -1477,42 +1488,6 @@ class DynamicModeHandler {
1477
1488
  constructor(est) {
1478
1489
  this.est = est;
1479
1490
  }
1480
- /**
1481
- * Metodo di supporto alla creazione di un router link parametrizzato all'oggetto corrente utilizzato nella modalità dinamica
1482
- *
1483
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1484
- * @param {string[]} parameterProps Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1485
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1486
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1487
- *
1488
- * @returns {any} Router link generato in base al parametri
1489
- */
1490
- generateRouterLink(path, parameterProps, item) {
1491
- if (this.est.DynamicTableRouterLinkCache[item._hash + path]) {
1492
- return this.est.DynamicTableRouterLinkCache[item._hash + path];
1493
- }
1494
- else {
1495
- let link = this.getRouterLink(path, parameterProps, item);
1496
- this.est.DynamicTableRouterLinkCache[item._hash + path] = link;
1497
- return link;
1498
- }
1499
- }
1500
- /**
1501
- * Crea un router link
1502
- *
1503
- * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
1504
- * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
1505
- * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
1506
- * @param {GenericItem} item Oggetto generico collegato a questo contesto
1507
- *
1508
- * @returns {any} Router link generato in base al parametri
1509
- */
1510
- getRouterLink(path, pars, item) {
1511
- for (let i = 0; i < pars.length; i++)
1512
- path = path.replace('{' + i + '}', item.properties[pars[i]]);
1513
- path = path.replace(/'/g, '"').replace(/ /g, '');
1514
- return JSON.parse(path);
1515
- }
1516
1491
  /** Se non ho l'Input **DynamicRowColumnsDefinition** in modalità dinamica lo riempio con il default nome della colonna = testo della colonna */
1517
1492
  eventuallyReviewDynamicColumns() {
1518
1493
  // Senza oggetti esco
@@ -1531,6 +1506,61 @@ class DynamicModeHandler {
1531
1506
  else
1532
1507
  this.est.UserDefinedDynamicCols = true;
1533
1508
  }
1509
+ /** Genera partendo dalle **DynamicRowColumnsDefinition** la lista di **EsThDirective** e **EsTdDirective** che servono per la tabella */
1510
+ emitThsAndTdsBasedOnDynamicDefinition() {
1511
+ // Senza dynamic columns esco
1512
+ if (!this.est.DynamicRowColumnsDefinition || this.est.DynamicRowColumnsDefinition.length == 0)
1513
+ return null;
1514
+ let ths = [];
1515
+ let tds = [];
1516
+ for (let i = 0; i < this.est.DynamicRowColumnsDefinition.length; i++) {
1517
+ let col = this.est.DynamicRowColumnsDefinition[i];
1518
+ ths.push(this.getTh(col));
1519
+ tds.push(this.getTd(col));
1520
+ }
1521
+ return { ths, tds };
1522
+ }
1523
+ /** @ignore Helper */
1524
+ getTh(col) {
1525
+ var ret = new EsThDirective(null);
1526
+ ret.th = col.PropertyName;
1527
+ ret.thPinned = col.Pinned;
1528
+ ret.thPinnable = col.Pinnable;
1529
+ ret.thPinnedWidth = col.PinnedWidth;
1530
+ ret.thVisible = col.Visible;
1531
+ ret.thOrder = col.DataOrder;
1532
+ ret.thOrderable = col.Orderable;
1533
+ ret.thWrap = col.HeaderWraps;
1534
+ ret.thClass = col.Clss;
1535
+ ret.thProperty = col.PropertyName;
1536
+ ret.thType = col.PropertyType;
1537
+ ret.thSource = col.PropertySource;
1538
+ ret.thEditorName = col.EditorName;
1539
+ ret.thEditorOptions = col.EditorOptions;
1540
+ ret.thRendererName = col.RendererName;
1541
+ ret.thRoutePath = col.RoutePath;
1542
+ ret.thRouteParameterProperties = col.RouteParameterProperties;
1543
+ //ret.thFixed = col.Fixed;
1544
+ //ret.thResizable = col.Resizable;
1545
+ //ret.thGroupClass = col.GroupClass;
1546
+ //ret.thGroup = col.Group;
1547
+ //ret.thAggregation = col.Aggregation;
1548
+ //ret.thMulti = col.Multi;
1549
+ //ret.thStaticContent = col.StaticContent;
1550
+ //ret.thBackgroundColor = col.BackgroundColor;
1551
+ //ret.thAlignment = col.Alignment;
1552
+ //ret.thFormat = col.Format;
1553
+ return ret;
1554
+ }
1555
+ /** @ignore Helper */
1556
+ getTd(col) {
1557
+ var ret = new EsTdDirective(null);
1558
+ ret.td = col.PropertyName;
1559
+ ret.tdClass = col.Clss;
1560
+ //ret.tdAlignment = col.Alignment;
1561
+ //ret.tdFormat = col.Format;
1562
+ return ret;
1563
+ }
1534
1564
  }
1535
1565
 
1536
1566
  /** Classe contenente la gestione della modalità gerarchica */
@@ -3077,65 +3107,61 @@ class SelectionHandler {
3077
3107
  * @param {{ row: number, column: number }} firstSelectionOverride Permette di overridare il primo elemento selezionato
3078
3108
  */
3079
3109
  singleCellSelection(event, row, column, firstSelectionOverride) {
3110
+ // Recupero la selezione precedente se presente come punto di partenza
3080
3111
  var first = firstSelectionOverride || this.lastSingleSelection;
3112
+ //Il punto di arrivo, che diventerà il prossimo punto di partenza, è la selezione corrente
3113
+ this.lastSingleSelection = { row, column };
3081
3114
  this.clearTextSelection(event);
3082
- // Nella selezione a range chissene frega se c'è o meno lo shift, si ragiona sempre a range
3083
- if (event.shiftKey && first) {
3084
- this.clearSelectionStatus({ row, column });
3085
- let rowAddition = row < first.row ? -1 : +1;
3086
- let columnAddition = column < first.column ? -1 : +1;
3087
- for (let ir = first.row; ir != row + rowAddition; ir += rowAddition) {
3088
- let firstRow = ir == first.row;
3089
- let lastRow = ir == row;
3090
- for (let ic = first.column; ic != column + columnAddition; ic += columnAddition) {
3091
- let firstCol = ic == first.column;
3092
- let lastCol = ic == column;
3093
- this.est.selectionStatus[ir][ic].selected = true;
3094
- this.est.selectionStatus[ir][ic].lborder = columnAddition > 0 ? firstCol : lastCol;
3095
- if (ic > 0)
3096
- this.est.selectionStatus[ir][ic - 1].roverlaps = this.est.selectionStatus[ir][ic].lborder;
3097
- this.est.selectionStatus[ir][ic].tborder = rowAddition > 0 ? firstRow : lastRow;
3098
- this.est.selectionStatus[ir][ic].rborder = columnAddition > 0 ? lastCol : firstCol;
3099
- if (this.est.selectionStatus[ir][ic + 1])
3100
- this.est.selectionStatus[ir][ic + 1].loverlaps = this.est.selectionStatus[ir][ic].rborder;
3101
- this.est.selectionStatus[ir][ic].bborder = rowAddition > 0 ? lastRow : firstRow;
3102
- }
3103
- }
3104
- this.lastSingleSelection = { row, column };
3105
- }
3106
- else {
3107
- // Ripulisco escludendo l'oggetto attuale che eventualmente ci penso io a deseezionare
3108
- this.clearSelectionStatus({ row, column });
3109
- let item = this.est.selectionStatus[row][column];
3110
- item.selected = !item.selected;
3111
- item.lborder = item.selected;
3112
- if (column > 0)
3113
- this.est.selectionStatus[row][column - 1].roverlaps = item.lborder;
3114
- item.tborder = item.selected;
3115
- item.rborder = item.selected;
3116
- if (this.est.selectionStatus[row][column + 1])
3117
- this.est.selectionStatus[row][column + 1].loverlaps = item.rborder;
3118
- item.bborder = item.selected;
3119
- this.lastSingleSelection = { row, column };
3120
- }
3115
+ this.clearSelectionStatusExcluding(this.lastSingleSelection);
3116
+ this.setSelectionStatusBorders(event.range && first ? first : this.lastSingleSelection, this.lastSingleSelection);
3121
3117
  // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
3122
3118
  this.est.cdr.markForCheck();
3123
3119
  }
3120
+ setSelectionStatusBorders(from, to) {
3121
+ let rowAddition = to.row < from.row ? -1 : +1;
3122
+ let columnAddition = to.column < from.column ? -1 : +1;
3123
+ let singleItem = from == to;
3124
+ for (let ir = from.row; ir != to.row + rowAddition; ir += rowAddition) {
3125
+ let firstRow = ir == from.row;
3126
+ let lastRow = ir == to.row;
3127
+ for (let ic = from.column; ic != to.column + columnAddition; ic += columnAddition) {
3128
+ let firstCol = ic == from.column;
3129
+ let lastCol = ic == to.column;
3130
+ let current = this.est.selectionStatus[ir][ic];
3131
+ let prevColumn = ic > 0 ? this.est.selectionStatus[ir][ic - 1] : null;
3132
+ let nextcolumn = this.est.selectionStatus[ir][ic + 1];
3133
+ let prevRow = ir > 0 ? this.est.selectionStatus[ir - 1][ic] : null;
3134
+ let nextRow = this.est.selectionStatus[ir + 1] ? this.est.selectionStatus[ir + 1][ic] : null;
3135
+ current.selected = singleItem ? !current.selected : true;
3136
+ current.lborder = !current.selected ? false : columnAddition > 0 ? firstCol : lastCol;
3137
+ current.tborder = !current.selected ? false : rowAddition > 0 ? firstRow : lastRow;
3138
+ current.rborder = !current.selected ? false : columnAddition > 0 ? lastCol : firstCol;
3139
+ current.bborder = !current.selected ? false : rowAddition > 0 ? lastRow : firstRow;
3140
+ if (prevRow)
3141
+ prevRow.boverlaps = current.tborder;
3142
+ if (nextRow)
3143
+ nextRow.toverlaps = current.bborder;
3144
+ if (prevColumn)
3145
+ prevColumn.roverlaps = current.lborder;
3146
+ if (nextcolumn)
3147
+ nextcolumn.loverlaps = current.rborder;
3148
+ }
3149
+ }
3150
+ }
3124
3151
  /**
3125
3152
  * Helper per ripulire lo stato di selezione delle singole celle della tabella, ad esclusione di una singola coordinata
3126
3153
  *
3127
3154
  * @param {{row: number, column: number}} exclusion Coordinata da escludere nella pulizia
3128
3155
  */
3129
- clearSelectionStatus(exclusion) {
3156
+ clearSelectionStatusExcluding(exclusion) {
3130
3157
  for (let row in this.est.selectionStatus) {
3131
3158
  for (let column in this.est.selectionStatus[row]) {
3132
- if (!exclusion || (exclusion && (row != exclusion.row.toString() || column != exclusion.column.toString()))) {
3133
- this.est.selectionStatus[row][column].selected = false;
3134
- this.est.selectionStatus[row][column].lborder = false;
3135
- this.est.selectionStatus[row][column].tborder = false;
3136
- this.est.selectionStatus[row][column].rborder = false;
3137
- this.est.selectionStatus[row][column].bborder = false;
3138
- }
3159
+ // Se è l'elemento che ho escluso dal cleanup, skippo
3160
+ if (exclusion && row == exclusion.row.toString() && column == exclusion.column.toString())
3161
+ continue;
3162
+ // Altrimenti pulisco
3163
+ let curr = this.est.selectionStatus[row][column];
3164
+ curr.selected = curr.lborder = curr.rborder = curr.tborder = curr.bborder = curr.loverlaps = curr.roverlaps = curr.toverlaps = curr.boverlaps = false;
3139
3165
  }
3140
3166
  }
3141
3167
  }
@@ -3165,10 +3191,10 @@ class SelectionHandler {
3165
3191
  */
3166
3192
  clearTextSelection(event) {
3167
3193
  // Seleziono del testo ma non ho shift premuto -> ignoro la selezione
3168
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
3194
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.range)
3169
3195
  return false;
3170
3196
  // Seleziono del testo e ho shift premuto -> annullo la selezione del testo
3171
- if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
3197
+ if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.range)
3172
3198
  this.est.utiExts.clearTextSelection();
3173
3199
  }
3174
3200
  /**
@@ -3314,10 +3340,7 @@ class UtilitiesHandler {
3314
3340
  for (let i = min; i <= max; i++)
3315
3341
  if (i !== 1)
3316
3342
  result.push({ val: i, cssClass: (i === page ? 'btn-main app-white-text' : 'app-white-button') });
3317
- result.push({
3318
- val: lastPage,
3319
- cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button')
3320
- });
3343
+ result.push({ val: lastPage, cssClass: (lastPage === page ? 'btn-main app-white-text' : 'app-white-button') });
3321
3344
  }
3322
3345
  return result;
3323
3346
  }
@@ -3392,15 +3415,35 @@ class CopyPasteDetector {
3392
3415
  });
3393
3416
  }
3394
3417
  }
3418
+ CopyPasteDetector.ɵprov = ɵɵdefineInjectable({ factory: function CopyPasteDetector_Factory() { return new CopyPasteDetector(); }, token: CopyPasteDetector, providedIn: "root" });
3395
3419
  CopyPasteDetector.decorators = [
3396
- { type: Injectable }
3420
+ { type: Injectable, args: [{ providedIn: "root" },] }
3397
3421
  ];
3398
3422
  CopyPasteDetector.ctorParameters = () => [];
3399
3423
 
3424
+ /** Classe che fornisce dei metodi di estensione in grado di riconoscere e dispatchare l'evento copia e incolla lanciato su una pagina web */
3425
+ class Logger {
3426
+ /** @ignore */
3427
+ constructor(debugMode) {
3428
+ this.debugMode = debugMode;
3429
+ }
3430
+ log(text) {
3431
+ if (this.debugMode)
3432
+ console.log("[@esfaenza/es-table @ " + (new Date()).toISOString() + "] " + text);
3433
+ }
3434
+ }
3435
+ Logger.ɵprov = ɵɵdefineInjectable({ factory: function Logger_Factory() { return new Logger(ɵɵinject(EST_DEBUG, 8)); }, token: Logger, providedIn: "root" });
3436
+ Logger.decorators = [
3437
+ { type: Injectable, args: [{ providedIn: "root" },] }
3438
+ ];
3439
+ Logger.ctorParameters = () => [
3440
+ { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [EST_DEBUG,] }] }
3441
+ ];
3442
+
3400
3443
  /** Componente che permette di rappresentare una griglia di valori */
3401
3444
  class EsTableComponent {
3402
3445
  /** @ignore */
3403
- constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts, copyPasteDetector, clipboardService) {
3446
+ constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts, copyPasteDetector, clipboardService, logger) {
3404
3447
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
3405
3448
  this.ngControl = ngControl;
3406
3449
  this.prefService = prefService;
@@ -3415,6 +3458,7 @@ class EsTableComponent {
3415
3458
  this.msgExts = msgExts;
3416
3459
  this.copyPasteDetector = copyPasteDetector;
3417
3460
  this.clipboardService = clipboardService;
3461
+ this.logger = logger;
3418
3462
  /** Subject utilizzato internamente lato EsTable per causare il Focus lato componente di Input */
3419
3463
  this.FocusSubject = new Subject();
3420
3464
  /** Se vengono effettuati 2 click a distanza inferiore a questi Millisecondi viene considerato un doppio click */
@@ -3500,6 +3544,10 @@ class EsTableComponent {
3500
3544
  this.ColumnsPinnable = null;
3501
3545
  /** Indica se dev'essere disponibile il sistema di aggiornamento automatico */
3502
3546
  this.AutoUpdate = null;
3547
+ /** Indica l'altezza cablata che deve assumere la tabella. Es: "100px" | "100%" ... */
3548
+ this.Height = null;
3549
+ /** Indica il colore di sfondo dello spazio vuoto (non ricoperto da dati). Particolarmente utile da impostare in caso di **Height** diverso da null */
3550
+ this.EmptySpaceBackgroundColor = null;
3503
3551
  /**
3504
3552
  * @experimental Indica se dev'essere l'estable a gestire la ricerca, anche la prima.
3505
3553
  *
@@ -3716,9 +3764,19 @@ class EsTableComponent {
3716
3764
  /** @ignore */
3717
3765
  this.propagateChange = (_) => { };
3718
3766
  /** Funzione di trackby per il body che dovrebbe evitare il 90% delle change detection */
3719
- this.bodyTrackBy = (index, item) => item._hash;
3767
+ this.bodyTrackBy = (_, item) => item._hash;
3768
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo id */
3769
+ this.idTrackBy = (_, item) => item.id;
3770
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo PropertyName */
3771
+ this.PropertyNameTrackBy = (_, item) => item.PropertyName;
3772
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
3773
+ this.IDTrackBy = (_, item) => item.ID;
3774
+ /** Funzione di trackby generica per tutti gli oggetti che hanno il campo ID */
3775
+ this.valTrackBy = (_, item) => item.val;
3720
3776
  // Range selection Experimentals
3721
3777
  this.mouseIsDown = false;
3778
+ this.rangeSelected = false;
3779
+ this.rangeStartWasIgnored = false;
3722
3780
  this.firstCoordinates = null;
3723
3781
  //* Piango
3724
3782
  this.EsTdsCache = {};
@@ -3765,7 +3823,7 @@ class EsTableComponent {
3765
3823
  return;
3766
3824
  let shouldEmit = !t.item._selected;
3767
3825
  t.item._selected = true;
3768
- this.selection_H.clearSelectionStatus();
3826
+ this.selection_H.clearSelectionStatusExcluding(null);
3769
3827
  var itemSelection = this.selection_H.handleItemsSelection([t.item]);
3770
3828
  this.changed();
3771
3829
  if (shouldEmit)
@@ -4064,7 +4122,7 @@ class EsTableComponent {
4064
4122
  }
4065
4123
  /** 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 */
4066
4124
  internalPostBoundSource() {
4067
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4125
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
4068
4126
  let View = this.View;
4069
4127
  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;
4070
4128
  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;
@@ -4072,6 +4130,7 @@ class EsTableComponent {
4072
4130
  let tds = tdsD && tdsD.length > 0 ? tdsD.toArray() : [];
4073
4131
  // Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
4074
4132
  this.dynamicMode_H.eventuallyReviewDynamicColumns();
4133
+ // Gestisce la richiesta per gruppi o per singoli oggetti
4075
4134
  this.bindDisplayToLoadedItemsOrGroups(View);
4076
4135
  // Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
4077
4136
  this.setupPagingInformations();
@@ -4082,16 +4141,24 @@ class EsTableComponent {
4082
4141
  let si = this.viewMode ? view.selection : this.arraymodeSelection;
4083
4142
  // N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
4084
4143
  // ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
4085
- // Espando i th e i td multipli duplicandoli
4086
- let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
4087
- ths = ret.expThs;
4088
- tds = ret.expTds;
4144
+ // 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
4145
+ if (!this.arrayMode && ((_l = this.DynamicRowColumnsDefinition) === null || _l === void 0 ? void 0 : _l.length) > 0) {
4146
+ this.logger.log("Generating ths and tds from Dynamic definition");
4147
+ let ret = this.dynamicMode_H.emitThsAndTdsBasedOnDynamicDefinition();
4148
+ ths = ret.ths;
4149
+ tds = ret.tds;
4150
+ }
4089
4151
  // Gestione delle view in modalità report, i th e i td vengono rigenerati dalle configurazioni della view
4090
4152
  if (!this.arrayMode && view.report_columns) {
4153
+ this.logger.log("Generating ths and tds from report results");
4091
4154
  let ret = this.reportMode_H.generateThsAndTdsFromView(view);
4092
4155
  ths = ret.ths;
4093
4156
  tds = ret.tds;
4094
4157
  }
4158
+ // Espando i th e i td multipli duplicandoli
4159
+ let ret = this.columnMetadata_H.expandMultiThsAndTds(ths, tds, itemsAndGroups);
4160
+ ths = ret.expThs;
4161
+ tds = ret.expTds;
4095
4162
  // 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
4096
4163
  for (let i = 0; i < ths.length; i++) {
4097
4164
  let th = ths[i];
@@ -4255,6 +4322,7 @@ class EsTableComponent {
4255
4322
  * @param {EsTdDirective[]} tds Celle della tabella
4256
4323
  */
4257
4324
  evaluateRowTds(ths, tds) {
4325
+ var _a;
4258
4326
  if (tds.length == 0)
4259
4327
  return;
4260
4328
  let columnsCache = {};
@@ -4287,13 +4355,14 @@ class EsTableComponent {
4287
4355
  PinnedWidth: thCasted.thPinnedWidth,
4288
4356
  GroupHeader: false,
4289
4357
  GroupAggregation: false,
4290
- Visible: columnsCache[td.td].visible, Wraps: false,
4358
+ Visible: columnsCache[td.td].visible,
4359
+ Wraps: false,
4291
4360
  Class: td.tdClass,
4292
4361
  Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template,
4293
4362
  Multi: td._multi,
4294
4363
  MultiProp: td._multi ? td.td.split('_')[0] : null,
4295
4364
  MultiIndex: td._multi ? td.td.split('_')[1] : null,
4296
- Alignment: td.tdAlignment || th.thAlignment,
4365
+ Alignment: (_a = (td.tdAlignment || th.thAlignment)) === null || _a === void 0 ? void 0 : _a.toLowerCase(),
4297
4366
  Format: td.tdFormat || th.thFormat,
4298
4367
  PropertyName: th.thProperty,
4299
4368
  PropertyType: th.thType,
@@ -4363,7 +4432,24 @@ class EsTableComponent {
4363
4432
  let toAdd;
4364
4433
  if (th.thIf || th.thGroup) {
4365
4434
  let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
4366
- 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 };
4435
+ toAdd = {
4436
+ Pinned: columnsListCache[th.th].pinned,
4437
+ Fixed: th.thFixed,
4438
+ PinnedWidth: th.thPinnedWidth,
4439
+ ID: th.th,
4440
+ Visible: th.thVisible,
4441
+ Class: thClass,
4442
+ Order: th.thOrder,
4443
+ Orderable: th.thOrderable,
4444
+ Template: th.Template,
4445
+ // Se non è nessun contenuto né nessun template mostro semplicemente l'ID dell'header
4446
+ Content: th.thStaticContent || th.Template ? '' : th.th,
4447
+ Wrap: th.thWrap,
4448
+ LeftBorder: th._lbord,
4449
+ RightBorder: th._rbord,
4450
+ Multi: th._multi,
4451
+ MultiContent: th._multi_content
4452
+ };
4367
4453
  this.TMPRowTHs.push(toAdd);
4368
4454
  // Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
4369
4455
  // li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
@@ -4460,7 +4546,7 @@ class EsTableComponent {
4460
4546
  * @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
4461
4547
  */
4462
4548
  globalCheckChanged(forcedVal = null) {
4463
- this.selection_H.clearSelectionStatus();
4549
+ this.selection_H.clearSelectionStatusExcluding(null);
4464
4550
  // 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
4465
4551
  let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
4466
4552
  var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
@@ -4479,7 +4565,7 @@ class EsTableComponent {
4479
4565
  */
4480
4566
  handleClick(event, item) {
4481
4567
  this.selection_H.clearTextSelection(event);
4482
- this.selection_H.clearSelectionStatus();
4568
+ this.selection_H.clearSelectionStatusExcluding(null);
4483
4569
  let selecteditems = [];
4484
4570
  if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
4485
4571
  let startSelecting = false;
@@ -4700,24 +4786,34 @@ class EsTableComponent {
4700
4786
  * @param {any} $event Evento nativo javascript
4701
4787
  * @param {TdElement} rowItem Riferimento a binder della riga
4702
4788
  * @param {any} item Item che rappresenta il contesto su cui è stato effettuato un click
4703
- * @param {number} rowIndex Indice della riga
4704
4789
  */
4705
- dbClickEditOrSingleClickRowSelection($event, rowItem, item, rowIndex) {
4706
- var _a, _b;
4790
+ dbClickEditOrSingleClickRowSelection($event, rowItem, item) {
4791
+ // Prima cosa da fare è controllare se ci sono dei range lasciati da operazioni precedenti (se applicabile) e ripulirli
4792
+ if (this.rangeSelected && !$event.ctrlKey && this.Selection) {
4793
+ this.logger.log("clearing previously selected range");
4794
+ this.selection_H.clearSelectionStatusExcluding(null);
4795
+ this.rangeSelected = false;
4796
+ return;
4797
+ }
4707
4798
  // Modalità Editable, gestisco i doppi click senza però rallentare la modalità di selezione a range
4708
4799
  if (this.Editable) {
4709
4800
  // Secondo click: se il timer non è scaduto è un doppio click ed eseguo il resto
4710
4801
  if (this.cellDbClickTimer) {
4802
+ this.logger.log("handling doubleclick on editable cell: " + (rowItem.PropertyName ? 'edit mode for property ' + rowItem.PropertyName : 'no property set, fallback to simple click'));
4711
4803
  if (rowItem.PropertyName)
4712
4804
  this.setupUserEdit(rowItem, item);
4805
+ else
4806
+ this.handleRowClick($event, item, this.Selection, true);
4713
4807
  this.clearCellClickTimer();
4714
4808
  return;
4715
4809
  }
4716
4810
  // Primo click: non fa niente e se il tempo per il secondo click scade resetta tutto
4717
4811
  this.cellDbClickTimer = setTimeout(() => {
4718
4812
  this.clearCellClickTimer();
4719
- if (!this.RangeSelection)
4813
+ if (!this.RangeSelection || !this.mouseIsDown) {
4814
+ this.logger.log("time's up for second click, handling single click");
4720
4815
  this.handleRowClick($event, item, this.Selection, true);
4816
+ }
4721
4817
  }, this.doubleClickBufferMs);
4722
4818
  }
4723
4819
  // In modalità a range la creazione del range è gestita dai mousedown, move ed up...
@@ -4728,8 +4824,7 @@ class EsTableComponent {
4728
4824
  if ($event.ctrlKey)
4729
4825
  return;
4730
4826
  // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
4731
- if ((((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0 && rowItem.edits && ((_b = rowItem.edits[item._hash]) === null || _b === void 0 ? void 0 : _b._editing)) ||
4732
- rowItem._editing)
4827
+ if (rowItem._editing)
4733
4828
  return;
4734
4829
  // Per evitare di rallentare a prescindere
4735
4830
  if (!this.Editable) {
@@ -4811,14 +4906,12 @@ class EsTableComponent {
4811
4906
  // Stessa cosa se ho custom cell dato che la gestione dei click viene affidata ai singoli TD
4812
4907
  if ($event.ctrlKey || (this.UseCustomCells && !internalCall))
4813
4908
  return true;
4814
- if (selection && !item.locked && !item._sep && !item._group) {
4815
- this.selection_H.clearSelectionStatus();
4909
+ if (selection)
4910
+ this.selection_H.clearSelectionStatusExcluding(null);
4911
+ if (selection && !item.locked && !item._sep && !item._group)
4816
4912
  this.handleClick($event, item);
4817
- }
4818
- else if (item._group) {
4819
- this.selection_H.clearSelectionStatus();
4913
+ else if (item._group)
4820
4914
  this.handleGroupClick(item);
4821
- }
4822
4915
  // Ora che non è attaccato direttamente all'html devo fare un markforcheck finite le operazioni sui grouping
4823
4916
  this.cdr.markForCheck();
4824
4917
  }
@@ -4839,15 +4932,11 @@ class EsTableComponent {
4839
4932
  */
4840
4933
  setupUserEdit(rowItem, item) {
4841
4934
  var _a;
4842
- this.selection_H.clearSelectionStatus();
4935
+ this.selection_H.clearSelectionStatusExcluding(null);
4843
4936
  if (this.Editable && rowItem.PropertyName) {
4844
- if (((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0) {
4845
- rowItem.edits[item._hash] = { _editing: true, old_value: item.properties[rowItem.PropertyName] };
4846
- }
4847
- else {
4848
- rowItem._editing = true;
4849
- rowItem.old_value = item[rowItem.PropertyName];
4850
- }
4937
+ let dynMode = ((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0;
4938
+ rowItem._editing = true;
4939
+ rowItem.old_value = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
4851
4940
  }
4852
4941
  this.cdr.detectChanges();
4853
4942
  setTimeout(() => { this.FocusSubject.next(); });
@@ -4862,7 +4951,7 @@ class EsTableComponent {
4862
4951
  finalizeUserEdit(rowItem, item, columnIndex) {
4863
4952
  var _a;
4864
4953
  let dynMode = ((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0;
4865
- let rowItm = dynMode ? (rowItem.edits[item._hash]) : rowItem;
4954
+ let rowItm = rowItem;
4866
4955
  rowItm._editing = false;
4867
4956
  let old = rowItm.old_value;
4868
4957
  let niu = dynMode ? item.properties[rowItem.PropertyName] : item[rowItem.PropertyName];
@@ -4873,22 +4962,27 @@ class EsTableComponent {
4873
4962
  this.onModelChange.emit([new EsTableModelChange(item, rowItem.ID, rowItem.PropertyName, old, niu)]);
4874
4963
  this.selectionStatus[item._ordinal][columnIndex].val_setter(niu);
4875
4964
  }
4876
- mousedown(event, rowItem, item) {
4877
- var _a, _b;
4965
+ mousedown(event, rowItem, _) {
4878
4966
  // Tasto diverso dal click sinistro -> ciao è stato bello e intenso
4879
4967
  if (event.buttons != 1 || !this.RangeSelection)
4880
4968
  return;
4881
4969
  // Sto lavorando su QUESTA es-table
4882
4970
  this.copyPasteDetector.ActiveEstReference = this;
4883
4971
  // Tutti i click su una cella già in edit non devono effettuare la selezione della riga
4884
- if ((((_a = this.DynamicRowColumnsDefinition) === null || _a === void 0 ? void 0 : _a.length) > 0 && rowItem.edits && ((_b = rowItem.edits[item._hash]) === null || _b === void 0 ? void 0 : _b._editing)) ||
4885
- rowItem._editing)
4972
+ if (rowItem._editing)
4886
4973
  return;
4887
- let id = event.currentTarget.id;
4888
4974
  this.mouseIsDown = true;
4889
- let coords = id.split('_');
4890
- this.firstCoordinates = { row: parseInt(coords[coords.length - 2]), column: parseInt(coords[coords.length - 1]) };
4891
- this.selection_H.singleCellSelection({ view: event.view, shiftKey: false }, this.firstCoordinates.row, this.firstCoordinates.column);
4975
+ let coords = event.currentTarget.id.split('_');
4976
+ let row = parseInt(coords[coords.length - 2]);
4977
+ let column = parseInt(coords[coords.length - 1]);
4978
+ this.firstCoordinates = { row, column };
4979
+ // 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)
4980
+ // e gestire la grafica in maniera un po' più precisa
4981
+ if (!this.rangeSelected || (event.ctrlKey || !this.Selection))
4982
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
4983
+ else
4984
+ this.rangeStartWasIgnored = true;
4985
+ this.logger.log(`mouse down on ${row}:${column}`);
4892
4986
  }
4893
4987
  mouseenter(event) {
4894
4988
  if (!this.RangeSelection)
@@ -4898,14 +4992,34 @@ class EsTableComponent {
4898
4992
  if (this.mouseIsDown && this.firstCoordinates) {
4899
4993
  let id = event.currentTarget.id;
4900
4994
  let coords = id.split('_');
4901
- let newCoords = { row: parseInt(coords[coords.length - 2]), column: parseInt(coords[coords.length - 1]) };
4902
- this.selection_H.singleCellSelection({ view: event.view, shiftKey: true }, newCoords.row, newCoords.column, this.firstCoordinates);
4995
+ let row = parseInt(coords[coords.length - 2]);
4996
+ let column = parseInt(coords[coords.length - 1]);
4997
+ // Se ho ignorato l'inizio della selezione nel mousedown lo recupero qui
4998
+ if (this.rangeStartWasIgnored) {
4999
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, this.firstCoordinates.row, this.firstCoordinates.column);
5000
+ this.rangeStartWasIgnored = false;
5001
+ }
5002
+ this.selection_H.singleCellSelection({ view: event.view, range: true }, row, column, this.firstCoordinates);
5003
+ this.logger.log(`mouse move over ${row}:${column}`);
5004
+ this.rangeSelected = true;
4903
5005
  }
4904
5006
  }
4905
5007
  mouseup(event) {
4906
5008
  if (!this.RangeSelection)
4907
5009
  return;
5010
+ let id = event.currentTarget.id;
5011
+ let coords = id.split('_');
5012
+ let row = parseInt(coords[coords.length - 2]);
5013
+ let column = parseInt(coords[coords.length - 1]);
5014
+ // Se il mouseup viene effettuato sulla stessa cella del primo mousedown e siamo in modalità di selezione deseleziono la cella perché è un semplice click
5015
+ if (this.mouseIsDown && this.firstCoordinates) {
5016
+ if (this.firstCoordinates.row == row && this.firstCoordinates.column == column && !event.ctrlKey && !this.rangeStartWasIgnored && this.Selection)
5017
+ this.selection_H.singleCellSelection({ view: event.view, range: false }, row, column);
5018
+ else if (event.ctrlKey || !this.Selection)
5019
+ this.rangeSelected = true;
5020
+ }
4908
5021
  this.mouseIsDown = false;
5022
+ this.logger.log(`mouse lifted up`);
4909
5023
  }
4910
5024
  getCellReference(object, column) {
4911
5025
  let fkThisShitImOut = this.utiExts.deepClone(object);
@@ -4925,8 +5039,8 @@ EsTableComponent.decorators = [
4925
5039
  viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }],
4926
5040
  changeDetection: ChangeDetectionStrategy.OnPush,
4927
5041
  encapsulation: ViewEncapsulation.None,
4928
- 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 <!-- 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\" 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 && 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 <!-- 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\" [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\" 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 }\"></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)=\"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\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition; let i = index\">\r\n\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\r\n <ng-container *ngIf=\"!rowItem.RoutePath && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.PropertyName}}\" \r\n [class.est-selected-cell]=\"selectionStatus[item._ordinal][i]?.selected\" \r\n [class.est-cell-lborder]=\"selectionStatus[item._ordinal][i]?.lborder\"\r\n [class.est-cell-tborder]=\"selectionStatus[item._ordinal][i]?.tborder\"\r\n [class.est-cell-rborder]=\"selectionStatus[item._ordinal][i]?.rborder\"\r\n [class.est-cell-bborder]=\"selectionStatus[item._ordinal][i]?.bborder\"\r\n [class.est-cell-lborder-tmp]=\"!selectionStatus[item._ordinal][i]?.lborder && !selectionStatus[item._ordinal][i]?.loverlaps\"\r\n [class.est-cell-rborder-tmp]=\"!selectionStatus[item._ordinal][i]?.rborder && !selectionStatus[item._ordinal][i]?.roverlaps\"\r\n (click)=\"dbClickEditOrSingleClickRowSelection($event, rowItem, item, i)\" \r\n class=\"{{UserDefinedDynamicCols ? rowItem.Clss : 'est-nowrap'}} est-default-row-height\" \r\n [Internal]=\"false\" [class.est-no-selection]=\"!!Editable\" [Context]=\"item._hash\"\r\n id=\"estd_{{rowItem.PropertyName}}_{{item._ordinal}}_{{i}}\" (mousedown)=\"mousedown($event, rowItem, item)\" (mouseenter)=\"mouseenter($event)\" (mouseup)=\"mouseup($event)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem.edits[item._hash]?._editing\" >\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.PropertyName, rowItem.RendererName) || defaultEsTd; context: { $implicit: { definition: rowItem, value: item.properties[rowItem.PropertyName], type: rowItem.PropertyType} }\"></ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem.edits[item._hash]?._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"findEditor(rowItem.PropertyName, rowItem.EditorName) || defaultEditor; context: { $implicit: { definition: rowItem, columnIndex: i, item: item, finalizer: finalizeUserEdit.bind(this, rowItem, item, i) } }\"></ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEditor let-ctx>\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 <!-- 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<!-- 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 <td *ngIf=\"HasPinnedColumns\" \r\n 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]=\"Editable &&!!rowItem.PropertyName\" [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, i)\">\r\n\r\n <div [class.est-edit-hidden]=\"rowItem._editing\" [class.est-pre]=\"!(Hierarchy && i == 0)\"\r\n [style.text-align]=\"rowItem.Alignment == 'Center' ? 'center' : rowItem.Alignment == 'Left' ? 'left' : rowItem.Alignment == 'Right' ? 'right' : null\"\r\n [style.color]=\"item.forecolors && rowItem.PropAccessor ? item.forecolors[rowItem.PropAccessor] : null\"\r\n [style.background-color]=\"item.backcolors && rowItem.PropAccessor ? item.backcolors[rowItem.PropAccessor] : null\">\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]) | est_format: rowItem.Format }}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"findEditor(rowItem.PropertyName) || defaultEditor; context: { $implicit: { definition: rowItem, columnIndex: i, item: item, finalizer: finalizeUserEdit.bind(this, rowItem, item, i) } }\"></ng-container>\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}}\" \r\n [class.est-selected-cell]=\"selectionStatus[item._ordinal][i]?.selected\" \r\n [class.est-cell-lborder]=\"selectionStatus[item._ordinal][i]?.lborder\"\r\n [class.est-cell-tborder]=\"selectionStatus[item._ordinal][i]?.tborder\"\r\n [class.est-cell-rborder]=\"selectionStatus[item._ordinal][i]?.rborder\"\r\n [class.est-cell-bborder]=\"selectionStatus[item._ordinal][i]?.bborder\"\r\n [class.est-ltab-border]=\"rowItem.LeftBorder && !selectionStatus[item._ordinal][i]?.lborder\" \r\n [class.est-rtab-border]=\"rowItem.RightBorder && !selectionStatus[item._ordinal][i]?.rborder\" \r\n [class.est-cell-lborder-tmp]=\"!selectionStatus[item._ordinal][i]?.lborder && !selectionStatus[item._ordinal][i]?.loverlaps && !rowItem.LeftBorder\"\r\n [class.est-cell-rborder-tmp]=\"!selectionStatus[item._ordinal][i]?.rborder && !selectionStatus[item._ordinal][i]?.roverlaps && !rowItem.RightBorder\"\r\n [class.est-no-selection]=\"Editable && !!rowItem.PropertyName\" [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, i)\"\r\n (onCellGeneration)=\"registerCell($event)\" [Context]=\"item._hash\"\r\n id=\"{{item._ordinal}}_{{i}}\" (mousedown)=\"mousedown($event, rowItem, item)\" (mouseenter)=\"mouseenter($event)\" (mouseup)=\"mouseup($event)\"\r\n [style.text-align]=\"rowItem.Alignment == 'Center' ? 'center' : rowItem.Alignment == 'Left' ? 'left' : rowItem.Alignment == 'Right' ? 'right' : null\"\r\n [style.color]=\"item.forecolors && rowItem.PropAccessor ? item.forecolors[rowItem.PropAccessor] : null\"\r\n [style.background-color]=\"item.backcolors && rowItem.PropAccessor ? item.backcolors[rowItem.PropAccessor] : null\">\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]) | est_format: rowItem.Format }}</span>\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"rowItem._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"findEditor(rowItem.PropertyName) || defaultEditor; context: { $implicit: { definition: rowItem, columnIndex: i, item: item, finalizer: finalizeUserEdit.bind(this, rowItem, item, i) } }\"></ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\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>",
4929
- styles: [".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:0;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density td,.est-high-density th{padding:0 .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{height:1px!important}.est-edit-hidden,.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-13,.est-fs-14{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{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.est-slider,.est-slider:before{position:absolute;transition:.4s}.est-slider:before{content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translateX(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-next,.est-page-prev{color:#000;font-size:inherit;padding:2px 0 0}.est-pinned-header{background-color:#fff;left:0;top:0;position:-webkit-sticky;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:0 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:-webkit-sticky;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:-webkit-sticky;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:-webkit-sticky;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:rgba(33,150,243,.2)}.est-cell-lborder{border-left:1.02px solid #2196f3!important}.est-cell-lborder-tmp{border-left:1.02px solid transparent!important}.est-cell-tborder{border-top:1.02px solid #2196f3!important}.est-cell-rborder{border-right:1.02px solid #2196f3!important}.est-cell-rborder-tmp{border-right:1.02px solid transparent!important}.est-cell-bborder{border-bottom:1.02px solid #2196f3!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:hsla(0,0%,46.7%,.4666666666666667)!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:hsla(0,0%,73.3%,.7333333333333333)!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 rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.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,.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}"]
5042
+ 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\" [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\" [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; trackBy: IDTrackBy\">\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 <!-- 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 }\"></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; 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 }\"></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\">\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>\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<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 rowItem of RowTDs[item._hash]; let i = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"rowItem.Pinned\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: { $implicit: { item: item, rowItem : rowItem, i:i, Pinned: true } };\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <!-- Eventuali operazioni custom nelle prime righe... hanno senso solo in modalit\u00E0 dinamica ma non si sa mai -->\r\n <ng-container *ngTemplateOutlet=\"customOperations; context: {$implicit: item };\"></ng-container>\r\n\r\n <!-- Body effettivo della riga -->\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index; trackBy: IDTrackBy\">\r\n <ng-container *ngIf=\"!rowItem.Pinned\">\r\n <ng-container *ngTemplateOutlet=\"customTd; context: {$implicit: {item: item, rowItem : rowItem, i:i, Pinned: false} };\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Blocco di operazioni custom da far apparire all'inizio della tabella -->\r\n<ng-template #customOperations let-item>\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last; trackBy: idTrackBy\">\r\n <ng-container *ngIf=\"!operation.conditionField || ((item.properties ? item.properties[operation.conditionField] : item[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 ? item.properties[operation.conditionField] : item[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-template>\r\n\r\n<!-- Cella customizzata, elemento grafico base per la tabella -->\r\n<ng-template #customTd let-ctx>\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 <!-- class=\"{{ UserDefinedDynamicCols ? ctx.rowItem.Class : 'est-nowrap'}} est-default-row-height\" -->\r\n\r\n <td *ngIf=\"ctx.rowItem?.Visible\" \r\n es-td=\"{{ctx.rowItem.Property || ctx.rowItem.ID}}\"\r\n id=\"estd_{{ctx.rowItem.Property || ctx.rowItem.ID}}_{{ctx.item._ordinal}}_{{ctx.i}}\" \r\n class=\"{{ ctx.rowItem.Class }} est-default-row-height\" \r\n [Context]=\"ctx.item._hash\" \r\n [class.est-no-selection]=\"Editable && ctx.rowItem.PropertyName\" \r\n [class.est-rg-hdr]=\"ctx.rowItem.GroupHeader\" \r\n [class.est-rg-agg]=\"ctx.rowItem.GroupAggregation\"\r\n [class.est-nowrap]=\"Hierarchy || !ctx.rowItem.Wraps\"\r\n \r\n [style.text-align]=\" (!ctx.Pinned && ctx.rowItem.Alignment) ? ctx.rowItem.Alignment : null\"\r\n [style.color]=\"(!ctx.Pinned && ctx.item.forecolors && ctx.rowItem.PropAccessor) ? ctx.item.forecolors[ctx.rowItem.PropAccessor] : null\"\r\n [style.background-color]=\"(!ctx.Pinned && ctx.item.backcolors && ctx.rowItem.PropAccessor) ? ctx.item.backcolors[ctx.rowItem.PropAccessor] : null\"\r\n\r\n [style.width.px]=\"ctx.Pinned ? ctx.rowItem.PinnedWidth : null\"\r\n [class.est-no-border]=\"ctx.Pinned\"\r\n\r\n [class.est-ltab-border]=\"ctx.rowItem.LeftBorder && !selectionStatus[ctx.item._ordinal][ctx.i]?.lborder\" \r\n [class.est-rtab-border]=\"ctx.rowItem.RightBorder && !selectionStatus[ctx.item._ordinal][ctx.i]?.rborder\" \r\n\r\n [class.est-selected-cell]=\"selectionStatus[ctx.item._ordinal][ctx.i]?.selected\"\r\n [class.est-cell-lborder]=\"selectionStatus[ctx.item._ordinal][ctx.i]?.lborder\"\r\n [class.est-cell-rborder]=\"selectionStatus[ctx.item._ordinal][ctx.i]?.rborder\"\r\n [class.est-cell-tborder]=\"selectionStatus[ctx.item._ordinal][ctx.i]?.tborder\"\r\n [class.est-cell-bborder]=\"selectionStatus[ctx.item._ordinal][ctx.i]?.bborder\"\r\n\r\n [class.est-cell-lborder-tmp]=\"!ctx.rowItem.LeftBorder && !selectionStatus[ctx.item._ordinal][ctx.i]?.lborder && !selectionStatus[ctx.item._ordinal][ctx.i]?.loverlaps\"\r\n [class.est-cell-rborder-tmp]=\"!ctx.rowItem.RightBorder && !selectionStatus[ctx.item._ordinal][ctx.i]?.rborder && !selectionStatus[ctx.item._ordinal][ctx.i]?.roverlaps\"\r\n [class.est-cell-tborder-tmp]=\"!selectionStatus[ctx.item._ordinal][ctx.i]?.tborder && !selectionStatus[ctx.item._ordinal][ctx.i]?.toverlaps\"\r\n [class.est-cell-bborder-tmp]=\"!selectionStatus[ctx.item._ordinal][ctx.i]?.bborder && !selectionStatus[ctx.item._ordinal][ctx.i]?.boverlaps\"\r\n\r\n (mousedown)=\"mousedown($event, ctx.rowItem, ctx.item)\" \r\n (mouseenter)=\"mouseenter($event)\" \r\n (mouseup)=\"mouseup($event)\"\r\n (onCellGeneration)=\"registerCell($event)\"\r\n \r\n (click)=\"dbClickEditOrSingleClickRowSelection($event, ctx.rowItem, ctx.item)\">\r\n\r\n <div [class.est-edit-hidden]=\"ctx.rowItem._editing\" [class.est-pre]=\"!(Hierarchy && ctx.i == 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=\"ctx.rowItem.Template\">\r\n <ng-container *ngIf=\"!ctx.rowItem.Multi\"><ng-container *ngTemplateOutlet=\"ctx.rowItem.Template; context: { $implicit: ctx.item }\"></ng-container></ng-container>\r\n <span *ngIf=\"ctx.rowItem.Multi\"><ng-container *ngTemplateOutlet=\"ctx.rowItem.Template; context: { $implicit: (ctx.item[ctx.rowItem.MultiProp] ? ctx.item[ctx.rowItem.MultiProp][ctx.rowItem.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=\"!ctx.rowItem.Template && !ctx.rowItem.Multi && !ctx.rowItem.Content\">\r\n <a *ngIf=\"ctx.rowItem.RoutePath\" [routerLink]=\"ctx.item | est_routerlink : ctx.rowItem.RoutePath : ctx.rowItem.RouteParameterProperties\" class=\"est-link\" [innerHTML]=\"ctx.item.properties ? ctx.item.properties[ctx.rowItem.PropertyName] : ctx.item[ctx.rowItem.PropertyName]\"></a>\r\n \r\n <span *ngIf=\"ctx.rowItem.PropAccessor\">\r\n {{(ctx.item.values? ctx.item.values[ctx.rowItem.PropAccessor] : ctx.item[ctx.rowItem.PropAccessor]) | est_format: ctx.rowItem.Format }}\r\n </span>\r\n\r\n <ng-container *ngIf=\"!ctx.rowItem.PropAccessor && !ctx.rowItem.RoutePath\">\r\n <ng-container *ngTemplateOutlet=\"ctx.rowItem.PropertyName | est_renderer: { name: ctx.rowItem.RendererName, src: EsTdsDirective, fallback: defaultEsTd }; context: { $implicit: { definition: ctx.rowItem, value: ctx.item.properties ? ctx.item.properties[ctx.rowItem.PropertyName] : ctx.item[ctx.rowItem.PropertyName], type: ctx.rowItem.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 && ctx.i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: ctx.item }\"></ng-container></ng-container>\r\n\r\n <!-- 1% Content programmatico per le casistiche di Row Grouping ecc... -->\r\n <ng-container *ngIf=\"ctx.rowItem.Content\">\r\n {{ctx.rowItem.Content}}\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"ctx.rowItem._editing\" class=\"est-mt-min-5\">\r\n <ng-container *ngTemplateOutlet=\"ctx.rowItem.PropertyName | est_editor: { name: ctx.rowItem.EditorName, src: EsTdEditorDirectives, fallback: defaultEditor}; context: { $implicit: { definition: ctx.rowItem, columnIndex: ctx.i, item: ctx.item, finalizer: finalizeUserEdit.bind(this, ctx.rowItem, ctx.item, ctx.i) } }\"></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>",
5043
+ styles: [".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:0;left:6px;bottom:0;width:1px;position:absolute;background-color:#ccc;height:100%}.est-pointer{cursor:pointer}.est-high-density td,.est-high-density th{padding:0 .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{height:1px!important}.est-edit-hidden,.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-13,.est-fs-14{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{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.est-slider,.est-slider:before{position:absolute;transition:.4s}.est-slider:before{content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translateX(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-next,.est-page-prev{color:#000;font-size:inherit;padding:2px 0 0}.est-pinned-header{background-color:#fff;left:0;top:0;position:-webkit-sticky;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:0 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:-webkit-sticky;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:-webkit-sticky;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:-webkit-sticky;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:rgba(33,150,243,.2)}.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:hsla(0,0%,46.7%,.4666666666666667)!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:hsla(0,0%,73.3%,.7333333333333333)!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 rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.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,.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}"]
4930
5044
  },] }
4931
5045
  ];
4932
5046
  EsTableComponent.ctorParameters = () => [
@@ -4942,7 +5056,8 @@ EsTableComponent.ctorParameters = () => [
4942
5056
  { type: DateService },
4943
5057
  { type: MessageService },
4944
5058
  { type: CopyPasteDetector },
4945
- { type: ClipboardService }
5059
+ { type: ClipboardService },
5060
+ { type: Logger }
4946
5061
  ];
4947
5062
  EsTableComponent.propDecorators = {
4948
5063
  EsTdEditorDirectives: [{ type: ContentChildren, args: [EsTdEditorDirective,] }],
@@ -4958,6 +5073,8 @@ EsTableComponent.propDecorators = {
4958
5073
  ColumnsResizable: [{ type: Input }],
4959
5074
  ColumnsPinnable: [{ type: Input }],
4960
5075
  AutoUpdate: [{ type: Input }],
5076
+ Height: [{ type: Input }],
5077
+ EmptySpaceBackgroundColor: [{ type: Input }],
4961
5078
  EsTableHandledSearch: [{ type: Input }],
4962
5079
  UseCustomCells: [{ type: Input }],
4963
5080
  MaxHeight: [{ type: Input }],
@@ -5177,7 +5294,7 @@ class EsTh {
5177
5294
  EsTh.decorators = [
5178
5295
  { type: Component, args: [{
5179
5296
  selector: "[es-th]",
5180
- 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>",
5297
+ 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>",
5181
5298
  changeDetection: ChangeDetectionStrategy.OnPush
5182
5299
  },] }
5183
5300
  ];
@@ -5205,59 +5322,26 @@ EsTh.propDecorators = {
5205
5322
  onMouseMove: [{ type: HostListener, args: ['window:mousemove.out-zone', ['$event'],] }]
5206
5323
  };
5207
5324
 
5208
- //Angular
5325
+ // Angular
5209
5326
  /** Componente rappresentante una singola cella del body della tabella */
5210
5327
  class EsTd {
5211
5328
  /** @ignore */
5212
- constructor(cdr, myself, renderer, sanitizer) {
5329
+ constructor(cdr) {
5213
5330
  this.cdr = cdr;
5214
- this.myself = myself;
5215
- this.renderer = renderer;
5216
- this.sanitizer = sanitizer;
5217
5331
  /** Id della cella, dev'essere lo stesso della colonna **EsTh** relativa */
5218
5332
  this.ID = "";
5219
- /** Valore da mostrare all'interno della cella. Se omesso verrà proiettato il contenuto dal template in cui è stata usata */
5220
- this.Display = null;
5221
- /** Template Angular da istanziare per questo TD */
5222
- this.Template = null;
5223
5333
  /** Quando questa cella viene generata questo evento permette di dire "ehi, sono nato!" */
5224
5334
  this.onCellGeneration = new EventEmitter();
5225
- // Ema commenta grazie
5335
+ /** Errore attualmente presente sulla cella */
5226
5336
  this.ValidationError = "";
5227
5337
  }
5228
- /**
5229
- * Imposta la visibilità o meno della cella, si traduce nell'applicazione o rimozione della classe **app-display-none**
5230
- *
5231
- * @param {boolean} expression Indicazione della visibilità
5232
- */
5233
- set Visible(expression) {
5234
- this._Visible = expression;
5235
- if (expression)
5236
- this.renderer.removeClass(this.myself.nativeElement, "app-display-none");
5237
- else
5238
- this.renderer.addClass(this.myself.nativeElement, "app-display-none");
5239
- }
5240
- /**
5241
- * Restituisce lo stato di Visibilità della cella in oggetto
5242
- *
5243
- * @returns {boolean} **true** se visibile, **false** altrimenti
5244
- */
5245
- get Visible() {
5246
- if (this._Visible == undefined)
5247
- this._Visible = true;
5248
- return this._Visible;
5249
- }
5250
5338
  /** @ignore */
5251
5339
  ngAfterViewInit() {
5252
5340
  this.onCellGeneration.emit({ id: this.ID, hash: this.Context, self: this });
5253
- // Se è Internal significa che è gestita internamente da ES-TABLE quindi evito di fare sti due passaggi di lettura del DOM
5254
- if (this.Internal)
5255
- return;
5256
- this.Content = this.Display === null || this.Display === "" ? this.sanitizer.bypassSecurityTrustHtml(this.myself.nativeElement.innerHTML) : this.sanitizer.bypassSecurityTrustHtml(this.Display);
5257
- this.Class = this.myself.nativeElement.className.replace("app-display-none", "");
5258
5341
  }
5259
- validationError(isError, error) {
5260
- this.ValidationError = isError ? error : "";
5342
+ /** Api per impostare un "errore" su questa cella in maniera programmatica */
5343
+ validationError(error) {
5344
+ this.ValidationError = error;
5261
5345
  this.cdr.markForCheck();
5262
5346
  }
5263
5347
  }
@@ -5270,20 +5354,12 @@ EsTd.decorators = [
5270
5354
  },] }
5271
5355
  ];
5272
5356
  EsTd.ctorParameters = () => [
5273
- { type: ChangeDetectorRef },
5274
- { type: ElementRef },
5275
- { type: Renderer2 },
5276
- { type: DomSanitizer }
5357
+ { type: ChangeDetectorRef }
5277
5358
  ];
5278
5359
  EsTd.propDecorators = {
5279
5360
  ID: [{ type: Input, args: ['es-td',] }],
5280
- Internal: [{ type: Input }],
5281
- RouterLink: [{ type: Input }],
5282
- Display: [{ type: Input }],
5283
- Template: [{ type: Input }],
5284
5361
  Context: [{ type: Input }],
5285
- onCellGeneration: [{ type: Output }],
5286
- Visible: [{ type: Input }]
5362
+ onCellGeneration: [{ type: Output }]
5287
5363
  };
5288
5364
 
5289
5365
  // Angular
@@ -5341,12 +5417,148 @@ EstLookupPipe.decorators = [
5341
5417
  { type: Pipe, args: [{ name: 'est_lookup' },] }
5342
5418
  ];
5343
5419
 
5420
+ class EstRouterLinkPipe {
5421
+ constructor() {
5422
+ /** Cache per i routerLink generati nelle tabelle dinamiche */
5423
+ this.routerLinksCache = {};
5424
+ }
5425
+ transform(item, path, parameters) {
5426
+ if (this.routerLinksCache[item._hash + path]) {
5427
+ return this.routerLinksCache[item._hash + path];
5428
+ }
5429
+ else {
5430
+ let link = this.getRouterLink(path, parameters, item);
5431
+ this.routerLinksCache[item._hash + path] = link;
5432
+ return link;
5433
+ }
5434
+ }
5435
+ /**
5436
+ * Crea un router link
5437
+ *
5438
+ * @param {string} path Path su cui navigare con eventuali parametri riferiti all'oggetto cotnestuale come {0}, {1}, ecc...
5439
+ * @param {string[]} pars Lista posizionale delle proprietà a cui bindare i riferimenti del parametro **path**
5440
+ * Es. Il valore dela proprietà all'indice 0 di questo array verrà sostituita al valore {0} del parametro **path**
5441
+ * @param {any} item Oggetto collegato a questo contesto. Può essere un oggetto generico (con "properties") o un oggetto ben definito
5442
+ *
5443
+ * @returns {any} Router link generato in base al parametri
5444
+ */
5445
+ getRouterLink(path, pars, item) {
5446
+ for (let i = 0; i < pars.length; i++)
5447
+ path = path.replace('{' + i + '}', item.properties ? item.properties[pars[i]] : item[pars[i]]);
5448
+ path = path.replace(/'/g, '"').replace(/ /g, '');
5449
+ return JSON.parse(path);
5450
+ }
5451
+ }
5452
+ EstRouterLinkPipe.decorators = [
5453
+ { type: Pipe, args: [{ name: 'est_routerlink' },] }
5454
+ ];
5455
+
5456
+ // Angular
5457
+ class EstRendererPipe {
5458
+ constructor(logger) {
5459
+ this.logger = logger;
5460
+ }
5461
+ transform(propName, params) {
5462
+ var EsTd = null;
5463
+ // Perf. Version di `params.src.find((item) => params.name ? item.td === params.name : item.tdForProperty === propName);`
5464
+ for (let i = 0; i < params.src.length; i++) {
5465
+ let item = params.src.get(i);
5466
+ if (params.name && item.td === params.name ||
5467
+ !params.name && item.tdForProperty === propName) {
5468
+ EsTd = item;
5469
+ break;
5470
+ }
5471
+ }
5472
+ // Name non trovato, fallback al nome della colonna
5473
+ if (propName && params.name && !EsTd) {
5474
+ this.logger.log(`Renderer retrieved in a non performant way`);
5475
+ EsTd = params.src.find((item) => item.tdForProperty === propName);
5476
+ }
5477
+ this.logger.log(`Renderer ${EsTd ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!EsTd ? '. Using fallback renderer' : ''}`);
5478
+ var ret = EsTd ? EsTd.Template : params.fallback;
5479
+ return ret;
5480
+ }
5481
+ }
5482
+ EstRendererPipe.decorators = [
5483
+ { type: Pipe, args: [{ name: 'est_renderer' },] }
5484
+ ];
5485
+ EstRendererPipe.ctorParameters = () => [
5486
+ { type: Logger }
5487
+ ];
5488
+
5489
+ // Angular
5490
+ class EstEditorPipe {
5491
+ constructor(logger) {
5492
+ this.logger = logger;
5493
+ }
5494
+ transform(propName, params) {
5495
+ var Editor = null;
5496
+ // Perf. Version di `params.src.find((item) => params.name ? item.editor === params.name : item.editorForProperty === propName);`
5497
+ for (let i = 0; i < params.src.length; i++) {
5498
+ let item = params.src.get(i);
5499
+ if (params.name && item.editor === params.name ||
5500
+ !params.name && item.editorForProperty === propName) {
5501
+ Editor = item;
5502
+ break;
5503
+ }
5504
+ }
5505
+ // Name non trovato, fallback al nome della colonna
5506
+ if (propName && params.name && !Editor) {
5507
+ this.logger.log(`Editor retrieved in a non performant way`);
5508
+ Editor = params.src.find((item) => item.editorForProperty === propName);
5509
+ }
5510
+ this.logger.log(`Editor ${Editor ? 'found' : 'NOT found'} for '${propName}${params.name ? '/' + params.name : ''}'${!Editor ? '. Using fallback editor' : ''}`);
5511
+ var ret = Editor ? Editor.Template : params.fallback;
5512
+ return ret;
5513
+ }
5514
+ }
5515
+ EstEditorPipe.decorators = [
5516
+ { type: Pipe, args: [{ name: 'est_editor' },] }
5517
+ ];
5518
+ EstEditorPipe.ctorParameters = () => [
5519
+ { type: Logger }
5520
+ ];
5521
+
5522
+ const MODULES = [
5523
+ CommonModule,
5524
+ FormsModule,
5525
+ RouterModule,
5526
+ LocalizationModule,
5527
+ ModalModule,
5528
+ BsDropdownModule,
5529
+ ContextMenuModule,
5530
+ MatSelectModule,
5531
+ MatInputModule,
5532
+ MatTooltipModule,
5533
+ DragDropModule,
5534
+ FormsAndValidationsModule
5535
+ ];
5536
+ const PUBLIC_ELEMENTS = [
5537
+ // Direttive
5538
+ EsTdDirective,
5539
+ EsThDirective,
5540
+ EsTdEditorDirective,
5541
+ // Componenti
5542
+ EsTableComponent,
5543
+ TablePagerComponent,
5544
+ EsTableTemplate
5545
+ ];
5546
+ const PRIVATE_ELEMENTS = [
5547
+ // Componenti
5548
+ EsTh,
5549
+ EsTd,
5550
+ // Pipes
5551
+ EstFormatPipe,
5552
+ EstLookupPipe,
5553
+ EstRouterLinkPipe,
5554
+ EstRendererPipe,
5555
+ EstEditorPipe
5556
+ ];
5344
5557
  class EsTableModule {
5345
5558
  static forRoot(config) {
5346
5559
  return {
5347
5560
  ngModule: EsTableModule,
5348
5561
  providers: [
5349
- CopyPasteDetector,
5350
5562
  { provide: EST_LOCALE, useValue: (config === null || config === void 0 ? void 0 : config.locale) || 'it-IT' },
5351
5563
  { provide: EST_DEBUG, useValue: (config === null || config === void 0 ? void 0 : config.debugMode) || false },
5352
5564
  { provide: EST_DEFAULTS, useValue: (config === null || config === void 0 ? void 0 : config.defaults) || null },
@@ -5356,23 +5568,10 @@ class EsTableModule {
5356
5568
  }
5357
5569
  EsTableModule.decorators = [
5358
5570
  { type: NgModule, args: [{
5359
- imports: [
5360
- CommonModule,
5361
- FormsModule,
5362
- RouterModule,
5363
- LocalizationModule,
5364
- ModalModule,
5365
- BsDropdownModule,
5366
- ContextMenuModule,
5367
- MatSelectModule,
5368
- MatInputModule,
5369
- MatTooltipModule,
5370
- DragDropModule,
5371
- FormsAndValidationsModule
5372
- ],
5373
- declarations: [EsTh, EsTd, EsTableComponent, EsTdDirective, EsThDirective, EsTdEditorDirective, TablePagerComponent, EsTableTemplate, EstFormatPipe, EstLookupPipe],
5571
+ imports: [MODULES],
5572
+ declarations: [...PUBLIC_ELEMENTS, ...PRIVATE_ELEMENTS],
5374
5573
  providers: [UtilityService, ExportService, HashingService, MessageService],
5375
- exports: [EsTableComponent, EsTdDirective, EsThDirective, EsTdEditorDirective, TablePagerComponent, EsTableTemplate]
5574
+ exports: [...PUBLIC_ELEMENTS]
5376
5575
  },] }
5377
5576
  ];
5378
5577
 
@@ -5458,5 +5657,5 @@ class ItemPropEditableReference {
5458
5657
  * Generated bundle index. Do not edit.
5459
5658
  */
5460
5659
 
5461
- 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, TablePagerLoc as ɵa, EST_LOCALE as ɵb, EST_DEBUG as ɵc, EST_DEFAULTS as ɵd, EsTableLoc as ɵe, UtilitiesHandler as ɵf, CopyPasteDetector as ɵg, EsTh as ɵh, EsTd as ɵi, EstFormatPipe as ɵj, EstLookupPipe as ɵk };
5660
+ 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, TablePagerLoc as ɵa, EST_LOCALE as ɵb, EST_DEBUG as ɵc, EST_DEFAULTS as ɵd, EsTableLoc as ɵe, UtilitiesHandler as ɵf, CopyPasteDetector as ɵg, Logger as ɵh, EsTh as ɵi, EsTd as ɵj, EstFormatPipe as ɵk, EstLookupPipe as ɵl, EstRouterLinkPipe as ɵm, EstRendererPipe as ɵn, EstEditorPipe as ɵo };
5462
5661
  //# sourceMappingURL=esfaenza-es-table.js.map