wuic-framework-lib 1.7.14 → 1.7.16
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.
- package/fesm2022/{wuic-framework-lib-chart-list.component-BEps71hL.mjs → wuic-framework-lib-chart-list.component-DKyCweHK.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-code-editor.component-c3x1X5O9.mjs → wuic-framework-lib-code-editor.component-DZCkJCeF.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-designer.component-CXHYNEm5.mjs → wuic-framework-lib-designer.component-CBH6VPF6.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-first-run-wizard.component-Hw4IM3po.mjs → wuic-framework-lib-first-run-wizard.component-tk1CynIi.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-framework-docs.component-BIULbCaM.mjs → wuic-framework-lib-framework-docs.component-GXDoB6Ry.mjs} +38 -18
- package/fesm2022/{wuic-framework-lib-pivot-builder.component-DP60RcD5.mjs → wuic-framework-lib-pivot-builder.component-LW0dR-JI.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-DysV00wF.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DWlKV-3c.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-report-designer.component-Cn3pUy16.mjs → wuic-framework-lib-report-designer.component-CsBJ6Y-O.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-report-scaffold-dialog.component-DdRrsp8w.mjs → wuic-framework-lib-report-scaffold-dialog.component-BkllSZe1.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-report-viewer.component-m-ianUWE.mjs → wuic-framework-lib-report-viewer.component-CXVRwUsg.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-scene3d-designer.component-DtFyJ3QF.mjs → wuic-framework-lib-scene3d-designer.component-C08YMpCG.mjs} +3 -3
- package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-I1Bidwkn.mjs → wuic-framework-lib-scene3d-light-baker-gpu-BGwU3xlr.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-B7uh74v4.mjs → wuic-framework-lib-scene3d-viewer.component-gAfNyKGn.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-scheduler-list.component-B6lWGWEd.mjs → wuic-framework-lib-scheduler-list.component-DaaYn4J1.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-Bpxi8la8.mjs → wuic-framework-lib-spreadsheet-list-sf.component-D8_lyL4X.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-timeline-list.component-DsvQ8Wro.mjs → wuic-framework-lib-timeline-list.component-BQk_5VXz.mjs} +4 -4
- package/fesm2022/{wuic-framework-lib-workflow-designer.component-DCQE7JQz.mjs → wuic-framework-lib-workflow-designer.component-DnmuNeX6.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-wuic-framework-lib-BlysiZLp.mjs → wuic-framework-lib-wuic-framework-lib-DyQrYx-t.mjs} +30 -22
- package/fesm2022/wuic-framework-lib.mjs +1 -1
- package/package.json +1 -1
|
@@ -16,12 +16,12 @@ import * as i1$3 from 'primeng/image';
|
|
|
16
16
|
import { ImageModule } from 'primeng/image';
|
|
17
17
|
import * as i8$1 from '@ngx-translate/core';
|
|
18
18
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
19
|
-
import { w as getThemeOptions, T as TranslationManagerService, U as UserInfoService } from './wuic-framework-lib-wuic-framework-lib-
|
|
19
|
+
import { w as getThemeOptions, T as TranslationManagerService, U as UserInfoService } from './wuic-framework-lib-wuic-framework-lib-DyQrYx-t.mjs';
|
|
20
20
|
import * as i1 from '@angular/router';
|
|
21
21
|
|
|
22
22
|
const frameworkDocsContent = {
|
|
23
23
|
"version": "1.0.0",
|
|
24
|
-
"generatedAt": "2026-09-
|
|
24
|
+
"generatedAt": "2026-09-26T12:41:59.450Z",
|
|
25
25
|
"groups": [
|
|
26
26
|
{
|
|
27
27
|
"id": "primi-passi",
|
|
@@ -2054,7 +2054,7 @@ const frameworkDocsContent = {
|
|
|
2054
2054
|
{
|
|
2055
2055
|
"id": "overview",
|
|
2056
2056
|
"title": "Overview",
|
|
2057
|
-
"html": "<h1>List Grid</h1><p>Componente principale per liste tabellari con filtri, sorting, paging server-side e azioni riga.</p><h2>Use cases</h2><ul><li>CRUD tabellari enterprise.</li><li>Report operativi con filtri multi-colonna.</li><li>Dataset molto grandi con <code>cursorMode</code>.</li></ul><h2>Cosa mostra la toolbar di default</h2><p>Aprendo una route appena scaffoldata, sopra la griglia c'e' la caption-bar. A sinistra:</p><table><thead><tr><th>Pulsante</th><th>Quando compare</th></tr></thead><tbody><tr><td><strong>Aggiorna</strong></td><td>sempre, salvo <code>md_hide_refresh</code></td></tr><tr><td><strong>Aggiungi</strong></td><td>con <code>md_insertable</code></td></tr><tr><td><strong>Azioni</strong></td><td>se la tabella ha custom action</td></tr><tr><td>Import / Export</td><td>sempre; il ramo import solo con <code>md_importable</code></td></tr><tr><td><strong>Report</strong></td><td>se alla route e' associato almeno un report</td></tr><tr><td><strong>Salva modifiche</strong> / <strong>Annulla modifiche</strong></td><td>solo con <code>md_inline_cell_edit</code> <strong>e</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A destra: <strong>Gestione stato</strong> (preceduto dalla tendina degli stati salvati, se ce ne sono),</p><p><strong>Pulisci filtri</strong> quando i filtri stanno sulle colonne, e <strong>Performance</strong> se l'inspector e'</p><p>abilitato sulla route.</p><p>> Le didascalie citate piu' sotto in questa pagina <strong>non si trovano su questo schermo</strong>, e non</p><p>> e' un difetto: quelle di export/import (<em>Continua in background</em>, <em>Annulla task</em>, *Interrompi</p><p>> e scarica parziale<em>, </em>Annulla import (rollback)<em>, </em>Stop e commit parziale*) vivono nella</p><p>> dialog di avanzamento, che esiste solo mentre un export o un import e' in corso; *Salva</p><p>> modifiche<em> e </em>Annulla modifiche* compaiono solo con i due flag qui sopra. Appartengono a</p><p>> momenti diversi dalla prima apertura della lista.</p><h2>Screenshot reference (manuale utente)</h2><ul><li><code>manual__grid__01.png</code>: modalita <code>inline cell edit</code> in list-grid.</li><li><code>manual__grid__02.png</code>: modalita <code>inline edit</code> (row-level) in list-grid.</li></ul><h2>Metadati inline editing</h2><p>Configurazione nel <code>md_props_bag</code> della tabella metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - abilita l'editing inline della riga in list-grid (celle editabili in contesto riga, senza apertura popup).</p><p> - utile quando vuoi mantenere la UX di tabella con editing rapido per record.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - abilita l'editing inline "cell-by-cell" (focus sulla singola cella).</p><p> - nota: nelle configurazioni legacy puo comparire come <code>md_inline_cell_editing</code>; il comportamento runtime e lo stesso.</p><p> - <strong>promozione runtime</strong>: quando <code>md_inline_cell_edit</code> e <code>true</code>, il componente forza</p><p> a runtime anche <code>md_inline_edit = true</code> indipendentemente dal valore in DB.</p><p> Entrambe le UX hanno bisogno della action column visibile, quindi sono mutualmente</p><p> non-esclusive a livello di rendering.</p><ul><li><code>md_batch_save</code></li></ul><p> - abilita il salvataggio batch delle modifiche pendenti (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - se usato insieme a inline-cell, le modifiche restano pending fino al salvataggio esplicito.</p><p> - <strong>prerequisito</strong>: <code>md_batch_save</code> ha effetto <strong>solo</strong> se <code>md_inline_cell_edit</code> e <code>true</code>.</p><p> Con <code>md_inline_cell_edit:false</code> il flag viene ignorato a runtime e i bottoni</p><p> "Salva modifiche / Annulla modifiche" non vengono renderizzati.</p><h3>Combinazioni valide</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Risultato runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>qualsiasi</td><td>Row-level inline edit con pencil. <code>md_batch_save</code> ignorato.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forzato a <code>true</code> a runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell con buffer pending + toolbar <code>Salva / Annulla modifiche</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>qualsiasi</td><td>Nessun inline editing. <code>md_batch_save</code> ignorato.</td></tr></tbody></table><p>Esempio row-level inline edit:</p><p>Snippet 1:</p><p>Esempio cell-by-cell con batch save:</p><p>Snippet 2:</p><h2>Toolbar export/import</h2><ul><li>Export XLS:</li></ul><p> - mostra dialog di progress con percentuale realtime;</p><p> - azioni: <code>Continua in background</code>, <code>Annulla task</code>, <code>Interrompi e scarica parziale</code>;</p><p> - in background crea una notifica con progress; click riapre il dialog.</p><p> - se il server ha gia' <code>maxConcurrentExports</code> export in corso, l'export aspetta in coda: dialog e notifica mostrano "In coda: posizione N" e parte da solo appena si libera un posto (annullabile anche mentre aspetta);</p><ul><li>Import XLS/XLSX (se <code>md_importable = true</code>):</li></ul><p> - dialog di progress dopo la conferma;</p><p> - azioni: <code>Continua in background</code>, <code>Annulla import (rollback)</code>, <code>Stop e commit parziale</code>;</p><p> - a fine import crea una notifica di riepilogo che porta alla route.</p><h2>Config metadata</h2><p>Impostazioni chiave in <code>md_props_bag</code> e metadati colonna.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flag opt-in che nascondono blocchi della toolbar della list-grid (<code>caption-bar</code>). Tutti sotto <code>md_props_bag.toolbar.*</code> (parsato in runtime come <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): nasconde nella <strong>caption-right</strong> il bottone "Gestione stato" (icona bookmark) + la <code><select></code> degli stati salvati. Utile per route hardcoded / demo dove il saved-state feature (persistenza per <code>user_id</code> + route via <code>MetaService</code>) non ha senso — es. Pattern 3 puro OData senza route metadata registrata.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): nasconde nella <strong>caption-left</strong> i pulsanti "Salva modifiche" (<code>pi-save</code>) + "Annulla modifiche" (<code>pi-times</code>) + l'indicatore conteggio changes (<code>grid-changes-indicator</code>, badge pencil + count). Generati dal framework quando <code>md_inline_cell_editing</code> + <code>md_batch_save</code> sono attivi. Pensato per <strong>nested grid in parametric-dialog</strong>: 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.</li></ul><p>Esempio nested rows in custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>Tipo TS in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (proprieta <code>extraProps.toolbar</code>). I flag NON disabilitano la logica <code>md_batch_save</code> sottostante (changes restano tracciate); rimuovono solo l'UI toolbar — il save effettivo passa dal flusso del padre.</p><h2>md_props_bag: archetypes.list</h2><p>Il componente legge <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>tipo: boolean (con parser tollerante)</li><li>valori accettati: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>default runtime: <code>true</code> quando assente o vuoto</li><li>effetto: distribuisce le larghezze colonna in percentuale (anziche px) quando non ci sono larghezze utente persistite.</li></ul><ul><li><code>virtualize</code>:</li><li>tipo: <code>boolean</code> oppure <code>object</code></li><li>valori accettati:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object con <code>enabled</code> (opzionale) e <code>itemSize</code> (opzionale)</li><li>default runtime: disabilitato (<code>false</code>) quando assente</li><li><code>enabled</code>:</li><li>default: <code>true</code> se il nodo <code>virtualize</code> e object senza <code>enabled</code>, altrimenti parser tollerante</li><li>effetto: abilita <code>virtualScroll</code> su <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>effetto: imposta <code>virtualScrollItemSize</code> (altezza riga virtuale in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>tipo: boolean (con parser tollerante)</li><li>default runtime: <code>false</code></li><li>effetto:</li><li>quando <code>true</code>, la griglia nasconde le icone filtro colonna (<code>p-columnFilter</code>) e usa la <code>wuic-filter-bar</code> sopra la tabella (a livello <code>data-repeater</code>/<code>bounded-repeater</code>) per applicare i filtri.</li></ul><p>Nota operativa:</p><ul><li>il suggest <code>md_props_bag</code> nel metadata editor espone anche il nodo checkabile <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Paging: md_pagesize e md_page_size_choice</h2><p>La griglia usa <code>md_pagesize</code> come dimensione pagina di default e <code>md_page_size_choice</code> come elenco valori selezionabili nel paginator.</p><p>Regole runtime:</p><ul><li>se <code>md_pagesize</code> e maggiore del valore massimo presente in <code>md_page_size_choice</code>, il framework aggiunge automaticamente <code>md_pagesize</code> alla lista opzioni;</li><li>la lista viene normalizzata (numeri validi, deduplica, ordinamento crescente).</li></ul><p>Esempio:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>risultato runtime: <code>10,25,50,100,200</code></li></ul><h2>Forzatura virtualizzazione su page size alto</h2><p>Quando l'utente seleziona nel paginator un valore <code>pageSize >= 1000</code>:</p><ul><li>la virtualizzazione viene forzata automaticamente anche se <code>md_props_bag.archetypes.list.virtualize</code> e assente o disabilitato;</li><li><code>virtualScrollItemSize</code> viene forzato al valore predefinito <code>44</code>.</li></ul><p>Questo comportamento protegge la resa della tabella su pagine molto grandi.</p><h2>Eventi e subscriptions (host)</h2><p><code>wuic-list-grid</code> espone eventi runtime utili per intercettare ciclo render e callback p-table lato progetto host.</p><p>Eventi disponibili:</p><ul><li><code>onAfterRender</code>: emesso a fine binding dati della griglia (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emesso prima del rendering logico della singola riga; supporta cancel tramite <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emesso dopo il rendering logico della singola riga.</li><li><code>onPaging</code>: emesso sugli eventi paging (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emesso sugli eventi sorting (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emesso sugli eventi filtering (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emesso su cambio selezione righe.</li><li><code>onPTableRowExpand</code>: emesso su expand riga.</li><li><code>onPTableRowCollapse</code>: emesso su collapse riga.</li><li><code>onPTableColumnResize</code>: emesso su resize colonna.</li><li><code>onPTableColumnReorder</code>: emesso su reorder colonne.</li></ul><h3>Esempio 1: binding diretto nel template</h3><p>Snippet 7:</p><h3>Esempio 2: subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — signature reale (gotcha)</h2><p><code><wuic-list-grid></code> accetta un input <code>[rowCustomSelect]</code> per intercettare la selezione di una riga (apertura dialog "scegli documento", master-detail, ecc.). La firma TypeScript dichiarata in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> è:</p><p>Snippet 9:</p><p><strong>Pero' a runtime la callback viene invocata con argomenti invertiti</strong> — il framework chiama <code>rowCustomSelect($event, rowData, dt)</code> (vedi <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> e <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Sintomo se sbagli ordine: <code>rowData?.id</code> e' undefined → guard precoce nel handler → la callback ritorna senza side-effect e la dialog/azione non parte. Nessun errore in console.</p><p>Forma corretta (allineata all'invocazione runtime):</p><p>Snippet 10:</p><p>Esempio integrato nel template:</p><p>Snippet 11:</p><p>> Note: i test in <code>designer.component.spec.ts</code> (es. riga 512) chiamano la callback con <code>({currentTarget: rowCell}, {id: 42}, null)</code> confermando l'ordine <code>($event, rowData, dt)</code>. Se in futuro il framework dovesse uniformare la signature dichiarata, si aggiornera' anche questa pagina.</p>",
|
|
2057
|
+
"html": "<h1>List Grid</h1><p>Componente principale per liste tabellari con filtri, sorting, paging server-side e azioni riga.</p><h2>Use cases</h2><ul><li>CRUD tabellari enterprise.</li><li>Report operativi con filtri multi-colonna.</li><li>Dataset molto grandi con <code>cursorMode</code>.</li></ul><h2>Cosa mostra la toolbar di default</h2><p>Aprendo una route appena scaffoldata, sopra la griglia c'e' la caption-bar. A sinistra:</p><table><thead><tr><th>Pulsante</th><th>Quando compare</th></tr></thead><tbody><tr><td><strong>Aggiorna</strong></td><td>sempre, salvo <code>md_hide_refresh</code></td></tr><tr><td><strong>Aggiungi</strong></td><td>con <code>md_insertable</code></td></tr><tr><td><strong>Azioni</strong></td><td>se la tabella ha custom action</td></tr><tr><td>Import / Export</td><td>sempre; il ramo import solo con <code>md_importable</code></td></tr><tr><td><strong>Report</strong></td><td>se alla route e' associato almeno un report</td></tr><tr><td><strong>Salva modifiche</strong> / <strong>Annulla modifiche</strong></td><td>solo con <code>md_inline_cell_edit</code> <strong>e</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A destra: <strong>Gestione stato</strong> (preceduto dalla tendina degli stati salvati, se ce ne sono),</p><p><strong>Pulisci filtri</strong> quando i filtri stanno sulle colonne, e <strong>Performance</strong> se l'inspector e'</p><p>abilitato sulla route.</p><p>> Le didascalie citate piu' sotto in questa pagina <strong>non si trovano su questo schermo</strong>, e non</p><p>> e' un difetto: quelle di export/import (<em>Continua in background</em>, <em>Annulla task</em>, *Interrompi</p><p>> e scarica parziale<em>, </em>Annulla import (rollback)<em>, </em>Stop e commit parziale*) vivono nella</p><p>> dialog di avanzamento, che esiste solo mentre un export o un import e' in corso; *Salva</p><p>> modifiche<em> e </em>Annulla modifiche* compaiono solo con i due flag qui sopra. Appartengono a</p><p>> momenti diversi dalla prima apertura della lista.</p><h2>Screenshot reference (manuale utente)</h2><ul><li><code>manual__grid__01.png</code>: modalita <code>inline cell edit</code> in list-grid.</li><li><code>manual__grid__02.png</code>: modalita <code>inline edit</code> (row-level) in list-grid.</li></ul><h2>Metadati inline editing</h2><p>Configurazione nel <code>md_props_bag</code> della tabella metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - abilita l'editing inline della riga in list-grid (celle editabili in contesto riga, senza apertura popup).</p><p> - utile quando vuoi mantenere la UX di tabella con editing rapido per record.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - abilita l'editing inline "cell-by-cell" (focus sulla singola cella).</p><p> - nota: nelle configurazioni legacy puo comparire come <code>md_inline_cell_editing</code>; il comportamento runtime e lo stesso.</p><p> - <strong>promozione runtime</strong>: quando <code>md_inline_cell_edit</code> e <code>true</code>, il componente forza</p><p> a runtime anche <code>md_inline_edit = true</code> indipendentemente dal valore in DB.</p><p> Entrambe le UX hanno bisogno della action column visibile, quindi sono mutualmente</p><p> non-esclusive a livello di rendering.</p><ul><li><code>md_batch_save</code></li></ul><p> - abilita il salvataggio batch delle modifiche pendenti (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - se usato insieme a inline-cell, le modifiche restano pending fino al salvataggio esplicito.</p><p> - <strong>prerequisito</strong>: <code>md_batch_save</code> ha effetto <strong>solo</strong> se <code>md_inline_cell_edit</code> e <code>true</code>.</p><p> Con <code>md_inline_cell_edit:false</code> il flag viene ignorato a runtime e i bottoni</p><p> "Salva modifiche / Annulla modifiche" non vengono renderizzati.</p><h3>Combinazioni valide</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Risultato runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>qualsiasi</td><td>Row-level inline edit con pencil. <code>md_batch_save</code> ignorato.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forzato a <code>true</code> a runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell con buffer pending + toolbar <code>Salva / Annulla modifiche</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>qualsiasi</td><td>Nessun inline editing. <code>md_batch_save</code> ignorato.</td></tr></tbody></table><p>Esempio row-level inline edit:</p><p>Snippet 1:</p><p>Esempio cell-by-cell con batch save:</p><p>Snippet 2:</p><h2>Toolbar export/import</h2><ul><li>Export XLS:</li></ul><p> - mostra dialog di progress con percentuale realtime;</p><p> - azioni: <code>Continua in background</code>, <code>Annulla task</code>, <code>Interrompi e scarica parziale</code>;</p><p> - in background crea una notifica con progress; click riapre il dialog.</p><p> - se il server ha gia' <code>maxConcurrentExports</code> export in corso, l'export aspetta in coda: dialog e notifica mostrano "In coda: posizione N" e parte da solo appena si libera un posto (annullabile anche mentre aspetta);</p><p> - SQL Server: se il database dati ha <code>ALLOW_SNAPSHOT_ISOLATION ON</code>, l'export legge in isolamento snapshot e non blocca le scritture sulla tabella mentre scrive il file (senza, un export lungo tiene i lock di lettura e insert/update sulla stessa tabella aspettano la sua fine). L'opzione si attiva una volta sul database (<code>ALTER DATABASE [<db dati>] SET ALLOW_SNAPSHOT_ISOLATION ON</code>) e non cambia il comportamento delle altre letture; con <code>READ_COMMITTED_SNAPSHOT ON</code> le due opzioni convivono. Il database del tutorial ha <code>READ_COMMITTED_SNAPSHOT ON</code>;</p><ul><li>Import XLS/XLSX (se <code>md_importable = true</code>):</li></ul><p> - dialog di progress dopo la conferma;</p><p> - azioni: <code>Continua in background</code>, <code>Annulla import (rollback)</code>, <code>Stop e commit parziale</code>;</p><p> - a fine import crea una notifica di riepilogo che porta alla route.</p><h2>Config metadata</h2><p>Impostazioni chiave in <code>md_props_bag</code> e metadati colonna.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flag opt-in che nascondono blocchi della toolbar della list-grid (<code>caption-bar</code>). Tutti sotto <code>md_props_bag.toolbar.*</code> (parsato in runtime come <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): nasconde nella <strong>caption-right</strong> il bottone "Gestione stato" (icona bookmark) + la <code><select></code> degli stati salvati. Utile per route hardcoded / demo dove il saved-state feature (persistenza per <code>user_id</code> + route via <code>MetaService</code>) non ha senso — es. Pattern 3 puro OData senza route metadata registrata.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): nasconde nella <strong>caption-left</strong> i pulsanti "Salva modifiche" (<code>pi-save</code>) + "Annulla modifiche" (<code>pi-times</code>) + l'indicatore conteggio changes (<code>grid-changes-indicator</code>, badge pencil + count). Generati dal framework quando <code>md_inline_cell_editing</code> + <code>md_batch_save</code> sono attivi. Pensato per <strong>nested grid in parametric-dialog</strong>: 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.</li></ul><p>Esempio nested rows in custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>Tipo TS in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (proprieta <code>extraProps.toolbar</code>). I flag NON disabilitano la logica <code>md_batch_save</code> sottostante (changes restano tracciate); rimuovono solo l'UI toolbar — il save effettivo passa dal flusso del padre.</p><h2>md_props_bag: archetypes.list</h2><p>Il componente legge <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>tipo: boolean (con parser tollerante)</li><li>valori accettati: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>default runtime: <code>true</code> quando assente o vuoto</li><li>effetto: distribuisce le larghezze colonna in percentuale (anziche px) quando non ci sono larghezze utente persistite.</li></ul><ul><li><code>virtualize</code>:</li><li>tipo: <code>boolean</code> oppure <code>object</code></li><li>valori accettati:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object con <code>enabled</code> (opzionale) e <code>itemSize</code> (opzionale)</li><li>default runtime: disabilitato (<code>false</code>) quando assente</li><li><code>enabled</code>:</li><li>default: <code>true</code> se il nodo <code>virtualize</code> e object senza <code>enabled</code>, altrimenti parser tollerante</li><li>effetto: abilita <code>virtualScroll</code> su <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>effetto: imposta <code>virtualScrollItemSize</code> (altezza riga virtuale in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>tipo: boolean (con parser tollerante)</li><li>default runtime: <code>false</code></li><li>effetto:</li><li>quando <code>true</code>, la griglia nasconde le icone filtro colonna (<code>p-columnFilter</code>) e usa la <code>wuic-filter-bar</code> sopra la tabella (a livello <code>data-repeater</code>/<code>bounded-repeater</code>) per applicare i filtri.</li></ul><p>Nota operativa:</p><ul><li>il suggest <code>md_props_bag</code> nel metadata editor espone anche il nodo checkabile <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Paging: md_pagesize e md_page_size_choice</h2><p>La griglia usa <code>md_pagesize</code> come dimensione pagina di default e <code>md_page_size_choice</code> come elenco valori selezionabili nel paginator.</p><p>Regole runtime:</p><ul><li>se <code>md_pagesize</code> e maggiore del valore massimo presente in <code>md_page_size_choice</code>, il framework aggiunge automaticamente <code>md_pagesize</code> alla lista opzioni;</li><li>la lista viene normalizzata (numeri validi, deduplica, ordinamento crescente).</li></ul><p>Esempio:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>risultato runtime: <code>10,25,50,100,200</code></li></ul><h2>Forzatura virtualizzazione su page size alto</h2><p>Quando l'utente seleziona nel paginator un valore <code>pageSize >= 1000</code>:</p><ul><li>la virtualizzazione viene forzata automaticamente anche se <code>md_props_bag.archetypes.list.virtualize</code> e assente o disabilitato;</li><li><code>virtualScrollItemSize</code> viene forzato al valore predefinito <code>44</code>.</li></ul><p>Questo comportamento protegge la resa della tabella su pagine molto grandi.</p><h2>Eventi e subscriptions (host)</h2><p><code>wuic-list-grid</code> espone eventi runtime utili per intercettare ciclo render e callback p-table lato progetto host.</p><p>Eventi disponibili:</p><ul><li><code>onAfterRender</code>: emesso a fine binding dati della griglia (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emesso prima del rendering logico della singola riga; supporta cancel tramite <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emesso dopo il rendering logico della singola riga.</li><li><code>onPaging</code>: emesso sugli eventi paging (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emesso sugli eventi sorting (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emesso sugli eventi filtering (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emesso su cambio selezione righe.</li><li><code>onPTableRowExpand</code>: emesso su expand riga.</li><li><code>onPTableRowCollapse</code>: emesso su collapse riga.</li><li><code>onPTableColumnResize</code>: emesso su resize colonna.</li><li><code>onPTableColumnReorder</code>: emesso su reorder colonne.</li></ul><h3>Esempio 1: binding diretto nel template</h3><p>Snippet 7:</p><h3>Esempio 2: subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — signature reale (gotcha)</h2><p><code><wuic-list-grid></code> accetta un input <code>[rowCustomSelect]</code> per intercettare la selezione di una riga (apertura dialog "scegli documento", master-detail, ecc.). La firma TypeScript dichiarata in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> è:</p><p>Snippet 9:</p><p><strong>Pero' a runtime la callback viene invocata con argomenti invertiti</strong> — il framework chiama <code>rowCustomSelect($event, rowData, dt)</code> (vedi <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> e <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Sintomo se sbagli ordine: <code>rowData?.id</code> e' undefined → guard precoce nel handler → la callback ritorna senza side-effect e la dialog/azione non parte. Nessun errore in console.</p><p>Forma corretta (allineata all'invocazione runtime):</p><p>Snippet 10:</p><p>Esempio integrato nel template:</p><p>Snippet 11:</p><p>> Note: i test in <code>designer.component.spec.ts</code> (es. riga 512) chiamano la callback con <code>({currentTarget: rowCell}, {id: 42}, null)</code> confermando l'ordine <code>($event, rowData, dt)</code>. Se in futuro il framework dovesse uniformare la signature dichiarata, si aggiornera' anche questa pagina.</p>",
|
|
2058
2058
|
"codeSamples": [
|
|
2059
2059
|
{
|
|
2060
2060
|
"id": "code_1",
|
|
@@ -6957,10 +6957,14 @@ const frameworkDocsContent = {
|
|
|
6957
6957
|
},
|
|
6958
6958
|
{
|
|
6959
6959
|
"id": "sec_5",
|
|
6960
|
-
"title": "
|
|
6960
|
+
"title": "Tabelle con chiave MAX"
|
|
6961
6961
|
},
|
|
6962
6962
|
{
|
|
6963
6963
|
"id": "sec_6",
|
|
6964
|
+
"title": "Comportamento PK esistente (import solo insert)"
|
|
6965
|
+
},
|
|
6966
|
+
{
|
|
6967
|
+
"id": "sec_7",
|
|
6964
6968
|
"title": "Colonne del file e lookup (export e import)"
|
|
6965
6969
|
}
|
|
6966
6970
|
],
|
|
@@ -6968,7 +6972,7 @@ const frameworkDocsContent = {
|
|
|
6968
6972
|
{
|
|
6969
6973
|
"id": "overview",
|
|
6970
6974
|
"title": "Overview",
|
|
6971
|
-
"html": "<h1>Import</h1><p>Abilita l'importazione dati da file Excel (<code>.xls</code>, <code>.xlsx</code>) nella route corrente della tabella metadata.</p><p>Quando attivo, nel <code>List Grid</code> compare un pulsante in toolbar (<code>Import XLS/XLSX</code>) che apre il file picker e invia il file al metodo di import già disponibile lato backend.</p><h2>Metadato tabella</h2><p>Il toggle principale e:</p><ul><li><code>md_importable</code></li></ul><p> Significato: mostra/nasconde il pulsante di import nella toolbar del <code>List Grid</code>.</p><p> Valori: <code>true | false</code>.</p><p> Default: <code>false</code> (se assente).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Le opzioni di import si configurano in <code>extraProps.import</code> (derivate da <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Note operative</h2><ul><li>Il pulsante e visibile se <code>md_importable = true</code>.</li><li>Il file e validato lato client per estensione (<code>xls</code>, <code>xlsx</code>) prima dell'upload.</li><li>L'import viene eseguito sulla route corrente (<code>md_route_name</code>) del datasource attivo.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): apre il dialog intermedio per scegliere opzioni import prima dell'upload.</p><p> - <code>true</code>: salta il dialog e avvia upload/import diretto usando le opzioni già definite in <code>md_props_bag.import</code>.</p><ul><li>Default consigliati nel suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (use column captions).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI e progress</h2><ul><li>Dopo la conferma import, si apre un dialog di progress con percentuale realtime.</li><li>Azioni disponibili:</li></ul><p> - <code>Continua in background</code>: chiude il dialog e crea una notifica di progress.</p><p> - <code>Annulla import (rollback)</code>: annulla e fa rollback.</p><p> - <code>Stop e commit parziale</code>: interrompe e conferma quanto fatto.</p><ul><li>A fine import viene creata una notifica riassuntiva (stesso testo del toast); click porta alla route dell'import senza refresh se si e già sulla stessa pagina.</li></ul><h2>Comportamento PK esistente (import solo insert)</h2><p>Se <code>import_type = "I"</code> e la PK del record esiste già:</p><ul><li>l'insert viene saltato;</li><li>il record viene conteggiato nel riepilogo come “inserimenti saltati (PK esistente)”.</li></ul><h2>Colonne del file e lookup (export e import)</h2><p>Export XLS e import usano le stesse regole, quindi un file esportato si reimporta così com'è.</p><h3>Intestazioni</h3><ul><li>Ogni colonna ha come intestazione la sua caption (<code>mc_display_string_in_view</code>; se vuota, il nome della colonna).</li><li>Se nello stesso file due colonne hanno la stessa caption, a ciascuna si aggiunge il nome fisico tra parentesi: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Senza collisioni le intestazioni restano quelle di sempre.</li><li>L'import riconosce una colonna dalla caption, dalla caption con il nome fisico (o il nome colonna) tra parentesi, oppure dal nome fisico / nome colonna.</li><li>Un'intestazione che corrisponde a più colonne (per esempio un file vecchio con due colonne <code>People</code>) viene rifiutata con l'errore "Ambiguous column": va scritta nella forma <code>caption (nome fisico)</code>.</li></ul><h3>Colonne lookup: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decide come viaggiano le colonne lookup (<code>mc_ui_column_type = lookupByID</code>):</p><table><thead><tr><th>Valore</th><th>Nel file</th><th>Note</th></tr></thead><tbody><tr><td><code>description</code> (default)</td><td>la descrizione del record collegato, sotto la caption</td><td>come sempre</td></tr><tr><td><code>key</code></td><td>la chiave del record collegato, sotto la caption</td><td></td></tr><tr><td><code>both</code></td><td>due colonne: la descrizione sotto la caption, la chiave sotto il nome fisico (<code>Ordine</code> + <code>OrderID</code>)</td><td>se la caption coincide con il nome fisico, la colonna descrizione diventa <code>caption (campo testo del lookup)</code>, es. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>L'export segue il valore della route; se <code>fkey_mode</code> manca vale <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Nel dialog di import la scelta "Colonne lookup nel file" è preselezionata dallo stesso valore e si può cambiare per il singolo import.</li></ul><h3>Da descrizione a chiave</h3><ul><li><strong>Solo la chiave</strong>: usata così com'è.</li><li><strong>Solo la descrizione</strong>: si cerca il record collegato con quella descrizione (campo testo del lookup).</li></ul><p> - Un solo record: si usa la sua chiave.</p><p> - Nessun record: errore sulla riga.</p><p> - Più record con la stessa descrizione: se la riga aggiorna un record esistente e la chiave che ha già corrisponde a quella descrizione, il collegamento resta com'è (l'utente non l'ha toccato). Altrimenti, e sempre per le righe nuove, è un errore che elenca le chiavi candidate: per inserire serve la chiave, cioè <code>key</code> o <code>both</code>.</p><ul><li><strong>Chiave e descrizione (`both`)</strong>: vale la chiave, se il suo record ha quella descrizione; se non coincidono (una delle due è stata cambiata e l'altra no) la riga va in errore.</li><li>Una chiave primaria che è anche un lookup (tabella 1:1) viene risolta prima del controllo di esistenza del record.</li><li>Con <code>commit_level</code> <code>R</code> o <code>I</code> un errore di lookup ferma l'import senza salvare; con <code>C</code> o <code>T</code> la riga viene saltata e l'import prosegue.</li></ul><h3>Date</h3><p>Le celle data scritte dall'export (numero con formato data, come in Excel) vengono lette come date: un file esportato e reimportato senza modifiche non viene più rifiutato sulle colonne data.</p>",
|
|
6975
|
+
"html": "<h1>Import</h1><p>Abilita l'importazione dati da file Excel (<code>.xls</code>, <code>.xlsx</code>) nella route corrente della tabella metadata.</p><p>Quando attivo, nel <code>List Grid</code> compare un pulsante in toolbar (<code>Import XLS/XLSX</code>) che apre il file picker e invia il file al metodo di import già disponibile lato backend.</p><h2>Metadato tabella</h2><p>Il toggle principale e:</p><ul><li><code>md_importable</code></li></ul><p> Significato: mostra/nasconde il pulsante di import nella toolbar del <code>List Grid</code>.</p><p> Valori: <code>true | false</code>.</p><p> Default: <code>false</code> (se assente).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Le opzioni di import si configurano in <code>extraProps.import</code> (derivate da <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Note operative</h2><ul><li>Il pulsante e visibile se <code>md_importable = true</code>.</li><li>Il file e validato lato client per estensione (<code>xls</code>, <code>xlsx</code>) prima dell'upload.</li><li>L'import viene eseguito sulla route corrente (<code>md_route_name</code>) del datasource attivo.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): apre il dialog intermedio per scegliere opzioni import prima dell'upload.</p><p> - <code>true</code>: salta il dialog e avvia upload/import diretto usando le opzioni già definite in <code>md_props_bag.import</code>.</p><ul><li>Default consigliati nel suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (use column captions).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI e progress</h2><ul><li>Dopo la conferma import, si apre un dialog di progress con percentuale realtime.</li><li>Azioni disponibili:</li></ul><p> - <code>Continua in background</code>: chiude il dialog e crea una notifica di progress.</p><p> - <code>Annulla import (rollback)</code>: annulla e fa rollback.</p><p> - <code>Stop e commit parziale</code>: interrompe e conferma quanto fatto.</p><ul><li>A fine import viene creata una notifica riassuntiva (stesso testo del toast); click porta alla route dell'import senza refresh se si e già sulla stessa pagina.</li></ul><h2>Tabelle con chiave MAX</h2><p>Sulle route con <code>md_primary_key_type = "MAX"</code> (e sulla "chiave dipendente" delle chiavi composte) la chiave di ogni riga nuova e' il massimo + 1, calcolato dentro l'insert con un lock sulla tabella: righe nuove dello stesso file prendono chiavi consecutive e inserimenti contemporanei non collidono. Il lock resta fino alla fine dell'import (una transazione per file): nel frattempo gli altri inserimenti sulla stessa tabella aspettano, e su Oracle anche update e delete. Per file grandi su tabelle molto usate conviene mettere la chiave nel file, o passare la tabella a <code>IDENTITY</code>/<code>SEQUENCE</code>.</p><h2>Comportamento PK esistente (import solo insert)</h2><p>Se <code>import_type = "I"</code> e la PK del record esiste già:</p><ul><li>l'insert viene saltato;</li><li>il record viene conteggiato nel riepilogo come “inserimenti saltati (PK esistente)”.</li></ul><h2>Colonne del file e lookup (export e import)</h2><p>Export XLS e import usano le stesse regole, quindi un file esportato si reimporta così com'è.</p><h3>Intestazioni</h3><ul><li>Ogni colonna ha come intestazione la sua caption (<code>mc_display_string_in_view</code>; se vuota, il nome della colonna).</li><li>Se nello stesso file due colonne hanno la stessa caption, a ciascuna si aggiunge il nome fisico tra parentesi: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Senza collisioni le intestazioni restano quelle di sempre.</li><li>L'import riconosce una colonna dalla caption, dalla caption con il nome fisico (o il nome colonna) tra parentesi, oppure dal nome fisico / nome colonna.</li><li>Un'intestazione che corrisponde a più colonne (per esempio un file vecchio con due colonne <code>People</code>) viene rifiutata con l'errore "Ambiguous column": va scritta nella forma <code>caption (nome fisico)</code>.</li></ul><h3>Colonne lookup: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decide come viaggiano le colonne lookup (<code>mc_ui_column_type = lookupByID</code>):</p><table><thead><tr><th>Valore</th><th>Nel file</th><th>Note</th></tr></thead><tbody><tr><td><code>description</code> (default)</td><td>la descrizione del record collegato, sotto la caption</td><td>come sempre</td></tr><tr><td><code>key</code></td><td>la chiave del record collegato, sotto la caption</td><td></td></tr><tr><td><code>both</code></td><td>due colonne: la descrizione sotto la caption, la chiave sotto il nome fisico (<code>Ordine</code> + <code>OrderID</code>)</td><td>se la caption coincide con il nome fisico, la colonna descrizione diventa <code>caption (campo testo del lookup)</code>, es. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>L'export segue il valore della route; se <code>fkey_mode</code> manca vale <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Nel dialog di import la scelta "Colonne lookup nel file" è preselezionata dallo stesso valore e si può cambiare per il singolo import.</li></ul><h3>Da descrizione a chiave</h3><ul><li><strong>Solo la chiave</strong>: usata così com'è.</li><li><strong>Solo la descrizione</strong>: si cerca il record collegato con quella descrizione (campo testo del lookup).</li></ul><p> - Un solo record: si usa la sua chiave.</p><p> - Nessun record: errore sulla riga.</p><p> - Più record con la stessa descrizione: se la riga aggiorna un record esistente e la chiave che ha già corrisponde a quella descrizione, il collegamento resta com'è (l'utente non l'ha toccato). Altrimenti, e sempre per le righe nuove, è un errore che elenca le chiavi candidate: per inserire serve la chiave, cioè <code>key</code> o <code>both</code>.</p><ul><li><strong>Chiave e descrizione (`both`)</strong>: vale la chiave, se il suo record ha quella descrizione; se non coincidono (una delle due è stata cambiata e l'altra no) la riga va in errore.</li><li>Una chiave primaria che è anche un lookup (tabella 1:1) viene risolta prima del controllo di esistenza del record.</li><li>Con <code>commit_level</code> <code>R</code> o <code>I</code> un errore di lookup ferma l'import senza salvare; con <code>C</code> o <code>T</code> la riga viene saltata e l'import prosegue.</li></ul><h3>Date</h3><p>Le celle data scritte dall'export (numero con formato data, come in Excel) vengono lette come date: un file esportato e reimportato senza modifiche non viene più rifiutato sulle colonne data.</p>",
|
|
6972
6976
|
"codeSamples": [
|
|
6973
6977
|
{
|
|
6974
6978
|
"id": "code_1",
|
|
@@ -8891,7 +8895,7 @@ const frameworkDocsContent = {
|
|
|
8891
8895
|
{
|
|
8892
8896
|
"id": "overview",
|
|
8893
8897
|
"title": "Overview",
|
|
8894
|
-
"html": "<h1>List Grid</h1><p>Main component for tabular lists with filters, sorting, server-side paging, and row actions.</p><h2>Use Cases</h2><ul><li>Enterprise tabular CRUD.</li><li>Operational reports with multi-column filters.</li><li>Very large datasets with <code>cursorMode</code>.</li></ul><h2>What the toolbar shows by default</h2><p>When you open a freshly scaffolded route, the caption bar sits above the grid. On the left:</p><table><thead><tr><th>Button</th><th>When it appears</th></tr></thead><tbody><tr><td><strong>Refresh</strong></td><td>always, unless <code>md_hide_refresh</code></td></tr><tr><td><strong>Add</strong></td><td>with <code>md_insertable</code></td></tr><tr><td><strong>Actions</strong></td><td>if the table has custom actions</td></tr><tr><td>Import / Export</td><td>always; the import branch only with <code>md_importable</code></td></tr><tr><td><strong>Reports</strong></td><td>if at least one report is bound to the route</td></tr><tr><td><strong>Save changes</strong> / <strong>Discard changes</strong></td><td>only with <code>md_inline_cell_edit</code> <strong>and</strong> <code>md_batch_save</code></td></tr></tbody></table><p>On the right: <strong>Manage state</strong> (preceded by the saved-states dropdown, when there are any),</p><p><strong>Clear filters</strong> when filters live on the columns, and <strong>Performance</strong> if the inspector is</p><p>enabled on the route.</p><p>> The captions quoted further down this page <strong>are not on that screen</strong>, and that is not a</p><p>> defect: the export/import ones (<em>Continue in background</em>, <em>Cancel task</em>, *Stop and download</p><p>> partial<em>, </em>Cancel import (rollback)<em>, </em>Stop and commit partial*) live in the progress dialog,</p><p>> which only exists while an export or import is running; <em>Save changes</em> and <em>Discard changes</em></p><p>> only appear with the two flags above. They belong to moments other than first opening the</p><p>> list.</p><h2>Screenshot Reference (User Manual)</h2><ul><li><code>manual__grid__01.png</code>: <code>inline cell edit</code> mode in list-grid.</li><li><code>manual__grid__02.png</code>: <code>inline edit</code> (row-level) mode in list-grid.</li></ul><h2>Inline Editing Metadata</h2><p>Configuration in the table metadata <code>md_props_bag</code>:</p><ul><li><code>md_inline_edit</code></li></ul><p> - Enables inline row editing in list-grid (editable cells in row context, without opening a popup).</p><p> - Useful when you want to maintain the table UX with quick editing per record.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - Enables "cell-by-cell" inline editing (focus on the individual cell).</p><p> - Note: in legacy configurations it may appear as <code>md_inline_cell_editing</code>; the runtime behavior is the same.</p><p> - <strong>Runtime promotion</strong>: when <code>md_inline_cell_edit</code> is <code>true</code>, the component forces</p><p> <code>md_inline_edit = true</code> at runtime regardless of the DB value.</p><p> Both UX modes need the action column visible, so they are mutually</p><p> non-exclusive at the rendering level.</p><ul><li><code>md_batch_save</code></li></ul><p> - Enables batch saving of pending changes (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - When used with inline-cell, changes remain pending until explicit save.</p><p> - <strong>Prerequisite</strong>: <code>md_batch_save</code> takes effect <strong>only</strong> if <code>md_inline_cell_edit</code> is <code>true</code>.</p><p> With <code>md_inline_cell_edit:false</code> the flag is ignored at runtime and the</p><p> "Save changes / Cancel changes" buttons are not rendered.</p><h3>Valid Combinations</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Runtime Result</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>any</td><td>Row-level inline edit with pencil. <code>md_batch_save</code> ignored.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forced to <code>true</code> at runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell with pending buffer + <code>Save / Cancel changes</code> toolbar.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>any</td><td>No inline editing. <code>md_batch_save</code> ignored.</td></tr></tbody></table><p>Row-level inline edit example:</p><p>Snippet 1:</p><p>Cell-by-cell with batch save example:</p><p>Snippet 2:</p><h2>Toolbar Export/Import</h2><ul><li>Export XLS:</li></ul><p> - Shows a progress dialog with real-time percentage;</p><p> - Actions: <code>Continue in background</code>, <code>Cancel task</code>, <code>Stop and download partial</code>;</p><p> - In background creates a notification with progress; click reopens the dialog.</p><p> - If the server is already running <code>maxConcurrentExports</code> exports, the export waits in a queue: dialog and notification show "Queued: position N" and it starts by itself as soon as a slot frees up (it can be cancelled while waiting too);</p><ul><li>Import XLS/XLSX (if <code>md_importable = true</code>):</li></ul><p> - Progress dialog after confirmation;</p><p> - Actions: <code>Continue in background</code>, <code>Cancel import (rollback)</code>, <code>Stop and partial commit</code>;</p><p> - At the end of import creates a summary notification that navigates to the route.</p><h2>Metadata Config</h2><p>Key settings in <code>md_props_bag</code> and column metadata.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Opt-in flags that hide blocks of the list-grid toolbar (<code>caption-bar</code>). All under <code>md_props_bag.toolbar.*</code> (parsed at runtime as <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): hides in the <strong>caption-right</strong> the "Manage state" button (bookmark icon) + the saved-states <code><select></code>. Useful for hardcoded / demo routes where the saved-state feature (persistence per <code>user_id</code> + route via <code>MetaService</code>) doesn't make sense — e.g. Pattern 3 pure OData without registered route metadata.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): hides in the <strong>caption-left</strong> the "Save changes" (<code>pi-save</code>) + "Discard changes" (<code>pi-times</code>) buttons + the changes count indicator (<code>grid-changes-indicator</code>, pencil badge + count). Generated by the framework when <code>md_inline_cell_editing</code> + <code>md_batch_save</code> are active. Designed for <strong>nested grids inside a parametric-dialog</strong>: the parent's save/cancel persists master + rows in one shot via the framework batch save, and the duplicate buttons on the nested grid confuse the UX.</li></ul><p>Example nested rows in custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>TS type in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (<code>extraProps.toolbar</code> property). The flags do NOT disable the underlying <code>md_batch_save</code> logic (changes are still tracked); they only remove the toolbar UI — the actual save flows through the parent.</p><h2>md_props_bag: archetypes.list</h2><p>The component reads <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>type: boolean (with tolerant parser)</li><li>accepted values: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>runtime default: <code>true</code> when absent or empty</li><li>effect: distributes column widths proportionally (instead of px) when no user-persisted widths exist.</li></ul><ul><li><code>virtualize</code>:</li><li>type: <code>boolean</code> or <code>object</code></li><li>accepted values:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object with <code>enabled</code> (optional) and <code>itemSize</code> (optional)</li><li>runtime default: disabled (<code>false</code>) when absent</li><li><code>enabled</code>:</li><li>default: <code>true</code> if the <code>virtualize</code> node is an object without <code>enabled</code>, otherwise tolerant parser</li><li>effect: enables <code>virtualScroll</code> on <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>effect: sets <code>virtualScrollItemSize</code> (virtual row height in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>type: boolean (with tolerant parser)</li><li>runtime default: <code>false</code></li><li>effect:</li><li>when <code>true</code>, the grid hides column filter icons (<code>p-columnFilter</code>) and uses the <code>wuic-filter-bar</code> above the table (at <code>data-repeater</code>/<code>bounded-repeater</code> level) to apply filters.</li></ul><p>Operational note:</p><ul><li>The <code>md_props_bag</code> suggest in the metadata editor also exposes the checkable <code>archetypes.list.advancedFilter</code> node.</li></ul><h2>Paging: md_pagesize and md_page_size_choice</h2><p>The grid uses <code>md_pagesize</code> as the default page size and <code>md_page_size_choice</code> as the list of selectable values in the paginator.</p><p>Runtime rules:</p><ul><li>If <code>md_pagesize</code> is greater than the maximum value present in <code>md_page_size_choice</code>, the framework automatically adds <code>md_pagesize</code> to the options list;</li><li>The list is normalized (valid numbers, deduplication, ascending sort).</li></ul><p>Example:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>runtime result: <code>10,25,50,100,200</code></li></ul><h2>Forced Virtualization on High Page Size</h2><p>When the user selects in the paginator a <code>pageSize >= 1000</code>:</p><ul><li>virtualization is automatically forced even if <code>md_props_bag.archetypes.list.virtualize</code> is absent or disabled;</li><li><code>virtualScrollItemSize</code> is forced to the default value <code>44</code>.</li></ul><p>This behavior protects the table rendering on very large pages.</p><h2>Events and Subscriptions (Host)</h2><p><code>wuic-list-grid</code> exposes runtime events useful for intercepting the render cycle and p-table callbacks on the host project side.</p><p>Available events:</p><ul><li><code>onAfterRender</code>: emitted at the end of grid data binding (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emitted before the logical rendering of a single row; supports cancel via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emitted after the logical rendering of a single row.</li><li><code>onPaging</code>: emitted on paging events (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emitted on sorting events (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emitted on filtering events (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emitted on row selection change.</li><li><code>onPTableRowExpand</code>: emitted on row expand.</li><li><code>onPTableRowCollapse</code>: emitted on row collapse.</li><li><code>onPTableColumnResize</code>: emitted on column resize.</li><li><code>onPTableColumnReorder</code>: emitted on column reorder.</li></ul><h3>Example 1: Direct Binding in Template</h3><p>Snippet 7:</p><h3>Example 2: Subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — actual signature (gotcha)</h2><p><code><wuic-list-grid></code> accepts a <code>[rowCustomSelect]</code> input to hook into row selection (opening a "pick a document" dialog, master-detail flow, etc.). The TypeScript signature declared in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> reads:</p><p>Snippet 9:</p><p><strong>However at runtime the callback is invoked with arguments reversed</strong> — the framework calls <code>rowCustomSelect($event, rowData, dt)</code> (see <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> and <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptom of wrong arg order: <code>rowData?.id</code> is undefined → early-return guard in your handler → the callback returns silently and your dialog/action never fires. No console error.</p><p>Correct form (matches runtime invocation):</p><p>Snippet 10:</p><p>Template usage:</p><p>Snippet 11:</p><p>> Note: tests in <code>designer.component.spec.ts</code> (e.g. line 512) invoke the callback with <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirming the <code>($event, rowData, dt)</code> order. If the framework eventually aligns the declared signature, this page will be updated as well.</p>",
|
|
8898
|
+
"html": "<h1>List Grid</h1><p>Main component for tabular lists with filters, sorting, server-side paging, and row actions.</p><h2>Use Cases</h2><ul><li>Enterprise tabular CRUD.</li><li>Operational reports with multi-column filters.</li><li>Very large datasets with <code>cursorMode</code>.</li></ul><h2>What the toolbar shows by default</h2><p>When you open a freshly scaffolded route, the caption bar sits above the grid. On the left:</p><table><thead><tr><th>Button</th><th>When it appears</th></tr></thead><tbody><tr><td><strong>Refresh</strong></td><td>always, unless <code>md_hide_refresh</code></td></tr><tr><td><strong>Add</strong></td><td>with <code>md_insertable</code></td></tr><tr><td><strong>Actions</strong></td><td>if the table has custom actions</td></tr><tr><td>Import / Export</td><td>always; the import branch only with <code>md_importable</code></td></tr><tr><td><strong>Reports</strong></td><td>if at least one report is bound to the route</td></tr><tr><td><strong>Save changes</strong> / <strong>Discard changes</strong></td><td>only with <code>md_inline_cell_edit</code> <strong>and</strong> <code>md_batch_save</code></td></tr></tbody></table><p>On the right: <strong>Manage state</strong> (preceded by the saved-states dropdown, when there are any),</p><p><strong>Clear filters</strong> when filters live on the columns, and <strong>Performance</strong> if the inspector is</p><p>enabled on the route.</p><p>> The captions quoted further down this page <strong>are not on that screen</strong>, and that is not a</p><p>> defect: the export/import ones (<em>Continue in background</em>, <em>Cancel task</em>, *Stop and download</p><p>> partial<em>, </em>Cancel import (rollback)<em>, </em>Stop and commit partial*) live in the progress dialog,</p><p>> which only exists while an export or import is running; <em>Save changes</em> and <em>Discard changes</em></p><p>> only appear with the two flags above. They belong to moments other than first opening the</p><p>> list.</p><h2>Screenshot Reference (User Manual)</h2><ul><li><code>manual__grid__01.png</code>: <code>inline cell edit</code> mode in list-grid.</li><li><code>manual__grid__02.png</code>: <code>inline edit</code> (row-level) mode in list-grid.</li></ul><h2>Inline Editing Metadata</h2><p>Configuration in the table metadata <code>md_props_bag</code>:</p><ul><li><code>md_inline_edit</code></li></ul><p> - Enables inline row editing in list-grid (editable cells in row context, without opening a popup).</p><p> - Useful when you want to maintain the table UX with quick editing per record.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - Enables "cell-by-cell" inline editing (focus on the individual cell).</p><p> - Note: in legacy configurations it may appear as <code>md_inline_cell_editing</code>; the runtime behavior is the same.</p><p> - <strong>Runtime promotion</strong>: when <code>md_inline_cell_edit</code> is <code>true</code>, the component forces</p><p> <code>md_inline_edit = true</code> at runtime regardless of the DB value.</p><p> Both UX modes need the action column visible, so they are mutually</p><p> non-exclusive at the rendering level.</p><ul><li><code>md_batch_save</code></li></ul><p> - Enables batch saving of pending changes (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - When used with inline-cell, changes remain pending until explicit save.</p><p> - <strong>Prerequisite</strong>: <code>md_batch_save</code> takes effect <strong>only</strong> if <code>md_inline_cell_edit</code> is <code>true</code>.</p><p> With <code>md_inline_cell_edit:false</code> the flag is ignored at runtime and the</p><p> "Save changes / Cancel changes" buttons are not rendered.</p><h3>Valid Combinations</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Runtime Result</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>any</td><td>Row-level inline edit with pencil. <code>md_batch_save</code> ignored.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forced to <code>true</code> at runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell with pending buffer + <code>Save / Cancel changes</code> toolbar.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>any</td><td>No inline editing. <code>md_batch_save</code> ignored.</td></tr></tbody></table><p>Row-level inline edit example:</p><p>Snippet 1:</p><p>Cell-by-cell with batch save example:</p><p>Snippet 2:</p><h2>Toolbar Export/Import</h2><ul><li>Export XLS:</li></ul><p> - Shows a progress dialog with real-time percentage;</p><p> - Actions: <code>Continue in background</code>, <code>Cancel task</code>, <code>Stop and download partial</code>;</p><p> - In background creates a notification with progress; click reopens the dialog.</p><p> - If the server is already running <code>maxConcurrentExports</code> exports, the export waits in a queue: dialog and notification show "Queued: position N" and it starts by itself as soon as a slot frees up (it can be cancelled while waiting too);</p><p> - SQL Server: if the data database has <code>ALLOW_SNAPSHOT_ISOLATION ON</code>, the export reads under snapshot isolation and does not block writes on the table while it writes the file (without it, a long export holds its read locks and inserts/updates on the same table wait until it ends). Enable it once on the database (<code>ALTER DATABASE [<data db>] SET ALLOW_SNAPSHOT_ISOLATION ON</code>); it does not change how other reads behave, and it works alongside <code>READ_COMMITTED_SNAPSHOT ON</code>. The tutorial database has <code>READ_COMMITTED_SNAPSHOT ON</code>;</p><ul><li>Import XLS/XLSX (if <code>md_importable = true</code>):</li></ul><p> - Progress dialog after confirmation;</p><p> - Actions: <code>Continue in background</code>, <code>Cancel import (rollback)</code>, <code>Stop and partial commit</code>;</p><p> - At the end of import creates a summary notification that navigates to the route.</p><h2>Metadata Config</h2><p>Key settings in <code>md_props_bag</code> and column metadata.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Opt-in flags that hide blocks of the list-grid toolbar (<code>caption-bar</code>). All under <code>md_props_bag.toolbar.*</code> (parsed at runtime as <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): hides in the <strong>caption-right</strong> the "Manage state" button (bookmark icon) + the saved-states <code><select></code>. Useful for hardcoded / demo routes where the saved-state feature (persistence per <code>user_id</code> + route via <code>MetaService</code>) doesn't make sense — e.g. Pattern 3 pure OData without registered route metadata.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): hides in the <strong>caption-left</strong> the "Save changes" (<code>pi-save</code>) + "Discard changes" (<code>pi-times</code>) buttons + the changes count indicator (<code>grid-changes-indicator</code>, pencil badge + count). Generated by the framework when <code>md_inline_cell_editing</code> + <code>md_batch_save</code> are active. Designed for <strong>nested grids inside a parametric-dialog</strong>: the parent's save/cancel persists master + rows in one shot via the framework batch save, and the duplicate buttons on the nested grid confuse the UX.</li></ul><p>Example nested rows in custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>TS type in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (<code>extraProps.toolbar</code> property). The flags do NOT disable the underlying <code>md_batch_save</code> logic (changes are still tracked); they only remove the toolbar UI — the actual save flows through the parent.</p><h2>md_props_bag: archetypes.list</h2><p>The component reads <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>type: boolean (with tolerant parser)</li><li>accepted values: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>runtime default: <code>true</code> when absent or empty</li><li>effect: distributes column widths proportionally (instead of px) when no user-persisted widths exist.</li></ul><ul><li><code>virtualize</code>:</li><li>type: <code>boolean</code> or <code>object</code></li><li>accepted values:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object with <code>enabled</code> (optional) and <code>itemSize</code> (optional)</li><li>runtime default: disabled (<code>false</code>) when absent</li><li><code>enabled</code>:</li><li>default: <code>true</code> if the <code>virtualize</code> node is an object without <code>enabled</code>, otherwise tolerant parser</li><li>effect: enables <code>virtualScroll</code> on <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>effect: sets <code>virtualScrollItemSize</code> (virtual row height in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>type: boolean (with tolerant parser)</li><li>runtime default: <code>false</code></li><li>effect:</li><li>when <code>true</code>, the grid hides column filter icons (<code>p-columnFilter</code>) and uses the <code>wuic-filter-bar</code> above the table (at <code>data-repeater</code>/<code>bounded-repeater</code> level) to apply filters.</li></ul><p>Operational note:</p><ul><li>The <code>md_props_bag</code> suggest in the metadata editor also exposes the checkable <code>archetypes.list.advancedFilter</code> node.</li></ul><h2>Paging: md_pagesize and md_page_size_choice</h2><p>The grid uses <code>md_pagesize</code> as the default page size and <code>md_page_size_choice</code> as the list of selectable values in the paginator.</p><p>Runtime rules:</p><ul><li>If <code>md_pagesize</code> is greater than the maximum value present in <code>md_page_size_choice</code>, the framework automatically adds <code>md_pagesize</code> to the options list;</li><li>The list is normalized (valid numbers, deduplication, ascending sort).</li></ul><p>Example:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>runtime result: <code>10,25,50,100,200</code></li></ul><h2>Forced Virtualization on High Page Size</h2><p>When the user selects in the paginator a <code>pageSize >= 1000</code>:</p><ul><li>virtualization is automatically forced even if <code>md_props_bag.archetypes.list.virtualize</code> is absent or disabled;</li><li><code>virtualScrollItemSize</code> is forced to the default value <code>44</code>.</li></ul><p>This behavior protects the table rendering on very large pages.</p><h2>Events and Subscriptions (Host)</h2><p><code>wuic-list-grid</code> exposes runtime events useful for intercepting the render cycle and p-table callbacks on the host project side.</p><p>Available events:</p><ul><li><code>onAfterRender</code>: emitted at the end of grid data binding (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emitted before the logical rendering of a single row; supports cancel via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emitted after the logical rendering of a single row.</li><li><code>onPaging</code>: emitted on paging events (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emitted on sorting events (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emitted on filtering events (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emitted on row selection change.</li><li><code>onPTableRowExpand</code>: emitted on row expand.</li><li><code>onPTableRowCollapse</code>: emitted on row collapse.</li><li><code>onPTableColumnResize</code>: emitted on column resize.</li><li><code>onPTableColumnReorder</code>: emitted on column reorder.</li></ul><h3>Example 1: Direct Binding in Template</h3><p>Snippet 7:</p><h3>Example 2: Subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — actual signature (gotcha)</h2><p><code><wuic-list-grid></code> accepts a <code>[rowCustomSelect]</code> input to hook into row selection (opening a "pick a document" dialog, master-detail flow, etc.). The TypeScript signature declared in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> reads:</p><p>Snippet 9:</p><p><strong>However at runtime the callback is invoked with arguments reversed</strong> — the framework calls <code>rowCustomSelect($event, rowData, dt)</code> (see <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> and <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptom of wrong arg order: <code>rowData?.id</code> is undefined → early-return guard in your handler → the callback returns silently and your dialog/action never fires. No console error.</p><p>Correct form (matches runtime invocation):</p><p>Snippet 10:</p><p>Template usage:</p><p>Snippet 11:</p><p>> Note: tests in <code>designer.component.spec.ts</code> (e.g. line 512) invoke the callback with <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirming the <code>($event, rowData, dt)</code> order. If the framework eventually aligns the declared signature, this page will be updated as well.</p>",
|
|
8895
8899
|
"codeSamples": [
|
|
8896
8900
|
{
|
|
8897
8901
|
"id": "code_1",
|
|
@@ -13794,10 +13798,14 @@ const frameworkDocsContent = {
|
|
|
13794
13798
|
},
|
|
13795
13799
|
{
|
|
13796
13800
|
"id": "sec_5",
|
|
13797
|
-
"title": "
|
|
13801
|
+
"title": "Tables with a MAX key"
|
|
13798
13802
|
},
|
|
13799
13803
|
{
|
|
13800
13804
|
"id": "sec_6",
|
|
13805
|
+
"title": "Existing PK Behavior (Insert-Only Import)"
|
|
13806
|
+
},
|
|
13807
|
+
{
|
|
13808
|
+
"id": "sec_7",
|
|
13801
13809
|
"title": "File columns and lookups (export and import)"
|
|
13802
13810
|
}
|
|
13803
13811
|
],
|
|
@@ -13805,7 +13813,7 @@ const frameworkDocsContent = {
|
|
|
13805
13813
|
{
|
|
13806
13814
|
"id": "overview",
|
|
13807
13815
|
"title": "Overview",
|
|
13808
|
-
"html": "<h1>Import</h1><p>Enables data import from Excel files (<code>.xls</code>, <code>.xlsx</code>) in the current metadata table route.</p><p>When active, an <code>Import XLS/XLSX</code> button appears in the <code>List Grid</code> toolbar that opens the file picker and sends the file to the backend import method already available.</p><h2>Table Metadata</h2><p>The main toggle is:</p><ul><li><code>md_importable</code></li></ul><p> Meaning: shows/hides the import button in the <code>List Grid</code> toolbar.</p><p> Values: <code>true | false</code>.</p><p> Default: <code>false</code> (if absent).</p><h2>Extra Props (<code>md_props_bag</code>)</h2><p>Import options are configured in <code>extraProps.import</code> (derived from <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Operational Notes</h2><ul><li>The button is visible if <code>md_importable = true</code>.</li><li>The file is validated client-side by extension (<code>xls</code>, <code>xlsx</code>) before upload.</li><li>The import is executed on the current route (<code>md_route_name</code>) of the active datasource.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): opens the intermediate dialog to choose import options before upload.</p><p> - <code>true</code>: skips the dialog and starts direct upload/import using the options already defined in <code>md_props_bag.import</code>.</p><ul><li>Recommended defaults in the suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (use column captions).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI and Progress</h2><ul><li>After import confirmation, a progress dialog opens with real-time percentage.</li><li>Available actions:</li></ul><p> - <code>Continue in background</code>: closes the dialog and creates a progress notification.</p><p> - <code>Cancel import (rollback)</code>: cancels and performs rollback.</p><p> - <code>Stop and partial commit</code>: stops and commits what has been done.</p><ul><li>At the end of import, a summary notification is created (same text as the toast); clicking navigates to the import route without refresh if already on the same page.</li></ul><h2>Existing PK Behavior (Insert-Only Import)</h2><p>If <code>import_type = "I"</code> and the record PK already exists:</p><ul><li>the insert is skipped;</li><li>the record is counted in the summary as "skipped inserts (existing PK)".</li></ul><h2>File columns and lookups (export and import)</h2><p>The XLS export and the import follow the same rules, so an exported file imports back as it is.</p><h3>Headers</h3><ul><li>Every column is headed by its caption (<code>mc_display_string_in_view</code>; if empty, the column name).</li><li>When two columns of the same file have the same caption, each one gets its physical name in parentheses: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Without collisions the headers stay as they always were.</li><li>The import recognises a column by its caption, by its caption with the physical name (or the column name) in parentheses, or by its physical name / column name.</li><li>A header that matches more than one column (for example an old file with two <code>People</code> columns) is refused with the error "Ambiguous column": write it as <code>caption (physical name)</code>.</li></ul><h3>Lookup columns: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decides how the lookup columns (<code>mc_ui_column_type = lookupByID</code>) travel:</p><table><thead><tr><th>Value</th><th>In the file</th><th>Notes</th></tr></thead><tbody><tr><td><code>description</code> (default)</td><td>the description of the linked record, under the caption</td><td>as always</td></tr><tr><td><code>key</code></td><td>the key of the linked record, under the caption</td><td></td></tr><tr><td><code>both</code></td><td>two columns: the description under the caption, the key under the physical name (<code>Order</code> + <code>OrderID</code>)</td><td>if the caption is the physical name, the description column becomes <code>caption (lookup text field)</code>, e.g. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>The export follows the route's value; without <code>fkey_mode</code>, <code>use_descriptive_fkey</code> applies (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>In the import dialog the "Lookup columns in the file" choice is preselected from the same value and can be changed for a single import.</li></ul><h3>From description to key</h3><ul><li><strong>Key only</strong>: used as is.</li><li><strong>Description only</strong>: the linked record with that description (lookup text field) is looked up.</li></ul><p> - One record: its key is used.</p><p> - No record: the row fails.</p><p> - More records with the same description: if the row updates an existing record and the key it already has matches that description, the link stays as it is (the user did not touch it). Otherwise, and always for new rows, it is an error listing the candidate keys: inserting needs the key, i.e. <code>key</code> or <code>both</code>.</p><ul><li><strong>Key and description (`both`)</strong>: the key wins if its record has that description; if they do not match (one of the two was changed and the other was not) the row fails.</li><li>A primary key that is also a lookup (1:1 table) is resolved before the check that the record exists.</li><li>With <code>commit_level</code> <code>R</code> or <code>I</code> a lookup error stops the import without saving; with <code>C</code> or <code>T</code> the row is skipped and the import goes on.</li></ul><h3>Dates</h3><p>Date cells written by the export (a number with a date format, as in Excel) are read as dates: a file exported and imported back unchanged is no longer refused on its date columns.</p>",
|
|
13816
|
+
"html": "<h1>Import</h1><p>Enables data import from Excel files (<code>.xls</code>, <code>.xlsx</code>) in the current metadata table route.</p><p>When active, an <code>Import XLS/XLSX</code> button appears in the <code>List Grid</code> toolbar that opens the file picker and sends the file to the backend import method already available.</p><h2>Table Metadata</h2><p>The main toggle is:</p><ul><li><code>md_importable</code></li></ul><p> Meaning: shows/hides the import button in the <code>List Grid</code> toolbar.</p><p> Values: <code>true | false</code>.</p><p> Default: <code>false</code> (if absent).</p><h2>Extra Props (<code>md_props_bag</code>)</h2><p>Import options are configured in <code>extraProps.import</code> (derived from <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Operational Notes</h2><ul><li>The button is visible if <code>md_importable = true</code>.</li><li>The file is validated client-side by extension (<code>xls</code>, <code>xlsx</code>) before upload.</li><li>The import is executed on the current route (<code>md_route_name</code>) of the active datasource.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): opens the intermediate dialog to choose import options before upload.</p><p> - <code>true</code>: skips the dialog and starts direct upload/import using the options already defined in <code>md_props_bag.import</code>.</p><ul><li>Recommended defaults in the suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (use column captions).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI and Progress</h2><ul><li>After import confirmation, a progress dialog opens with real-time percentage.</li><li>Available actions:</li></ul><p> - <code>Continue in background</code>: closes the dialog and creates a progress notification.</p><p> - <code>Cancel import (rollback)</code>: cancels and performs rollback.</p><p> - <code>Stop and partial commit</code>: stops and commits what has been done.</p><ul><li>At the end of import, a summary notification is created (same text as the toast); clicking navigates to the import route without refresh if already on the same page.</li></ul><h2>Tables with a MAX key</h2><p>On routes with <code>md_primary_key_type = "MAX"</code> (and on the "dependent key" of composite keys) the key of every new row is the maximum + 1, computed inside the insert with a lock on the table: new rows of the same file get consecutive keys and concurrent inserts do not collide. The lock lasts until the import ends (one transaction per file): meanwhile other inserts on the same table wait, and on Oracle updates and deletes too. For large files on busy tables put the key in the file, or switch the table to <code>IDENTITY</code>/<code>SEQUENCE</code>.</p><h2>Existing PK Behavior (Insert-Only Import)</h2><p>If <code>import_type = "I"</code> and the record PK already exists:</p><ul><li>the insert is skipped;</li><li>the record is counted in the summary as "skipped inserts (existing PK)".</li></ul><h2>File columns and lookups (export and import)</h2><p>The XLS export and the import follow the same rules, so an exported file imports back as it is.</p><h3>Headers</h3><ul><li>Every column is headed by its caption (<code>mc_display_string_in_view</code>; if empty, the column name).</li><li>When two columns of the same file have the same caption, each one gets its physical name in parentheses: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Without collisions the headers stay as they always were.</li><li>The import recognises a column by its caption, by its caption with the physical name (or the column name) in parentheses, or by its physical name / column name.</li><li>A header that matches more than one column (for example an old file with two <code>People</code> columns) is refused with the error "Ambiguous column": write it as <code>caption (physical name)</code>.</li></ul><h3>Lookup columns: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decides how the lookup columns (<code>mc_ui_column_type = lookupByID</code>) travel:</p><table><thead><tr><th>Value</th><th>In the file</th><th>Notes</th></tr></thead><tbody><tr><td><code>description</code> (default)</td><td>the description of the linked record, under the caption</td><td>as always</td></tr><tr><td><code>key</code></td><td>the key of the linked record, under the caption</td><td></td></tr><tr><td><code>both</code></td><td>two columns: the description under the caption, the key under the physical name (<code>Order</code> + <code>OrderID</code>)</td><td>if the caption is the physical name, the description column becomes <code>caption (lookup text field)</code>, e.g. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>The export follows the route's value; without <code>fkey_mode</code>, <code>use_descriptive_fkey</code> applies (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>In the import dialog the "Lookup columns in the file" choice is preselected from the same value and can be changed for a single import.</li></ul><h3>From description to key</h3><ul><li><strong>Key only</strong>: used as is.</li><li><strong>Description only</strong>: the linked record with that description (lookup text field) is looked up.</li></ul><p> - One record: its key is used.</p><p> - No record: the row fails.</p><p> - More records with the same description: if the row updates an existing record and the key it already has matches that description, the link stays as it is (the user did not touch it). Otherwise, and always for new rows, it is an error listing the candidate keys: inserting needs the key, i.e. <code>key</code> or <code>both</code>.</p><ul><li><strong>Key and description (`both`)</strong>: the key wins if its record has that description; if they do not match (one of the two was changed and the other was not) the row fails.</li><li>A primary key that is also a lookup (1:1 table) is resolved before the check that the record exists.</li><li>With <code>commit_level</code> <code>R</code> or <code>I</code> a lookup error stops the import without saving; with <code>C</code> or <code>T</code> the row is skipped and the import goes on.</li></ul><h3>Dates</h3><p>Date cells written by the export (a number with a date format, as in Excel) are read as dates: a file exported and imported back unchanged is no longer refused on its date columns.</p>",
|
|
13809
13817
|
"codeSamples": [
|
|
13810
13818
|
{
|
|
13811
13819
|
"id": "code_1",
|
|
@@ -15728,7 +15736,7 @@ const frameworkDocsContent = {
|
|
|
15728
15736
|
{
|
|
15729
15737
|
"id": "overview",
|
|
15730
15738
|
"title": "Overview",
|
|
15731
|
-
"html": "<h1>List Grid</h1><p>Composant principal pour les listes tabulaires avec filtres, tri, pagination cote serveur et actions sur les lignes.</p><h2>Cas d'utilisation</h2><ul><li>CRUD tabulaires enterprise.</li><li>Rapports operationnels avec filtres multi-colonnes.</li><li>Jeux de donnees tres volumineux avec <code>cursorMode</code>.</li></ul><h2>Ce que la toolbar affiche par defaut</h2><p>En ouvrant une route fraichement scaffoldee, la caption-bar se trouve au-dessus de la grille.</p><p>A gauche :</p><table><thead><tr><th>Bouton</th><th>Quand il apparait</th></tr></thead><tbody><tr><td><strong>Actualiser</strong></td><td>toujours, sauf <code>md_hide_refresh</code></td></tr><tr><td><strong>Ajouter</strong></td><td>avec <code>md_insertable</code></td></tr><tr><td><strong>Actes</strong></td><td>si la table a des actions custom</td></tr><tr><td>Import / Export</td><td>toujours ; la branche import seulement avec <code>md_importable</code></td></tr><tr><td><strong>Rapports</strong></td><td>si au moins un rapport est associe a la route</td></tr><tr><td><strong>Enregistrer les modifications</strong> / <strong>Annuler les modifications</strong></td><td>seulement avec <code>md_inline_cell_edit</code> <strong>et</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A droite : <strong>Gerer l'etat</strong> (precede de la liste des etats sauvegardes, s'il y en a),</p><p><strong>Effacer les filtres</strong> quand les filtres sont sur les colonnes, et <strong>Performance</strong> si</p><p>l'inspector est active sur la route.</p><p>> Les libelles cites plus bas dans cette page <strong>ne sont pas sur cet ecran</strong>, et ce n'est pas un</p><p>> defaut : ceux de l'export/import (<em>Continuer en arriere-plan</em>, <em>Annuler la tache</em>, *Arreter et</p><p>> telecharger partiel<em>, </em>Annuler l'import (rollback)<em>, </em>Arreter et valider partiel*) vivent dans</p><p>> la boite de progression, qui n'existe que pendant un export ou un import ; *Enregistrer les</p><p>> modifications<em> et </em>Annuler les modifications* n'apparaissent qu'avec les deux flags ci-dessus.</p><p>> Ils appartiennent a d'autres moments que la premiere ouverture de la liste.</p><h2>Reference de capture d'ecran (manuel utilisateur)</h2><ul><li><code>manual__grid__01.png</code> : mode <code>inline cell edit</code> dans list-grid.</li><li><code>manual__grid__02.png</code> : mode <code>inline edit</code> (au niveau ligne) dans list-grid.</li></ul><h2>Metadonnees inline editing</h2><p>Configuration dans le <code>md_props_bag</code> de la table metadata :</p><ul><li><code>md_inline_edit</code></li></ul><p> - active l'edition inline de la ligne dans list-grid (cellules editables dans le contexte de la ligne, sans ouverture de popup).</p><p> - utile lorsque vous souhaitez conserver l'UX tabulaire avec une edition rapide par enregistrement.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - active l'edition inline "cellule par cellule" (focus sur la cellule individuelle).</p><p> - note : dans les configurations legacy, il peut apparaitre sous le nom <code>md_inline_cell_editing</code> ; le comportement runtime est le meme.</p><p> - <strong>promotion runtime</strong> : lorsque <code>md_inline_cell_edit</code> est <code>true</code>, le composant force</p><p> a runtime egalement <code>md_inline_edit = true</code> independamment de la valeur en DB.</p><p> Les deux UX necessitent que la colonne d'actions soit visible, elles sont donc mutuellement</p><p> non exclusives au niveau du rendu.</p><ul><li><code>md_batch_save</code></li></ul><p> - active la sauvegarde batch des modifications en attente (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - si utilise conjointement avec inline-cell, les modifications restent en attente jusqu'a la sauvegarde explicite.</p><p> - <strong>prerequis</strong> : <code>md_batch_save</code> n'a d'effet <strong>que</strong> si <code>md_inline_cell_edit</code> est <code>true</code>.</p><p> Avec <code>md_inline_cell_edit:false</code>, le flag est ignore a runtime et les boutons</p><p> "Sauvegarder les modifications / Annuler les modifications" ne sont pas affiches.</p><h3>Combinaisons valides</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Resultat runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>quelconque</td><td>Edition inline au niveau ligne avec crayon. <code>md_batch_save</code> ignore.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Autosave cellule par cellule au blur. <code>md_inline_edit</code> force a <code>true</code> a runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cellule par cellule avec buffer en attente + barre d'outils <code>Sauvegarder / Annuler les modifications</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>quelconque</td><td>Aucune edition inline. <code>md_batch_save</code> ignore.</td></tr></tbody></table><p>Exemple edition inline au niveau ligne :</p><p>Snippet 1:</p><p>Exemple cellule par cellule avec sauvegarde batch :</p><p>Snippet 2:</p><h2>Barre d'outils export/import</h2><ul><li>Export XLS :</li></ul><p> - affiche une boite de dialogue de progression avec pourcentage en temps reel ;</p><p> - actions : <code>Continuer en arriere-plan</code>, <code>Annuler la tache</code>, <code>Interrompre et telecharger le partiel</code> ;</p><p> - en arriere-plan, cree une notification avec progression ; un clic rouvre la boite de dialogue.</p><p> - si le serveur execute deja <code>maxConcurrentExports</code> exports, l'export attend dans une file : la boite de dialogue et la notification affichent "En file d'attente : position N" et il demarre tout seul des qu'une place se libere (annulable aussi pendant l'attente) ;</p><ul><li>Import XLS/XLSX (si <code>md_importable = true</code>) :</li></ul><p> - boite de dialogue de progression apres la confirmation ;</p><p> - actions : <code>Continuer en arriere-plan</code>, <code>Annuler l'import (rollback)</code>, <code>Arreter et commit partiel</code> ;</p><p> - a la fin de l'import, cree une notification recapitulative qui redirige vers la route.</p><h2>Config metadata</h2><p>Parametres cles dans <code>md_props_bag</code> et metadonnees de colonnes.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flags opt-in qui masquent des blocs de la barre d'outils de la list-grid (<code>caption-bar</code>). Tous sous <code>md_props_bag.toolbar.*</code> (parse au runtime comme <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, defaut <code>false</code>) : masque dans la <strong>caption-right</strong> le bouton "Gestion etat" (icone bookmark) + le <code><select></code> des etats enregistres. Utile pour les routes hardcoded / demo ou la fonctionnalite saved-state (persistance par <code>user_id</code> + route via <code>MetaService</code>) n'a pas de sens — par ex. Pattern 3 pur OData sans route metadata enregistree.</li><li><code>hideBatchActions</code> (boolean, defaut <code>false</code>) : masque dans la <strong>caption-left</strong> les boutons "Enregistrer les modifications" (<code>pi-save</code>) + "Annuler les modifications" (<code>pi-times</code>) + l'indicateur de comptage des changements (<code>grid-changes-indicator</code>, badge pencil + count). Generes par le framework quand <code>md_inline_cell_editing</code> + <code>md_batch_save</code> sont actifs. Concu pour les <strong>grids imbriquees dans un parametric-dialog</strong> : le save/cancel du parent persiste le master + les lignes en un seul coup via le batch save framework, et les boutons en double sur la grid imbriquee perturbent l'UX.</li></ul><p>Exemple de lignes imbriquees dans un edit-form custom (patch runtime) :</p><p>Snippet 5:</p><p>Type TS dans <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (propriete <code>extraProps.toolbar</code>). Les flags ne desactivent PAS la logique <code>md_batch_save</code> sous-jacente (les changements restent traces) ; ils suppriment uniquement l'UI de la barre d'outils — le save effectif passe par le flux du parent.</p><h2>md_props_bag: archetypes.list</h2><p>Le composant lit <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code> :</li><li>type : boolean (avec parser tolerant)</li><li>valeurs acceptees : <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>valeur par defaut runtime : <code>true</code> lorsqu'absent ou vide</li><li>effet : distribue les largeurs de colonnes en pourcentage (au lieu de px) lorsqu'il n'y a pas de largeurs utilisateur persistees.</li></ul><ul><li><code>virtualize</code> :</li><li>type : <code>boolean</code> ou <code>object</code></li><li>valeurs acceptees :</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object avec <code>enabled</code> (optionnel) et <code>itemSize</code> (optionnel)</li><li>valeur par defaut runtime : desactive (<code>false</code>) lorsqu'absent</li><li><code>enabled</code> :</li><li>par defaut : <code>true</code> si le noeud <code>virtualize</code> est un objet sans <code>enabled</code>, sinon parser tolerant</li><li>effet : active <code>virtualScroll</code> sur <code>p-table</code></li><li><code>itemSize</code> :</li><li>par defaut : <code>44</code></li><li>effet : definit <code>virtualScrollItemSize</code> (hauteur de la ligne virtuelle en px)</li></ul><ul><li><code>advancedFilter</code> :</li><li>type : boolean (avec parser tolerant)</li><li>valeur par defaut runtime : <code>false</code></li><li>effet :</li><li>lorsque <code>true</code>, la grille masque les icones de filtre de colonne (<code>p-columnFilter</code>) et utilise la <code>wuic-filter-bar</code> au-dessus de la table (au niveau <code>data-repeater</code>/<code>bounded-repeater</code>) pour appliquer les filtres.</li></ul><p>Note operationnelle :</p><ul><li>le suggest <code>md_props_bag</code> dans le metadata editor expose egalement le noeud cochable <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Pagination : md_pagesize et md_page_size_choice</h2><p>La grille utilise <code>md_pagesize</code> comme taille de page par defaut et <code>md_page_size_choice</code> comme liste de valeurs selectionnables dans le paginateur.</p><p>Regles runtime :</p><ul><li>si <code>md_pagesize</code> est superieur a la valeur maximale presente dans <code>md_page_size_choice</code>, le framework ajoute automatiquement <code>md_pagesize</code> a la liste d'options ;</li><li>la liste est normalisee (nombres valides, deduplication, tri croissant).</li></ul><p>Exemple :</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>resultat runtime : <code>10,25,50,100,200</code></li></ul><h2>Activation forcee de la virtualisation sur une taille de page elevee</h2><p>Lorsque l'utilisateur selectionne dans le paginateur une valeur <code>pageSize >= 1000</code> :</p><ul><li>la virtualisation est forcee automatiquement meme si <code>md_props_bag.archetypes.list.virtualize</code> est absent ou desactive ;</li><li><code>virtualScrollItemSize</code> est force a la valeur par defaut <code>44</code>.</li></ul><p>Ce comportement protege le rendu de la table sur des pages tres volumineuses.</p><h2>Evenements et subscriptions (host)</h2><p><code>wuic-list-grid</code> expose des evenements runtime utiles pour intercepter le cycle de rendu et les callbacks p-table cote projet host.</p><p>Evenements disponibles :</p><ul><li><code>onAfterRender</code> : emis a la fin du binding des donnees de la grille (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code> : emis avant le rendu logique de la ligne individuelle ; supporte l'annulation via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code> : emis apres le rendu logique de la ligne individuelle.</li><li><code>onPaging</code> : emis sur les evenements de pagination (<code>p-table onPage</code>).</li><li><code>onSorting</code> : emis sur les evenements de tri (<code>p-table onSort</code>).</li><li><code>onFiltering</code> : emis sur les evenements de filtrage (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code> : emis lors du changement de selection des lignes.</li><li><code>onPTableRowExpand</code> : emis lors de l'expansion d'une ligne.</li><li><code>onPTableRowCollapse</code> : emis lors de la reduction d'une ligne.</li><li><code>onPTableColumnResize</code> : emis lors du redimensionnement d'une colonne.</li><li><code>onPTableColumnReorder</code> : emis lors de la reorganisation des colonnes.</li></ul><h3>Exemple 1 : binding direct dans le template</h3><p>Snippet 7:</p><h3>Exemple 2 : subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — signature reelle (piege)</h2><p><code><wuic-list-grid></code> accepte une entree <code>[rowCustomSelect]</code> pour intercepter la selection d'une ligne (ouverture d'une dialog "choisir un document", flux master-detail, etc.). La signature TypeScript declaree dans <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> est :</p><p>Snippet 9:</p><p><strong>Mais au runtime la callback est invoquee avec les arguments inverses</strong> — le framework appelle <code>rowCustomSelect($event, rowData, dt)</code> (voir <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> et <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptome en cas d'ordre incorrect : <code>rowData?.id</code> est undefined → guard precoce dans votre handler → la callback retourne silencieusement et votre dialog/action ne demarre pas. Aucune erreur en console.</p><p>Forme correcte (alignee a l'invocation runtime) :</p><p>Snippet 10:</p><p>Utilisation dans le template :</p><p>Snippet 11:</p><p>> Note : les tests dans <code>designer.component.spec.ts</code> (par ex. ligne 512) invoquent la callback avec <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirmant l'ordre <code>($event, rowData, dt)</code>. Si le framework finit par aligner la signature declaree, cette page sera mise a jour.</p>",
|
|
15739
|
+
"html": "<h1>List Grid</h1><p>Composant principal pour les listes tabulaires avec filtres, tri, pagination cote serveur et actions sur les lignes.</p><h2>Cas d'utilisation</h2><ul><li>CRUD tabulaires enterprise.</li><li>Rapports operationnels avec filtres multi-colonnes.</li><li>Jeux de donnees tres volumineux avec <code>cursorMode</code>.</li></ul><h2>Ce que la toolbar affiche par defaut</h2><p>En ouvrant une route fraichement scaffoldee, la caption-bar se trouve au-dessus de la grille.</p><p>A gauche :</p><table><thead><tr><th>Bouton</th><th>Quand il apparait</th></tr></thead><tbody><tr><td><strong>Actualiser</strong></td><td>toujours, sauf <code>md_hide_refresh</code></td></tr><tr><td><strong>Ajouter</strong></td><td>avec <code>md_insertable</code></td></tr><tr><td><strong>Actes</strong></td><td>si la table a des actions custom</td></tr><tr><td>Import / Export</td><td>toujours ; la branche import seulement avec <code>md_importable</code></td></tr><tr><td><strong>Rapports</strong></td><td>si au moins un rapport est associe a la route</td></tr><tr><td><strong>Enregistrer les modifications</strong> / <strong>Annuler les modifications</strong></td><td>seulement avec <code>md_inline_cell_edit</code> <strong>et</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A droite : <strong>Gerer l'etat</strong> (precede de la liste des etats sauvegardes, s'il y en a),</p><p><strong>Effacer les filtres</strong> quand les filtres sont sur les colonnes, et <strong>Performance</strong> si</p><p>l'inspector est active sur la route.</p><p>> Les libelles cites plus bas dans cette page <strong>ne sont pas sur cet ecran</strong>, et ce n'est pas un</p><p>> defaut : ceux de l'export/import (<em>Continuer en arriere-plan</em>, <em>Annuler la tache</em>, *Arreter et</p><p>> telecharger partiel<em>, </em>Annuler l'import (rollback)<em>, </em>Arreter et valider partiel*) vivent dans</p><p>> la boite de progression, qui n'existe que pendant un export ou un import ; *Enregistrer les</p><p>> modifications<em> et </em>Annuler les modifications* n'apparaissent qu'avec les deux flags ci-dessus.</p><p>> Ils appartiennent a d'autres moments que la premiere ouverture de la liste.</p><h2>Reference de capture d'ecran (manuel utilisateur)</h2><ul><li><code>manual__grid__01.png</code> : mode <code>inline cell edit</code> dans list-grid.</li><li><code>manual__grid__02.png</code> : mode <code>inline edit</code> (au niveau ligne) dans list-grid.</li></ul><h2>Metadonnees inline editing</h2><p>Configuration dans le <code>md_props_bag</code> de la table metadata :</p><ul><li><code>md_inline_edit</code></li></ul><p> - active l'edition inline de la ligne dans list-grid (cellules editables dans le contexte de la ligne, sans ouverture de popup).</p><p> - utile lorsque vous souhaitez conserver l'UX tabulaire avec une edition rapide par enregistrement.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - active l'edition inline "cellule par cellule" (focus sur la cellule individuelle).</p><p> - note : dans les configurations legacy, il peut apparaitre sous le nom <code>md_inline_cell_editing</code> ; le comportement runtime est le meme.</p><p> - <strong>promotion runtime</strong> : lorsque <code>md_inline_cell_edit</code> est <code>true</code>, le composant force</p><p> a runtime egalement <code>md_inline_edit = true</code> independamment de la valeur en DB.</p><p> Les deux UX necessitent que la colonne d'actions soit visible, elles sont donc mutuellement</p><p> non exclusives au niveau du rendu.</p><ul><li><code>md_batch_save</code></li></ul><p> - active la sauvegarde batch des modifications en attente (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - si utilise conjointement avec inline-cell, les modifications restent en attente jusqu'a la sauvegarde explicite.</p><p> - <strong>prerequis</strong> : <code>md_batch_save</code> n'a d'effet <strong>que</strong> si <code>md_inline_cell_edit</code> est <code>true</code>.</p><p> Avec <code>md_inline_cell_edit:false</code>, le flag est ignore a runtime et les boutons</p><p> "Sauvegarder les modifications / Annuler les modifications" ne sont pas affiches.</p><h3>Combinaisons valides</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Resultat runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>quelconque</td><td>Edition inline au niveau ligne avec crayon. <code>md_batch_save</code> ignore.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Autosave cellule par cellule au blur. <code>md_inline_edit</code> force a <code>true</code> a runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cellule par cellule avec buffer en attente + barre d'outils <code>Sauvegarder / Annuler les modifications</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>quelconque</td><td>Aucune edition inline. <code>md_batch_save</code> ignore.</td></tr></tbody></table><p>Exemple edition inline au niveau ligne :</p><p>Snippet 1:</p><p>Exemple cellule par cellule avec sauvegarde batch :</p><p>Snippet 2:</p><h2>Barre d'outils export/import</h2><ul><li>Export XLS :</li></ul><p> - affiche une boite de dialogue de progression avec pourcentage en temps reel ;</p><p> - actions : <code>Continuer en arriere-plan</code>, <code>Annuler la tache</code>, <code>Interrompre et telecharger le partiel</code> ;</p><p> - en arriere-plan, cree une notification avec progression ; un clic rouvre la boite de dialogue.</p><p> - si le serveur execute deja <code>maxConcurrentExports</code> exports, l'export attend dans une file : la boite de dialogue et la notification affichent "En file d'attente : position N" et il demarre tout seul des qu'une place se libere (annulable aussi pendant l'attente) ;</p><p> - SQL Server : si la base de donnees a <code>ALLOW_SNAPSHOT_ISOLATION ON</code>, l'export lit en isolation snapshot et ne bloque pas les ecritures sur la table pendant qu'il ecrit le fichier (sans cela, un export long garde ses verrous de lecture et les insert/update sur la meme table attendent sa fin). L'option s'active une fois sur la base (<code>ALTER DATABASE [<base de donnees>] SET ALLOW_SNAPSHOT_ISOLATION ON</code>) et ne change pas le comportement des autres lectures ; elle cohabite avec <code>READ_COMMITTED_SNAPSHOT ON</code>. La base du tutoriel a <code>READ_COMMITTED_SNAPSHOT ON</code> ;</p><ul><li>Import XLS/XLSX (si <code>md_importable = true</code>) :</li></ul><p> - boite de dialogue de progression apres la confirmation ;</p><p> - actions : <code>Continuer en arriere-plan</code>, <code>Annuler l'import (rollback)</code>, <code>Arreter et commit partiel</code> ;</p><p> - a la fin de l'import, cree une notification recapitulative qui redirige vers la route.</p><h2>Config metadata</h2><p>Parametres cles dans <code>md_props_bag</code> et metadonnees de colonnes.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flags opt-in qui masquent des blocs de la barre d'outils de la list-grid (<code>caption-bar</code>). Tous sous <code>md_props_bag.toolbar.*</code> (parse au runtime comme <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, defaut <code>false</code>) : masque dans la <strong>caption-right</strong> le bouton "Gestion etat" (icone bookmark) + le <code><select></code> des etats enregistres. Utile pour les routes hardcoded / demo ou la fonctionnalite saved-state (persistance par <code>user_id</code> + route via <code>MetaService</code>) n'a pas de sens — par ex. Pattern 3 pur OData sans route metadata enregistree.</li><li><code>hideBatchActions</code> (boolean, defaut <code>false</code>) : masque dans la <strong>caption-left</strong> les boutons "Enregistrer les modifications" (<code>pi-save</code>) + "Annuler les modifications" (<code>pi-times</code>) + l'indicateur de comptage des changements (<code>grid-changes-indicator</code>, badge pencil + count). Generes par le framework quand <code>md_inline_cell_editing</code> + <code>md_batch_save</code> sont actifs. Concu pour les <strong>grids imbriquees dans un parametric-dialog</strong> : le save/cancel du parent persiste le master + les lignes en un seul coup via le batch save framework, et les boutons en double sur la grid imbriquee perturbent l'UX.</li></ul><p>Exemple de lignes imbriquees dans un edit-form custom (patch runtime) :</p><p>Snippet 5:</p><p>Type TS dans <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (propriete <code>extraProps.toolbar</code>). Les flags ne desactivent PAS la logique <code>md_batch_save</code> sous-jacente (les changements restent traces) ; ils suppriment uniquement l'UI de la barre d'outils — le save effectif passe par le flux du parent.</p><h2>md_props_bag: archetypes.list</h2><p>Le composant lit <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code> :</li><li>type : boolean (avec parser tolerant)</li><li>valeurs acceptees : <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>valeur par defaut runtime : <code>true</code> lorsqu'absent ou vide</li><li>effet : distribue les largeurs de colonnes en pourcentage (au lieu de px) lorsqu'il n'y a pas de largeurs utilisateur persistees.</li></ul><ul><li><code>virtualize</code> :</li><li>type : <code>boolean</code> ou <code>object</code></li><li>valeurs acceptees :</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object avec <code>enabled</code> (optionnel) et <code>itemSize</code> (optionnel)</li><li>valeur par defaut runtime : desactive (<code>false</code>) lorsqu'absent</li><li><code>enabled</code> :</li><li>par defaut : <code>true</code> si le noeud <code>virtualize</code> est un objet sans <code>enabled</code>, sinon parser tolerant</li><li>effet : active <code>virtualScroll</code> sur <code>p-table</code></li><li><code>itemSize</code> :</li><li>par defaut : <code>44</code></li><li>effet : definit <code>virtualScrollItemSize</code> (hauteur de la ligne virtuelle en px)</li></ul><ul><li><code>advancedFilter</code> :</li><li>type : boolean (avec parser tolerant)</li><li>valeur par defaut runtime : <code>false</code></li><li>effet :</li><li>lorsque <code>true</code>, la grille masque les icones de filtre de colonne (<code>p-columnFilter</code>) et utilise la <code>wuic-filter-bar</code> au-dessus de la table (au niveau <code>data-repeater</code>/<code>bounded-repeater</code>) pour appliquer les filtres.</li></ul><p>Note operationnelle :</p><ul><li>le suggest <code>md_props_bag</code> dans le metadata editor expose egalement le noeud cochable <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Pagination : md_pagesize et md_page_size_choice</h2><p>La grille utilise <code>md_pagesize</code> comme taille de page par defaut et <code>md_page_size_choice</code> comme liste de valeurs selectionnables dans le paginateur.</p><p>Regles runtime :</p><ul><li>si <code>md_pagesize</code> est superieur a la valeur maximale presente dans <code>md_page_size_choice</code>, le framework ajoute automatiquement <code>md_pagesize</code> a la liste d'options ;</li><li>la liste est normalisee (nombres valides, deduplication, tri croissant).</li></ul><p>Exemple :</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>resultat runtime : <code>10,25,50,100,200</code></li></ul><h2>Activation forcee de la virtualisation sur une taille de page elevee</h2><p>Lorsque l'utilisateur selectionne dans le paginateur une valeur <code>pageSize >= 1000</code> :</p><ul><li>la virtualisation est forcee automatiquement meme si <code>md_props_bag.archetypes.list.virtualize</code> est absent ou desactive ;</li><li><code>virtualScrollItemSize</code> est force a la valeur par defaut <code>44</code>.</li></ul><p>Ce comportement protege le rendu de la table sur des pages tres volumineuses.</p><h2>Evenements et subscriptions (host)</h2><p><code>wuic-list-grid</code> expose des evenements runtime utiles pour intercepter le cycle de rendu et les callbacks p-table cote projet host.</p><p>Evenements disponibles :</p><ul><li><code>onAfterRender</code> : emis a la fin du binding des donnees de la grille (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code> : emis avant le rendu logique de la ligne individuelle ; supporte l'annulation via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code> : emis apres le rendu logique de la ligne individuelle.</li><li><code>onPaging</code> : emis sur les evenements de pagination (<code>p-table onPage</code>).</li><li><code>onSorting</code> : emis sur les evenements de tri (<code>p-table onSort</code>).</li><li><code>onFiltering</code> : emis sur les evenements de filtrage (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code> : emis lors du changement de selection des lignes.</li><li><code>onPTableRowExpand</code> : emis lors de l'expansion d'une ligne.</li><li><code>onPTableRowCollapse</code> : emis lors de la reduction d'une ligne.</li><li><code>onPTableColumnResize</code> : emis lors du redimensionnement d'une colonne.</li><li><code>onPTableColumnReorder</code> : emis lors de la reorganisation des colonnes.</li></ul><h3>Exemple 1 : binding direct dans le template</h3><p>Snippet 7:</p><h3>Exemple 2 : subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — signature reelle (piege)</h2><p><code><wuic-list-grid></code> accepte une entree <code>[rowCustomSelect]</code> pour intercepter la selection d'une ligne (ouverture d'une dialog "choisir un document", flux master-detail, etc.). La signature TypeScript declaree dans <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> est :</p><p>Snippet 9:</p><p><strong>Mais au runtime la callback est invoquee avec les arguments inverses</strong> — le framework appelle <code>rowCustomSelect($event, rowData, dt)</code> (voir <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> et <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptome en cas d'ordre incorrect : <code>rowData?.id</code> est undefined → guard precoce dans votre handler → la callback retourne silencieusement et votre dialog/action ne demarre pas. Aucune erreur en console.</p><p>Forme correcte (alignee a l'invocation runtime) :</p><p>Snippet 10:</p><p>Utilisation dans le template :</p><p>Snippet 11:</p><p>> Note : les tests dans <code>designer.component.spec.ts</code> (par ex. ligne 512) invoquent la callback avec <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirmant l'ordre <code>($event, rowData, dt)</code>. Si le framework finit par aligner la signature declaree, cette page sera mise a jour.</p>",
|
|
15732
15740
|
"codeSamples": [
|
|
15733
15741
|
{
|
|
15734
15742
|
"id": "code_1",
|
|
@@ -20631,10 +20639,14 @@ const frameworkDocsContent = {
|
|
|
20631
20639
|
},
|
|
20632
20640
|
{
|
|
20633
20641
|
"id": "sec_5",
|
|
20634
|
-
"title": "
|
|
20642
|
+
"title": "Tables a cle MAX"
|
|
20635
20643
|
},
|
|
20636
20644
|
{
|
|
20637
20645
|
"id": "sec_6",
|
|
20646
|
+
"title": "Comportement PK existante (import insertion uniquement)"
|
|
20647
|
+
},
|
|
20648
|
+
{
|
|
20649
|
+
"id": "sec_7",
|
|
20638
20650
|
"title": "Colonnes du fichier et lookups (export et import)"
|
|
20639
20651
|
}
|
|
20640
20652
|
],
|
|
@@ -20642,7 +20654,7 @@ const frameworkDocsContent = {
|
|
|
20642
20654
|
{
|
|
20643
20655
|
"id": "overview",
|
|
20644
20656
|
"title": "Overview",
|
|
20645
|
-
"html": "<h1>Import</h1><p>Active l'importation de donnees depuis des fichiers Excel (<code>.xls</code>, <code>.xlsx</code>) dans la route courante de la table metadata.</p><p>Lorsqu'il est actif, un bouton apparait dans la barre d'outils du <code>List Grid</code> (<code>Import XLS/XLSX</code>) qui ouvre le selecteur de fichier et envoie le fichier a la methode d'import deja disponible cote backend.</p><h2>Metadonnee table</h2><p>Le toggle principal est :</p><ul><li><code>md_importable</code></li></ul><p> Signification : affiche/masque le bouton d'import dans la barre d'outils du <code>List Grid</code>.</p><p> Valeurs : <code>true | false</code>.</p><p> Defaut : <code>false</code> (si absent).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Les options d'import se configurent dans <code>extraProps.import</code> (derivees de <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Notes operationnelles</h2><ul><li>Le bouton est visible si <code>md_importable = true</code>.</li><li>Le fichier est valide cote client par extension (<code>xls</code>, <code>xlsx</code>) avant l'upload.</li><li>L'import est execute sur la route courante (<code>md_route_name</code>) de la datasource active.</li><li><code>skipsettings</code> :</li></ul><p> - <code>false</code> (defaut) : ouvre le dialogue intermediaire pour choisir les options d'import avant l'upload.</p><p> - <code>true</code> : saute le dialogue et lance l'upload/import direct en utilisant les options deja definies dans <code>md_props_bag.import</code>.</p><ul><li>Valeurs par defaut conseillee dans le suggest :</li></ul><p> - <code>use_column_captions = "C"</code> (utiliser les captions de colonnes).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>Interface et progression</h2><ul><li>Apres la confirmation d'import, un dialogue de progression s'ouvre avec le pourcentage en temps reel.</li><li>Actions disponibles :</li></ul><p> - <code>Continua in background</code> : ferme le dialogue et cree une notification de progression.</p><p> - <code>Annulla import (rollback)</code> : annule et effectue un rollback.</p><p> - <code>Stop e commit parziale</code> : interrompt et confirme ce qui a ete fait.</p><ul><li>A la fin de l'import, une notification recapitulative est creee (meme texte que le toast) ; le clic mene a la route de l'import sans rafraichissement si l'on est deja sur la meme page.</li></ul><h2>Comportement PK existante (import insertion uniquement)</h2><p>Si <code>import_type = "I"</code> et la PK de l'enregistrement existe deja :</p><ul><li>l'insertion est ignoree ;</li><li>l'enregistrement est comptabilise dans le recapitulatif comme "insertions ignorees (PK existante)".</li></ul><h2>Colonnes du fichier et lookups (export et import)</h2><p>L'export XLS et l'import suivent les mêmes règles : un fichier exporté se réimporte tel quel.</p><h3>En-têtes</h3><ul><li>Chaque colonne a pour en-tête sa caption (<code>mc_display_string_in_view</code> ; si vide, le nom de la colonne).</li><li>Si deux colonnes du même fichier ont la même caption, chacune reçoit son nom physique entre parenthèses : <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Sans collision, les en-têtes restent ceux de toujours.</li><li>L'import reconnaît une colonne par sa caption, par sa caption suivie du nom physique (ou du nom de colonne) entre parenthèses, ou par son nom physique / nom de colonne.</li><li>Un en-tête qui correspond à plusieurs colonnes (par exemple un ancien fichier avec deux colonnes <code>People</code>) est refusé avec l'erreur "Ambiguous column" : il faut l'écrire sous la forme <code>caption (nom physique)</code>.</li></ul><h3>Colonnes lookup : <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> décide comment voyagent les colonnes lookup (<code>mc_ui_column_type = lookupByID</code>) :</p><table><thead><tr><th>Valeur</th><th>Dans le fichier</th><th>Notes</th></tr></thead><tbody><tr><td><code>description</code> (défaut)</td><td>la description de l'enregistrement lié, sous la caption</td><td>comme toujours</td></tr><tr><td><code>key</code></td><td>la clé de l'enregistrement lié, sous la caption</td><td></td></tr><tr><td><code>both</code></td><td>deux colonnes : la description sous la caption, la clé sous le nom physique (<code>Commande</code> + <code>OrderID</code>)</td><td>si la caption est le nom physique, la colonne description devient <code>caption (champ texte du lookup)</code>, par ex. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>L'export suit la valeur de la route ; sans <code>fkey_mode</code>, <code>use_descriptive_fkey</code> s'applique (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Dans la boîte de dialogue d'import, le choix "Colonnes lookup dans le fichier" est présélectionné avec la même valeur et peut être modifié pour un import.</li></ul><h3>De la description à la clé</h3><ul><li><strong>Clé seule</strong> : utilisée telle quelle.</li><li><strong>Description seule</strong> : on cherche l'enregistrement lié ayant cette description (champ texte du lookup).</li></ul><p> - Un seul enregistrement : sa clé est utilisée.</p><p> - Aucun : la ligne est en erreur.</p><p> - Plusieurs enregistrements avec la même description : si la ligne met à jour un enregistrement existant et que la clé qu'il a déjà correspond à cette description, le lien reste inchangé (l'utilisateur n'y a pas touché). Sinon, et toujours pour les nouvelles lignes, c'est une erreur qui liste les clés candidates : pour insérer il faut la clé, donc <code>key</code> ou <code>both</code>.</p><ul><li><strong>Clé et description (`both`)</strong> : la clé l'emporte si son enregistrement a cette description ; si elles ne correspondent pas (l'une a été modifiée et pas l'autre) la ligne est en erreur.</li><li>Une clé primaire qui est aussi un lookup (table 1:1) est résolue avant le contrôle d'existence de l'enregistrement.</li><li>Avec <code>commit_level</code> <code>R</code> ou <code>I</code>, une erreur de lookup arrête l'import sans enregistrer ; avec <code>C</code> ou <code>T</code>, la ligne est ignorée et l'import continue.</li></ul><h3>Dates</h3><p>Les cellules date écrites par l'export (nombre avec un format date, comme dans Excel) sont lues comme des dates : un fichier exporté puis réimporté sans modification n'est plus refusé sur ses colonnes date.</p>",
|
|
20657
|
+
"html": "<h1>Import</h1><p>Active l'importation de donnees depuis des fichiers Excel (<code>.xls</code>, <code>.xlsx</code>) dans la route courante de la table metadata.</p><p>Lorsqu'il est actif, un bouton apparait dans la barre d'outils du <code>List Grid</code> (<code>Import XLS/XLSX</code>) qui ouvre le selecteur de fichier et envoie le fichier a la methode d'import deja disponible cote backend.</p><h2>Metadonnee table</h2><p>Le toggle principal est :</p><ul><li><code>md_importable</code></li></ul><p> Signification : affiche/masque le bouton d'import dans la barre d'outils du <code>List Grid</code>.</p><p> Valeurs : <code>true | false</code>.</p><p> Defaut : <code>false</code> (si absent).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Les options d'import se configurent dans <code>extraProps.import</code> (derivees de <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Notes operationnelles</h2><ul><li>Le bouton est visible si <code>md_importable = true</code>.</li><li>Le fichier est valide cote client par extension (<code>xls</code>, <code>xlsx</code>) avant l'upload.</li><li>L'import est execute sur la route courante (<code>md_route_name</code>) de la datasource active.</li><li><code>skipsettings</code> :</li></ul><p> - <code>false</code> (defaut) : ouvre le dialogue intermediaire pour choisir les options d'import avant l'upload.</p><p> - <code>true</code> : saute le dialogue et lance l'upload/import direct en utilisant les options deja definies dans <code>md_props_bag.import</code>.</p><ul><li>Valeurs par defaut conseillee dans le suggest :</li></ul><p> - <code>use_column_captions = "C"</code> (utiliser les captions de colonnes).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>Interface et progression</h2><ul><li>Apres la confirmation d'import, un dialogue de progression s'ouvre avec le pourcentage en temps reel.</li><li>Actions disponibles :</li></ul><p> - <code>Continua in background</code> : ferme le dialogue et cree une notification de progression.</p><p> - <code>Annulla import (rollback)</code> : annule et effectue un rollback.</p><p> - <code>Stop e commit parziale</code> : interrompt et confirme ce qui a ete fait.</p><ul><li>A la fin de l'import, une notification recapitulative est creee (meme texte que le toast) ; le clic mene a la route de l'import sans rafraichissement si l'on est deja sur la meme page.</li></ul><h2>Tables a cle MAX</h2><p>Sur les routes avec <code>md_primary_key_type = "MAX"</code> (et sur la "cle dependante" des cles composees) la cle de chaque nouvelle ligne est le maximum + 1, calcule dans l'insert avec un verrou sur la table : les nouvelles lignes du meme fichier recoivent des cles consecutives et les insertions simultanees n'entrent pas en collision. Le verrou dure jusqu'a la fin de l'import (une transaction par fichier) : pendant ce temps les autres insertions sur la meme table attendent, et sur Oracle aussi les update et delete. Pour de gros fichiers sur des tables tres utilisees, mettez la cle dans le fichier ou passez la table en <code>IDENTITY</code>/<code>SEQUENCE</code>.</p><h2>Comportement PK existante (import insertion uniquement)</h2><p>Si <code>import_type = "I"</code> et la PK de l'enregistrement existe deja :</p><ul><li>l'insertion est ignoree ;</li><li>l'enregistrement est comptabilise dans le recapitulatif comme "insertions ignorees (PK existante)".</li></ul><h2>Colonnes du fichier et lookups (export et import)</h2><p>L'export XLS et l'import suivent les mêmes règles : un fichier exporté se réimporte tel quel.</p><h3>En-têtes</h3><ul><li>Chaque colonne a pour en-tête sa caption (<code>mc_display_string_in_view</code> ; si vide, le nom de la colonne).</li><li>Si deux colonnes du même fichier ont la même caption, chacune reçoit son nom physique entre parenthèses : <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Sans collision, les en-têtes restent ceux de toujours.</li><li>L'import reconnaît une colonne par sa caption, par sa caption suivie du nom physique (ou du nom de colonne) entre parenthèses, ou par son nom physique / nom de colonne.</li><li>Un en-tête qui correspond à plusieurs colonnes (par exemple un ancien fichier avec deux colonnes <code>People</code>) est refusé avec l'erreur "Ambiguous column" : il faut l'écrire sous la forme <code>caption (nom physique)</code>.</li></ul><h3>Colonnes lookup : <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> décide comment voyagent les colonnes lookup (<code>mc_ui_column_type = lookupByID</code>) :</p><table><thead><tr><th>Valeur</th><th>Dans le fichier</th><th>Notes</th></tr></thead><tbody><tr><td><code>description</code> (défaut)</td><td>la description de l'enregistrement lié, sous la caption</td><td>comme toujours</td></tr><tr><td><code>key</code></td><td>la clé de l'enregistrement lié, sous la caption</td><td></td></tr><tr><td><code>both</code></td><td>deux colonnes : la description sous la caption, la clé sous le nom physique (<code>Commande</code> + <code>OrderID</code>)</td><td>si la caption est le nom physique, la colonne description devient <code>caption (champ texte du lookup)</code>, par ex. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>L'export suit la valeur de la route ; sans <code>fkey_mode</code>, <code>use_descriptive_fkey</code> s'applique (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Dans la boîte de dialogue d'import, le choix "Colonnes lookup dans le fichier" est présélectionné avec la même valeur et peut être modifié pour un import.</li></ul><h3>De la description à la clé</h3><ul><li><strong>Clé seule</strong> : utilisée telle quelle.</li><li><strong>Description seule</strong> : on cherche l'enregistrement lié ayant cette description (champ texte du lookup).</li></ul><p> - Un seul enregistrement : sa clé est utilisée.</p><p> - Aucun : la ligne est en erreur.</p><p> - Plusieurs enregistrements avec la même description : si la ligne met à jour un enregistrement existant et que la clé qu'il a déjà correspond à cette description, le lien reste inchangé (l'utilisateur n'y a pas touché). Sinon, et toujours pour les nouvelles lignes, c'est une erreur qui liste les clés candidates : pour insérer il faut la clé, donc <code>key</code> ou <code>both</code>.</p><ul><li><strong>Clé et description (`both`)</strong> : la clé l'emporte si son enregistrement a cette description ; si elles ne correspondent pas (l'une a été modifiée et pas l'autre) la ligne est en erreur.</li><li>Une clé primaire qui est aussi un lookup (table 1:1) est résolue avant le contrôle d'existence de l'enregistrement.</li><li>Avec <code>commit_level</code> <code>R</code> ou <code>I</code>, une erreur de lookup arrête l'import sans enregistrer ; avec <code>C</code> ou <code>T</code>, la ligne est ignorée et l'import continue.</li></ul><h3>Dates</h3><p>Les cellules date écrites par l'export (nombre avec un format date, comme dans Excel) sont lues comme des dates : un fichier exporté puis réimporté sans modification n'est plus refusé sur ses colonnes date.</p>",
|
|
20646
20658
|
"codeSamples": [
|
|
20647
20659
|
{
|
|
20648
20660
|
"id": "code_1",
|
|
@@ -22565,7 +22577,7 @@ const frameworkDocsContent = {
|
|
|
22565
22577
|
{
|
|
22566
22578
|
"id": "overview",
|
|
22567
22579
|
"title": "Overview",
|
|
22568
|
-
"html": "<h1>List Grid</h1><p>Componente principal para listas tabulares con filtros, sorting, paging server-side y acciones de fila.</p><h2>Casos de uso</h2><ul><li>CRUD tabulares enterprise.</li><li>Informes operativos con filtros multi-columna.</li><li>Datasets muy grandes con <code>cursorMode</code>.</li></ul><h2>Qué muestra la toolbar por defecto</h2><p>Al abrir una ruta recién scaffoldada, la caption-bar está encima de la rejilla. A la izquierda:</p><table><thead><tr><th>Botón</th><th>Cuándo aparece</th></tr></thead><tbody><tr><td><strong>Actualizar</strong></td><td>siempre, salvo <code>md_hide_refresh</code></td></tr><tr><td><strong>Agregar</strong></td><td>con <code>md_insertable</code></td></tr><tr><td><strong>Comportamiento</strong></td><td>si la tabla tiene acciones personalizadas</td></tr><tr><td>Import / Export</td><td>siempre; la rama de import solo con <code>md_importable</code></td></tr><tr><td><strong>Informes</strong></td><td>si hay al menos un informe asociado a la ruta</td></tr><tr><td><strong>Guardar cambios</strong> / <strong>Descartar cambios</strong></td><td>solo con <code>md_inline_cell_edit</code> <strong>y</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A la derecha: <strong>Gestionar estado</strong> (precedido por el desplegable de estados guardados, si los</p><p>hay), <strong>Limpiar filtros</strong> cuando los filtros están en las columnas, y <strong>Rendimiento</strong> si el</p><p>inspector está habilitado en la ruta.</p><p>> Las etiquetas citadas más abajo en esta página <strong>no están en esa pantalla</strong>, y no es un</p><p>> defecto: las de export/import (<em>Continuar en segundo plano</em>, <em>Cancelar tarea</em>, *Detener y</p><p>> descargar parcial<em>, </em>Cancelar import (rollback)<em>, </em>Detener y confirmar parcial*) viven en el</p><p>> diálogo de progreso, que solo existe mientras un export o un import está en curso; *Guardar</p><p>> cambios<em> y </em>Descartar cambios* solo aparecen con los dos flags de arriba. Pertenecen a</p><p>> momentos distintos de la primera apertura de la lista.</p><h2>Screenshot de referencia (manual de usuario)</h2><ul><li><code>manual__grid__01.png</code>: modalidad <code>inline cell edit</code> en list-grid.</li><li><code>manual__grid__02.png</code>: modalidad <code>inline edit</code> (row-level) en list-grid.</li></ul><h2>Metadatos de inline editing</h2><p>Configuración en el <code>md_props_bag</code> de la tabla metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - habilita el editing inline de la fila en list-grid (celdas editables en contexto de fila, sin apertura de popup).</p><p> - útil cuando se quiere mantener la UX de tabla con edición rápida por registro.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - habilita el editing inline "celda por celda" (foco en la celda individual).</p><p> - nota: en configuraciones legacy puede aparecer como <code>md_inline_cell_editing</code>; el comportamiento runtime es el mismo.</p><p> - <strong>promoción runtime</strong>: cuando <code>md_inline_cell_edit</code> es <code>true</code>, el componente fuerza</p><p> en runtime también <code>md_inline_edit = true</code> independientemente del valor en DB.</p><p> Ambas UX necesitan la action column visible, por lo que son mutuamente</p><p> no-exclusivas a nivel de renderizado.</p><ul><li><code>md_batch_save</code></li></ul><p> - habilita el guardado batch de los cambios pendientes (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - si se usa junto con inline-cell, los cambios quedan pending hasta el guardado explícito.</p><p> - <strong>prerequisito</strong>: <code>md_batch_save</code> tiene efecto <strong>solo</strong> si <code>md_inline_cell_edit</code> es <code>true</code>.</p><p> Con <code>md_inline_cell_edit:false</code> el flag se ignora en runtime y los botones</p><p> "Guardar cambios / Cancelar cambios" no se renderizan.</p><h3>Combinaciones válidas</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Resultado runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>cualquiera</td><td>Inline edit a nivel de fila con pencil. <code>md_batch_save</code> ignorado.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forzado a <code>true</code> en runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell con buffer pending + toolbar <code>Guardar / Cancelar cambios</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>cualquiera</td><td>Sin inline editing. <code>md_batch_save</code> ignorado.</td></tr></tbody></table><p>Ejemplo row-level inline edit:</p><p>Snippet 1:</p><p>Ejemplo cell-by-cell con batch save:</p><p>Snippet 2:</p><h2>Toolbar export/import</h2><ul><li>Export XLS:</li></ul><p> - muestra diálogo de progreso con porcentaje en tiempo real;</p><p> - acciones: <code>Continuar en background</code>, <code>Cancelar tarea</code>, <code>Interrumpir y descargar parcial</code>;</p><p> - en background crea una notificación con progreso; el clic reabre el diálogo.</p><p> - si el servidor ya ejecuta <code>maxConcurrentExports</code> exportaciones, la exportación espera en cola: el diálogo y la notificación muestran "En cola: posición N" y arranca sola en cuanto queda un hueco libre (también se puede cancelar mientras espera);</p><ul><li>Import XLS/XLSX (si <code>md_importable = true</code>):</li></ul><p> - diálogo de progreso tras la confirmación;</p><p> - acciones: <code>Continuar en background</code>, <code>Cancelar import (rollback)</code>, <code>Detener y commit parcial</code>;</p><p> - al finalizar el import crea una notificación de resumen que lleva a la route.</p><h2>Config metadata</h2><p>Ajustes clave en <code>md_props_bag</code> y metadatos de columna.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flags opt-in que ocultan bloques de la toolbar de la list-grid (<code>caption-bar</code>). Todos bajo <code>md_props_bag.toolbar.*</code> (parseado en runtime como <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): oculta en la <strong>caption-right</strong> el botón "Gestionar estado" (icono bookmark) + el <code><select></code> de estados guardados. Útil para rutas hardcoded / demo donde el feature saved-state (persistencia por <code>user_id</code> + ruta vía <code>MetaService</code>) no tiene sentido — p. ej. Pattern 3 puro OData sin route metadata registrada.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): oculta en la <strong>caption-left</strong> los botones "Guardar cambios" (<code>pi-save</code>) + "Descartar cambios" (<code>pi-times</code>) + el indicador de conteo de changes (<code>grid-changes-indicator</code>, badge pencil + count). Generados por el framework cuando <code>md_inline_cell_editing</code> + <code>md_batch_save</code> están activos. Diseñado para <strong>nested grids dentro de un parametric-dialog</strong>: el save/cancel del padre persiste master + filas en un golpe vía batch save framework, y los botones duplicados en la nested grid confunden la UX.</li></ul><p>Ejemplo nested rows en custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>Tipo TS en <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (propiedad <code>extraProps.toolbar</code>). Los flags NO deshabilitan la lógica <code>md_batch_save</code> subyacente (los changes siguen siendo trackeados); solo eliminan la UI de la toolbar — el save efectivo pasa por el flujo del padre.</p><h2>md_props_bag: archetypes.list</h2><p>El componente lee <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>tipo: boolean (con parser tolerante)</li><li>valores aceptados: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>default runtime: <code>true</code> cuando ausente o vacío</li><li>efecto: distribuye los anchos de columna en porcentaje (en lugar de px) cuando no hay anchos de usuario persistidos.</li></ul><ul><li><code>virtualize</code>:</li><li>tipo: <code>boolean</code> o <code>object</code></li><li>valores aceptados:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object con <code>enabled</code> (opcional) y <code>itemSize</code> (opcional)</li><li>default runtime: deshabilitado (<code>false</code>) cuando ausente</li><li><code>enabled</code>:</li><li>default: <code>true</code> si el nodo <code>virtualize</code> es un object sin <code>enabled</code>, de lo contrario parser tolerante</li><li>efecto: habilita <code>virtualScroll</code> en <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>efecto: establece <code>virtualScrollItemSize</code> (altura de fila virtual en px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>tipo: boolean (con parser tolerante)</li><li>default runtime: <code>false</code></li><li>efecto:</li><li>cuando <code>true</code>, la grilla oculta los iconos de filtro de columna (<code>p-columnFilter</code>) y usa la <code>wuic-filter-bar</code> sobre la tabla (a nivel <code>data-repeater</code>/<code>bounded-repeater</code>) para aplicar los filtros.</li></ul><p>Nota operativa:</p><ul><li>el suggest <code>md_props_bag</code> en el metadata editor expone también el nodo checkeable <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Paging: md_pagesize y md_page_size_choice</h2><p>La grilla usa <code>md_pagesize</code> como tamaño de página por defecto y <code>md_page_size_choice</code> como lista de valores seleccionables en el paginador.</p><p>Reglas runtime:</p><ul><li>si <code>md_pagesize</code> es mayor que el valor máximo presente en <code>md_page_size_choice</code>, el framework agrega automáticamente <code>md_pagesize</code> a la lista de opciones;</li><li>la lista se normaliza (números válidos, deduplicación, orden ascendente).</li></ul><p>Ejemplo:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>resultado runtime: <code>10,25,50,100,200</code></li></ul><h2>Forzado de virtualización en page size alto</h2><p>Cuando el usuario selecciona en el paginador un valor <code>pageSize >= 1000</code>:</p><ul><li>la virtualización se fuerza automáticamente aunque <code>md_props_bag.archetypes.list.virtualize</code> esté ausente o deshabilitado;</li><li><code>virtualScrollItemSize</code> se fuerza al valor predeterminado <code>44</code>.</li></ul><p>Este comportamiento protege el rendimiento de la tabla en páginas muy grandes.</p><h2>Eventos y subscriptions (host)</h2><p><code>wuic-list-grid</code> expone eventos runtime útiles para interceptar el ciclo de render y callbacks de p-table en el proyecto host.</p><p>Eventos disponibles:</p><ul><li><code>onAfterRender</code>: emitido al finalizar el binding de datos de la grilla (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emitido antes del renderizado lógico de la fila individual; soporta cancelación mediante <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emitido después del renderizado lógico de la fila individual.</li><li><code>onPaging</code>: emitido en los eventos de paging (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emitido en los eventos de sorting (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emitido en los eventos de filtering (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emitido al cambiar la selección de filas.</li><li><code>onPTableRowExpand</code>: emitido al expandir una fila.</li><li><code>onPTableRowCollapse</code>: emitido al colapsar una fila.</li><li><code>onPTableColumnResize</code>: emitido al redimensionar una columna.</li><li><code>onPTableColumnReorder</code>: emitido al reordenar columnas.</li></ul><h3>Ejemplo 1: binding directo en el template</h3><p>Snippet 7:</p><h3>Ejemplo 2: subscribe vía ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — firma real (gotcha)</h2><p><code><wuic-list-grid></code> acepta una entrada <code>[rowCustomSelect]</code> para interceptar la seleccion de una fila (apertura de un dialog "elige un documento", flujo master-detail, etc.). La firma TypeScript declarada en <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> es:</p><p>Snippet 9:</p><p><strong>Pero en runtime la callback se invoca con argumentos invertidos</strong> — el framework llama <code>rowCustomSelect($event, rowData, dt)</code> (ver <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> y <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Sintoma cuando el orden es erroneo: <code>rowData?.id</code> es undefined → guard temprano en tu handler → la callback retorna silenciosamente y tu dialog/accion no arranca. Ningun error en consola.</p><p>Forma correcta (alineada con la invocacion runtime):</p><p>Snippet 10:</p><p>Uso en el template:</p><p>Snippet 11:</p><p>> Nota: los tests en <code>designer.component.spec.ts</code> (p. ej. linea 512) invocan la callback con <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirmando el orden <code>($event, rowData, dt)</code>. Si en el futuro el framework alinea la firma declarada, esta pagina se actualizara.</p>",
|
|
22580
|
+
"html": "<h1>List Grid</h1><p>Componente principal para listas tabulares con filtros, sorting, paging server-side y acciones de fila.</p><h2>Casos de uso</h2><ul><li>CRUD tabulares enterprise.</li><li>Informes operativos con filtros multi-columna.</li><li>Datasets muy grandes con <code>cursorMode</code>.</li></ul><h2>Qué muestra la toolbar por defecto</h2><p>Al abrir una ruta recién scaffoldada, la caption-bar está encima de la rejilla. A la izquierda:</p><table><thead><tr><th>Botón</th><th>Cuándo aparece</th></tr></thead><tbody><tr><td><strong>Actualizar</strong></td><td>siempre, salvo <code>md_hide_refresh</code></td></tr><tr><td><strong>Agregar</strong></td><td>con <code>md_insertable</code></td></tr><tr><td><strong>Comportamiento</strong></td><td>si la tabla tiene acciones personalizadas</td></tr><tr><td>Import / Export</td><td>siempre; la rama de import solo con <code>md_importable</code></td></tr><tr><td><strong>Informes</strong></td><td>si hay al menos un informe asociado a la ruta</td></tr><tr><td><strong>Guardar cambios</strong> / <strong>Descartar cambios</strong></td><td>solo con <code>md_inline_cell_edit</code> <strong>y</strong> <code>md_batch_save</code></td></tr></tbody></table><p>A la derecha: <strong>Gestionar estado</strong> (precedido por el desplegable de estados guardados, si los</p><p>hay), <strong>Limpiar filtros</strong> cuando los filtros están en las columnas, y <strong>Rendimiento</strong> si el</p><p>inspector está habilitado en la ruta.</p><p>> Las etiquetas citadas más abajo en esta página <strong>no están en esa pantalla</strong>, y no es un</p><p>> defecto: las de export/import (<em>Continuar en segundo plano</em>, <em>Cancelar tarea</em>, *Detener y</p><p>> descargar parcial<em>, </em>Cancelar import (rollback)<em>, </em>Detener y confirmar parcial*) viven en el</p><p>> diálogo de progreso, que solo existe mientras un export o un import está en curso; *Guardar</p><p>> cambios<em> y </em>Descartar cambios* solo aparecen con los dos flags de arriba. Pertenecen a</p><p>> momentos distintos de la primera apertura de la lista.</p><h2>Screenshot de referencia (manual de usuario)</h2><ul><li><code>manual__grid__01.png</code>: modalidad <code>inline cell edit</code> en list-grid.</li><li><code>manual__grid__02.png</code>: modalidad <code>inline edit</code> (row-level) en list-grid.</li></ul><h2>Metadatos de inline editing</h2><p>Configuración en el <code>md_props_bag</code> de la tabla metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - habilita el editing inline de la fila en list-grid (celdas editables en contexto de fila, sin apertura de popup).</p><p> - útil cuando se quiere mantener la UX de tabla con edición rápida por registro.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - habilita el editing inline "celda por celda" (foco en la celda individual).</p><p> - nota: en configuraciones legacy puede aparecer como <code>md_inline_cell_editing</code>; el comportamiento runtime es el mismo.</p><p> - <strong>promoción runtime</strong>: cuando <code>md_inline_cell_edit</code> es <code>true</code>, el componente fuerza</p><p> en runtime también <code>md_inline_edit = true</code> independientemente del valor en DB.</p><p> Ambas UX necesitan la action column visible, por lo que son mutuamente</p><p> no-exclusivas a nivel de renderizado.</p><ul><li><code>md_batch_save</code></li></ul><p> - habilita el guardado batch de los cambios pendientes (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - si se usa junto con inline-cell, los cambios quedan pending hasta el guardado explícito.</p><p> - <strong>prerequisito</strong>: <code>md_batch_save</code> tiene efecto <strong>solo</strong> si <code>md_inline_cell_edit</code> es <code>true</code>.</p><p> Con <code>md_inline_cell_edit:false</code> el flag se ignora en runtime y los botones</p><p> "Guardar cambios / Cancelar cambios" no se renderizan.</p><h3>Combinaciones válidas</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Resultado runtime</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>cualquiera</td><td>Inline edit a nivel de fila con pencil. <code>md_batch_save</code> ignorado.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Cell-by-cell autosave on blur. <code>md_inline_edit</code> forzado a <code>true</code> en runtime.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Cell-by-cell con buffer pending + toolbar <code>Guardar / Cancelar cambios</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>cualquiera</td><td>Sin inline editing. <code>md_batch_save</code> ignorado.</td></tr></tbody></table><p>Ejemplo row-level inline edit:</p><p>Snippet 1:</p><p>Ejemplo cell-by-cell con batch save:</p><p>Snippet 2:</p><h2>Toolbar export/import</h2><ul><li>Export XLS:</li></ul><p> - muestra diálogo de progreso con porcentaje en tiempo real;</p><p> - acciones: <code>Continuar en background</code>, <code>Cancelar tarea</code>, <code>Interrumpir y descargar parcial</code>;</p><p> - en background crea una notificación con progreso; el clic reabre el diálogo.</p><p> - si el servidor ya ejecuta <code>maxConcurrentExports</code> exportaciones, la exportación espera en cola: el diálogo y la notificación muestran "En cola: posición N" y arranca sola en cuanto queda un hueco libre (también se puede cancelar mientras espera);</p><p> - SQL Server: si la base de datos tiene <code>ALLOW_SNAPSHOT_ISOLATION ON</code>, la exportación lee con aislamiento snapshot y no bloquea las escrituras en la tabla mientras escribe el archivo (sin ella, una exportación larga mantiene sus bloqueos de lectura y los insert/update en la misma tabla esperan a que termine). La opción se activa una vez en la base (<code>ALTER DATABASE [<base de datos>] SET ALLOW_SNAPSHOT_ISOLATION ON</code>) y no cambia el comportamiento de las demás lecturas; convive con <code>READ_COMMITTED_SNAPSHOT ON</code>. La base del tutorial tiene <code>READ_COMMITTED_SNAPSHOT ON</code>;</p><ul><li>Import XLS/XLSX (si <code>md_importable = true</code>):</li></ul><p> - diálogo de progreso tras la confirmación;</p><p> - acciones: <code>Continuar en background</code>, <code>Cancelar import (rollback)</code>, <code>Detener y commit parcial</code>;</p><p> - al finalizar el import crea una notificación de resumen que lleva a la route.</p><h2>Config metadata</h2><p>Ajustes clave en <code>md_props_bag</code> y metadatos de columna.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Flags opt-in que ocultan bloques de la toolbar de la list-grid (<code>caption-bar</code>). Todos bajo <code>md_props_bag.toolbar.*</code> (parseado en runtime como <code>tableMetadata.extraProps.toolbar</code>).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): oculta en la <strong>caption-right</strong> el botón "Gestionar estado" (icono bookmark) + el <code><select></code> de estados guardados. Útil para rutas hardcoded / demo donde el feature saved-state (persistencia por <code>user_id</code> + ruta vía <code>MetaService</code>) no tiene sentido — p. ej. Pattern 3 puro OData sin route metadata registrada.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): oculta en la <strong>caption-left</strong> los botones "Guardar cambios" (<code>pi-save</code>) + "Descartar cambios" (<code>pi-times</code>) + el indicador de conteo de changes (<code>grid-changes-indicator</code>, badge pencil + count). Generados por el framework cuando <code>md_inline_cell_editing</code> + <code>md_batch_save</code> están activos. Diseñado para <strong>nested grids dentro de un parametric-dialog</strong>: el save/cancel del padre persiste master + filas en un golpe vía batch save framework, y los botones duplicados en la nested grid confunden la UX.</li></ul><p>Ejemplo nested rows en custom edit-form (runtime patch):</p><p>Snippet 5:</p><p>Tipo TS en <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (propiedad <code>extraProps.toolbar</code>). Los flags NO deshabilitan la lógica <code>md_batch_save</code> subyacente (los changes siguen siendo trackeados); solo eliminan la UI de la toolbar — el save efectivo pasa por el flujo del padre.</p><h2>md_props_bag: archetypes.list</h2><p>El componente lee <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>tipo: boolean (con parser tolerante)</li><li>valores aceptados: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>default runtime: <code>true</code> cuando ausente o vacío</li><li>efecto: distribuye los anchos de columna en porcentaje (en lugar de px) cuando no hay anchos de usuario persistidos.</li></ul><ul><li><code>virtualize</code>:</li><li>tipo: <code>boolean</code> o <code>object</code></li><li>valores aceptados:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>object con <code>enabled</code> (opcional) y <code>itemSize</code> (opcional)</li><li>default runtime: deshabilitado (<code>false</code>) cuando ausente</li><li><code>enabled</code>:</li><li>default: <code>true</code> si el nodo <code>virtualize</code> es un object sin <code>enabled</code>, de lo contrario parser tolerante</li><li>efecto: habilita <code>virtualScroll</code> en <code>p-table</code></li><li><code>itemSize</code>:</li><li>default: <code>44</code></li><li>efecto: establece <code>virtualScrollItemSize</code> (altura de fila virtual en px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>tipo: boolean (con parser tolerante)</li><li>default runtime: <code>false</code></li><li>efecto:</li><li>cuando <code>true</code>, la grilla oculta los iconos de filtro de columna (<code>p-columnFilter</code>) y usa la <code>wuic-filter-bar</code> sobre la tabla (a nivel <code>data-repeater</code>/<code>bounded-repeater</code>) para aplicar los filtros.</li></ul><p>Nota operativa:</p><ul><li>el suggest <code>md_props_bag</code> en el metadata editor expone también el nodo checkeable <code>archetypes.list.advancedFilter</code>.</li></ul><h2>Paging: md_pagesize y md_page_size_choice</h2><p>La grilla usa <code>md_pagesize</code> como tamaño de página por defecto y <code>md_page_size_choice</code> como lista de valores seleccionables en el paginador.</p><p>Reglas runtime:</p><ul><li>si <code>md_pagesize</code> es mayor que el valor máximo presente en <code>md_page_size_choice</code>, el framework agrega automáticamente <code>md_pagesize</code> a la lista de opciones;</li><li>la lista se normaliza (números válidos, deduplicación, orden ascendente).</li></ul><p>Ejemplo:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>resultado runtime: <code>10,25,50,100,200</code></li></ul><h2>Forzado de virtualización en page size alto</h2><p>Cuando el usuario selecciona en el paginador un valor <code>pageSize >= 1000</code>:</p><ul><li>la virtualización se fuerza automáticamente aunque <code>md_props_bag.archetypes.list.virtualize</code> esté ausente o deshabilitado;</li><li><code>virtualScrollItemSize</code> se fuerza al valor predeterminado <code>44</code>.</li></ul><p>Este comportamiento protege el rendimiento de la tabla en páginas muy grandes.</p><h2>Eventos y subscriptions (host)</h2><p><code>wuic-list-grid</code> expone eventos runtime útiles para interceptar el ciclo de render y callbacks de p-table en el proyecto host.</p><p>Eventos disponibles:</p><ul><li><code>onAfterRender</code>: emitido al finalizar el binding de datos de la grilla (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: emitido antes del renderizado lógico de la fila individual; soporta cancelación mediante <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: emitido después del renderizado lógico de la fila individual.</li><li><code>onPaging</code>: emitido en los eventos de paging (<code>p-table onPage</code>).</li><li><code>onSorting</code>: emitido en los eventos de sorting (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: emitido en los eventos de filtering (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: emitido al cambiar la selección de filas.</li><li><code>onPTableRowExpand</code>: emitido al expandir una fila.</li><li><code>onPTableRowCollapse</code>: emitido al colapsar una fila.</li><li><code>onPTableColumnResize</code>: emitido al redimensionar una columna.</li><li><code>onPTableColumnReorder</code>: emitido al reordenar columnas.</li></ul><h3>Ejemplo 1: binding directo en el template</h3><p>Snippet 7:</p><h3>Ejemplo 2: subscribe vía ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — firma real (gotcha)</h2><p><code><wuic-list-grid></code> acepta una entrada <code>[rowCustomSelect]</code> para interceptar la seleccion de una fila (apertura de un dialog "elige un documento", flujo master-detail, etc.). La firma TypeScript declarada en <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> es:</p><p>Snippet 9:</p><p><strong>Pero en runtime la callback se invoca con argumentos invertidos</strong> — el framework llama <code>rowCustomSelect($event, rowData, dt)</code> (ver <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> y <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Sintoma cuando el orden es erroneo: <code>rowData?.id</code> es undefined → guard temprano en tu handler → la callback retorna silenciosamente y tu dialog/accion no arranca. Ningun error en consola.</p><p>Forma correcta (alineada con la invocacion runtime):</p><p>Snippet 10:</p><p>Uso en el template:</p><p>Snippet 11:</p><p>> Nota: los tests en <code>designer.component.spec.ts</code> (p. ej. linea 512) invocan la callback con <code>({currentTarget: rowCell}, {id: 42}, null)</code>, confirmando el orden <code>($event, rowData, dt)</code>. Si en el futuro el framework alinea la firma declarada, esta pagina se actualizara.</p>",
|
|
22569
22581
|
"codeSamples": [
|
|
22570
22582
|
{
|
|
22571
22583
|
"id": "code_1",
|
|
@@ -27468,10 +27480,14 @@ const frameworkDocsContent = {
|
|
|
27468
27480
|
},
|
|
27469
27481
|
{
|
|
27470
27482
|
"id": "sec_5",
|
|
27471
|
-
"title": "
|
|
27483
|
+
"title": "Tablas con clave MAX"
|
|
27472
27484
|
},
|
|
27473
27485
|
{
|
|
27474
27486
|
"id": "sec_6",
|
|
27487
|
+
"title": "Comportamiento PK existente (importación solo insert)"
|
|
27488
|
+
},
|
|
27489
|
+
{
|
|
27490
|
+
"id": "sec_7",
|
|
27475
27491
|
"title": "Columnas del archivo y lookups (export e import)"
|
|
27476
27492
|
}
|
|
27477
27493
|
],
|
|
@@ -27479,7 +27495,7 @@ const frameworkDocsContent = {
|
|
|
27479
27495
|
{
|
|
27480
27496
|
"id": "overview",
|
|
27481
27497
|
"title": "Overview",
|
|
27482
|
-
"html": "<h1>Import</h1><p>Habilita la importación de datos desde archivos Excel (<code>.xls</code>, <code>.xlsx</code>) en la route actual de la tabla metadata.</p><p>Cuando está activo, en el <code>List Grid</code> aparece un botón en la barra de herramientas (<code>Import XLS/XLSX</code>) que abre el selector de archivos y envía el archivo al método de importación ya disponible en el backend.</p><h2>Metadato de tabla</h2><p>El toggle principal es:</p><ul><li><code>md_importable</code></li></ul><p> Significado: muestra/oculta el botón de importación en la barra de herramientas del <code>List Grid</code>.</p><p> Valores: <code>true | false</code>.</p><p> Default: <code>false</code> (si está ausente).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Las opciones de importación se configuran en <code>extraProps.import</code> (derivadas de <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Notas operativas</h2><ul><li>El botón es visible si <code>md_importable = true</code>.</li><li>El archivo se valida del lado del cliente por extensión (<code>xls</code>, <code>xlsx</code>) antes del upload.</li><li>La importación se ejecuta en la route actual (<code>md_route_name</code>) del datasource activo.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): abre el diálogo intermedio para elegir opciones de importación antes del upload.</p><p> - <code>true</code>: omite el diálogo e inicia upload/importación directa usando las opciones ya definidas en <code>md_props_bag.import</code>.</p><ul><li>Defaults recomendados en el suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (usar títulos de columna).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI y progreso</h2><ul><li>Después de la confirmación de importación, se abre un diálogo de progreso con porcentaje en tiempo real.</li><li>Acciones disponibles:</li></ul><p> - <code>Continuar en segundo plano</code>: cierra el diálogo y crea una notificación de progreso.</p><p> - <code>Cancelar importación (rollback)</code>: cancela y realiza rollback.</p><p> - <code>Detener y commit parcial</code>: interrumpe y confirma lo realizado hasta el momento.</p><ul><li>Al finalizar la importación se crea una notificación resumida (mismo texto del toast); el clic lleva a la route de la importación sin refresh si ya se está en la misma página.</li></ul><h2>Comportamiento PK existente (importación solo insert)</h2><p>Si <code>import_type = "I"</code> y la PK del registro ya existe:</p><ul><li>el insert se omite;</li><li>el registro se contabiliza en el resumen como "inserciones omitidas (PK existente)".</li></ul><h2>Columnas del archivo y lookups (export e import)</h2><p>El export XLS y el import siguen las mismas reglas, así que un archivo exportado se vuelve a importar tal cual.</p><h3>Encabezados</h3><ul><li>Cada columna tiene como encabezado su caption (<code>mc_display_string_in_view</code>; si está vacía, el nombre de la columna).</li><li>Si dos columnas del mismo archivo tienen la misma caption, a cada una se le añade su nombre físico entre paréntesis: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Sin colisiones los encabezados quedan como siempre.</li><li>El import reconoce una columna por su caption, por su caption con el nombre físico (o el nombre de columna) entre paréntesis, o por su nombre físico / nombre de columna.</li><li>Un encabezado que corresponde a varias columnas (por ejemplo un archivo antiguo con dos columnas <code>People</code>) se rechaza con el error "Ambiguous column": hay que escribirlo como <code>caption (nombre físico)</code>.</li></ul><h3>Columnas lookup: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decide cómo viajan las columnas lookup (<code>mc_ui_column_type = lookupByID</code>):</p><table><thead><tr><th>Valor</th><th>En el archivo</th><th>Notas</th></tr></thead><tbody><tr><td><code>description</code> (por defecto)</td><td>la descripción del registro vinculado, bajo la caption</td><td>como siempre</td></tr><tr><td><code>key</code></td><td>la clave del registro vinculado, bajo la caption</td><td></td></tr><tr><td><code>both</code></td><td>dos columnas: la descripción bajo la caption, la clave bajo el nombre físico (<code>Pedido</code> + <code>OrderID</code>)</td><td>si la caption coincide con el nombre físico, la columna descripción pasa a ser <code>caption (campo de texto del lookup)</code>, p. ej. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>El export sigue el valor de la route; sin <code>fkey_mode</code> vale <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>En el diálogo de import la opción "Columnas lookup en el archivo" viene preseleccionada con el mismo valor y se puede cambiar para un import concreto.</li></ul><h3>De la descripción a la clave</h3><ul><li><strong>Solo la clave</strong>: se usa tal cual.</li><li><strong>Solo la descripción</strong>: se busca el registro vinculado con esa descripción (campo de texto del lookup).</li></ul><p> - Un solo registro: se usa su clave.</p><p> - Ninguno: la fila da error.</p><p> - Varios registros con la misma descripción: si la fila actualiza un registro existente y la clave que ya tiene corresponde a esa descripción, el vínculo se mantiene (el usuario no lo ha tocado). Si no, y siempre para las filas nuevas, es un error que lista las claves candidatas: para insertar hace falta la clave, es decir <code>key</code> o <code>both</code>.</p><ul><li><strong>Clave y descripción (`both`)</strong>: vale la clave si su registro tiene esa descripción; si no coinciden (una de las dos se cambió y la otra no) la fila da error.</li><li>Una clave primaria que también es un lookup (tabla 1:1) se resuelve antes de comprobar si el registro existe.</li><li>Con <code>commit_level</code> <code>R</code> o <code>I</code> un error de lookup detiene el import sin guardar; con <code>C</code> o <code>T</code> la fila se omite y el import continúa.</li></ul><h3>Fechas</h3><p>Las celdas de fecha escritas por el export (número con formato de fecha, como en Excel) se leen como fechas: un archivo exportado y reimportado sin cambios ya no se rechaza en sus columnas de fecha.</p>",
|
|
27498
|
+
"html": "<h1>Import</h1><p>Habilita la importación de datos desde archivos Excel (<code>.xls</code>, <code>.xlsx</code>) en la route actual de la tabla metadata.</p><p>Cuando está activo, en el <code>List Grid</code> aparece un botón en la barra de herramientas (<code>Import XLS/XLSX</code>) que abre el selector de archivos y envía el archivo al método de importación ya disponible en el backend.</p><h2>Metadato de tabla</h2><p>El toggle principal es:</p><ul><li><code>md_importable</code></li></ul><p> Significado: muestra/oculta el botón de importación en la barra de herramientas del <code>List Grid</code>.</p><p> Valores: <code>true | false</code>.</p><p> Default: <code>false</code> (si está ausente).</p><h2>Extra props (<code>md_props_bag</code>)</h2><p>Las opciones de importación se configuran en <code>extraProps.import</code> (derivadas de <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Notas operativas</h2><ul><li>El botón es visible si <code>md_importable = true</code>.</li><li>El archivo se valida del lado del cliente por extensión (<code>xls</code>, <code>xlsx</code>) antes del upload.</li><li>La importación se ejecuta en la route actual (<code>md_route_name</code>) del datasource activo.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (default): abre el diálogo intermedio para elegir opciones de importación antes del upload.</p><p> - <code>true</code>: omite el diálogo e inicia upload/importación directa usando las opciones ya definidas en <code>md_props_bag.import</code>.</p><ul><li>Defaults recomendados en el suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (usar títulos de columna).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI y progreso</h2><ul><li>Después de la confirmación de importación, se abre un diálogo de progreso con porcentaje en tiempo real.</li><li>Acciones disponibles:</li></ul><p> - <code>Continuar en segundo plano</code>: cierra el diálogo y crea una notificación de progreso.</p><p> - <code>Cancelar importación (rollback)</code>: cancela y realiza rollback.</p><p> - <code>Detener y commit parcial</code>: interrumpe y confirma lo realizado hasta el momento.</p><ul><li>Al finalizar la importación se crea una notificación resumida (mismo texto del toast); el clic lleva a la route de la importación sin refresh si ya se está en la misma página.</li></ul><h2>Tablas con clave MAX</h2><p>En las rutas con <code>md_primary_key_type = "MAX"</code> (y en la "clave dependiente" de las claves compuestas) la clave de cada fila nueva es el máximo + 1, calculado dentro del insert con un bloqueo sobre la tabla: las filas nuevas del mismo archivo reciben claves consecutivas y las inserciones simultáneas no colisionan. El bloqueo dura hasta el final de la importación (una transacción por archivo): mientras tanto las demás inserciones en la misma tabla esperan, y en Oracle también los update y delete. Para archivos grandes en tablas muy usadas conviene poner la clave en el archivo o pasar la tabla a <code>IDENTITY</code>/<code>SEQUENCE</code>.</p><h2>Comportamiento PK existente (importación solo insert)</h2><p>Si <code>import_type = "I"</code> y la PK del registro ya existe:</p><ul><li>el insert se omite;</li><li>el registro se contabiliza en el resumen como "inserciones omitidas (PK existente)".</li></ul><h2>Columnas del archivo y lookups (export e import)</h2><p>El export XLS y el import siguen las mismas reglas, así que un archivo exportado se vuelve a importar tal cual.</p><h3>Encabezados</h3><ul><li>Cada columna tiene como encabezado su caption (<code>mc_display_string_in_view</code>; si está vacía, el nombre de la columna).</li><li>Si dos columnas del mismo archivo tienen la misma caption, a cada una se le añade su nombre físico entre paréntesis: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Sin colisiones los encabezados quedan como siempre.</li><li>El import reconoce una columna por su caption, por su caption con el nombre físico (o el nombre de columna) entre paréntesis, o por su nombre físico / nombre de columna.</li><li>Un encabezado que corresponde a varias columnas (por ejemplo un archivo antiguo con dos columnas <code>People</code>) se rechaza con el error "Ambiguous column": hay que escribirlo como <code>caption (nombre físico)</code>.</li></ul><h3>Columnas lookup: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> decide cómo viajan las columnas lookup (<code>mc_ui_column_type = lookupByID</code>):</p><table><thead><tr><th>Valor</th><th>En el archivo</th><th>Notas</th></tr></thead><tbody><tr><td><code>description</code> (por defecto)</td><td>la descripción del registro vinculado, bajo la caption</td><td>como siempre</td></tr><tr><td><code>key</code></td><td>la clave del registro vinculado, bajo la caption</td><td></td></tr><tr><td><code>both</code></td><td>dos columnas: la descripción bajo la caption, la clave bajo el nombre físico (<code>Pedido</code> + <code>OrderID</code>)</td><td>si la caption coincide con el nombre físico, la columna descripción pasa a ser <code>caption (campo de texto del lookup)</code>, p. ej. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>El export sigue el valor de la route; sin <code>fkey_mode</code> vale <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>En el diálogo de import la opción "Columnas lookup en el archivo" viene preseleccionada con el mismo valor y se puede cambiar para un import concreto.</li></ul><h3>De la descripción a la clave</h3><ul><li><strong>Solo la clave</strong>: se usa tal cual.</li><li><strong>Solo la descripción</strong>: se busca el registro vinculado con esa descripción (campo de texto del lookup).</li></ul><p> - Un solo registro: se usa su clave.</p><p> - Ninguno: la fila da error.</p><p> - Varios registros con la misma descripción: si la fila actualiza un registro existente y la clave que ya tiene corresponde a esa descripción, el vínculo se mantiene (el usuario no lo ha tocado). Si no, y siempre para las filas nuevas, es un error que lista las claves candidatas: para insertar hace falta la clave, es decir <code>key</code> o <code>both</code>.</p><ul><li><strong>Clave y descripción (`both`)</strong>: vale la clave si su registro tiene esa descripción; si no coinciden (una de las dos se cambió y la otra no) la fila da error.</li><li>Una clave primaria que también es un lookup (tabla 1:1) se resuelve antes de comprobar si el registro existe.</li><li>Con <code>commit_level</code> <code>R</code> o <code>I</code> un error de lookup detiene el import sin guardar; con <code>C</code> o <code>T</code> la fila se omite y el import continúa.</li></ul><h3>Fechas</h3><p>Las celdas de fecha escritas por el export (número con formato de fecha, como en Excel) se leen como fechas: un archivo exportado y reimportado sin cambios ya no se rechaza en sus columnas de fecha.</p>",
|
|
27483
27499
|
"codeSamples": [
|
|
27484
27500
|
{
|
|
27485
27501
|
"id": "code_1",
|
|
@@ -29402,7 +29418,7 @@ const frameworkDocsContent = {
|
|
|
29402
29418
|
{
|
|
29403
29419
|
"id": "overview",
|
|
29404
29420
|
"title": "Overview",
|
|
29405
|
-
"html": "<h1>List Grid</h1><p>Hauptkomponente fuer tabellarische Listen mit Filtern, Sortierung, serverseitigem Paging und Zeilenaktionen.</p><h2>Anwendungsfaelle</h2><ul><li>Enterprise-CRUD-Tabellen.</li><li>Operative Reports mit Multi-Spalten-Filtern.</li><li>Sehr grosse Datasets mit <code>cursorMode</code>.</li></ul><h2>Was die Toolbar standardmaessig zeigt</h2><p>Beim Oeffnen einer frisch gescaffoldeten Route sitzt die Caption-Bar ueber dem Grid. Links:</p><table><thead><tr><th>Schaltflaeche</th><th>Wann sie erscheint</th></tr></thead><tbody><tr><td><strong>Aktualisieren</strong></td><td>immer, ausser bei <code>md_hide_refresh</code></td></tr><tr><td><strong>Hinzufuegen</strong></td><td>mit <code>md_insertable</code></td></tr><tr><td><strong>Aktionen</strong></td><td>wenn die Tabelle Custom Actions hat</td></tr><tr><td>Import / Export</td><td>immer; der Import-Zweig nur mit <code>md_importable</code></td></tr><tr><td><strong>Berichte</strong></td><td>wenn der Route mindestens ein Report zugeordnet ist</td></tr><tr><td><strong>Aenderungen speichern</strong> / <strong>Aenderungen verwerfen</strong></td><td>nur mit <code>md_inline_cell_edit</code> <strong>und</strong> <code>md_batch_save</code></td></tr></tbody></table><p>Rechts: <strong>Status verwalten</strong> (davor die Auswahl der gespeicherten Zustaende, falls vorhanden),</p><p><strong>Filter loeschen</strong>, wenn die Filter auf den Spalten sitzen, und <strong>Performance</strong>, wenn der</p><p>Inspector fuer die Route aktiviert ist.</p><p>> Die weiter unten auf dieser Seite zitierten Beschriftungen **stehen nicht auf diesem</p><p>> Bildschirm*<em>, und das ist kein Fehler: die von Export/Import (</em>Im Hintergrund fortfahren*,</p><p>> <em>Task abbrechen</em>, <em>Stoppen und teilweise herunterladen</em>, <em>Import abbrechen (Rollback)</em>,</p><p>> <em>Stoppen und teilweise committen</em>) leben im Fortschrittsdialog, den es nur waehrend eines</p><p>> laufenden Exports oder Imports gibt; <em>Aenderungen speichern</em> und <em>Aenderungen verwerfen</em></p><p>> erscheinen nur mit den beiden Flags oben. Sie gehoeren zu anderen Momenten als dem ersten</p><p>> Oeffnen der Liste.</p><h2>Screenshot-Referenz (Benutzerhandbuch)</h2><ul><li><code>manual__grid__01.png</code>: Modus <code>inline cell edit</code> im List-Grid.</li><li><code>manual__grid__02.png</code>: Modus <code>inline edit</code> (Row-Level) im List-Grid.</li></ul><h2>Metadaten Inline-Editing</h2><p>Konfiguration im <code>md_props_bag</code> der Tabellen-Metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - aktiviert das Inline-Editing der Zeile im List-Grid (editierbare Zellen im Zeilenkontext, ohne Popup-Oeffnung).</p><p> - nuetzlich wenn die Tabellen-UX mit schnellem Editing pro Datensatz beibehalten werden soll.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - aktiviert das Inline-Editing "Zelle fuer Zelle" (Fokus auf einzelne Zelle).</p><p> - Hinweis: in Legacy-Konfigurationen kann dies als <code>md_inline_cell_editing</code> erscheinen; das Runtime-Verhalten ist identisch.</p><p> - <strong>Runtime-Promotion</strong>: wenn <code>md_inline_cell_edit</code> <code>true</code> ist, erzwingt die Komponente</p><p> zur Laufzeit auch <code>md_inline_edit = true</code>, unabhaengig vom DB-Wert.</p><p> Beide UX benoetigen die sichtbare Action-Spalte, daher sind sie auf Rendering-Ebene</p><p> nicht gegenseitig ausschliessend.</p><ul><li><code>md_batch_save</code></li></ul><p> - aktiviert das Batch-Speichern der ausstehenden Aenderungen (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - bei Verwendung zusammen mit Inline-Cell bleiben die Aenderungen ausstehend bis zum expliziten Speichern.</p><p> - <strong>Voraussetzung</strong>: <code>md_batch_save</code> wirkt <strong>nur</strong> wenn <code>md_inline_cell_edit</code> <code>true</code> ist.</p><p> Mit <code>md_inline_cell_edit:false</code> wird das Flag zur Laufzeit ignoriert und die Buttons</p><p> "Aenderungen speichern / Aenderungen verwerfen" werden nicht gerendert.</p><h3>Gueltige Kombinationen</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Runtime-Ergebnis</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>beliebig</td><td>Row-Level Inline-Edit mit Pencil. <code>md_batch_save</code> ignoriert.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Zelle-fuer-Zelle Autosave bei Blur. <code>md_inline_edit</code> wird zur Laufzeit auf <code>true</code> erzwungen.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Zelle-fuer-Zelle mit Pending-Buffer + Toolbar <code>Speichern / Aenderungen verwerfen</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>beliebig</td><td>Kein Inline-Editing. <code>md_batch_save</code> ignoriert.</td></tr></tbody></table><p>Beispiel Row-Level Inline-Edit:</p><p>Snippet 1:</p><p>Beispiel Zelle-fuer-Zelle mit Batch-Save:</p><p>Snippet 2:</p><h2>Toolbar Export/Import</h2><ul><li>Export XLS:</li></ul><p> - zeigt Fortschrittsdialog mit Echtzeit-Prozentsatz;</p><p> - Aktionen: <code>Im Hintergrund fortsetzen</code>, <code>Task abbrechen</code>, <code>Unterbrechen und teilweise herunterladen</code>;</p><p> - im Hintergrund wird eine Benachrichtigung mit Fortschritt erstellt; Klick oeffnet den Dialog erneut.</p><p> - fuehrt der Server bereits <code>maxConcurrentExports</code> Exporte aus, wartet der Export in einer Warteschlange: Dialog und Benachrichtigung zeigen "In der Warteschlange: Position N", und er startet von selbst, sobald ein Platz frei wird (auch waehrend des Wartens abbrechbar);</p><ul><li>Import XLS/XLSX (wenn <code>md_importable = true</code>):</li></ul><p> - Fortschrittsdialog nach Bestaetigung;</p><p> - Aktionen: <code>Im Hintergrund fortsetzen</code>, <code>Import abbrechen (Rollback)</code>, <code>Stop und teilweise Commit</code>;</p><p> - nach Import-Ende wird eine Zusammenfassungs-Benachrichtigung erstellt, die zur Route fuehrt.</p><h2>Config Metadata</h2><p>Schluessel-Einstellungen in <code>md_props_bag</code> und Spalten-Metadaten.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Opt-in-Flags, die Bloecke der list-grid Toolbar (<code>caption-bar</code>) ausblenden. Alle unter <code>md_props_bag.toolbar.*</code> (zur Laufzeit als <code>tableMetadata.extraProps.toolbar</code> geparst).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): blendet in der <strong>caption-right</strong> den Button "Status verwalten" (Bookmark-Icon) + das <code><select></code> der gespeicherten Zustaende aus. Nuetzlich fuer hardcoded / Demo-Routes, bei denen das Saved-State-Feature (Persistenz pro <code>user_id</code> + Route via <code>MetaService</code>) keinen Sinn ergibt — z.B. Pattern 3 reines OData ohne registrierte Route-Metadaten.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): blendet in der <strong>caption-left</strong> die Buttons "Aenderungen speichern" (<code>pi-save</code>) + "Aenderungen verwerfen" (<code>pi-times</code>) + den Aenderungs-Zaehler-Indikator (<code>grid-changes-indicator</code>, Pencil-Badge + Count) aus. Vom Framework generiert, wenn <code>md_inline_cell_editing</code> + <code>md_batch_save</code> aktiv sind. Konzipiert fuer <strong>verschachtelte Grids in einem parametric-dialog</strong>: Save/Cancel des Parents persistiert Master + Zeilen in einem Schritt via Framework Batch Save, und die Duplikat-Buttons auf der nested Grid verwirren die UX.</li></ul><p>Beispiel nested rows in custom edit-form (Runtime-Patch):</p><p>Snippet 5:</p><p>TS-Typ in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (<code>extraProps.toolbar</code> Property). Die Flags deaktivieren NICHT die zugrundeliegende <code>md_batch_save</code>-Logik (Aenderungen werden weiterhin getrackt); sie entfernen nur die Toolbar-UI — der eigentliche Save laeuft ueber den Parent-Flow.</p><h2>md_props_bag: archetypes.list</h2><p>Die Komponente liest <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>Typ: boolean (mit tolerantem Parser)</li><li>akzeptierte Werte: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>Runtime-Default: <code>true</code> wenn absent oder leer</li><li>Effekt: verteilt die Spaltenbreiten prozentual (anstelle von px), wenn keine vom Benutzer persistierten Breiten vorhanden sind.</li></ul><ul><li><code>virtualize</code>:</li><li>Typ: <code>boolean</code> oder <code>object</code></li><li>akzeptierte Werte:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>Object mit <code>enabled</code> (optional) und <code>itemSize</code> (optional)</li><li>Runtime-Default: deaktiviert (<code>false</code>) wenn absent</li><li><code>enabled</code>:</li><li>Default: <code>true</code> wenn der <code>virtualize</code>-Knoten ein Object ohne <code>enabled</code> ist, sonst toleranter Parser</li><li>Effekt: aktiviert <code>virtualScroll</code> auf <code>p-table</code></li><li><code>itemSize</code>:</li><li>Default: <code>44</code></li><li>Effekt: setzt <code>virtualScrollItemSize</code> (virtuelle Zeilenhoehe in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>Typ: boolean (mit tolerantem Parser)</li><li>Runtime-Default: <code>false</code></li><li>Effekt:</li><li>wenn <code>true</code>, blendet das Grid die Spalten-Filter-Icons (<code>p-columnFilter</code>) aus und verwendet die <code>wuic-filter-bar</code> ueber der Tabelle (auf <code>data-repeater</code>/<code>bounded-repeater</code>-Ebene), um die Filter anzuwenden.</li></ul><p>Betriebshinweis:</p><ul><li>der <code>md_props_bag</code>-Suggest im Metadata-Editor stellt auch den checkbaren Knoten <code>archetypes.list.advancedFilter</code> bereit.</li></ul><h2>Paging: md_pagesize und md_page_size_choice</h2><p>Das Grid verwendet <code>md_pagesize</code> als Standard-Seitengroesse und <code>md_page_size_choice</code> als Liste der im Paginator auswaehlbaren Werte.</p><p>Runtime-Regeln:</p><ul><li>wenn <code>md_pagesize</code> groesser als der maximale Wert in <code>md_page_size_choice</code> ist, fuegt das Framework <code>md_pagesize</code> automatisch zur Optionsliste hinzu;</li><li>die Liste wird normalisiert (gueltige Zahlen, Deduplizierung, aufsteigende Sortierung).</li></ul><p>Beispiel:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>Runtime-Ergebnis: <code>10,25,50,100,200</code></li></ul><h2>Erzwungene Virtualisierung bei hoher Seitengroesse</h2><p>Wenn der Benutzer im Paginator einen Wert <code>pageSize >= 1000</code> auswaehlt:</p><ul><li>wird die Virtualisierung automatisch erzwungen, auch wenn <code>md_props_bag.archetypes.list.virtualize</code> absent oder deaktiviert ist;</li><li><code>virtualScrollItemSize</code> wird auf den Standardwert <code>44</code> gesetzt.</li></ul><p>Dieses Verhalten schuetzt das Rendering der Tabelle bei sehr grossen Seiten.</p><h2>Events und Subscriptions (Host)</h2><p><code>wuic-list-grid</code> stellt Runtime-Events bereit, die nuetzlich sind, um den Render-Zyklus und die p-table-Callbacks auf der Host-Projektseite zu intercepten.</p><p>Verfuegbare Events:</p><ul><li><code>onAfterRender</code>: wird am Ende des Datenbindings des Grids emittiert (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: wird vor dem logischen Rendering der einzelnen Zeile emittiert; unterstuetzt Cancel via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: wird nach dem logischen Rendering der einzelnen Zeile emittiert.</li><li><code>onPaging</code>: wird bei Paging-Events emittiert (<code>p-table onPage</code>).</li><li><code>onSorting</code>: wird bei Sorting-Events emittiert (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: wird bei Filtering-Events emittiert (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: wird bei Aenderung der Zeilenauswahl emittiert.</li><li><code>onPTableRowExpand</code>: wird beim Expandieren einer Zeile emittiert.</li><li><code>onPTableRowCollapse</code>: wird beim Collapsen einer Zeile emittiert.</li><li><code>onPTableColumnResize</code>: wird beim Spalten-Resize emittiert.</li><li><code>onPTableColumnReorder</code>: wird beim Spalten-Reorder emittiert.</li></ul><h3>Beispiel 1: direktes Binding im Template</h3><p>Snippet 7:</p><h3>Beispiel 2: Subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — tatsachliche Signatur (Falle)</h2><p><code><wuic-list-grid></code> akzeptiert ein <code>[rowCustomSelect]</code>-Input zum Abfangen der Zeilenauswahl (Offnen eines "Dokument auswahlen"-Dialogs, Master-Detail-Flow, etc.). Die TypeScript-Signatur in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> lautet:</p><p>Snippet 9:</p><p><strong>Zur Laufzeit wird der Callback jedoch mit umgekehrten Argumenten aufgerufen</strong> — das Framework ruft <code>rowCustomSelect($event, rowData, dt)</code> auf (siehe <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> und <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptom bei falscher Reihenfolge: <code>rowData?.id</code> ist undefined → fruhzeitiger Guard im Handler → der Callback kehrt stillschweigend zuruck und der Dialog/die Aktion startet nicht. Kein Konsolenfehler.</p><p>Korrekte Form (auf Laufzeit-Invocation abgestimmt):</p><p>Snippet 10:</p><p>Verwendung im Template:</p><p>Snippet 11:</p><p>> Hinweis: Die Tests in <code>designer.component.spec.ts</code> (z.B. Zeile 512) rufen den Callback mit <code>({currentTarget: rowCell}, {id: 42}, null)</code> auf und bestatigen die Reihenfolge <code>($event, rowData, dt)</code>. Sollte das Framework die deklarierte Signatur kunftig angleichen, wird auch diese Seite aktualisiert.</p>",
|
|
29421
|
+
"html": "<h1>List Grid</h1><p>Hauptkomponente fuer tabellarische Listen mit Filtern, Sortierung, serverseitigem Paging und Zeilenaktionen.</p><h2>Anwendungsfaelle</h2><ul><li>Enterprise-CRUD-Tabellen.</li><li>Operative Reports mit Multi-Spalten-Filtern.</li><li>Sehr grosse Datasets mit <code>cursorMode</code>.</li></ul><h2>Was die Toolbar standardmaessig zeigt</h2><p>Beim Oeffnen einer frisch gescaffoldeten Route sitzt die Caption-Bar ueber dem Grid. Links:</p><table><thead><tr><th>Schaltflaeche</th><th>Wann sie erscheint</th></tr></thead><tbody><tr><td><strong>Aktualisieren</strong></td><td>immer, ausser bei <code>md_hide_refresh</code></td></tr><tr><td><strong>Hinzufuegen</strong></td><td>mit <code>md_insertable</code></td></tr><tr><td><strong>Aktionen</strong></td><td>wenn die Tabelle Custom Actions hat</td></tr><tr><td>Import / Export</td><td>immer; der Import-Zweig nur mit <code>md_importable</code></td></tr><tr><td><strong>Berichte</strong></td><td>wenn der Route mindestens ein Report zugeordnet ist</td></tr><tr><td><strong>Aenderungen speichern</strong> / <strong>Aenderungen verwerfen</strong></td><td>nur mit <code>md_inline_cell_edit</code> <strong>und</strong> <code>md_batch_save</code></td></tr></tbody></table><p>Rechts: <strong>Status verwalten</strong> (davor die Auswahl der gespeicherten Zustaende, falls vorhanden),</p><p><strong>Filter loeschen</strong>, wenn die Filter auf den Spalten sitzen, und <strong>Performance</strong>, wenn der</p><p>Inspector fuer die Route aktiviert ist.</p><p>> Die weiter unten auf dieser Seite zitierten Beschriftungen **stehen nicht auf diesem</p><p>> Bildschirm*<em>, und das ist kein Fehler: die von Export/Import (</em>Im Hintergrund fortfahren*,</p><p>> <em>Task abbrechen</em>, <em>Stoppen und teilweise herunterladen</em>, <em>Import abbrechen (Rollback)</em>,</p><p>> <em>Stoppen und teilweise committen</em>) leben im Fortschrittsdialog, den es nur waehrend eines</p><p>> laufenden Exports oder Imports gibt; <em>Aenderungen speichern</em> und <em>Aenderungen verwerfen</em></p><p>> erscheinen nur mit den beiden Flags oben. Sie gehoeren zu anderen Momenten als dem ersten</p><p>> Oeffnen der Liste.</p><h2>Screenshot-Referenz (Benutzerhandbuch)</h2><ul><li><code>manual__grid__01.png</code>: Modus <code>inline cell edit</code> im List-Grid.</li><li><code>manual__grid__02.png</code>: Modus <code>inline edit</code> (Row-Level) im List-Grid.</li></ul><h2>Metadaten Inline-Editing</h2><p>Konfiguration im <code>md_props_bag</code> der Tabellen-Metadata:</p><ul><li><code>md_inline_edit</code></li></ul><p> - aktiviert das Inline-Editing der Zeile im List-Grid (editierbare Zellen im Zeilenkontext, ohne Popup-Oeffnung).</p><p> - nuetzlich wenn die Tabellen-UX mit schnellem Editing pro Datensatz beibehalten werden soll.</p><ul><li><code>md_inline_cell_edit</code></li></ul><p> - aktiviert das Inline-Editing "Zelle fuer Zelle" (Fokus auf einzelne Zelle).</p><p> - Hinweis: in Legacy-Konfigurationen kann dies als <code>md_inline_cell_editing</code> erscheinen; das Runtime-Verhalten ist identisch.</p><p> - <strong>Runtime-Promotion</strong>: wenn <code>md_inline_cell_edit</code> <code>true</code> ist, erzwingt die Komponente</p><p> zur Laufzeit auch <code>md_inline_edit = true</code>, unabhaengig vom DB-Wert.</p><p> Beide UX benoetigen die sichtbare Action-Spalte, daher sind sie auf Rendering-Ebene</p><p> nicht gegenseitig ausschliessend.</p><ul><li><code>md_batch_save</code></li></ul><p> - aktiviert das Batch-Speichern der ausstehenden Aenderungen (<code>Save changes</code> / <code>Cancel changes</code>).</p><p> - bei Verwendung zusammen mit Inline-Cell bleiben die Aenderungen ausstehend bis zum expliziten Speichern.</p><p> - <strong>Voraussetzung</strong>: <code>md_batch_save</code> wirkt <strong>nur</strong> wenn <code>md_inline_cell_edit</code> <code>true</code> ist.</p><p> Mit <code>md_inline_cell_edit:false</code> wird das Flag zur Laufzeit ignoriert und die Buttons</p><p> "Aenderungen speichern / Aenderungen verwerfen" werden nicht gerendert.</p><h3>Gueltige Kombinationen</h3><table><thead><tr><th><code>md_inline_edit</code></th><th><code>md_inline_cell_edit</code></th><th><code>md_batch_save</code></th><th>Runtime-Ergebnis</th></tr></thead><tbody><tr><td><code>true</code></td><td><code>false</code></td><td>beliebig</td><td>Row-Level Inline-Edit mit Pencil. <code>md_batch_save</code> ignoriert.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>false</code></td><td>Zelle-fuer-Zelle Autosave bei Blur. <code>md_inline_edit</code> wird zur Laufzeit auf <code>true</code> erzwungen.</td></tr><tr><td><code>false</code></td><td><code>true</code></td><td><code>true</code></td><td>Zelle-fuer-Zelle mit Pending-Buffer + Toolbar <code>Speichern / Aenderungen verwerfen</code>.</td></tr><tr><td><code>false</code></td><td><code>false</code></td><td>beliebig</td><td>Kein Inline-Editing. <code>md_batch_save</code> ignoriert.</td></tr></tbody></table><p>Beispiel Row-Level Inline-Edit:</p><p>Snippet 1:</p><p>Beispiel Zelle-fuer-Zelle mit Batch-Save:</p><p>Snippet 2:</p><h2>Toolbar Export/Import</h2><ul><li>Export XLS:</li></ul><p> - zeigt Fortschrittsdialog mit Echtzeit-Prozentsatz;</p><p> - Aktionen: <code>Im Hintergrund fortsetzen</code>, <code>Task abbrechen</code>, <code>Unterbrechen und teilweise herunterladen</code>;</p><p> - im Hintergrund wird eine Benachrichtigung mit Fortschritt erstellt; Klick oeffnet den Dialog erneut.</p><p> - fuehrt der Server bereits <code>maxConcurrentExports</code> Exporte aus, wartet der Export in einer Warteschlange: Dialog und Benachrichtigung zeigen "In der Warteschlange: Position N", und er startet von selbst, sobald ein Platz frei wird (auch waehrend des Wartens abbrechbar);</p><p> - SQL Server: hat die Datenbank <code>ALLOW_SNAPSHOT_ISOLATION ON</code>, liest der Export mit Snapshot-Isolation und blockiert keine Schreibvorgaenge auf der Tabelle, waehrend er die Datei schreibt (ohne diese Option haelt ein langer Export seine Lesesperren und Insert/Update auf derselben Tabelle warten bis zu seinem Ende). Die Option wird einmal auf der Datenbank aktiviert (<code>ALTER DATABASE [<Datenbank>] SET ALLOW_SNAPSHOT_ISOLATION ON</code>) und aendert das Verhalten der anderen Lesevorgaenge nicht; sie funktioniert zusammen mit <code>READ_COMMITTED_SNAPSHOT ON</code>. Die Tutorial-Datenbank hat <code>READ_COMMITTED_SNAPSHOT ON</code>;</p><ul><li>Import XLS/XLSX (wenn <code>md_importable = true</code>):</li></ul><p> - Fortschrittsdialog nach Bestaetigung;</p><p> - Aktionen: <code>Im Hintergrund fortsetzen</code>, <code>Import abbrechen (Rollback)</code>, <code>Stop und teilweise Commit</code>;</p><p> - nach Import-Ende wird eine Zusammenfassungs-Benachrichtigung erstellt, die zur Route fuehrt.</p><h2>Config Metadata</h2><p>Schluessel-Einstellungen in <code>md_props_bag</code> und Spalten-Metadaten.</p><p>Snippet 3:</p><h2>md_props_bag: toolbar</h2><p>Opt-in-Flags, die Bloecke der list-grid Toolbar (<code>caption-bar</code>) ausblenden. Alle unter <code>md_props_bag.toolbar.*</code> (zur Laufzeit als <code>tableMetadata.extraProps.toolbar</code> geparst).</p><p>Snippet 4:</p><ul><li><code>hideManageState</code> (boolean, default <code>false</code>): blendet in der <strong>caption-right</strong> den Button "Status verwalten" (Bookmark-Icon) + das <code><select></code> der gespeicherten Zustaende aus. Nuetzlich fuer hardcoded / Demo-Routes, bei denen das Saved-State-Feature (Persistenz pro <code>user_id</code> + Route via <code>MetaService</code>) keinen Sinn ergibt — z.B. Pattern 3 reines OData ohne registrierte Route-Metadaten.</li><li><code>hideBatchActions</code> (boolean, default <code>false</code>): blendet in der <strong>caption-left</strong> die Buttons "Aenderungen speichern" (<code>pi-save</code>) + "Aenderungen verwerfen" (<code>pi-times</code>) + den Aenderungs-Zaehler-Indikator (<code>grid-changes-indicator</code>, Pencil-Badge + Count) aus. Vom Framework generiert, wenn <code>md_inline_cell_editing</code> + <code>md_batch_save</code> aktiv sind. Konzipiert fuer <strong>verschachtelte Grids in einem parametric-dialog</strong>: Save/Cancel des Parents persistiert Master + Zeilen in einem Schritt via Framework Batch Save, und die Duplikat-Buttons auf der nested Grid verwirren die UX.</li></ul><p>Beispiel nested rows in custom edit-form (Runtime-Patch):</p><p>Snippet 5:</p><p>TS-Typ in <a href=\"../api/wuic-framework-lib.metadatitabella.html\">`metadati_tabella.ts`</a> (<code>extraProps.toolbar</code> Property). Die Flags deaktivieren NICHT die zugrundeliegende <code>md_batch_save</code>-Logik (Aenderungen werden weiterhin getrackt); sie entfernen nur die Toolbar-UI — der eigentliche Save laeuft ueber den Parent-Flow.</p><h2>md_props_bag: archetypes.list</h2><p>Die Komponente liest <code>md_props_bag.archetypes.list</code>.</p><p>Snippet 6:</p><ul><li><code>proportionalColwidth</code>:</li><li>Typ: boolean (mit tolerantem Parser)</li><li>akzeptierte Werte: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>"true"</code>, <code>"false"</code>, <code>"1"</code>, <code>"0"</code></li><li>Runtime-Default: <code>true</code> wenn absent oder leer</li><li>Effekt: verteilt die Spaltenbreiten prozentual (anstelle von px), wenn keine vom Benutzer persistierten Breiten vorhanden sind.</li></ul><ul><li><code>virtualize</code>:</li><li>Typ: <code>boolean</code> oder <code>object</code></li><li>akzeptierte Werte:</li><li><code>true</code>/<code>false</code>, <code>1</code>/<code>0</code>, <code>"true"</code>/<code>"false"</code>, <code>"1"</code>/<code>"0"</code></li><li>Object mit <code>enabled</code> (optional) und <code>itemSize</code> (optional)</li><li>Runtime-Default: deaktiviert (<code>false</code>) wenn absent</li><li><code>enabled</code>:</li><li>Default: <code>true</code> wenn der <code>virtualize</code>-Knoten ein Object ohne <code>enabled</code> ist, sonst toleranter Parser</li><li>Effekt: aktiviert <code>virtualScroll</code> auf <code>p-table</code></li><li><code>itemSize</code>:</li><li>Default: <code>44</code></li><li>Effekt: setzt <code>virtualScrollItemSize</code> (virtuelle Zeilenhoehe in px)</li></ul><ul><li><code>advancedFilter</code>:</li><li>Typ: boolean (mit tolerantem Parser)</li><li>Runtime-Default: <code>false</code></li><li>Effekt:</li><li>wenn <code>true</code>, blendet das Grid die Spalten-Filter-Icons (<code>p-columnFilter</code>) aus und verwendet die <code>wuic-filter-bar</code> ueber der Tabelle (auf <code>data-repeater</code>/<code>bounded-repeater</code>-Ebene), um die Filter anzuwenden.</li></ul><p>Betriebshinweis:</p><ul><li>der <code>md_props_bag</code>-Suggest im Metadata-Editor stellt auch den checkbaren Knoten <code>archetypes.list.advancedFilter</code> bereit.</li></ul><h2>Paging: md_pagesize und md_page_size_choice</h2><p>Das Grid verwendet <code>md_pagesize</code> als Standard-Seitengroesse und <code>md_page_size_choice</code> als Liste der im Paginator auswaehlbaren Werte.</p><p>Runtime-Regeln:</p><ul><li>wenn <code>md_pagesize</code> groesser als der maximale Wert in <code>md_page_size_choice</code> ist, fuegt das Framework <code>md_pagesize</code> automatisch zur Optionsliste hinzu;</li><li>die Liste wird normalisiert (gueltige Zahlen, Deduplizierung, aufsteigende Sortierung).</li></ul><p>Beispiel:</p><ul><li><code>md_pagesize = 200</code></li><li><code>md_page_size_choice = "10,25,50,100"</code></li><li>Runtime-Ergebnis: <code>10,25,50,100,200</code></li></ul><h2>Erzwungene Virtualisierung bei hoher Seitengroesse</h2><p>Wenn der Benutzer im Paginator einen Wert <code>pageSize >= 1000</code> auswaehlt:</p><ul><li>wird die Virtualisierung automatisch erzwungen, auch wenn <code>md_props_bag.archetypes.list.virtualize</code> absent oder deaktiviert ist;</li><li><code>virtualScrollItemSize</code> wird auf den Standardwert <code>44</code> gesetzt.</li></ul><p>Dieses Verhalten schuetzt das Rendering der Tabelle bei sehr grossen Seiten.</p><h2>Events und Subscriptions (Host)</h2><p><code>wuic-list-grid</code> stellt Runtime-Events bereit, die nuetzlich sind, um den Render-Zyklus und die p-table-Callbacks auf der Host-Projektseite zu intercepten.</p><p>Verfuegbare Events:</p><ul><li><code>onAfterRender</code>: wird am Ende des Datenbindings des Grids emittiert (<code>rows</code>, <code>totalRecords</code>, <code>metaInfo</code>, <code>datasource</code>).</li><li><code>onBeforeRowRender</code>: wird vor dem logischen Rendering der einzelnen Zeile emittiert; unterstuetzt Cancel via <code>event.cancelRender()</code>.</li><li><code>onAfterRowRender</code>: wird nach dem logischen Rendering der einzelnen Zeile emittiert.</li><li><code>onPaging</code>: wird bei Paging-Events emittiert (<code>p-table onPage</code>).</li><li><code>onSorting</code>: wird bei Sorting-Events emittiert (<code>p-table onSort</code>).</li><li><code>onFiltering</code>: wird bei Filtering-Events emittiert (<code>p-table onFilter</code>).</li><li><code>onPTableSelectionChange</code>: wird bei Aenderung der Zeilenauswahl emittiert.</li><li><code>onPTableRowExpand</code>: wird beim Expandieren einer Zeile emittiert.</li><li><code>onPTableRowCollapse</code>: wird beim Collapsen einer Zeile emittiert.</li><li><code>onPTableColumnResize</code>: wird beim Spalten-Resize emittiert.</li><li><code>onPTableColumnReorder</code>: wird beim Spalten-Reorder emittiert.</li></ul><h3>Beispiel 1: direktes Binding im Template</h3><p>Snippet 7:</p><h3>Beispiel 2: Subscribe via ViewChild</h3><p>Snippet 8:</p><h2><code>rowCustomSelect</code> — tatsachliche Signatur (Falle)</h2><p><code><wuic-list-grid></code> akzeptiert ein <code>[rowCustomSelect]</code>-Input zum Abfangen der Zeilenauswahl (Offnen eines "Dokument auswahlen"-Dialogs, Master-Detail-Flow, etc.). Die TypeScript-Signatur in <a href=\"../../src/lib/component/list-grid/list-grid.component.ts#L140\">list-grid.component.ts:140</a> lautet:</p><p>Snippet 9:</p><p><strong>Zur Laufzeit wird der Callback jedoch mit umgekehrten Argumenten aufgerufen</strong> — das Framework ruft <code>rowCustomSelect($event, rowData, dt)</code> auf (siehe <a href=\"../../src/lib/component/dynamic-template/dynamic-template.component.ts#L447\">dynamic-template.component.ts:447</a> und <a href=\"../../src/lib/component/dynamic-template/dynamic-card-template.component.ts#L205\">dynamic-card-template.component.ts:205</a>).</p><p>Symptom bei falscher Reihenfolge: <code>rowData?.id</code> ist undefined → fruhzeitiger Guard im Handler → der Callback kehrt stillschweigend zuruck und der Dialog/die Aktion startet nicht. Kein Konsolenfehler.</p><p>Korrekte Form (auf Laufzeit-Invocation abgestimmt):</p><p>Snippet 10:</p><p>Verwendung im Template:</p><p>Snippet 11:</p><p>> Hinweis: Die Tests in <code>designer.component.spec.ts</code> (z.B. Zeile 512) rufen den Callback mit <code>({currentTarget: rowCell}, {id: 42}, null)</code> auf und bestatigen die Reihenfolge <code>($event, rowData, dt)</code>. Sollte das Framework die deklarierte Signatur kunftig angleichen, wird auch diese Seite aktualisiert.</p>",
|
|
29406
29422
|
"codeSamples": [
|
|
29407
29423
|
{
|
|
29408
29424
|
"id": "code_1",
|
|
@@ -34305,10 +34321,14 @@ const frameworkDocsContent = {
|
|
|
34305
34321
|
},
|
|
34306
34322
|
{
|
|
34307
34323
|
"id": "sec_5",
|
|
34308
|
-
"title": "
|
|
34324
|
+
"title": "Tabellen mit MAX-Schluessel"
|
|
34309
34325
|
},
|
|
34310
34326
|
{
|
|
34311
34327
|
"id": "sec_6",
|
|
34328
|
+
"title": "Verhalten bei vorhandener PK (nur Insert-Import)"
|
|
34329
|
+
},
|
|
34330
|
+
{
|
|
34331
|
+
"id": "sec_7",
|
|
34312
34332
|
"title": "Spalten der Datei und Lookups (Export und Import)"
|
|
34313
34333
|
}
|
|
34314
34334
|
],
|
|
@@ -34316,7 +34336,7 @@ const frameworkDocsContent = {
|
|
|
34316
34336
|
{
|
|
34317
34337
|
"id": "overview",
|
|
34318
34338
|
"title": "Overview",
|
|
34319
|
-
"html": "<h1>Import</h1><p>Ermoeglicht den Datenimport aus Excel-Dateien (<code>.xls</code>, <code>.xlsx</code>) in die aktuelle Route der Metadaten-Tabelle.</p><p>Wenn aktiviert, erscheint im <code>List Grid</code> eine Schaltflaeche in der Toolbar (<code>Import XLS/XLSX</code>), die den Dateiauswahldialog oeffnet und die Datei an die bereits im Backend verfuegbare Import-Methode sendet.</p><h2>Tabellen-Metadatum</h2><p>Der Hauptschalter ist:</p><ul><li><code>md_importable</code></li></ul><p> Bedeutung: Zeigt/verbirgt die Import-Schaltflaeche in der Toolbar des <code>List Grid</code>.</p><p> Werte: <code>true | false</code>.</p><p> Standard: <code>false</code> (wenn nicht vorhanden).</p><h2>Zusaetzliche Eigenschaften (<code>md_props_bag</code>)</h2><p>Die Import-Optionen werden in <code>extraProps.import</code> konfiguriert (abgeleitet von <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Operative Hinweise</h2><ul><li>Die Schaltflaeche ist sichtbar, wenn <code>md_importable = true</code>.</li><li>Die Datei wird clientseitig auf die Erweiterung (<code>xls</code>, <code>xlsx</code>) vor dem Upload validiert.</li><li>Der Import wird auf der aktuellen Route (<code>md_route_name</code>) der aktiven Datenquelle ausgefuehrt.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (Standard): Oeffnet den Zwischendialog zur Auswahl der Import-Optionen vor dem Upload.</p><p> - <code>true</code>: Ueberspringt den Dialog und startet den Upload/Import direkt mit den bereits in <code>md_props_bag.import</code> definierten Optionen.</p><ul><li>Empfohlene Standardwerte im Suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (Spaltenuberschriften verwenden).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI und Fortschritt</h2><ul><li>Nach der Import-Bestaetigung oeffnet sich ein Fortschrittsdialog mit Echtzeit-Prozentanzeige.</li><li>Verfuegbare Aktionen:</li></ul><p> - <code>Im Hintergrund fortfahren</code>: Schliesst den Dialog und erstellt eine Fortschrittsbenachrichtigung.</p><p> - <code>Import abbrechen (Rollback)</code>: Bricht ab und fuehrt ein Rollback durch.</p><p> - <code>Stoppen und teilweise committen</code>: Unterbricht und bestaetigt das bisher Erledigte.</p><ul><li>Nach Abschluss des Imports wird eine Zusammenfassungsbenachrichtigung erstellt (gleicher Text wie der Toast); ein Klick fuehrt zur Import-Route, ohne die Seite neu zu laden, wenn man sich bereits auf derselben Seite befindet.</li></ul><h2>Verhalten bei vorhandener PK (nur Insert-Import)</h2><p>Wenn <code>import_type = "I"</code> und die PK des Datensatzes bereits existiert:</p><ul><li>wird der Insert uebersprungen;</li><li>der Datensatz wird in der Zusammenfassung als "uebersprungene Einfuegungen (PK vorhanden)" gezaehlt.</li></ul><h2>Spalten der Datei und Lookups (Export und Import)</h2><p>XLS-Export und Import folgen denselben Regeln, sodass eine exportierte Datei unverändert wieder importiert werden kann.</p><h3>Spaltenüberschriften</h3><ul><li>Jede Spalte trägt ihre Caption als Überschrift (<code>mc_display_string_in_view</code>; falls leer, den Spaltennamen).</li><li>Haben zwei Spalten derselben Datei die gleiche Caption, erhält jede ihren physischen Namen in Klammern: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Ohne Kollision bleiben die Überschriften wie bisher.</li><li>Der Import erkennt eine Spalte an ihrer Caption, an der Caption mit dem physischen Namen (oder Spaltennamen) in Klammern oder am physischen Namen / Spaltennamen.</li><li>Eine Überschrift, die zu mehreren Spalten passt (z. B. eine alte Datei mit zwei Spalten <code>People</code>), wird mit dem Fehler "Ambiguous column" abgelehnt: Sie muss als <code>Caption (physischer Name)</code> geschrieben werden.</li></ul><h3>Lookup-Spalten: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> legt fest, wie Lookup-Spalten (<code>mc_ui_column_type = lookupByID</code>) übertragen werden:</p><table><thead><tr><th>Wert</th><th>In der Datei</th><th>Hinweise</th></tr></thead><tbody><tr><td><code>description</code> (Standard)</td><td>die Beschreibung des verknüpften Datensatzes, unter der Caption</td><td>wie bisher</td></tr><tr><td><code>key</code></td><td>der Schlüssel des verknüpften Datensatzes, unter der Caption</td><td></td></tr><tr><td><code>both</code></td><td>zwei Spalten: die Beschreibung unter der Caption, der Schlüssel unter dem physischen Namen (<code>Auftrag</code> + <code>OrderID</code>)</td><td>ist die Caption der physische Name, wird die Beschreibungsspalte zu <code>Caption (Textfeld des Lookups)</code>, z. B. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>Der Export folgt dem Wert der Route; ohne <code>fkey_mode</code> gilt <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Im Import-Dialog ist die Auswahl "Lookup-Spalten in der Datei" mit demselben Wert vorbelegt und kann für einen einzelnen Import geändert werden.</li></ul><h3>Von der Beschreibung zum Schlüssel</h3><ul><li><strong>Nur Schlüssel</strong>: wird unverändert verwendet.</li><li><strong>Nur Beschreibung</strong>: Der verknüpfte Datensatz mit dieser Beschreibung (Textfeld des Lookups) wird gesucht.</li></ul><p> - Genau ein Datensatz: sein Schlüssel wird verwendet.</p><p> - Keiner: Die Zeile ist fehlerhaft.</p><p> - Mehrere Datensätze mit derselben Beschreibung: Aktualisiert die Zeile einen vorhandenen Datensatz und passt dessen bisheriger Schlüssel zu dieser Beschreibung, bleibt die Verknüpfung erhalten (der Benutzer hat sie nicht geändert). Andernfalls, und bei neuen Zeilen immer, ist es ein Fehler mit der Liste der möglichen Schlüssel: Zum Einfügen wird der Schlüssel benötigt, also <code>key</code> oder <code>both</code>.</p><ul><li><strong>Schlüssel und Beschreibung (`both`)</strong>: Der Schlüssel gilt, wenn sein Datensatz diese Beschreibung hat; passen sie nicht zusammen (eines wurde geändert, das andere nicht), ist die Zeile fehlerhaft.</li><li>Ein Primärschlüssel, der zugleich Lookup ist (1:1-Tabelle), wird vor der Prüfung aufgelöst, ob der Datensatz existiert.</li><li>Mit <code>commit_level</code> <code>R</code> oder <code>I</code> beendet ein Lookup-Fehler den Import ohne zu speichern; mit <code>C</code> oder <code>T</code> wird die Zeile übersprungen und der Import fortgesetzt.</li></ul><h3>Datumswerte</h3><p>Datumszellen aus dem Export (Zahl mit Datumsformat, wie in Excel) werden als Datum gelesen: Eine unverändert exportierte und wieder importierte Datei wird bei Datumsspalten nicht mehr abgelehnt.</p>",
|
|
34339
|
+
"html": "<h1>Import</h1><p>Ermoeglicht den Datenimport aus Excel-Dateien (<code>.xls</code>, <code>.xlsx</code>) in die aktuelle Route der Metadaten-Tabelle.</p><p>Wenn aktiviert, erscheint im <code>List Grid</code> eine Schaltflaeche in der Toolbar (<code>Import XLS/XLSX</code>), die den Dateiauswahldialog oeffnet und die Datei an die bereits im Backend verfuegbare Import-Methode sendet.</p><h2>Tabellen-Metadatum</h2><p>Der Hauptschalter ist:</p><ul><li><code>md_importable</code></li></ul><p> Bedeutung: Zeigt/verbirgt die Import-Schaltflaeche in der Toolbar des <code>List Grid</code>.</p><p> Werte: <code>true | false</code>.</p><p> Standard: <code>false</code> (wenn nicht vorhanden).</p><h2>Zusaetzliche Eigenschaften (<code>md_props_bag</code>)</h2><p>Die Import-Optionen werden in <code>extraProps.import</code> konfiguriert (abgeleitet von <code>md_props_bag</code>).</p><p>Snippet 1:</p><h2>Operative Hinweise</h2><ul><li>Die Schaltflaeche ist sichtbar, wenn <code>md_importable = true</code>.</li><li>Die Datei wird clientseitig auf die Erweiterung (<code>xls</code>, <code>xlsx</code>) vor dem Upload validiert.</li><li>Der Import wird auf der aktuellen Route (<code>md_route_name</code>) der aktiven Datenquelle ausgefuehrt.</li><li><code>skipsettings</code>:</li></ul><p> - <code>false</code> (Standard): Oeffnet den Zwischendialog zur Auswahl der Import-Optionen vor dem Upload.</p><p> - <code>true</code>: Ueberspringt den Dialog und startet den Upload/Import direkt mit den bereits in <code>md_props_bag.import</code> definierten Optionen.</p><ul><li>Empfohlene Standardwerte im Suggest:</li></ul><p> - <code>use_column_captions = "C"</code> (Spaltenuberschriften verwenden).</p><p> - <code>use_descriptive_fkey = true</code>.</p><h2>UI und Fortschritt</h2><ul><li>Nach der Import-Bestaetigung oeffnet sich ein Fortschrittsdialog mit Echtzeit-Prozentanzeige.</li><li>Verfuegbare Aktionen:</li></ul><p> - <code>Im Hintergrund fortfahren</code>: Schliesst den Dialog und erstellt eine Fortschrittsbenachrichtigung.</p><p> - <code>Import abbrechen (Rollback)</code>: Bricht ab und fuehrt ein Rollback durch.</p><p> - <code>Stoppen und teilweise committen</code>: Unterbricht und bestaetigt das bisher Erledigte.</p><ul><li>Nach Abschluss des Imports wird eine Zusammenfassungsbenachrichtigung erstellt (gleicher Text wie der Toast); ein Klick fuehrt zur Import-Route, ohne die Seite neu zu laden, wenn man sich bereits auf derselben Seite befindet.</li></ul><h2>Tabellen mit MAX-Schluessel</h2><p>Auf Routen mit <code>md_primary_key_type = "MAX"</code> (und beim "abhaengigen Schluessel" zusammengesetzter Schluessel) ist der Schluessel jeder neuen Zeile das Maximum + 1, berechnet im Insert mit einer Sperre auf der Tabelle: neue Zeilen derselben Datei erhalten fortlaufende Schluessel und gleichzeitige Inserts kollidieren nicht. Die Sperre haelt bis zum Ende des Imports (eine Transaktion pro Datei): solange warten andere Inserts auf derselben Tabelle, unter Oracle auch Update und Delete. Fuer grosse Dateien auf stark genutzten Tabellen den Schluessel in die Datei aufnehmen oder die Tabelle auf <code>IDENTITY</code>/<code>SEQUENCE</code> umstellen.</p><h2>Verhalten bei vorhandener PK (nur Insert-Import)</h2><p>Wenn <code>import_type = "I"</code> und die PK des Datensatzes bereits existiert:</p><ul><li>wird der Insert uebersprungen;</li><li>der Datensatz wird in der Zusammenfassung als "uebersprungene Einfuegungen (PK vorhanden)" gezaehlt.</li></ul><h2>Spalten der Datei und Lookups (Export und Import)</h2><p>XLS-Export und Import folgen denselben Regeln, sodass eine exportierte Datei unverändert wieder importiert werden kann.</p><h3>Spaltenüberschriften</h3><ul><li>Jede Spalte trägt ihre Caption als Überschrift (<code>mc_display_string_in_view</code>; falls leer, den Spaltennamen).</li><li>Haben zwei Spalten derselben Datei die gleiche Caption, erhält jede ihren physischen Namen in Klammern: <code>People (ContactPersonID)</code>, <code>People (LastEditedBy)</code>. Ohne Kollision bleiben die Überschriften wie bisher.</li><li>Der Import erkennt eine Spalte an ihrer Caption, an der Caption mit dem physischen Namen (oder Spaltennamen) in Klammern oder am physischen Namen / Spaltennamen.</li><li>Eine Überschrift, die zu mehreren Spalten passt (z. B. eine alte Datei mit zwei Spalten <code>People</code>), wird mit dem Fehler "Ambiguous column" abgelehnt: Sie muss als <code>Caption (physischer Name)</code> geschrieben werden.</li></ul><h3>Lookup-Spalten: <code>fkey_mode</code></h3><p><code>md_props_bag.import.fkey_mode</code> legt fest, wie Lookup-Spalten (<code>mc_ui_column_type = lookupByID</code>) übertragen werden:</p><table><thead><tr><th>Wert</th><th>In der Datei</th><th>Hinweise</th></tr></thead><tbody><tr><td><code>description</code> (Standard)</td><td>die Beschreibung des verknüpften Datensatzes, unter der Caption</td><td>wie bisher</td></tr><tr><td><code>key</code></td><td>der Schlüssel des verknüpften Datensatzes, unter der Caption</td><td></td></tr><tr><td><code>both</code></td><td>zwei Spalten: die Beschreibung unter der Caption, der Schlüssel unter dem physischen Namen (<code>Auftrag</code> + <code>OrderID</code>)</td><td>ist die Caption der physische Name, wird die Beschreibungsspalte zu <code>Caption (Textfeld des Lookups)</code>, z. B. <code>OrderID (CustomerPurchaseOrderNumber)</code></td></tr></tbody></table><ul><li>Der Export folgt dem Wert der Route; ohne <code>fkey_mode</code> gilt <code>use_descriptive_fkey</code> (<code>true</code> = <code>description</code>, <code>false</code> = <code>key</code>).</li><li>Im Import-Dialog ist die Auswahl "Lookup-Spalten in der Datei" mit demselben Wert vorbelegt und kann für einen einzelnen Import geändert werden.</li></ul><h3>Von der Beschreibung zum Schlüssel</h3><ul><li><strong>Nur Schlüssel</strong>: wird unverändert verwendet.</li><li><strong>Nur Beschreibung</strong>: Der verknüpfte Datensatz mit dieser Beschreibung (Textfeld des Lookups) wird gesucht.</li></ul><p> - Genau ein Datensatz: sein Schlüssel wird verwendet.</p><p> - Keiner: Die Zeile ist fehlerhaft.</p><p> - Mehrere Datensätze mit derselben Beschreibung: Aktualisiert die Zeile einen vorhandenen Datensatz und passt dessen bisheriger Schlüssel zu dieser Beschreibung, bleibt die Verknüpfung erhalten (der Benutzer hat sie nicht geändert). Andernfalls, und bei neuen Zeilen immer, ist es ein Fehler mit der Liste der möglichen Schlüssel: Zum Einfügen wird der Schlüssel benötigt, also <code>key</code> oder <code>both</code>.</p><ul><li><strong>Schlüssel und Beschreibung (`both`)</strong>: Der Schlüssel gilt, wenn sein Datensatz diese Beschreibung hat; passen sie nicht zusammen (eines wurde geändert, das andere nicht), ist die Zeile fehlerhaft.</li><li>Ein Primärschlüssel, der zugleich Lookup ist (1:1-Tabelle), wird vor der Prüfung aufgelöst, ob der Datensatz existiert.</li><li>Mit <code>commit_level</code> <code>R</code> oder <code>I</code> beendet ein Lookup-Fehler den Import ohne zu speichern; mit <code>C</code> oder <code>T</code> wird die Zeile übersprungen und der Import fortgesetzt.</li></ul><h3>Datumswerte</h3><p>Datumszellen aus dem Export (Zahl mit Datumsformat, wie in Excel) werden als Datum gelesen: Eine unverändert exportierte und wieder importierte Datei wird bei Datumsspalten nicht mehr abgelehnt.</p>",
|
|
34320
34340
|
"codeSamples": [
|
|
34321
34341
|
{
|
|
34322
34342
|
"id": "code_1",
|
|
@@ -35829,4 +35849,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
35829
35849
|
}] } });
|
|
35830
35850
|
|
|
35831
35851
|
export { FrameworkDocsComponent };
|
|
35832
|
-
//# sourceMappingURL=wuic-framework-lib-framework-docs.component-
|
|
35852
|
+
//# sourceMappingURL=wuic-framework-lib-framework-docs.component-GXDoB6Ry.mjs.map
|