wuic-framework-lib 1.0.11 → 1.0.19

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.
Files changed (16) hide show
  1. package/fesm2022/{wuic-framework-lib-chart-list.component-vuzmQW9F.mjs → wuic-framework-lib-chart-list.component-C0OYuZoM.mjs} +8 -8
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-BjbIkm4g.mjs → wuic-framework-lib-code-editor.component-B8OQ3Z0k.mjs} +258 -258
  3. package/fesm2022/{wuic-framework-lib-designer.component-BM3elB-a.mjs → wuic-framework-lib-designer.component-DsWgWtFj.mjs} +99 -105
  4. package/fesm2022/{wuic-framework-lib-first-run-wizard.component-5tcl67dK.mjs → wuic-framework-lib-first-run-wizard.component-wR_LrvPK.mjs} +244 -38
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-BGcJ7k1X.mjs → wuic-framework-lib-framework-docs.component-eyzu9tdV.mjs} +31 -15
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-ChNyMAfi.mjs → wuic-framework-lib-pivot-builder.component-BFdZW5Ch.mjs} +215 -88
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-DFLR_EmK.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-B583WbYe.mjs} +2 -2
  8. package/fesm2022/{wuic-framework-lib-report-designer.component-B_SC7VkW.mjs → wuic-framework-lib-report-designer.component-HJUpslLX.mjs} +12 -12
  9. package/fesm2022/{wuic-framework-lib-report-viewer.component-BTK-p8xF.mjs → wuic-framework-lib-report-viewer.component-El32zpzi.mjs} +81 -11
  10. package/fesm2022/{wuic-framework-lib-scheduler-list.component-CIoGVf4O.mjs → wuic-framework-lib-scheduler-list.component-E8s_e533.mjs} +16 -16
  11. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-DQ5OxO4j.mjs → wuic-framework-lib-spreadsheet-list-sf.component-CDn0qi_C.mjs} +19 -5
  12. package/fesm2022/{wuic-framework-lib-workflow-designer.component-BHLT4MER.mjs → wuic-framework-lib-workflow-designer.component-hL7oKqYO.mjs} +2 -2
  13. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-DDokY6wY.mjs → wuic-framework-lib-wuic-framework-lib-ABS_G7lO.mjs} +2149 -1089
  14. package/fesm2022/wuic-framework-lib.mjs +1 -1
  15. package/package.json +1 -1
  16. package/types/wuic-framework-lib.d.ts +308 -24
@@ -16,12 +16,12 @@ import * as i1$3 from 'primeng/image';
16
16
  import { ImageModule } from 'primeng/image';
17
17
  import * as i2 from '@ngx-translate/core';
18
18
  import { TranslateService, TranslateModule } from '@ngx-translate/core';
19
- import { q as getThemeOptions, T as TranslationManagerService, U as UserInfoService } from './wuic-framework-lib-wuic-framework-lib-DDokY6wY.mjs';
19
+ import { r as getThemeOptions, T as TranslationManagerService, U as UserInfoService } from './wuic-framework-lib-wuic-framework-lib-ABS_G7lO.mjs';
20
20
  import * as i1 from '@angular/router';
21
21
 
22
22
  const frameworkDocsContent = {
23
23
  "version": "1.0.0",
24
- "generatedAt": "2026-04-27T15:49:14.823Z",
24
+ "generatedAt": "2026-05-03T15:13:16.104Z",
25
25
  "groups": [
26
26
  {
27
27
  "id": "primi-passi",
@@ -2018,7 +2018,7 @@ const frameworkDocsContent = {
2018
2018
  "id": "code_1",
2019
2019
  "title": "Snippet 1",
2020
2020
  "language": "json",
2021
- "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyph: glyph, scale: 1.2 }); return pin.element;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
2021
+ "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyphText: glyph, scale: 1.2 }); return pin;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
2022
2022
  },
2023
2023
  {
2024
2024
  "id": "code_2",
@@ -4172,7 +4172,7 @@ const frameworkDocsContent = {
4172
4172
  {
4173
4173
  "id": "overview",
4174
4174
  "title": "Overview",
4175
- "html": "<h1>Catalogo Componenti</h1><p>Totale cartelle componenti rilevate: 48.</p><h2>Componenti disponibili</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Export da public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li></ul>",
4175
+ "html": "<h1>Catalogo Componenti</h1><p>Totale cartelle componenti rilevate: 49.</p><h2>Componenti disponibili</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>error-dialog</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Export da public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li><li>error-dialog/error-dialog.component</li></ul>",
4176
4176
  "codeSamples": []
4177
4177
  }
4178
4178
  ],
@@ -4512,10 +4512,14 @@ const frameworkDocsContent = {
4512
4512
  },
4513
4513
  {
4514
4514
  "id": "sec_13",
4515
- "title": "Note operative"
4515
+ "title": "Authentication:Ldap (LDAP / Active Directory)"
4516
4516
  },
4517
4517
  {
4518
4518
  "id": "sec_14",
4519
+ "title": "Note operative"
4520
+ },
4521
+ {
4522
+ "id": "sec_15",
4519
4523
  "title": "appsettings.json reale (snapshot)"
4520
4524
  }
4521
4525
  ],
@@ -4523,12 +4527,24 @@ const frameworkDocsContent = {
4523
4527
  {
4524
4528
  "id": "overview",
4525
4529
  "title": "Overview",
4526
- "html": "<h1>AppSettings</h1><p>Parametri applicativi, configurazioni ambiente e override runtime.</p><p>Questa pagina documenta le chiavi usate dal framework in <code>appsettings.json</code> e <code>appsettings.{Environment}.json</code>.</p><h2>Convenzioni generali</h2><ul><li>I valori sotto <code>AppSettings</code> sono letti come stringa e poi convertiti (<code>bool/int</code>) dal backend.</li><li>Per flag booleani usare <code>true|false</code>.</li><li>Per chiavi numeriche usare interi positivi (secondi/minuti/timeout).</li><li>Le chiavi sono case-sensitive lato JSON.</li></ul><h2>AppSettings - Core bootstrap</h2><ul><li><code>firstRun</code></li></ul><p> Significato: abilita il flusso di prima configurazione/provisioning.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>preScaffold</code></li></ul><p> Significato: abilita pre-scaffolding di oggetti metadata/app.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>projectDataFolder</code></li></ul><p> Significato: root progetto applicativo (es. CrmApp) usata per file, assembly e risorse runtime.</p><p> Valori: path assoluto filesystem.</p><ul><li><code>projectAssemblyName</code></li></ul><p> Significato: assembly applicativo caricato dinamicamente.</p><p> Valori: path assoluto <code>.dll</code>.</p><ul><li><code>defaultSiteRoute</code></li></ul><p> Significato: route iniziale client dopo bootstrap/login.</p><p> Valori: hash-route (es. <code>#/</code>).</p><ul><li><code>license-email</code></li></ul><p> Significato: email/licenza installazione.</p><p> Valori: email valida.</p><h2>AppSettings - Database e provider</h2><ul><li><code>dbms</code></li></ul><p> Significato: provider DB principale route dati.</p><p> Valori enum-like: <code>mssql | mysql | postgresql | oracle | xml</code>.</p><p> Default tipico: <code>mssql</code>.</p><ul><li><code>meta-dbms</code></li></ul><p> Significato: provider DB metadata (route di sistema).</p><p> Valori enum-like: <code>mssql | mysql | postgresql | oracle | xml</code>.</p><p> Default tipico: uguale a <code>dbms</code>.</p><ul><li><code>allowMultipleDBMS</code></li></ul><p> Significato: abilita convivenza provider multipli nel runtime.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>connection</code></li></ul><p> Significato: connection string base usata da servizi/scaffolding.</p><p> Valori: connection string provider-specific.</p><ul><li><code>DataDBName</code></li></ul><p> Significato: nome database dati di default.</p><p> Valori: nome DB.</p><ul><li><code>connectionByUser</code></li></ul><p> Significato: usa connessione/contesto legato all&#39;utente corrente in punti runtime specifici.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><h2>AppSettings - CRUD, query, filtri</h2><ul><li><code>autoGeneratedQueryTimeout</code></li></ul><p> Significato: timeout (secondi) query SQL autogenerate.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>120</code>.</p><ul><li><code>storedProcTimeout</code></li></ul><p> Significato: timeout (secondi) esecuzione stored procedure.</p><p> Valori: intero positivo.</p><ul><li><code>enableServerSideCrudChangeLog</code></li></ul><p> Significato: abilita logging lato server delle operazioni CRUD.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>true</code>.</p><ul><li><code>logicDeleteField</code></li></ul><p> Significato: campo globale per cancellazione logica (se non definito in metadata tabella).</p><p> Valori: nome colonna.</p><ul><li><code>logicDeleteValue</code></li></ul><p> Significato: valore che rappresenta &quot;record cancellato logicamente&quot;.</p><p> Valori: string/numero compatibile col tipo del campo.</p><p> Default tipico: <code>1</code>.</p><ul><li><code>cacheDataMinutes</code></li></ul><p> Significato: durata cache dati in minuti (quando caching route attivo).</p><p> Valori: intero positivo.</p><ul><li><code>cacheDataIncludedRoutes</code></li></ul><p> Significato: whitelist route cacheabili.</p><p> Valori: lista route separata da virgole.</p><ul><li><code>cacheDataExcludedRoutes</code></li></ul><p> Significato: blacklist route da escludere dalla cache.</p><p> Valori: lista route separata da virgole.</p><ul><li><code>traceQuery</code></li></ul><p> Significato: abilita tracing query SQL con tempi esecuzione.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>sqlVerbose</code></li></ul><p> Significato: abilita output SQL verboso in endpoint/tools che lo supportano.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>logInvoke</code></li></ul><p> Significato: abilita log invocazioni funzioni dinamiche/callback.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Sicurezza, login, sessione</h2><ul><li><code>customAuthentication</code></li></ul><p> Significato: delega autenticazione a logica custom applicativa.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>enableCookieAuthentication</code></li></ul><p> Significato: controlla <strong>chi</strong> scrive il cookie di sessione <code>k-user</code> e con <strong>quale policy</strong>. Il backend espone in entrambe le modalita&#39; lo stesso wire format (<code>k-user=&lt;urlencoded-json&gt;</code>), cambia solo il mittente e gli attributi del cookie.</p><p> Valori: <code>true | false</code>. Default: <code>false</code>.</p><p> Confronto sintetico delle due modalita&#39;:</p><table><thead><tr><th>Aspetto</th><th><code>false</code> (legacy / client-managed)</th><th><code>true</code> (server-managed)</th></tr></thead><tbody><tr><td>Chi scrive il cookie</td><td>Frontend JavaScript dopo il login</td><td>Backend via <code>Set-Cookie</code></td></tr><tr><td><code>HttpOnly</code></td><td>No (leggibile da JS)</td><td>Si (protezione XSS)</td></tr><tr><td><code>SameSite</code></td><td>—</td><td><code>Lax</code> (protezione CSRF)</td></tr><tr><td><code>Secure</code></td><td>—</td><td>Si in HTTPS, off su <code>http://localhost</code></td></tr><tr><td><code>Expires</code></td><td>—</td><td><code>sessionTimeoutMinutes</code> (default 60)</td></tr><tr><td>Validazione sessione server</td><td>Nessuna (basta il cookie)</td><td>Token + IP + timeout su DB ad ogni request</td></tr><tr><td>Single-session per utente</td><td>No (sessioni concorrenti libere)</td><td>Si (ultimo login vince)</td></tr><tr><td>IP binding</td><td>No</td><td>Si (cambio IP forza re-login)</td></tr><tr><td>Schema DB richiesto</td><td>Standard</td><td>Colonne <code>token</code>, <code>ip</code>, <code>LastActivityDate</code></td></tr><tr><td>Logout</td><td><code>MetaService.logout</code></td><td><code>MetaService.logoutSession</code></td></tr><tr><td>Quando usarlo</td><td>Sviluppo, CI, proxy SSO, retrocompatibilita&#39;</td><td>Produzione, deploy esposti su internet</td></tr></tbody></table><p> ### Comportamento single-session (modalita&#39; <code>true</code>)</p><p> Ogni login genera un nuovo token che sovrascrive il precedente. Conseguenze pratiche:</p><p> - Se lo stesso utente si logga da <strong>due browser diversi</strong> (o due finestre anonime), l&#39;ultimo login vince: il primo browser viene disconnesso con il messaggio <em>&quot;Sessione terminata: e&#39; stato effettuato l&#39;accesso con lo stesso utente da un altro browser.&quot;</em> — sia navigando una pagina, sia facendo refresh.</p><p> - Il browser con l&#39;ultimo login <strong>non subisce impatti</strong>.</p><p> - Due tab nello <strong>stesso browser</strong> non hanno questo problema: condividono lo stesso cookie, quindi il token si aggiorna su entrambe.</p><p> ### Trappole note</p><p> - Se modifichi <code>appsettings.json</code> a mano mentre il backend e&#39; running, serve un restart (l&#39;editor AppSettings web fa il flush automaticamente).</p><p> - Dopo un flip da <code>false</code> a <code>true</code>, i cookie preesistenti non hanno il token → gli utenti devono rifare il login.</p><p> - I test E2E (<code>backend-api-client.mjs</code>) rilevano la modalita&#39; automaticamente e funzionano in entrambi i casi.</p><ul><li><code>enableODATAAuthentication</code></li></ul><p> Significato: abilita auth per endpoint OData.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>enableGuest</code></li></ul><p> Significato: abilita accesso ospite.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>applyGrantByDefaultToGuest</code></li></ul><p> Significato: applica grant di default anche all&#39;utente guest.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>grantDashSaveToGuest</code></li></ul><p> Significato: consente salvataggio dashboard al guest.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>default-role-id</code></li></ul><p> Significato: ruolo assegnato in fallback/default.</p><p> Valori: intero (ID ruolo).</p><ul><li><code>sessionTimeoutMinutes</code></li></ul><p> Significato: timeout sessione utente in minuti.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>60</code>.</p><ul><li><code>notifySessionExpirationBefore</code></li></ul><p> Significato: anticipo (minuti) notifica scadenza sessione.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>1</code> o <code>2</code> a seconda ambiente.</p><ul><li><code>enableUserLanguageSwitch</code></li></ul><p> Significato: abilita switch lingua utente in UI.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Password e policy credenziali</h2><ul><li><code>IsPwdEncripted</code></li></ul><p> Significato: indica se le password in store sono hashate.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>encriptionMethod</code></li></ul><p> Significato: algoritmo hash legacy usato per verifica password.</p><p> Valori enum-like: <code>SHA1 | MD5</code>.</p><p> Default tipico: <code>SHA1</code>.</p><ul><li><code>password_min_length</code> e <code>password_min_length </code></li></ul><p> Significato: lunghezza minima password (nota: in alcuni file esiste variante con spazio finale nel nome chiave).</p><p> Valori: intero positivo.</p><p> Default tipico: <code>8</code>.</p><h2>AppSettings - Captcha, doppio token, URL applicative</h2><ul><li><code>captcha_public_key</code></li></ul><p> Significato: chiave pubblica captcha.</p><p> Valori: string.</p><ul><li><code>captcha_private_key</code></li></ul><p> Significato: chiave privata captcha.</p><p> Valori: string.</p><ul><li><code>enableDoubleTokenAuthentication</code></li></ul><p> Significato: abilita step di verifica token aggiuntivo nel flusso login/attivazione previsto.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>site-url</code></li></ul><p> Significato: URL base sito per link assoluti email/workflow.</p><p> Valori: URL assoluto.</p><ul><li><code>content-url</code></li></ul><p> Significato: URL base contenuti/link di conferma (mailing, read-confirm, ecc.).</p><p> Valori: URL assoluto.</p><h2>AppSettings - Email e notifiche mail</h2><ul><li><code>email-host</code></li></ul><p> Significato: host SMTP.</p><p> Valori: hostname/IP.</p><ul><li><code>email-port</code></li></ul><p> Significato: porta SMTP.</p><p> Valori: intero (<code>25</code>, <code>465</code>, <code>587</code>, ...).</p><ul><li><code>email-ssl</code></li></ul><p> Significato: abilita TLS/SSL SMTP.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>email-user</code></li></ul><p> Significato: username SMTP.</p><p> Valori: string.</p><ul><li><code>email-pwd</code></li></ul><p> Significato: password SMTP.</p><p> Valori: string/segreto.</p><ul><li><code>email-sender-address-mailing</code></li></ul><p> Significato: mittente email di mailing/notifiche.</p><p> Valori: email valida.</p><ul><li><code>email-sender-name-mailing</code></li></ul><p> Significato: display name mittente mailing.</p><p> Valori: string.</p><ul><li><code>email-sender-address-registration</code></li></ul><p> Significato: mittente email registrazione/attivazione.</p><p> Valori: email valida.</p><ul><li><code>email-admin-registration</code></li></ul><p> Significato: destinatario amministrativo eventi registrazione.</p><p> Valori: email valida.</p><ul><li><code>email_confirm_token_subject</code></li></ul><p> Significato: subject template email conferma token.</p><p> Valori: string.</p><ul><li><code>email_confirm_token_body</code></li></ul><p> Significato: body template email conferma token.</p><p> Valori: string (anche HTML).</p><h2>AppSettings - Upload e media</h2><ul><li><code>uploadFolder</code></li></ul><p> Significato: cartella root upload file/immagini.</p><p> Valori: path assoluto o virtual path risolto dal server.</p><ul><li><code>base64Image</code></li></ul><p> Significato: forza gestione immagini in formato base64 dove previsto.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Report e runtime report viewer</h2><ul><li><code>ReportMode</code></li></ul><p> Significato: modalità rendering report nel viewer.</p><p> Valori enum-like osservati: <code>web</code> (default fallback) e modalità custom gestite lato controller.</p><p> Nota: se assente, il backend usa fallback <code>web</code>.</p><ul><li><code>reportQueryTimeout</code></li></ul><p> Significato: timeout query dataset report (secondi).</p><p> Valori: intero positivo.</p><h2>AppSettings - Record translations (chiavi legacy in AppSettings)</h2><ul><li><code>recordTranslationsEnabled</code></li></ul><p> Significato: abilita traduzione record per campo.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>recordTranslationsDefaultTableName</code></li></ul><p> Significato: tabella default traduzioni record.</p><p> Valori: nome tabella.</p><ul><li><code>recordTranslationsTranslationJsonFieldName</code></li></ul><p> Significato: nome campo JSON traduzioni.</p><p> Valori: nome colonna.</p><ul><li><code>recordTranslationsDefaultLanguage</code></li></ul><p> Significato: lingua fallback traduzioni record.</p><p> Valori: culture code (es. <code>it-IT</code>, <code>en-US</code>).</p><ul><li><code>recordTranslationsFieldNames</code></li></ul><p> Significato: elenco campi traducibili.</p><p> Valori: lista separata da virgole.</p><h2>Sezioni top-level correlate (fuori da AppSettings)</h2><ul><li><code>RecordTranslations:Enabled</code></li></ul><p> Significato: switch principale runtime traduzioni record.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>RecordTranslations:DefaultTableName</code></li></ul><p> Significato: tabella fisica traduzioni.</p><p> Valori: nome tabella.</p><ul><li><code>RecordTranslations:TranslationJsonFieldName</code></li></ul><p> Significato: campo JSON traduzioni.</p><p> Valori: nome colonna.</p><ul><li><code>RecordTranslations:DefaultLanguage</code></li></ul><p> Significato: lingua fallback.</p><p> Valori: culture code.</p><ul><li><code>RecordTranslations:FieldNames</code></li></ul><p> Significato: campi traducibili.</p><p> Valori: array di stringhe.</p><ul><li><code>Scheduler:Enabled</code></li></ul><p> Significato: abilita hosted service scheduling.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Scheduler:PollSeconds</code></li></ul><p> Significato: polling scheduler in secondi.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:MaxTasksPerCycle</code></li></ul><p> Significato: massimo task processati per ciclo.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:RetryDelaySeconds</code></li></ul><p> Significato: ritardo retry task falliti.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:SqlCommandTimeoutSeconds</code></li></ul><p> Significato: timeout SQL scheduler.</p><p> Valori: intero positivo.</p><ul><li><code>Notifications:Enabled</code></li></ul><p> Significato: abilita subsystem notifiche realtime.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Notifications:Mode</code></li></ul><p> Significato: modalità watcher backend notifiche.</p><p> Valori enum-like: <code>SqlDependency | Polling</code>.</p><ul><li><code>Notifications:PollSeconds</code></li></ul><p> Significato: polling notifiche se <code>Mode = Polling</code>.</p><p> Valori: intero positivo.</p><ul><li><code>Authentication:OAuth:Enabled</code></li></ul><p> Significato: abilita login OAuth/OIDC.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:OAuth:Provider</code></li></ul><p> Significato: provider OAuth visualizzato/gestito.</p><p> Valori enum-like usato in config: <code>Google</code> (estendibile a provider custom compatibili OIDC).</p><ul><li><code>Authentication:OAuth:Authority</code></li></ul><p> Significato: authority/issuer OIDC.</p><p> Valori: URL.</p><ul><li><code>Authentication:OAuth:ClientId</code></li></ul><p> Significato: client id applicazione OAuth.</p><p> Valori: string.</p><ul><li><code>Authentication:OAuth:ClientSecret</code></li></ul><p> Significato: client secret OAuth.</p><p> Valori: string/segreto.</p><ul><li><code>Authentication:OAuth:RequireHttpsMetadata</code></li></ul><p> Significato: richiede metadati OIDC via HTTPS.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:OAuth:CallbackPath</code></li></ul><p> Significato: path callback signin.</p><p> Valori: path assoluto.</p><ul><li><code>Authentication:OAuth:SignedOutCallbackPath</code></li></ul><p> Significato: path callback signout.</p><p> Valori: path assoluto.</p><ul><li><code>Authentication:OAuth:AllowedReturnOrigins</code></li></ul><p> Significato: whitelist origin di ritorno consentite.</p><p> Valori: array URL/origin.</p><ul><li><code>Authentication:OAuth:Scopes</code></li></ul><p> Significato: scope richiesti al provider.</p><p> Valori: array stringhe (<code>openid</code>, <code>profile</code>, <code>email</code>, ...).</p><h2>Note operative</h2><ul><li>In produzione usare sempre secret manager/variabili ambiente per password/token (<code>email-pwd</code>, <code>ClientSecret</code>, captcha key, ecc.).</li><li>Se abiliti <code>allowMultipleDBMS</code>, validare che <code>dbms</code> e <code>meta-dbms</code> siano entrambi supportati dal deploy.</li><li>Per notifiche realtime, <code>Notifications:Mode=SqlDependency</code> richiede setup SQL compatibile; in alternativa usare <code>Polling</code>.</li></ul><h2>appsettings.json reale (snapshot)</h2><p>Snippet 1:</p>",
4530
+ "html": "<h1>AppSettings</h1><p>Parametri applicativi, configurazioni ambiente e override runtime.</p><p>Questa pagina documenta le chiavi usate dal framework in <code>appsettings.json</code> e <code>appsettings.{Environment}.json</code>.</p><h2>Convenzioni generali</h2><ul><li>I valori sotto <code>AppSettings</code> sono letti come stringa e poi convertiti (<code>bool/int</code>) dal backend.</li><li>Per flag booleani usare <code>true|false</code>.</li><li>Per chiavi numeriche usare interi positivi (secondi/minuti/timeout).</li><li>Le chiavi sono case-sensitive lato JSON.</li></ul><h2>AppSettings - Core bootstrap</h2><ul><li><code>firstRun</code></li></ul><p> Significato: abilita il flusso di prima configurazione/provisioning.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>preScaffold</code></li></ul><p> Significato: abilita pre-scaffolding di oggetti metadata/app.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>projectDataFolder</code></li></ul><p> Significato: root progetto applicativo (es. CrmApp) usata per file, assembly e risorse runtime.</p><p> Valori: path assoluto filesystem.</p><ul><li><code>projectAssemblyName</code></li></ul><p> Significato: assembly applicativo caricato dinamicamente.</p><p> Valori: path assoluto <code>.dll</code>.</p><ul><li><code>defaultSiteRoute</code></li></ul><p> Significato: route iniziale client dopo bootstrap/login.</p><p> Valori: hash-route (es. <code>#/</code>).</p><ul><li><code>license-email</code></li></ul><p> Significato: email/licenza installazione.</p><p> Valori: email valida.</p><h2>AppSettings - Database e provider</h2><ul><li><code>dbms</code></li></ul><p> Significato: provider DB principale route dati.</p><p> Valori enum-like: <code>mssql | mysql | postgresql | oracle | xml</code>.</p><p> Default tipico: <code>mssql</code>.</p><ul><li><code>meta-dbms</code></li></ul><p> Significato: provider DB metadata (route di sistema).</p><p> Valori enum-like: <code>mssql | mysql | postgresql | oracle | xml</code>.</p><p> Default tipico: uguale a <code>dbms</code>.</p><ul><li><code>allowMultipleDBMS</code></li></ul><p> Significato: abilita convivenza provider multipli nel runtime.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>connection</code></li></ul><p> Significato: connection string base usata da servizi/scaffolding.</p><p> Valori: connection string provider-specific.</p><ul><li><code>DataDBName</code></li></ul><p> Significato: nome database dati di default.</p><p> Valori: nome DB.</p><ul><li><code>connectionByUser</code></li></ul><p> Significato: usa connessione/contesto legato all&#39;utente corrente in punti runtime specifici.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><h2>AppSettings - CRUD, query, filtri</h2><ul><li><code>autoGeneratedQueryTimeout</code></li></ul><p> Significato: timeout (secondi) query SQL autogenerate.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>120</code>.</p><ul><li><code>storedProcTimeout</code></li></ul><p> Significato: timeout (secondi) esecuzione stored procedure.</p><p> Valori: intero positivo.</p><ul><li><code>enableServerSideCrudChangeLog</code></li></ul><p> Significato: abilita logging lato server delle operazioni CRUD.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>true</code>.</p><ul><li><code>logicDeleteField</code></li></ul><p> Significato: campo globale per cancellazione logica (se non definito in metadata tabella).</p><p> Valori: nome colonna.</p><ul><li><code>logicDeleteValue</code></li></ul><p> Significato: valore che rappresenta &quot;record cancellato logicamente&quot;.</p><p> Valori: string/numero compatibile col tipo del campo.</p><p> Default tipico: <code>1</code>.</p><ul><li><code>cacheDataMinutes</code></li></ul><p> Significato: durata cache dati in minuti (quando caching route attivo).</p><p> Valori: intero positivo.</p><ul><li><code>cacheDataIncludedRoutes</code></li></ul><p> Significato: whitelist route cacheabili.</p><p> Valori: lista route separata da virgole.</p><ul><li><code>cacheDataExcludedRoutes</code></li></ul><p> Significato: blacklist route da escludere dalla cache.</p><p> Valori: lista route separata da virgole.</p><ul><li><code>traceQuery</code></li></ul><p> Significato: abilita tracing query SQL con tempi esecuzione.</p><p> Valori: <code>true | false</code>.</p><p> Default tipico: <code>false</code>.</p><ul><li><code>sqlVerbose</code></li></ul><p> Significato: abilita output SQL verboso in endpoint/tools che lo supportano.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>logInvoke</code></li></ul><p> Significato: abilita log invocazioni funzioni dinamiche/callback.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Sicurezza, login, sessione</h2><ul><li><code>customAuthentication</code></li></ul><p> Significato: delega autenticazione a logica custom applicativa.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>enableCookieAuthentication</code></li></ul><p> Significato: controlla <strong>chi</strong> scrive il cookie di sessione <code>k-user</code> e con <strong>quale policy</strong>. Il backend espone in entrambe le modalita&#39; lo stesso wire format (<code>k-user=&lt;urlencoded-json&gt;</code>), cambia solo il mittente e gli attributi del cookie.</p><p> Valori: <code>true | false</code>. Default: <code>false</code>.</p><p> Confronto sintetico delle due modalita&#39;:</p><table><thead><tr><th>Aspetto</th><th><code>false</code> (legacy / client-managed)</th><th><code>true</code> (server-managed)</th></tr></thead><tbody><tr><td>Chi scrive il cookie</td><td>Frontend JavaScript dopo il login</td><td>Backend via <code>Set-Cookie</code></td></tr><tr><td><code>HttpOnly</code></td><td>No (leggibile da JS)</td><td>Si (protezione XSS)</td></tr><tr><td><code>SameSite</code></td><td>—</td><td><code>Lax</code> (protezione CSRF)</td></tr><tr><td><code>Secure</code></td><td>—</td><td>Si in HTTPS, off su <code>http://localhost</code></td></tr><tr><td><code>Expires</code></td><td>—</td><td><code>sessionTimeoutMinutes</code> (default 60)</td></tr><tr><td>Validazione sessione server</td><td>Nessuna (basta il cookie)</td><td>Token + IP + timeout su DB ad ogni request</td></tr><tr><td>Single-session per utente</td><td>No (sessioni concorrenti libere)</td><td>Si (ultimo login vince)</td></tr><tr><td>IP binding</td><td>No</td><td>Si (cambio IP forza re-login)</td></tr><tr><td>Schema DB richiesto</td><td>Standard</td><td>Colonne <code>token</code>, <code>ip</code>, <code>LastActivityDate</code></td></tr><tr><td>Logout</td><td><code>MetaService.logout</code></td><td><code>MetaService.logoutSession</code></td></tr><tr><td>Quando usarlo</td><td>Sviluppo, CI, proxy SSO, retrocompatibilita&#39;</td><td>Produzione, deploy esposti su internet</td></tr></tbody></table><p> ### Comportamento single-session (modalita&#39; <code>true</code>)</p><p> Ogni login genera un nuovo token che sovrascrive il precedente. Conseguenze pratiche:</p><p> - Se lo stesso utente si logga da <strong>due browser diversi</strong> (o due finestre anonime), l&#39;ultimo login vince: il primo browser viene disconnesso con il messaggio <em>&quot;Sessione terminata: e&#39; stato effettuato l&#39;accesso con lo stesso utente da un altro browser.&quot;</em> — sia navigando una pagina, sia facendo refresh.</p><p> - Il browser con l&#39;ultimo login <strong>non subisce impatti</strong>.</p><p> - Due tab nello <strong>stesso browser</strong> non hanno questo problema: condividono lo stesso cookie, quindi il token si aggiorna su entrambe.</p><p> ### Trappole note</p><p> - Se modifichi <code>appsettings.json</code> a mano mentre il backend e&#39; running, serve un restart (l&#39;editor AppSettings web fa il flush automaticamente).</p><p> - Dopo un flip da <code>false</code> a <code>true</code>, i cookie preesistenti non hanno il token → gli utenti devono rifare il login.</p><p> - I test E2E (<code>backend-api-client.mjs</code>) rilevano la modalita&#39; automaticamente e funzionano in entrambi i casi.</p><ul><li><code>enableODATAAuthentication</code></li></ul><p> Significato: abilita auth per endpoint OData.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>enableGuest</code></li></ul><p> Significato: abilita accesso ospite.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>applyGrantByDefaultToGuest</code></li></ul><p> Significato: applica grant di default anche all&#39;utente guest.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>grantDashSaveToGuest</code></li></ul><p> Significato: consente salvataggio dashboard al guest.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>default-role-id</code></li></ul><p> Significato: ruolo assegnato in fallback/default.</p><p> Valori: intero (ID ruolo).</p><ul><li><code>sessionTimeoutMinutes</code></li></ul><p> Significato: timeout sessione utente in minuti.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>60</code>.</p><ul><li><code>notifySessionExpirationBefore</code></li></ul><p> Significato: anticipo (minuti) notifica scadenza sessione.</p><p> Valori: intero positivo.</p><p> Default tipico: <code>1</code> o <code>2</code> a seconda ambiente.</p><ul><li><code>enableUserLanguageSwitch</code></li></ul><p> Significato: abilita switch lingua utente in UI.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Password e policy credenziali</h2><ul><li><code>IsPwdEncripted</code></li></ul><p> Significato: indica se le password in store sono hashate.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>encriptionMethod</code></li></ul><p> Significato: algoritmo hash legacy usato per verifica password.</p><p> Valori enum-like: <code>SHA1 | MD5</code>.</p><p> Default tipico: <code>SHA1</code>.</p><ul><li><code>password_min_length</code> e <code>password_min_length </code></li></ul><p> Significato: lunghezza minima password (nota: in alcuni file esiste variante con spazio finale nel nome chiave).</p><p> Valori: intero positivo.</p><p> Default tipico: <code>8</code>.</p><h2>AppSettings - Captcha, doppio token, URL applicative</h2><ul><li><code>captcha_public_key</code></li></ul><p> Significato: chiave pubblica captcha.</p><p> Valori: string.</p><ul><li><code>captcha_private_key</code></li></ul><p> Significato: chiave privata captcha.</p><p> Valori: string.</p><ul><li><code>enableDoubleTokenAuthentication</code></li></ul><p> Significato: abilita step di verifica token aggiuntivo nel flusso login/attivazione previsto.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>site-url</code></li></ul><p> Significato: URL base sito per link assoluti email/workflow.</p><p> Valori: URL assoluto.</p><ul><li><code>content-url</code></li></ul><p> Significato: URL base contenuti/link di conferma (mailing, read-confirm, ecc.).</p><p> Valori: URL assoluto.</p><h2>AppSettings - Email e notifiche mail</h2><ul><li><code>email-host</code></li></ul><p> Significato: host SMTP.</p><p> Valori: hostname/IP.</p><ul><li><code>email-port</code></li></ul><p> Significato: porta SMTP.</p><p> Valori: intero (<code>25</code>, <code>465</code>, <code>587</code>, ...).</p><ul><li><code>email-ssl</code></li></ul><p> Significato: abilita TLS/SSL SMTP.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>email-user</code></li></ul><p> Significato: username SMTP.</p><p> Valori: string.</p><ul><li><code>email-pwd</code></li></ul><p> Significato: password SMTP.</p><p> Valori: string/segreto.</p><ul><li><code>email-sender-address-mailing</code></li></ul><p> Significato: mittente email di mailing/notifiche.</p><p> Valori: email valida.</p><ul><li><code>email-sender-name-mailing</code></li></ul><p> Significato: display name mittente mailing.</p><p> Valori: string.</p><ul><li><code>email-sender-address-registration</code></li></ul><p> Significato: mittente email registrazione/attivazione.</p><p> Valori: email valida.</p><ul><li><code>email-admin-registration</code></li></ul><p> Significato: destinatario amministrativo eventi registrazione.</p><p> Valori: email valida.</p><ul><li><code>email_confirm_token_subject</code></li></ul><p> Significato: subject template email conferma token.</p><p> Valori: string.</p><ul><li><code>email_confirm_token_body</code></li></ul><p> Significato: body template email conferma token.</p><p> Valori: string (anche HTML).</p><h2>AppSettings - Upload e media</h2><ul><li><code>uploadFolder</code></li></ul><p> Significato: cartella root upload file/immagini.</p><p> Valori: path assoluto o virtual path risolto dal server.</p><ul><li><code>base64Image</code></li></ul><p> Significato: forza gestione immagini in formato base64 dove previsto.</p><p> Valori: <code>true | false</code>.</p><h2>AppSettings - Report e runtime report viewer</h2><ul><li><code>ReportMode</code></li></ul><p> Significato: modalità rendering report nel viewer.</p><p> Valori enum-like osservati: <code>web</code> (default fallback) e modalità custom gestite lato controller.</p><p> Nota: se assente, il backend usa fallback <code>web</code>.</p><ul><li><code>reportQueryTimeout</code></li></ul><p> Significato: timeout query dataset report (secondi).</p><p> Valori: intero positivo.</p><h2>AppSettings - Record translations (chiavi legacy in AppSettings)</h2><ul><li><code>recordTranslationsEnabled</code></li></ul><p> Significato: abilita traduzione record per campo.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>recordTranslationsDefaultTableName</code></li></ul><p> Significato: tabella default traduzioni record.</p><p> Valori: nome tabella.</p><ul><li><code>recordTranslationsTranslationJsonFieldName</code></li></ul><p> Significato: nome campo JSON traduzioni.</p><p> Valori: nome colonna.</p><ul><li><code>recordTranslationsDefaultLanguage</code></li></ul><p> Significato: lingua fallback traduzioni record.</p><p> Valori: culture code (es. <code>it-IT</code>, <code>en-US</code>).</p><ul><li><code>recordTranslationsFieldNames</code></li></ul><p> Significato: elenco campi traducibili.</p><p> Valori: lista separata da virgole.</p><h2>Sezioni top-level correlate (fuori da AppSettings)</h2><ul><li><code>RecordTranslations:Enabled</code></li></ul><p> Significato: switch principale runtime traduzioni record.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>RecordTranslations:DefaultTableName</code></li></ul><p> Significato: tabella fisica traduzioni.</p><p> Valori: nome tabella.</p><ul><li><code>RecordTranslations:TranslationJsonFieldName</code></li></ul><p> Significato: campo JSON traduzioni.</p><p> Valori: nome colonna.</p><ul><li><code>RecordTranslations:DefaultLanguage</code></li></ul><p> Significato: lingua fallback.</p><p> Valori: culture code.</p><ul><li><code>RecordTranslations:FieldNames</code></li></ul><p> Significato: campi traducibili.</p><p> Valori: array di stringhe.</p><ul><li><code>Scheduler:Enabled</code></li></ul><p> Significato: abilita hosted service scheduling.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Scheduler:PollSeconds</code></li></ul><p> Significato: polling scheduler in secondi.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:MaxTasksPerCycle</code></li></ul><p> Significato: massimo task processati per ciclo.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:RetryDelaySeconds</code></li></ul><p> Significato: ritardo retry task falliti.</p><p> Valori: intero positivo.</p><ul><li><code>Scheduler:SqlCommandTimeoutSeconds</code></li></ul><p> Significato: timeout SQL scheduler.</p><p> Valori: intero positivo.</p><ul><li><code>Notifications:Enabled</code></li></ul><p> Significato: abilita subsystem notifiche realtime.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Notifications:Mode</code></li></ul><p> Significato: modalità watcher backend notifiche.</p><p> Valori enum-like: <code>SqlDependency | Polling</code>.</p><ul><li><code>Notifications:PollSeconds</code></li></ul><p> Significato: polling notifiche se <code>Mode = Polling</code>.</p><p> Valori: intero positivo.</p><ul><li><code>Authentication:OAuth:Enabled</code></li></ul><p> Significato: abilita login OAuth/OIDC.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:OAuth:Provider</code></li></ul><p> Significato: provider OAuth visualizzato/gestito.</p><p> Valori enum-like usato in config: <code>Google</code> (estendibile a provider custom compatibili OIDC).</p><ul><li><code>Authentication:OAuth:Authority</code></li></ul><p> Significato: authority/issuer OIDC.</p><p> Valori: URL.</p><ul><li><code>Authentication:OAuth:ClientId</code></li></ul><p> Significato: client id applicazione OAuth.</p><p> Valori: string.</p><ul><li><code>Authentication:OAuth:ClientSecret</code></li></ul><p> Significato: client secret OAuth.</p><p> Valori: string/segreto.</p><ul><li><code>Authentication:OAuth:RequireHttpsMetadata</code></li></ul><p> Significato: richiede metadati OIDC via HTTPS.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:OAuth:CallbackPath</code></li></ul><p> Significato: path callback signin.</p><p> Valori: path assoluto.</p><ul><li><code>Authentication:OAuth:SignedOutCallbackPath</code></li></ul><p> Significato: path callback signout.</p><p> Valori: path assoluto.</p><ul><li><code>Authentication:OAuth:AllowedReturnOrigins</code></li></ul><p> Significato: whitelist origin di ritorno consentite.</p><p> Valori: array URL/origin.</p><ul><li><code>Authentication:OAuth:Scopes</code></li></ul><p> Significato: scope richiesti al provider.</p><p> Valori: array stringhe (<code>openid</code>, <code>profile</code>, <code>email</code>, ...).</p><h3>ADFS via OpenID Connect</h3><p>ADFS 4.0+ (Windows Server 2016+) parla OIDC nativamente: l&#39;integrazione con WUIC <strong>non richiede codice nuovo</strong>, basta la sezione <code>Authentication.OAuth</code> configurata sul tenant ADFS. La pipeline e&#39; la stessa di Google/Auth0/Keycloak — <code>Provider=&quot;OpenIdConnect&quot;</code> instrada il flusso su <code>services.AddOpenIdConnect(...)</code> in <a href=\"../../../../Startup.cs#L264\">Startup.cs:264</a>.</p><p><strong>Pre-requisiti lato ADFS:</strong></p><p>1. <strong>Federation Service Name</strong> raggiungibile in HTTPS dal backend WUIC (es. <code>https://adfs.contoso.com/adfs</code>).</p><p>2. Endpoint OIDC abilitato: verifica che <code>https://adfs.contoso.com/adfs/.well-known/openid-configuration</code> risponda 200 con il discovery document.</p><p>3. <strong>Application Group</strong> registrata in ADFS Management Console (<code>adfs.msc</code> → Application Groups → Add Application Group → &quot;Server application accessing a web API&quot;):</p><p> - Redirect URI: <code>https://&lt;host-wuic&gt;/signin-oidc</code></p><p> - Annotare <code>ClientId</code> (auto-generato) e generare un <code>ClientSecret</code>.</p><p>4. <strong>Issuance Transform Rules</strong> sul Web API: emettere almeno <code>email</code>, <code>name</code>, <code>upn</code> come claim (servono al frontend per popolare il profilo utente).</p><p><strong>Configurazione lato KonvergenceCore:</strong></p><p>Snippet 1:</p><p><strong>Trappole note:</strong></p><ul><li><strong>`RequireHttpsMetadata=true` obbligatorio in produzione</strong>: ADFS espone i metadati firmati su HTTPS; mai disabilitarlo se non in dev contro un ADFS con cert self-signed.</li><li><strong>`CallbackPath`</strong> deve corrispondere <strong>letteralmente</strong> al Redirect URI registrato in ADFS (case-sensitive sulla path). Se cambi uno, cambia anche l&#39;altro.</li><li><strong>Scopes</strong>: ADFS supporta <code>openid</code>, <code>profile</code>, <code>email</code>, e custom scope definiti nelle Application Permissions. Se richiedi uno scope non concesso al client, ADFS risponde con <code>invalid_scope</code> durante il consent.</li><li><strong>Single Logout (SLO)</strong>: <code>SignedOutCallbackPath</code> viene chiamato solo se ADFS e&#39; configurato per emettere il logout token. Se manca, dopo il logout WUIC il browser resta loggato in ADFS e un nuovo login WUIC e&#39; silent SSO.</li><li><strong>Coesistenza con LDAP</strong>: la sezione <code>Authentication.OAuth</code> (federazione browser-redirect) e <code>Authentication.Ldap</code> (bind diretto da username/password) sono indipendenti. Possono coesistere — il front-end mostra un pulsante &quot;Login con ADFS&quot; oltre al form locale.</li><li><strong>Provider distinto da Google</strong>: il branch <code>Provider==Google</code> in <a href=\"../../../../Startup.cs#L241\">Startup.cs:241</a> usa <code>AddGoogle()</code> con scope cablati. Per ADFS impostare <strong>`Provider=OpenIdConnect`</strong> (non <code>Google</code>) altrimenti la pipeline punta a <code>accounts.google.com</code>.</li><li><strong>ADFS 2.0 / 3.0 (Windows Server 2008R2-2012R2)</strong>: parlano solo WS-Federation o SAML 2.0, non OIDC. Per quei tenant servirebbe un PackageReference aggiuntivo (<code>Microsoft.AspNetCore.Authentication.WsFederation</code> o <code>Sustainsys.Saml2</code>) e un nuovo branch in <code>Startup.ConfigureServices</code> — fuori scope di questa sezione.</li></ul><h2>Authentication:Ldap (LDAP / Active Directory)</h2><p>WUIC supporta autenticazione LDAP/AD come provider opzionale <strong>prima</strong> del login DB tradizionale (LDAP-first). Quando <code>Authentication:Ldap:Enabled=true</code>, il backend tenta una bind verso il directory server configurato; se la bind riesce e l&#39;utente non esiste ancora nella tabella utenti locale, viene auto-provisionato con <code>Authentication:Ldap:DefaultRoleId</code> (o, in fallback, <code>AppSettings:default-role-id</code>). Se LDAP è offline e <code>FallbackToDbOnFailure=true</code>, il login ricade automaticamente sul provider DB — utile per garantire l&#39;accesso <code>admin/admin</code> anche in caso di outage del directory server.</p><p>Esempio minimo:</p><p>Snippet 2:</p><p>Chiavi disponibili:</p><ul><li><code>Authentication:Ldap:Enabled</code></li></ul><p> Significato: abilita il provider LDAP davanti al DB. Quando <code>false</code>, il flusso e&#39; identico a un deploy senza la sezione.</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:Ldap:Host</code></li></ul><p> Significato: hostname del directory server (AD DC, OpenLDAP, ApacheDS).</p><p> Valori: string.</p><ul><li><code>Authentication:Ldap:Port</code></li></ul><p> Significato: porta del directory server.</p><p> Valori: intero. Tipicamente <code>389</code> (plain o StartTLS) o <code>636</code> (LDAPS).</p><ul><li><code>Authentication:Ldap:UseSsl</code></li></ul><p> Significato: apre la connessione direttamente in LDAPS (TLS at-connect).</p><p> Valori: <code>true | false</code>.</p><ul><li><code>Authentication:Ldap:UseStartTls</code></li></ul><p> Significato: apre in plain e poi promuove a TLS via StartTLS extended op (RFC 4511).</p><p> Valori: <code>true | false</code>. Mutuamente esclusivo con <code>UseSsl</code>.</p><ul><li><code>Authentication:Ldap:BaseDn</code></li></ul><p> Significato: DN base sotto cui cercare gli utenti.</p><p> Valori: string DN (es. <code>DC=example,DC=com</code>).</p><ul><li><code>Authentication:Ldap:UserSearchFilter</code></li></ul><p> Significato: filter LDAP per individuare la entry utente. Il placeholder <code>{username}</code> viene sostituito con lo username (RFC 4515 escaping applicato lato C# per prevenire injection).</p><p> Valori: string filter. Default: <code>(&amp;(objectClass=user)(sAMAccountName={username}))</code> (Active Directory). Per OpenLDAP usare tipicamente <code>(&amp;(objectClass=inetOrgPerson)(uid={username}))</code>.</p><ul><li><code>Authentication:Ldap:UsernameAttribute</code></li></ul><p> Significato: attributo della entry da cui leggere lo username canonico (usato come <code>username_column_name</code> nella tabella utenti locale).</p><p> Valori: string. Default: <code>sAMAccountName</code>.</p><ul><li><code>Authentication:Ldap:DisplayNameAttribute</code></li></ul><p> Significato: attributo da cui leggere il display name (usato come <code>user_description_column_name</code>).</p><p> Valori: string. Default: <code>displayName</code>.</p><ul><li><code>Authentication:Ldap:EmailAttribute</code></li></ul><p> Significato: attributo da cui leggere l&#39;email (usato come <code>email_column_name</code>).</p><p> Valori: string. Default: <code>mail</code>.</p><ul><li><code>Authentication:Ldap:BindDn</code></li></ul><p> Significato: DN del service account read-only usato per la search. Vuoto = anonymous bind (alcuni AD lo permettono per ricerche limitate, OpenLDAP di solito no).</p><p> Valori: string DN.</p><ul><li><code>Authentication:Ldap:BindPassword</code></li></ul><p> Significato: password del service account. <strong>Mai committare</strong>: usare secret manager/env var (<code>Authentication__Ldap__BindPassword</code>) o riempire post-install dall&#39;editor AppSettings.</p><p> Valori: string/segreto.</p><ul><li><code>Authentication:Ldap:ConnectTimeoutSeconds</code></li></ul><p> Significato: timeout di connessione (in secondi) verso il directory server. Allo scadere il login fa fallback al DB se <code>FallbackToDbOnFailure=true</code>.</p><p> Valori: intero positivo. Default: <code>5</code>.</p><ul><li><code>Authentication:Ldap:FallbackToDbOnFailure</code></li></ul><p> Significato: se LDAP e&#39; irraggiungibile o ritorna errore non legato alle credenziali, ricade sul login DB tradizionale. Garantisce l&#39;accesso <code>admin/admin</code> durante outage del directory.</p><p> Valori: <code>true | false</code>. Default: <code>true</code>.</p><ul><li><code>Authentication:Ldap:AutoProvision</code></li></ul><p> Significato: al primo login LDAP riuscito di un utente sconosciuto al DB locale, crea automaticamente la riga in <code>_metadati__tabelle.user_table_name</code> (default <code>utenti</code>) con il default role.</p><p> Valori: <code>true | false</code>. Default: <code>true</code>.</p><ul><li><code>Authentication:Ldap:DefaultRoleId</code></li></ul><p> Significato: id ruolo assegnato in auto-provisioning. Override di <code>AppSettings:default-role-id</code>. Se entrambi <code>null</code>, il default e&#39; <code>1</code>.</p><p> Valori: intero o <code>null</code>.</p><h3>Trappole note</h3><ul><li><strong>Bind password mai committata</strong>: il template <code>appsettings.linux.*.json</code> usa <code>__SET_LDAP_BIND_PASSWORD__</code> come placeholder; il deploy script la sostituisce. Per i template &quot;dev&quot; (<code>appsettings.json</code>, <code>appsettings.Development.json</code>) il valore di default e&#39; la stringa vuota — mai un segreto reale.</li><li><strong>AD vs OpenLDAP filter</strong>: AD usa <code>sAMAccountName</code>, OpenLDAP usa <code>uid</code>. Cambiare di conseguenza <code>UserSearchFilter</code> e <code>UsernameAttribute</code>.</li><li><strong>StartTLS su porta 636</strong>: errore comune. La 636 e&#39; LDAPS (<code>UseSsl=true</code>); StartTLS gira sulla 389.</li><li><strong>Nessun cambiamento al cookie path</strong>: utenti LDAP e DB ricevono lo stesso cookie <code>k-user</code>. La differenza e&#39; solo <em>come</em> vengono autenticate le credenziali.</li><li><strong>Sentinel password</strong>: il provisioner inserisce <code>&#39;__LDAP__&#39;</code> come valore della password column locale per gli utenti auto-provisionati. Non viene mai usata per autenticare (la bind LDAP ha gia&#39; validato), ma la colonna deve essere NOT NULL-compatibile.</li><li><strong>Toggle a runtime</strong>: tutte le chiavi <code>Authentication:Ldap:*</code> sono <code>RestartAndLogout</code>: editarle dall&#39;AppSettings editor richiede restart pulito.</li></ul><h2>Note operative</h2><ul><li>In produzione usare sempre secret manager/variabili ambiente per password/token (<code>email-pwd</code>, <code>ClientSecret</code>, captcha key, ecc.).</li><li>Se abiliti <code>allowMultipleDBMS</code>, validare che <code>dbms</code> e <code>meta-dbms</code> siano entrambi supportati dal deploy.</li><li>Per notifiche realtime, <code>Notifications:Mode=SqlDependency</code> richiede setup SQL compatibile; in alternativa usare <code>Polling</code>.</li></ul><h2>appsettings.json reale (snapshot)</h2><p>Snippet 3:</p>",
4527
4531
  "codeSamples": [
4528
4532
  {
4529
4533
  "id": "code_1",
4530
4534
  "title": "Snippet 1",
4531
4535
  "language": "json",
4536
+ "code": "\"Authentication\": {\n \"OAuth\": {\n \"Enabled\": true,\n \"Provider\": \"OpenIdConnect\",\n \"Authority\": \"https://adfs.contoso.com/adfs\",\n \"ClientId\": \"<application-group-client-id>\",\n \"ClientSecret\": \"__SET_VIA_SECRET_MANAGER__\",\n \"RequireHttpsMetadata\": true,\n \"CallbackPath\": \"/signin-oidc\",\n \"SignedOutCallbackPath\": \"/signout-callback-oidc\",\n \"AllowedReturnOrigins\": [\n \"https://<host-wuic>\"\n ],\n \"Scopes\": [\"openid\", \"profile\", \"email\"]\n }\n}"
4537
+ },
4538
+ {
4539
+ "id": "code_2",
4540
+ "title": "Snippet 2",
4541
+ "language": "json",
4542
+ "code": "\"Authentication\": {\n \"Ldap\": {\n \"Enabled\": true,\n \"Host\": \"ldap.corp.example.com\",\n \"Port\": 389,\n \"UseStartTls\": true,\n \"BaseDn\": \"OU=Users,DC=corp,DC=example,DC=com\",\n \"UserSearchFilter\": \"(&(objectClass=user)(sAMAccountName={username}))\",\n \"UsernameAttribute\": \"sAMAccountName\",\n \"DisplayNameAttribute\": \"displayName\",\n \"EmailAttribute\": \"mail\",\n \"BindDn\": \"CN=svc-wuic,OU=ServiceAccounts,DC=corp,DC=example,DC=com\",\n \"BindPassword\": \"__SET_VIA_SECRET_MANAGER__\",\n \"ConnectTimeoutSeconds\": 5,\n \"FallbackToDbOnFailure\": true,\n \"AutoProvision\": true,\n \"DefaultRoleId\": null\n }\n}"
4543
+ },
4544
+ {
4545
+ "id": "code_3",
4546
+ "title": "Snippet 3",
4547
+ "language": "json",
4532
4548
  "code": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Warning\"\n }\n },\n \"Authentication\": {\n \"OAuth\": {\n \"Enabled\": false,\n \"Provider\": \"Google\",\n \"Authority\": \"\",\n \"ClientId\": \"__REDACTED__\",\n \"ClientSecret\": \"__REDACTED__\",\n \"RequireHttpsMetadata\": true,\n \"CallbackPath\": \"/signin-google\",\n \"SignedOutCallbackPath\": \"/signout-callback-oidc\",\n \"AllowedReturnOrigins\": [],\n \"Scopes\": [\n \"openid\",\n \"profile\",\n \"email\"\n ]\n }\n },\n \"AppSettings\": {\n \"firstRun\": \"false\",\n \"preScaffold\": \"false\",\n \"dbms\": \"mssql\",\n \"meta-dbms\": \"mssql\",\n \"allowMultipleDBMS\": \"false\",\n \"connectionByUser\": \"false\",\n \"logicDeleteValue\": \"1\",\n \"logicDeleteField\": \"Stato_Record\",\n \"enableServerSideCrudChangeLog\": \"true\",\n \"base64Image\": \"false\",\n \"customAuthentication\": \"false\",\n \"logInvoke\": \"false\",\n \"sqlVerbose\": \"true\",\n \"license-email\": \"__REDACTED__\",\n \"connection\": \"Data Source=localhost\\\\sqlexpress;Initial Catalog=WideWorldImporters;Integrated Security=False;Persist Security Info=True;User ID=sa;Password=***REDACTED***;Encrypt=False;TrustServerCertificate=True\",\n \"DataDBName\": \"WideWorldImporters\",\n \"projectDataFolder\": \"C:\\\\src\\\\Wuic\\\\CrmApp\",\n \"projectAssemblyName\": \"C:\\\\src\\\\Wuic\\\\KonvergenceCore\\\\bin\\\\Debug\\\\net10.0\\\\KonvergenceCore.dll\",\n \"sessionTimeoutMinutes\": \"60\",\n \"notifySessionExpirationBefore\": \"1\",\n \"enableUserLanguageSwitch\": \"true\",\n \"enableGuest\": \"false\",\n \"applyGrantByDefaultToGuest\": \"false\",\n \"defaultSiteRoute\": \"#/\",\n \"IsPwdEncripted\": \"false\",\n \"encriptionMethod\": \"SHA1\",\n \"enableCookieAuthentication\": \"false\",\n \"enableODATAAuthentication\": \"false\",\n \"password_min_length \": \"8\",\n \"email-host\": \"smtp.example.com\",\n \"email-port\": \"25\",\n \"email-ssl\": \"false\",\n \"email-user\": \"__REDACTED__\",\n \"email-pwd\": \"__REDACTED__\",\n \"default-role-id\": \"1\",\n \"email-sender-address-registration\": \"\",\n \"email-admin-registration\": \"\",\n \"email-sender-name-mailing\": \"Wuic Cloud\",\n \"email-sender-address-mailing\": \"__REDACTED__\",\n \"autoGeneratedQueryTimeout\": \"120\",\n \"uploadFolder\": \"C:\\\\src\\\\Wuic\\\\CrmApp\\\\Upload\"\n },\n \"RecordTranslations\": {\n \"Enabled\": false,\n \"DefaultTableName\": \"_record_field_translations\",\n \"TranslationJsonFieldName\": \"translation_json\",\n \"FieldNames\": []\n },\n \"Scheduler\": {\n \"Enabled\": true,\n \"PollSeconds\": 15,\n \"MaxTasksPerCycle\": 20,\n \"RetryDelaySeconds\": 60,\n \"SqlCommandTimeoutSeconds\": 300\n },\n \"Notifications\": {\n \"Enabled\": true,\n \"Mode\": \"SqlDependency\",\n \"PollSeconds\": 5\n },\n \"ConnectionStrings\": {\n \"MetaDataSQLConnection\": \"Data Source=localhost\\\\sqlexpress;Initial Catalog=MetadataCRM;Integrated Security=False;Persist Security Info=True;User ID=sa;Password=***REDACTED***;Encrypt=False;TrustServerCertificate=True\",\n \"DataSQLConnection\": \"Data Source=localhost\\\\sqlexpress;Initial Catalog=AdvancedCRM;Integrated Security=False;Persist Security Info=True;User ID=sa;Password=***REDACTED***;Encrypt=False;TrustServerCertificate=True\"\n },\n \"NugetHost\": {\n \"StaticAngularRoot\": \"..\\\\\\\\KonvergenceCore\"\n },\n \"AllowedHosts\": \"*\",\n \"CrmApp\": {\n \"StaticAngularRoot\": \"..\\\\\\\\KonvergenceCore\"\n }\n}"
4533
4549
  }
4534
4550
  ]
@@ -7011,7 +7027,7 @@ const frameworkDocsContent = {
7011
7027
  "id": "code_1",
7012
7028
  "title": "Snippet 1",
7013
7029
  "language": "json",
7014
- "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyph: glyph, scale: 1.2 }); return pin.element;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Population: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
7030
+ "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyphText: glyph, scale: 1.2 }); return pin;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Population: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
7015
7031
  },
7016
7032
  {
7017
7033
  "id": "code_2",
@@ -9165,7 +9181,7 @@ const frameworkDocsContent = {
9165
9181
  {
9166
9182
  "id": "overview",
9167
9183
  "title": "Overview",
9168
- "html": "<h1>Component Catalog</h1><p>Total component folders detected: 48.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li></ul>",
9184
+ "html": "<h1>Component Catalog</h1><p>Total component folders detected: 49.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>error-dialog</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li><li>error-dialog/error-dialog.component</li></ul>",
9169
9185
  "codeSamples": []
9170
9186
  }
9171
9187
  ],
@@ -11993,7 +12009,7 @@ const frameworkDocsContent = {
11993
12009
  "id": "code_1",
11994
12010
  "title": "Snippet 1",
11995
12011
  "language": "json",
11996
- "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyph: glyph, scale: 1.2 }); return pin.element;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
12012
+ "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyphText: glyph, scale: 1.2 }); return pin;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
11997
12013
  },
11998
12014
  {
11999
12015
  "id": "code_2",
@@ -14147,7 +14163,7 @@ const frameworkDocsContent = {
14147
14163
  {
14148
14164
  "id": "overview",
14149
14165
  "title": "Overview",
14150
- "html": "<h1>Component Catalog</h1><p>Total component folders detected: 48.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li></ul>",
14166
+ "html": "<h1>Component Catalog</h1><p>Total component folders detected: 49.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>error-dialog</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li><li>error-dialog/error-dialog.component</li></ul>",
14151
14167
  "codeSamples": []
14152
14168
  }
14153
14169
  ],
@@ -16986,7 +17002,7 @@ const frameworkDocsContent = {
16986
17002
  "id": "code_1",
16987
17003
  "title": "Snippet 1",
16988
17004
  "language": "json",
16989
- "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyph: glyph, scale: 1.2 }); return pin.element;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
17005
+ "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyphText: glyph, scale: 1.2 }); return pin;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
16990
17006
  },
16991
17007
  {
16992
17008
  "id": "code_2",
@@ -19140,7 +19156,7 @@ const frameworkDocsContent = {
19140
19156
  {
19141
19157
  "id": "overview",
19142
19158
  "title": "Overview",
19143
- "html": "<h1>Component Catalog</h1><p>Total component folders detected: 48.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li></ul>",
19159
+ "html": "<h1>Component Catalog</h1><p>Total component folders detected: 49.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>error-dialog</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li><li>error-dialog/error-dialog.component</li></ul>",
19144
19160
  "codeSamples": []
19145
19161
  }
19146
19162
  ],
@@ -21979,7 +21995,7 @@ const frameworkDocsContent = {
21979
21995
  "id": "code_1",
21980
21996
  "title": "Snippet 1",
21981
21997
  "language": "json",
21982
- "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyph: glyph, scale: 1.2 }); return pin.element;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
21998
+ "code": "{\n \"archetypes\": {\n \"map\": {\n \"advancedFilter\": false,\n \"center\": {\n \"lat\": 39.8283,\n \"lng\": -98.5795\n },\n \"zoom\": 4,\n \"minZoom\": 3,\n \"maxZoom\": 14,\n \"useCurrentLocation\": false,\n \"useClusterer\": true,\n \"filterByBoundaries\": false,\n \"titleField\": \"CityName\",\n \"infoField\": \"StateProvinceID__dictionary_display_value\",\n \"customMarkerImageSrc\": \"\",\n \"customMarkerImageSrcField\": \"\",\n \"markerContentCallback\": \"const glyph = String(record?.CityName || 'C').trim().charAt(0).toUpperCase() || 'C'; const pop = Number(record?.LatestRecordedPopulation || 0); const bg = pop > 1000000 ? '#B91C1C' : (pop > 300000 ? '#EA580C' : '#2563EB'); const pin = new google.maps.marker.PinElement({ background: bg, borderColor: '#0F172A', glyphColor: '#FFFFFF', glyphText: glyph, scale: 1.2 }); return pin;\",\n \"infoFunction\": \"\",\n \"itemTemplateString\": \"<div class=\\\"map-info\\\"> <div class=\\\"map-info-title\\\">{{ rowData.record?.CityName || rowData.title }}</div> <div>{{ rowData.record?.StateProvinceID__dictionary_display_value || rowData.record?.StateProvinceID || '' }}</div> <div>Popolazione: {{ rowData.record?.LatestRecordedPopulation | number:'1.0-0' }}</div> <div>{{ rowData.record?.Location || '' }}</div> <wuic-data-action-button-lazy [data]=\\\"rowData.record\\\" [metaInfo]=\\\"metaInfo\\\" [datasource]=\\\"datasource\\\" [simplified]=\\\"true\\\"></wuic-data-action-button-lazy> </div>\"\n }\n }\n}"
21983
21999
  },
21984
22000
  {
21985
22001
  "id": "code_2",
@@ -24133,7 +24149,7 @@ const frameworkDocsContent = {
24133
24149
  {
24134
24150
  "id": "overview",
24135
24151
  "title": "Overview",
24136
- "html": "<h1>Component Catalog</h1><p>Total component folders detected: 48.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li></ul>",
24152
+ "html": "<h1>Component Catalog</h1><p>Total component folders detected: 49.</p><h2>Available components</h2><ul><li>app-settings-editor</li><li>archetype-configurator</li><li>bounded-repeater</li><li>carousel-list</li><li>chart-list</li><li>code-editor</li><li>css-sheet-editor</li><li>dashboard</li><li>data-action-button</li><li>data-repeater</li><li>data-source</li><li>designer</li><li>dynamic-dashboard-template</li><li>dynamic-field-template</li><li>dynamic-form-template</li><li>dynamic-generic-template</li><li>dynamic-repeater-template</li><li>dynamic-template</li><li>error-dialog</li><li>field</li><li>filter-bar</li><li>first-run-wizard</li><li>framework-docs</li><li>image-wrapper</li><li>import-export-button</li><li>kanban-list</li><li>list-grid</li><li>map-list</li><li>meta-menu</li><li>metadata-editor</li><li>notification-bell</li><li>pager</li><li>parametric-dialog</li><li>pivot-builder</li><li>prompt-dialog-fallback-host</li><li>rag-chatbot</li><li>rag-chatbot-fab</li><li>report-designer</li><li>report-viewer</li><li>scheduler-list</li><li>split</li><li>split-area</li><li>spreadsheet-list-sf</li><li>tab-panel-wrapper</li><li>tab-view-wrapper</li><li>tree-list</li><li>upload-dialog</li><li>workflow-designer</li><li>workflow-runner</li></ul><h2>Exports from public-api</h2><ul><li>data-source/data-source.component</li><li>list-grid/list-grid.component</li><li>import-export-button/import-export-button.component</li><li>pager/pager.component</li><li>filter-bar/filter-bar.component</li><li>map-list/map-list.component</li><li>carousel-list/carousel-list.component</li><li>tree-list/tree-list.component</li><li>parametric-dialog/parametric-dialog.component</li><li>upload-dialog/upload-dialog.component</li><li>app-settings-editor/app-settings-editor.component</li><li>data-action-button/data-action-button.component</li><li>meta-menu/meta-menu.component</li><li>field/text-editor/text-editor.component</li><li>field/text-area-editor/text-area-editor.component</li><li>field/number-editor/number-editor.component</li><li>field/lookup-editor/lookup-editor.component</li><li>field/dictionary-editor/dictionary-editor.component</li><li>field/boolean-editor/boolean-editor.component</li><li>field/date-editor/date-editor.component</li><li>field/html-editor/html-editor.component</li><li>field/upload-editor/upload-editor.component</li><li>field/button-editor/button-editor.component</li><li>field/field-editor/field-editor.component</li><li>field/code-area-editor/code-area-editor.component</li><li>dynamic-template/dynamic-template.component</li><li>image-wrapper/image-wrapper.component</li><li>field/color-editor/color-editor.component</li><li>field/property-array-editor/property-array-editor.component</li><li>field/property-object-editor/property-object-editor.component</li><li>field/tree-view-selector/tree-view-selector.component</li><li>workflow-designer/workflow-designer.component</li><li>workflow-runner/workflow-runner.component</li><li>notification-bell/notification-bell.component</li><li>bounded-repeater/bounded-repeater.component</li><li>framework-docs/framework-docs.component</li><li>designer/designer.route.component</li><li>workflow-designer/workflow-designer.route.component</li><li>kanban-list/kanban-list.component</li><li>data-repeater/data-repeater.component</li><li>bounded-repeater/bounded-repeater-pending-changes.guard</li><li>rag-chatbot/rag-chatbot.component</li><li>rag-chatbot-fab/rag-chatbot-fab.component</li><li>error-dialog/error-dialog.component</li></ul>",
24137
24153
  "codeSamples": []
24138
24154
  }
24139
24155
  ],
@@ -26402,4 +26418,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
26402
26418
  }] } });
26403
26419
 
26404
26420
  export { FrameworkDocsComponent };
26405
- //# sourceMappingURL=wuic-framework-lib-framework-docs.component-BGcJ7k1X.mjs.map
26421
+ //# sourceMappingURL=wuic-framework-lib-framework-docs.component-eyzu9tdV.mjs.map