Overview

List Grid

Componente principale per liste tabellari con filtri, sorting, paging server-side e azioni riga.

Use cases

  • CRUD tabellari enterprise.
  • Report operativi con filtri multi-colonna.
  • Dataset molto grandi con cursorMode.

Screenshot reference (manuale utente)

  • manual__grid__01.png: modalita inline cell edit in list-grid.
  • manual__grid__02.png: modalita inline edit (row-level) in list-grid.

Metadati inline editing

Configurazione nel md_props_bag della tabella metadata:

  • md_inline_edit

- abilita l'editing inline della riga in list-grid (celle editabili in contesto riga, senza apertura popup).

- utile quando vuoi mantenere la UX di tabella con editing rapido per record.

  • md_inline_cell_edit

- abilita l'editing inline "cell-by-cell" (focus sulla singola cella).

- nota: nelle configurazioni legacy puo comparire come md_inline_cell_editing; il comportamento runtime e lo stesso.

- promozione runtime: quando md_inline_cell_edit e true, il componente forza

a runtime anche md_inline_edit = true indipendentemente dal valore in DB.

Entrambe le UX hanno bisogno della action column visibile, quindi sono mutualmente

non-esclusive a livello di rendering.

  • md_batch_save

- abilita il salvataggio batch delle modifiche pendenti (Save changes / Cancel changes).

- se usato insieme a inline-cell, le modifiche restano pending fino al salvataggio esplicito.

- prerequisito: md_batch_save ha effetto solo se md_inline_cell_edit e true.

Con md_inline_cell_edit:false il flag viene ignorato a runtime e i bottoni

"Salva modifiche / Annulla modifiche" non vengono renderizzati.

Combinazioni valide

md_inline_editmd_inline_cell_editmd_batch_saveRisultato runtime
truefalsequalsiasiRow-level inline edit con pencil. md_batch_save ignorato.
falsetruefalseCell-by-cell autosave on blur. md_inline_edit forzato a true a runtime.
falsetruetrueCell-by-cell con buffer pending + toolbar Salva / Annulla modifiche.
falsefalsequalsiasiNessun inline editing. md_batch_save ignorato.

Esempio row-level inline edit:

Snippet 1JSON
{
  "md_inline_edit": true,
  "md_inline_cell_edit": false,
  "md_batch_save": false
}

Esempio cell-by-cell con batch save:

Snippet 2JSON
{
  "md_inline_edit": false,
  "md_inline_cell_edit": true,
  "md_batch_save": true
}

Toolbar export/import

  • Export XLS:

- mostra dialog di progress con percentuale realtime;

- azioni: Continua in background, Annulla task, Interrompi e scarica parziale;

- in background crea una notifica con progress; click riapre il dialog.

  • Import XLS/XLSX (se md_importable = true):

- dialog di progress dopo la conferma;

- azioni: Continua in background, Annulla import (rollback), Stop e commit parziale;

- a fine import crea una notifica di riepilogo che porta alla route.

Config metadata

Impostazioni chiave in md_props_bag e metadati colonna.

Snippet 3JSON
{
  "serverProperties": {
    "queryOptimization": {
      "enabled": true,
      "countPolicy": "cursor",
      "sqlServerHint": "none"
    }

md_props_bag: toolbar

Flag opt-in che nascondono blocchi della toolbar della list-grid (caption-bar). Tutti sotto md_props_bag.toolbar.* (parsato in runtime come tableMetadata.extraProps.toolbar).

Snippet 4JSON
{
  "toolbar": {
    "hideManageState": true,
    "hideBatchActions": true
  }
}
  • hideManageState (boolean, default false): nasconde nella caption-right il bottone "Gestione stato" (icona bookmark) + la <select> degli stati salvati. Utile per route hardcoded / demo dove il saved-state feature (persistenza per user_id + route via MetaService) non ha senso — es. Pattern 3 puro OData senza route metadata registrata.
  • hideBatchActions (boolean, default false): nasconde nella caption-left i pulsanti "Salva modifiche" (pi-save) + "Annulla modifiche" (pi-times) + l'indicatore conteggio changes (grid-changes-indicator, badge pencil + count). Generati dal framework quando md_inline_cell_editing + md_batch_save sono attivi. Pensato per nested grid in parametric-dialog: il save/cancel del padre persiste master + righe in un colpo via batch save framework, e i pulsanti duplicati sulla nested grid confondono l'UX.

Esempio nested rows in custom edit-form (runtime patch):

Snippet 5ts
this.righeDs.metaInfo.tableMetadata.extraProps = Object.assign(
  this.righeDs.metaInfo.tableMetadata.extraProps || {},
  { toolbar: { hideManageState: true, hideBatchActions: true } }
) as any;

Tipo TS in `metadati_tabella.ts` (proprieta extraProps.toolbar). I flag NON disabilitano la logica md_batch_save sottostante (changes restano tracciate); rimuovono solo l'UI toolbar — il save effettivo passa dal flusso del padre.

md_props_bag: archetypes.list

Il componente legge md_props_bag.archetypes.list.

Snippet 6JSON
{
  "archetypes": {
    "list": {
      "proportionalColwidth": true,
      "advancedFilter": false,
      "virtualize": {
        "enabled": true,
  • proportionalColwidth:
  • tipo: boolean (con parser tollerante)
  • valori accettati: true, false, 1, 0, "true", "false", "1", "0"
  • default runtime: true quando assente o vuoto
  • effetto: distribuisce le larghezze colonna in percentuale (anziche px) quando non ci sono larghezze utente persistite.
  • virtualize:
  • tipo: boolean oppure object
  • valori accettati:
  • true/false, 1/0, "true"/"false", "1"/"0"
  • object con enabled (opzionale) e itemSize (opzionale)
  • default runtime: disabilitato (false) quando assente
  • enabled:
  • default: true se il nodo virtualize e object senza enabled, altrimenti parser tollerante
  • effetto: abilita virtualScroll su p-table
  • itemSize:
  • default: 44
  • effetto: imposta virtualScrollItemSize (altezza riga virtuale in px)
  • advancedFilter:
  • tipo: boolean (con parser tollerante)
  • default runtime: false
  • effetto:
  • quando true, la griglia nasconde le icone filtro colonna (p-columnFilter) e usa la wuic-filter-bar sopra la tabella (a livello data-repeater/bounded-repeater) per applicare i filtri.

Nota operativa:

  • il suggest md_props_bag nel metadata editor espone anche il nodo checkabile archetypes.list.advancedFilter.

Paging: md_pagesize e md_page_size_choice

La griglia usa md_pagesize come dimensione pagina di default e md_page_size_choice come elenco valori selezionabili nel paginator.

Regole runtime:

  • se md_pagesize e maggiore del valore massimo presente in md_page_size_choice, il framework aggiunge automaticamente md_pagesize alla lista opzioni;
  • la lista viene normalizzata (numeri validi, deduplica, ordinamento crescente).

Esempio:

  • md_pagesize = 200
  • md_page_size_choice = "10,25,50,100"
  • risultato runtime: 10,25,50,100,200

Forzatura virtualizzazione su page size alto

Quando l'utente seleziona nel paginator un valore pageSize >= 1000:

  • la virtualizzazione viene forzata automaticamente anche se md_props_bag.archetypes.list.virtualize e assente o disabilitato;
  • virtualScrollItemSize viene forzato al valore predefinito 44.

Questo comportamento protegge la resa della tabella su pagine molto grandi.

Eventi e subscriptions (host)

wuic-list-grid espone eventi runtime utili per intercettare ciclo render e callback p-table lato progetto host.

Eventi disponibili:

  • onAfterRender: emesso a fine binding dati della griglia (rows, totalRecords, metaInfo, datasource).
  • onBeforeRowRender: emesso prima del rendering logico della singola riga; supporta cancel tramite event.cancelRender().
  • onAfterRowRender: emesso dopo il rendering logico della singola riga.
  • onPaging: emesso sugli eventi paging (p-table onPage).
  • onSorting: emesso sugli eventi sorting (p-table onSort).
  • onFiltering: emesso sugli eventi filtering (p-table onFilter).
  • onPTableSelectionChange: emesso su cambio selezione righe.
  • onPTableRowExpand: emesso su expand riga.
  • onPTableRowCollapse: emesso su collapse riga.
  • onPTableColumnResize: emesso su resize colonna.
  • onPTableColumnReorder: emesso su reorder colonne.

Esempio 1: binding diretto nel template

Snippet 7HTML
<wuic-list-grid
  [hardcodedDatasource]="citiesDs"
  (onAfterRender)="handleAfterRender($event)"
  (onBeforeRowRender)="handleBeforeRowRender($event)"
  (onAfterRowRender)="handleAfterRowRender($event)"
  (onPaging)="handlePaging($event)"
  (onSorting)="handleSorting($event)"

Esempio 2: subscribe via ViewChild

Snippet 8ts
import { AfterViewInit, OnDestroy, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs';
import {
  ListGridAfterRenderEvent,
  ListGridAfterRowRenderEvent,
  ListGridBeforeRowRenderEvent,
  ListGridComponent

rowCustomSelect — signature reale (gotcha)

<wuic-list-grid> accetta un input [rowCustomSelect] per intercettare la selezione di una riga (apertura dialog "scegli documento", master-detail, ecc.). La firma TypeScript dichiarata in list-grid.component.ts:140 è:

Snippet 9ts
@Input() rowCustomSelect: (rowData: any, $event: any, dt: Table) => void;

Pero' a runtime la callback viene invocata con argomenti invertiti — il framework chiama rowCustomSelect($event, rowData, dt) (vedi dynamic-template.component.ts:447 e dynamic-card-template.component.ts:205).

Sintomo se sbagli ordine: rowData?.id e' undefined → guard precoce nel handler → la callback ritorna senza side-effect e la dialog/azione non parte. Nessun errore in console.

Forma corretta (allineata all'invocazione runtime):

Snippet 10ts
onRowSelected = (_event: any, rowData: any, _dt: any): void => {
  // rowData e' il record dato dalla list-grid
  this.handleSelection(rowData);
};

Esempio integrato nel template:

Snippet 11HTML
<wuic-data-source #ds [hardcodedRoute]="'preventivi'" [autoload]="true"></wuic-data-source>
<wuic-list-grid [hardcodedDatasource]="ds" [rowCustomSelect]="onRowSelected"></wuic-list-grid>

> Note: i test in designer.component.spec.ts (es. riga 512) chiamano la callback con ({currentTarget: rowCell}, {id: 42}, null) confermando l'ordine ($event, rowData, dt). Se in futuro il framework dovesse uniformare la signature dichiarata, si aggiornera' anche questa pagina.

Screenshot

List grid - interazione base
List grid - interazione base
list-grid / list-grid-main
list-grid / list-grid-main
list-grid / manual-grid-01
list-grid / manual-grid-01
list-grid / manual-grid-02
list-grid / manual-grid-02