GB_AGGridSQLWidget_mod

Widget HTML5/CWP per AVEVA Wonderware / System Platform basato su AG Grid.

Struttura:
- GB_AGGridSQLWidget_mod/index.html
- GB_AGGridSQLWidget_mod/widget.wjson
- GB_AGGridSQLWidget_mod/build/build.min.js
- GB_AGGridSQLWidget_mod/build/build.min.css
- resources/libs/ag-grid-community.min.js
- resources/libs/ag-grid.css
- resources/libs/ag-theme-quartz.css

Contratto Widget Properties allineato a GBRevoGrid:
- Columns: JSON array di definizioni colonna.
- ColumnsWidths: lista opzionale di larghezze separate da pipe; se valorizzata sovrascrive width/size in Columns.
- Data: JSON array di righe.
- FontSize, HeaderHeight, HeaderFontSize, RowHeight: aspetto griglia.
- IsDirty: scritto dal widget quando una cella viene modificata.
- IsEditable: abilita/disabilita editing.
- IsDebugMode: abilita log console.
- ColumnsProperties: JSON array di attributi aggiuntivi colonna.
- ColumnsOptions: JSON array di opzioni dropdown per colonna.
- ConditionalCellStyles: JSON array di regole per cambiare stile testo/sfondo cella in base ai dati della riga.
- SelectedRowIndex: indice della riga dell'ultima cella cliccata/modificata, -1 se non disponibile.
- SelectedColumnField: nome campo/colonna dell'ultima cella cliccata/modificata.
- SelectedCellValue: valore dell'ultima cella cliccata/modificata, come stringa.

- RowsToSelect: righe da evidenziare/selezionare nel formato <nome_campo>=<valore_1>|<valore_2>|..., ad esempio Articolo=45A|45C oppure Ordine=OPR26-29889. Per compatibilita, il campo Ordine viene riconosciuto anche quando la colonna e esposta come OdP.
- Per i selettori ordine, SelectedRowBackgroundColor viene applicato solo alle righe con Ord/Ordine/OdP uguale a uno degli ordini estratti. Le righe non corrispondenti mantengono i colori alternati anche dopo un click. Il mapping DOM usa esclusivamente row-index e non aria-rowindex, che include l'offset dell'intestazione AG Grid.

Il widget non apre connessioni SQL Server e non usa fetch/XMLHttpRequest.
La connessione diretta a SQL Server deve essere gestita lato HMI/System Platform,
poi i risultati devono essere scritti nella property Data e le colonne nella property Columns.


Rigenerato con struttura compatibile con New-CwpFromFolder_CORRETTO.ps1: entry ZIP con backslash, cartella radice inclusa e senza directory-entry esplicite. Le librerie sono in ./resources/libs rispetto al widget.


FIX COLORI:
- Aggiunta alternanza colori righe personalizzabile.
- Nuove Widget Properties: HeaderBackgroundColor, HeaderTextColor, OddRowBackgroundColor, EvenRowBackgroundColor, SelectedRowBackgroundColor, RowTextColor, BorderColor.
- Archivio CWP generato con logica compatibile con New-CwpFromFolder_CORRETTO.ps1.

FIX STILI CONDIZIONALI CELLA:
- Aggiunta Widget Property ConditionalCellStyles.
- Dopo la modifica di una cella il widget forza il refresh delle celle, così gli stili condizionali vengono ricalcolati subito.
- Il parser accetta anche JSON passato da AVEVA come stringa tra virgolette.
- Il parser accetta anche stringhe AVEVA con doppie virgolette interne, ad esempio "[{""field"":""Valore""}]".
- ColumnsProperties accetta sia JSON array sia lista separata da pipe, ad esempio {"editable":false}|{"filter":false}.
- Le larghezze esplicite delle colonne width/size/minWidth non vengono piu sovrascritte da sizeColumnsToFit.
- ColumnsWidths puo essere collegata direttamente dal wrapper al widget interno: GB_AGGridSQLWidget_mod1.ColumnsWidths = ColumnsWidths.
- FontSize aggiorna sia le classi CSS sia la variabile AG Grid --ag-font-size.
- Quando ColumnsWidths e valorizzata, width/minWidth/maxWidth vengono impostati allo stesso valore per rendere visibile il ridimensionamento anche sotto i limiti minimi del tema AG Grid.
- FontSize viene applicato anche a .ag-cell-value, .ag-cell-wrapper, .ag-cell-edit-wrapper e agli input editor.
- Gli stili condizionali riconoscono i nomi campo anche con differenze di accento/maiuscole, ad esempio Quantità e Quantita.
- ColumnsProperties ora rispetta editable:false, readonly:true, readOnly:true, filter:false, filterable:false e isFilterable:false.
- Formato:
  [
    {"targetField":"Quantità","when":{"field":"Note","operator":"notEmpty"},"textColor":"#ff0000"},
    {"targetField":"Quantità","when":{"field":"Quantità","operator":">","value":300},"textColor":"#ff0000","backgroundColor":"#fff2cc"}
  ]
- Campi supportati: targetField/target/column, when.field, when.operator, when.value, textColor/color, backgroundColor/bgColor, fontWeight, fontStyle, elseTextColor/elseColor, elseBackgroundColor/elseBgColor, elseFontWeight, elseFontStyle.
- Operatori supportati: notEmpty, empty, notNull, isNull, equals, notEquals, contains, startsWith, endsWith, in, notIn, >, >=, <, <=.

FIX DATI SELEZIONATI:
- Aggiunte Widget Properties SelectedRowIndex, SelectedColumnField, SelectedCellValue e SelectedRowData.
- Il widget aggiorna queste properties su click cella, click riga, cambio selezione e modifica cella.
- Gli eventi di riga aggiornano solo SelectedRowData/SelectedRowIndex e non svuotano piu SelectedColumnField/SelectedCellValue valorizzati dal click cella.
- Nel simbolo wrapper collegare le properties interne a Custom Properties pubbliche se devono essere lette da script HMI o da simboli che importano il simbolo base.

FIX EDIT/FILTER:
- Quando IsEditable diventa false, il widget interrompe eventuali edit in corso e rigenera le colonne come non editabili.
- Quando IsFilterable diventa false, il widget pulisce i filtri attivi e rigenera le colonne senza filtro.
- La logica di editabilita e deny-by-default: una colonna e editabile solo se IsEditable=true e la colonna ha {"editable":true}.
- Esempio: per rendere editabili solo qta e Note aggiuntive, impostare IsEditable=true e mettere {"editable":true} solo sulle relative colonne.
- Quando IsFilterable=false, vengono disabilitati filter, floatingFilter, pulsante filtro header e tab menu delle colonne.
- Per compatibilita con la schermata di produzione, con IsEditable=true il widget riconosce anche direttamente le colonne qta/quantita e Note aggiuntive/Note produzione come editabili.
- Quando IsFilterable=false, il widget nasconde anche via CSS le icone filtro residue renderizzate da AG Grid nel runtime HMI.
