@esfaenza/es-table 20.3.15 → 20.3.17

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.
@@ -6593,6 +6593,11 @@ class EsTable2Component {
6593
6593
  // ===========================================================================
6594
6594
  this.onChange = () => { };
6595
6595
  this.onTouched = () => { };
6596
+ // ===========================================================================
6597
+ // ControlValueAccessor
6598
+ // ===========================================================================
6599
+ /** Timeout di debounce del writeValue in modalità EsTableHandledSearch */
6600
+ this.searchCallTimeout = null;
6596
6601
  /** Ancora per la selezione a range stile Windows (Shift+click) */
6597
6602
  this.selectionAnchor = null;
6598
6603
  // ===========================================================================
@@ -6630,6 +6635,9 @@ class EsTable2Component {
6630
6635
  left: Math.min(s.a.c, s.f.c), right: Math.max(s.a.c, s.f.c)
6631
6636
  };
6632
6637
  }, ...(ngDevMode ? [{ debugName: "rangeRect" }] : []));
6638
+ /** true se il mousedown corrente è un click sulla singola cella già selezionata
6639
+ * (→ un click senza trascinamento la deseleziona) */
6640
+ this.rangeClickToggle = false;
6633
6641
  /** Avviso transitorio mostrato in un piccolo toast (es. incolla incompatibile) */
6634
6642
  this.notice = signal(null, ...(ngDevMode ? [{ debugName: "notice" }] : []));
6635
6643
  this.noticeTimer = null;
@@ -6667,6 +6675,8 @@ class EsTable2Component {
6667
6675
  this.headerRO?.disconnect();
6668
6676
  if (this.noticeTimer)
6669
6677
  clearTimeout(this.noticeTimer);
6678
+ if (this.searchCallTimeout)
6679
+ clearTimeout(this.searchCallTimeout);
6670
6680
  }
6671
6681
  /** Risoluzione input: valore esplicito || default di progetto || hard default */
6672
6682
  io(v, d, hard) {
@@ -6677,10 +6687,17 @@ class EsTable2Component {
6677
6687
  this.thDirectives?.changes.subscribe(() => { this.buildColumns(); this.refresh(); });
6678
6688
  this.tdDirectives?.changes.subscribe(() => { this.buildColumns(); this.refresh(); });
6679
6689
  }
6680
- // ===========================================================================
6681
- // ControlValueAccessor
6682
- // ===========================================================================
6683
- writeValue(obj) {
6690
+ writeValue(obj, throttle = true) {
6691
+ // Modalità EsTableHandledSearch: il writeValue viene debouncato (come l'originale),
6692
+ // così binding ravvicinati non generano ricerche a raffica.
6693
+ if (this.EsTableHandledSearch() && throttle) {
6694
+ if (this.searchCallTimeout)
6695
+ clearTimeout(this.searchCallTimeout);
6696
+ this.searchCallTimeout = setTimeout(() => this.writeValue(obj, false), this.SearchThrottle());
6697
+ return;
6698
+ }
6699
+ // È arrivato un nuovo modello → nessuna ricerca "in progress"
6700
+ this.researchInProgress.set(false);
6684
6701
  this.view.set(obj ?? null);
6685
6702
  this.detectMode(obj);
6686
6703
  this.syncOrdersFromView();
@@ -6688,11 +6705,59 @@ class EsTable2Component {
6688
6705
  if (obj)
6689
6706
  this.firstBind.set(false);
6690
6707
  this.cdr.markForCheck();
6708
+ // Auto-ricerca: la valorizzazione dell'ngModel chiede al consumer di cercare
6709
+ // (storicamente serviva ad applicare le preferenze colonne senza che il modello
6710
+ // in arrivo le sovrascrivesse). Il flag `selfsearch` evita loop; `firstsearch`
6711
+ // (true su `new AppSearch()`) salta l'auto-ricerca al primo bind.
6712
+ this.handleWriteValueAutoSearch();
6691
6713
  }
6692
6714
  registerOnChange(fn) { this.onChange = fn; }
6693
6715
  registerOnTouched(fn) { this.onTouched = fn; }
6694
6716
  setDisabledState() { }
6695
- changed() { this.onChange(this.view()); }
6717
+ /** Blocco auto-ricerca a fine writeValue (modalità EsTableHandledSearch) */
6718
+ handleWriteValueAutoSearch() {
6719
+ if (!this.EsTableHandledSearch() || !this.view())
6720
+ return;
6721
+ const v = this.view();
6722
+ if (!v.selfsearch && !v.firstsearch) {
6723
+ v.selfsearch = true;
6724
+ this.changed(true); // svuota gli items + propaga (mostra "vuoto" mentre cerca)
6725
+ this.onSearchRequest.emit(false);
6726
+ }
6727
+ else if (v.selfsearch) {
6728
+ v.selfsearch = false; // ricerca rientrata: azzero il guard
6729
+ this.changed();
6730
+ }
6731
+ }
6732
+ /**
6733
+ * Richiesta di ricerca (paging/ordinamento). In modalità EsTableHandledSearch
6734
+ * imposta il guard `selfsearch` così il writeValue di rientro non ri-cerca.
6735
+ */
6736
+ emitSearchRequest(arg) {
6737
+ this.researchInProgress.set(true);
6738
+ const v = this.view();
6739
+ if (v && !v.selfsearch && this.EsTableHandledSearch()) {
6740
+ v.selfsearch = true;
6741
+ this.changed(true);
6742
+ this.onSearchRequest.emit(false);
6743
+ }
6744
+ else {
6745
+ this.onSearchRequest.emit(arg);
6746
+ }
6747
+ }
6748
+ changed(clearItems = false) {
6749
+ if (clearItems && this.viewMode()) {
6750
+ const isp = this.ItemSourceProperty();
6751
+ const v = this.view();
6752
+ if (v) {
6753
+ if (!isp)
6754
+ v.items = [];
6755
+ else
6756
+ v[isp] = [];
6757
+ }
6758
+ }
6759
+ this.onChange(this.view());
6760
+ }
6696
6761
  // ===========================================================================
6697
6762
  // Mode & column model
6698
6763
  // ===========================================================================
@@ -7095,7 +7160,7 @@ class EsTable2Component {
7095
7160
  v.orders = list;
7096
7161
  v.internalsearchrequest = true;
7097
7162
  this.onOrderChanged.emit(new AppOrdering(col.id, next ?? undefined));
7098
- this.onSearchRequest.emit(false);
7163
+ this.emitSearchRequest(false);
7099
7164
  }
7100
7165
  else {
7101
7166
  this.refresh();
@@ -7116,7 +7181,7 @@ class EsTable2Component {
7116
7181
  const v = this.view();
7117
7182
  v.page = p;
7118
7183
  v.internalsearchrequest = true;
7119
- this.onSearchRequest.emit(false);
7184
+ this.emitSearchRequest(false);
7120
7185
  }
7121
7186
  else {
7122
7187
  this.arrayPage.set(p);
@@ -7130,7 +7195,7 @@ class EsTable2Component {
7130
7195
  v.itemsperpageoverride = n;
7131
7196
  v.page = 1;
7132
7197
  v.internalsearchrequest = true;
7133
- this.onSearchRequest.emit(false);
7198
+ this.emitSearchRequest(false);
7134
7199
  }
7135
7200
  else {
7136
7201
  this.ArraymodeItemsPerPage.set(n);
@@ -7394,6 +7459,11 @@ class EsTable2Component {
7394
7459
  // Una sola selezione alla volta: avviare un range azzera l'eventuale selezione di riga
7395
7460
  if (this.hasSelection)
7396
7461
  this.clearSelection();
7462
+ // Se ri-clicco l'unica cella già selezionata (range 1×1 su questa cella), un
7463
+ // click senza drag la deseleziona (gestito nel mouseup).
7464
+ const prev = this.rangeSel();
7465
+ this.rangeClickToggle = !!prev &&
7466
+ prev.a.r === co.r && prev.a.c === co.c && prev.f.r === co.r && prev.f.c === co.c;
7397
7467
  this.rangeDragging.set(true);
7398
7468
  this.rangeSel.set({ a: co, f: co });
7399
7469
  this.clearTextSelection();
@@ -7413,12 +7483,22 @@ class EsTable2Component {
7413
7483
  return;
7414
7484
  if (s.f.r === co.r && s.f.c === co.c)
7415
7485
  return; // nessun cambiamento → niente ricalcolo (no debounce necessario)
7486
+ this.rangeClickToggle = false; // è un drag, non un click di toggle
7416
7487
  this.rangeSel.set({ a: s.a, f: co });
7417
7488
  this.clearTextSelection();
7418
7489
  this.cdr.markForCheck();
7419
7490
  }
7420
- onDocMouseUp() { if (this.rangeDragging())
7421
- this.rangeDragging.set(false); }
7491
+ onDocMouseUp() {
7492
+ if (!this.rangeDragging())
7493
+ return;
7494
+ this.rangeDragging.set(false);
7495
+ // click (nessun drag) sull'unica cella già selezionata → deseleziona
7496
+ if (this.rangeClickToggle) {
7497
+ this.rangeClickToggle = false;
7498
+ this.rangeSel.set(null);
7499
+ this.cdr.markForCheck();
7500
+ }
7501
+ }
7422
7502
  flashNotice(msg) {
7423
7503
  this.notice.set(msg);
7424
7504
  this.cdr.markForCheck();