Overview
Custom Actions
Il framework permette di aggiungere azioni personalizzate sopra una <wuic-list-grid>. Esistono due tipi distinti, con tabella metadata e firma callback diverse:
- Table action (azione di tabella / bulk): bottone nella toolbar sopra la griglia, opera su selezione multipla o sull'intera vista.
- Row action (azione di riga): bottone su ogni riga, opera sul singolo record.
> La distinzione è importante: _mtdt__cstom__actions__tabelle contiene solo table-action. Per una row-action si crea invece una colonna virtuale in _metadati__colonne. Non esiste un campo di scope in _mtdt__cstom__actions__tabelle: un'azione inserita lì è sempre una table-action, anche se il callback usa record.
Table action (toolbar / bulk)
Si registra in _mtdt__cstom__actions__tabelle. Il callback ha questa firma:
function (datasource, metaInfo, record, event, wtoolbox) {
// datasource : il DataSourceComponent della griglia
// metaInfo : metadati tabella/colonne
// record : record correnti / selezionati
// event : evento UI
// wtoolbox : servizi framework (notifiche, dialog, ...)
}- Per abilitare la selezione multipla sulla griglia imposta
mdmultipleselection=1sulla tabella metadata. - Per rinfrescare la UI dopo l'azione usa
datasource.fetchData()(NONrefresh()). - Per un toast di conferma usa
wtoolbox.messageNotificationService.add().
async function (datasource, metaInfo, record, event, wtoolbox) {
const ids = (datasource.resultInfo?.selected || []).map(r => r.id.value);
await fetch('/api/Custom/bulkApprove', { method: 'POST', body: JSON.stringify(ids) });
await datasource.fetchData();
wtoolbox.messageNotificationService.add({ severity: 'success', summary: 'Approvati', detail: ids.length + ' record' });
}Row action (bottone per riga)
Si crea come colonna virtuale in _metadati__colonne:
mc_ui_column_type = 'button'mc_voa_class = 6(classe della colonna-bottone)- callback nel campo
mcbuttonaction(text)
Il callback riceve il record della riga ed è quindi adatto ad azioni single-record (stampa singola riga, apertura dialog one-click, cambio stato del record corrente).
-- esempio: bottone "Stampa" su ogni riga di fatture_inviate
INSERT INTO _metadati__colonne (md_id, mc_nome_colonna, mc_ui_column_type, mc_voa_class, mcbuttonaction, mc_ordine)
VALUES (@md_id, 'print_action', 'button', 6, '<callback JS>', 100);Tabella di confronto
| Table action | Row action | |
|---|---|---|
| Tabella metadata | _mtdt__cstom__actions__tabelle | _metadati__colonne (colonna virtuale) |
| Posizione UI | toolbar sopra la griglia | bottone su ogni riga |
| Scope | selezione multipla / vista | singolo record |
| Callback | (datasource, metaInfo, record, event, wtoolbox) | callback in mcbuttonaction, riceve il record |
| Multi-select | mdmultipleselection=1 | n/a |
| Refresh UI | datasource.fetchData() | datasource.fetchData() |
Vedi anche
- List grid — la griglia su cui agiscono le azioni.
- Metadata integration — modello dei metadati tabelle/colonne.
<!-- incode-injection -->
Iniezione in-code (solo questo componente)
Le table action si possono iniettare anche direttamente nel `.ts` del componente, senza patch SQL. Differenza fondamentale: la patch SQL su _mtdt__cstom__actions__tabelle rende l'azione visibile in ogni componente che usa quella route (persistente, route-wide); l'iniezione in-code la limita a questo solo componente.
L'azione è un elemento dell'array metaInfo.tableMetadata._Metadati_Custom_Actions_Tabelles (già inizializzato a []). Campi della classe MetadatiCustomActionTabella: button_caption (etichetta, obbligatorio), button_image? (icona PrimeNG), action_callback__fn — la FUNZIONE eseguita al click, firma (datasource, metaInfo, record, event, wtoolbox) => void (non una stringa; la variante stringa serializzata è action_callback), disable_callback__fn? per disabilitare condizionalmente, ordine?.
Wiring: ottieni il DataSourceComponent con @ViewChild('ds', { static: true }) e fai il push in `ngOnInit` (NON ngAfterViewInit) quando fetchInfo$ pubblica i metadati — così la patch precede il primo render della <wuic-list-grid> figlia (che si iscrive a fetchInfo$ nel suo ngOnInit, dopo quello del padre). Guard idempotente .some(...) perché fetchInfo$ riemette. Refresh UI con datasource.fetchData() (non refresh()).
import { Component, ViewChild, OnInit } from '@angular/core';
import { DataSourceComponent, ListGridComponent } from 'wuic-framework-lib';
@Component({
selector: 'app-aziende-grid',
imports: [DataSourceComponent, ListGridComponent],
template: `Iniezione in-code — row action (bottone per riga)
La row action (bottone su ogni riga) si inietta in-code come colonna virtuale bottone in metaInfo.columnMetadata — non in _Metadati_Custom_Actions_Tabelles (quello è solo toolbar/bulk).
⚠️ Differenza critica rispetto alla versione DB. La stringa mcbuttonaction viene compilata in mc_button_action__fn da MetadataProviderService solo al caricamento dei metadati dal DB. Una colonna pushata in ngOnInit è dopo quel load → la stringa non viene mai compilata, e DataActionButtonComponent (che richiede mc_button_action__fn in isMetadataButtonEnabled) lascia il bottone disabilitato. Quindi in-code si imposta direttamente la FUNZIONE `mc_button_action__fn`, non la stringa.
Campi della button column (runtime, classe MetadatiColonna):
mc_ui_column_type: 'button'mc_button_caption— etichetta del bottone (senza → label =mc_nome_colonna, es."rinnova_action"invece di"Rinnova")mc_button_image?— icona PrimeNG (es.'pi pi-refresh')mc_button_action__fn— la FUNZIONE eseguita al click, firma(datasource, record, event, field, wtoolbox) => void(NON la stringamcbuttonaction/mc_button_action)mc_button_confirm_message?,mc_button_visibility_condition?— opzionali
record nel callback è { [col]: BehaviorSubject<any> } → leggi i valori con record['<col>']?.value (la PK con record['<PK>']?.value).
ngOnInit() {
this.ds.fetchInfo$.subscribe(info => {
if (!info?.metaInfo) return;
const cols = info.metaInfo.columnMetadata;
if (cols.some(c => c.mc_nome_colonna === 'rinnova_action')) return; // idempotente (BehaviorSubject riemette)
cols.push({
mc_nome_colonna: 'rinnova_action',Versus la versione DB (sezione "Row action" sopra): lì la callback è la stringa mcbuttonaction, compilata dal framework al load. Le due strade NON sono intercambiabili: DB = stringa `mcbuttonaction`, in-code = funzione `mc_button_action__fn`.