wuic-framework-lib 1.3.2 → 1.7.0

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 (27) hide show
  1. package/fesm2022/{wuic-framework-lib-chart-list.component-DAP-TPJR.mjs → wuic-framework-lib-chart-list.component-Bl424n7x.mjs} +49 -37
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-CLMDvOWs.mjs → wuic-framework-lib-code-editor.component-N6HMl2mf.mjs} +441 -277
  3. package/fesm2022/{wuic-framework-lib-designer.component-DA7abiLW.mjs → wuic-framework-lib-designer.component-Bd2fwl6H.mjs} +1948 -641
  4. package/fesm2022/{wuic-framework-lib-first-run-wizard.component-BLrUrfZ9.mjs → wuic-framework-lib-first-run-wizard.component-NN6cWVHL.mjs} +18 -20
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-DphKhTef.mjs → wuic-framework-lib-framework-docs.component-B867JAYe.mjs} +4205 -380
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-BqUUwrJM.mjs → wuic-framework-lib-pivot-builder.component-DWukH0L-.mjs} +578 -66
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-DZrhwMH5.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DWO1Rcgv.mjs} +2 -2
  8. package/fesm2022/wuic-framework-lib-report-designer.component-QcrU81m6.mjs +380 -0
  9. package/fesm2022/wuic-framework-lib-report-scaffold-dialog.component-U-zdOoRV.mjs +431 -0
  10. package/fesm2022/{wuic-framework-lib-report-viewer.component-CIN2fY0P.mjs → wuic-framework-lib-report-viewer.component-B4LhA3SL.mjs} +8 -13
  11. package/fesm2022/wuic-framework-lib-scene3d-designer.component-DjOfzKLo.mjs +4813 -0
  12. package/fesm2022/wuic-framework-lib-scene3d-light-baker-gpu-C96T9uIW.mjs +303 -0
  13. package/fesm2022/wuic-framework-lib-scene3d-shader-effect-DjHyCAFK.mjs +2807 -0
  14. package/fesm2022/wuic-framework-lib-scene3d-viewer.component-Dboz1fjl.mjs +1130 -0
  15. package/fesm2022/{wuic-framework-lib-scheduler-list.component-CdcI1Uor.mjs → wuic-framework-lib-scheduler-list.component--wY21R3o.mjs} +169 -53
  16. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-j1HTRI_P.mjs → wuic-framework-lib-spreadsheet-list-sf.component-Ek30J8v-.mjs} +147 -106
  17. package/fesm2022/{wuic-framework-lib-stimulsoft-license.service-BIyxB4pO.mjs → wuic-framework-lib-stimulsoft-license.service-CsNNSFYs.mjs} +3 -3
  18. package/fesm2022/wuic-framework-lib-timeline-list.component-aqCH4P0G.mjs +805 -0
  19. package/fesm2022/wuic-framework-lib-workflow-designer.component-DMM8BeXm.mjs +9504 -0
  20. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs → wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs} +14713 -8403
  21. package/fesm2022/wuic-framework-lib.mjs +1 -1
  22. package/package.json +5 -2
  23. package/styles/_wuic-tokens.scss +82 -0
  24. package/styles/styles.scss +160 -0
  25. package/types/wuic-framework-lib.d.ts +5971 -3666
  26. package/fesm2022/wuic-framework-lib-report-designer.component-D_qbefud.mjs +0 -194
  27. package/fesm2022/wuic-framework-lib-workflow-designer.component-SE_7ZogW.mjs +0 -5114
@@ -6,17 +6,17 @@ import * as i1$1 from '@angular/forms';
6
6
  import { FormsModule } from '@angular/forms';
7
7
  import * as i1 from '@angular/common/http';
8
8
  import { HttpContext } from '@angular/common/http';
9
- import { G as GlobalHandler, W as WtoolboxService, n as WUIC_SUPPRESS_GLOBAL_ERROR } from './wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs';
9
+ import { G as GlobalHandler, W as WtoolboxService, p as WUIC_SUPPRESS_GLOBAL_ERROR } from './wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs';
10
10
  import { firstValueFrom } from 'rxjs';
11
11
  import * as i8 from '@ngx-translate/core';
12
12
  import { TranslateModule } from '@ngx-translate/core';
13
13
  import * as i4 from 'primeng/button';
14
14
  import { ButtonModule } from 'primeng/button';
15
- import * as i6 from 'primeng/select';
15
+ import * as i5 from 'primeng/select';
16
16
  import { SelectModule } from 'primeng/select';
17
- import * as i11 from 'primeng/progressbar';
17
+ import * as i6 from 'primeng/progressbar';
18
18
  import { ProgressBarModule } from 'primeng/progressbar';
19
- import * as i6$1 from 'primeng/tooltip';
19
+ import * as i7 from 'primeng/tooltip';
20
20
  import { TooltipModule } from 'primeng/tooltip';
21
21
  import * as i2 from 'primeng/dialog';
22
22
  import { DialogModule } from 'primeng/dialog';
@@ -364,14 +364,14 @@ class WuicFirstRunWizardComponent {
364
364
  ], '620px', '400px');
365
365
  const rawConfirm = promptResult?.confirmDrop;
366
366
  let confirmDropValue = rawConfirm;
367
- if (rawConfirm && typeof rawConfirm === 'object' && 'value' in rawConfirm && typeof rawConfirm.value !== 'function') {
368
- confirmDropValue = rawConfirm.value;
367
+ if (rawConfirm && typeof rawConfirm === 'object' && 'value' in rawConfirm && typeof (rawConfirm).value !== 'function') {
368
+ confirmDropValue = (rawConfirm).value;
369
369
  }
370
- else if (rawConfirm && typeof rawConfirm.getValue === 'function') {
371
- confirmDropValue = rawConfirm.getValue();
370
+ else if (rawConfirm && typeof (rawConfirm).getValue === 'function') {
371
+ confirmDropValue = (rawConfirm).getValue();
372
372
  }
373
373
  if (confirmDropValue && typeof confirmDropValue === 'object' && 'value' in confirmDropValue) {
374
- confirmDropValue = confirmDropValue.value;
374
+ confirmDropValue = (confirmDropValue).value;
375
375
  }
376
376
  const confirmDrop = String(confirmDropValue ?? 'no').toLowerCase() === 'yes';
377
377
  if (confirmDrop) {
@@ -958,8 +958,7 @@ class WuicFirstRunWizardComponent {
958
958
  parts.push(`Password=${password}`);
959
959
  parts.push('Persist Security Info=true');
960
960
  }
961
- parts.push('Encrypt=False');
962
- parts.push('TrustServerCertificate=True');
961
+ parts.push('Encrypt=False', 'TrustServerCertificate=True');
963
962
  if (databaseName)
964
963
  parts.push(`initial catalog=${databaseName}`);
965
964
  return parts.join(';');
@@ -1014,8 +1013,7 @@ class WuicFirstRunWizardComponent {
1014
1013
  continue;
1015
1014
  filtered.push(part);
1016
1015
  }
1017
- filtered.push('Encrypt=False');
1018
- filtered.push('TrustServerCertificate=True');
1016
+ filtered.push('Encrypt=False', 'TrustServerCertificate=True');
1019
1017
  return filtered.join(';');
1020
1018
  }
1021
1019
  getConnValue(map, keys) {
@@ -1088,7 +1086,7 @@ class WuicFirstRunWizardComponent {
1088
1086
  const detail = fromBackend.message || fromBackend.error || fromBackend.title;
1089
1087
  if (detail)
1090
1088
  parts.push(String(detail));
1091
- const rootMessage = fromBackend.rootMessage;
1089
+ const rootMessage = (fromBackend).rootMessage;
1092
1090
  if (rootMessage && (!detail || !String(detail).includes(String(rootMessage)))) {
1093
1091
  parts.push(String(rootMessage));
1094
1092
  }
@@ -1099,11 +1097,11 @@ class WuicFirstRunWizardComponent {
1099
1097
  // (lanciati come `throw new InvalidOperationException(marker)` lato server)
1100
1098
  // restano sepolti in `args.message` → il flow `if (firstRunError.includes(marker))`
1101
1099
  // del wizard non trova mai il match e perde il prompt di overwrite.
1102
- const argsMsg = fromBackend.args?.message;
1100
+ const argsMsg = (fromBackend).args?.message;
1103
1101
  if (argsMsg && !parts.some(p => p.includes(String(argsMsg)))) {
1104
1102
  parts.push(String(argsMsg));
1105
1103
  }
1106
- const fallbackMsg = fromBackend.fallbackMessage;
1104
+ const fallbackMsg = (fromBackend).fallbackMessage;
1107
1105
  if (fallbackMsg && !parts.some(p => p.includes(String(fallbackMsg)))) {
1108
1106
  parts.push(String(fallbackMsg));
1109
1107
  }
@@ -1143,7 +1141,7 @@ class WuicFirstRunWizardComponent {
1143
1141
  }
1144
1142
  // Togli il prefisso fully-qualified del tipo eccezione .NET
1145
1143
  // (es. "System.InvalidOperationException: " / "System.Data.SqlClient.SqlException: ").
1146
- msg = msg.replace(/^(?:[A-Za-z_][\w]*\.)+[A-Za-z_]\w*(?:Exception|Error)\s*:\s*/, '').trim();
1144
+ msg = msg.replace(/^(?:[A-Za-z_]\w*\.)+[A-Za-z_]\w*(?:Exception|Error)\s*:\s*/, '').trim();
1147
1145
  return msg || original;
1148
1146
  }
1149
1147
  // ════════════════════════════════════════════════════════════════════════
@@ -1290,11 +1288,11 @@ class WuicFirstRunWizardComponent {
1290
1288
  || Object.keys(bundles).find(l => l.startsWith(browserLang.substring(0, 2)))
1291
1289
  || 'it-IT';
1292
1290
  this.translate.setDefaultLang(resolvedLang);
1293
- void this.translate.use(resolvedLang);
1291
+ this.translate.use(resolvedLang);
1294
1292
  }
1295
1293
  }
1296
1294
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WuicFirstRunWizardComponent, deps: [{ token: i1.HttpClient }, { token: i8.TranslateService }, { token: i3.MessageService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
1297
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WuicFirstRunWizardComponent, isStandalone: true, selector: "wuic-first-run-wizard-impl", outputs: { complete: "complete" }, ngImport: i0, template: "@if (showFirstRunInstall) {\n<div class=\"first-run-overlay\">\n <div class=\"first-run-card first-run-card-wide\">\n <div class=\"first-run-title\">Configurazione iniziale progetto</div>\n <div class=\"first-run-subtitle\">Seleziona DBMS, connessione dati e nome database metadati.</div>\n\n <!-- BODY scrollabile: header (title/subtitle) e footer (progress + CTA)\n restano sempre visibili, solo questo blocco scrolla quando il form\n e' piu' alto della viewport. -->\n <div class=\"first-run-body\">\n\n <!-- Grid 2 colonne: sx = connessione + scaffold / dx = admin + RAG.\n Su viewport stretti (< 720px) il grid collassa a 1 colonna. -->\n <div class=\"first-run-grid\">\n\n <!-- \u2500\u2500 COLONNA SINISTRA: Database + Setup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"first-run-col\">\n\n @if (firstRunSetupModeOptions.length > 1) {\n <div class=\"first-run-field\">\n <label for=\"first-run-mode\">Modalit\u00E0 setup</label>\n <p-select [options]=\"firstRunSetupModeOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.setupMode\" (ngModelChange)=\"onFirstRunSetupModeChanged($event)\"\n [disabled]=\"firstRunInstalling\" [style]=\"{ width: '100%' }\" inputId=\"first-run-mode\"></p-select>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-dbms\">DBMS</label>\n <p-select [options]=\"firstRunDbmsOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.dbms\" (ngModelChange)=\"onFirstRunDbmsChanged($event)\"\n [disabled]=\"firstRunInstalling\" [style]=\"{ width: '100%' }\" inputId=\"first-run-dbms\"></p-select>\n </div>\n\n @if (firstRunForm.setupMode === 'tutorial') {\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.createTutorialIfMissing\"\n (ngModelChange)=\"firstRunForm.createTutorialIfMissing = !!$event\" [disabled]=\"firstRunInstalling\" />\n Crea tutorial se manca\n </label>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-datasql\">DataSQLConnection</label>\n <input id=\"first-run-datasql\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.dataConnectionString\" (ngModelChange)=\"onFirstRunConnectionChanged($event)\"\n [disabled]=\"firstRunInstalling\"\n placeholder=\"es. data source=localhost\\sqlexpress;User ID=sa;Password=...;initial catalog=WideWorldImporters\" />\n </div>\n\n <div class=\"first-run-field\">\n <p-button label=\"Test connessione e carica DB\" severity=\"secondary\" [outlined]=\"true\"\n [loading]=\"firstRunConnectionTesting\"\n [disabled]=\"firstRunInstalling || firstRunLoading || !firstRunForm.dataConnectionString\"\n (onClick)=\"testFirstRunConnectionAndLoadDatabases()\"></p-button>\n </div>\n\n @if (firstRunForm.setupMode === 'tutorial') {\n <div class=\"first-run-field\">\n <label for=\"first-run-datadb\">Database dati tutorial</label>\n <input id=\"first-run-datadb\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.tutorialDataDbName\"\n (ngModelChange)=\"firstRunForm.tutorialDataDbName = $event; firstRunForm.dataDbName = $event\"\n [disabled]=\"firstRunInstalling || !firstRunConnectionValid\"\n placeholder=\"WideWorldImporters\" />\n </div>\n } @else {\n <div class=\"first-run-field\">\n <label for=\"first-run-datadb\">Database dati</label>\n <p-select [options]=\"firstRunDataDbOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.dataDbName\" (ngModelChange)=\"firstRunForm.dataDbName = $event\"\n [disabled]=\"firstRunInstalling || firstRunDbLoading || !firstRunConnectionValid\" [filter]=\"true\"\n [editable]=\"true\" [style]=\"{ width: '100%' }\" inputId=\"first-run-datadb\"\n placeholder=\"Seleziona o digita database\"></p-select>\n <div style=\"margin-top: 0.5rem;\">\n <p-button label=\"Aggiorna elenco DB\" severity=\"secondary\" [outlined]=\"true\" size=\"small\"\n [loading]=\"firstRunDbLoading\" [disabled]=\"firstRunInstalling || !firstRunConnectionValid\"\n (onClick)=\"testFirstRunConnectionAndLoadDatabases()\"></p-button>\n </div>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-metadb\">@if (firstRunForm.setupMode === 'tutorial') {Nome DB metadati tutorial} @else {Nome DB metadati}</label>\n <input id=\"first-run-metadb\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.setupMode === 'tutorial' ? firstRunForm.tutorialMetadataDbName : firstRunForm.metadataDbName\"\n (ngModelChange)=\"firstRunForm.metadataDbName = $event; firstRunForm.tutorialMetadataDbName = $event\"\n [disabled]=\"firstRunInstalling\"\n placeholder=\"metadataDB\" />\n </div>\n\n @if (firstRunForm.setupMode !== 'tutorial') {\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.scaffoldExistingDatabase\"\n (ngModelChange)=\"firstRunForm.scaffoldExistingDatabase = !!$event\"\n [disabled]=\"firstRunInstalling\" />\n Esegui scaffold automatico delle tabelle del DB selezionato\n </label>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Popola <code>_metadati__tabelle</code> / <code>_metadati__colonne</code> al termine dell'installazione.\n Operazione potenzialmente lunga su DB con molte tabelle.\n </small>\n </div>\n }\n </div>\n\n <!-- \u2500\u2500 COLONNA DESTRA: Admin + RAG \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"first-run-col\">\n\n <div class=\"first-run-section-title\">Utente admin iniziale</div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-username\">Username admin iniziale</label>\n <input id=\"first-run-admin-username\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.adminUsername\"\n (ngModelChange)=\"firstRunForm.adminUsername = $event\"\n [disabled]=\"firstRunInstalling\" autocomplete=\"off\"\n placeholder=\"admin\" />\n </div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-password\">Password admin iniziale</label>\n <input id=\"first-run-admin-password\" class=\"first-run-input\" type=\"password\"\n [ngModel]=\"firstRunForm.adminPassword\"\n (ngModelChange)=\"firstRunForm.adminPassword = $event\"\n [disabled]=\"firstRunInstalling\" autocomplete=\"new-password\"\n placeholder=\"(min 4 caratteri)\" />\n </div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-language\">Lingua admin iniziale</label>\n <p-select [options]=\"firstRunAdminLanguageOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.adminLanguage\"\n (ngModelChange)=\"firstRunForm.adminLanguage = $event\"\n [disabled]=\"firstRunInstalling\"\n [style]=\"{ width: '100%' }\" inputId=\"first-run-admin-language\"></p-select>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Lingua applicata all'utente admin dopo il primo login. Puoi cambiarla in seguito dal profilo utente.\n </small>\n </div>\n\n <div class=\"first-run-section-title first-run-section-title-rag\">RAG Chatbot (opzionale)</div>\n\n <div class=\"first-run-field\">\n <small style=\"display:block; margin-bottom:8px; opacity:0.8; font-size:0.85rem; line-height:1.4;\">\n Il RAG Chatbot \u00E8 gi\u00E0 incluso e funziona <strong>out-of-the-box</strong>: l'engine \u00E8 nativo\n <strong>.NET/ONNX</strong> (nessun Python, nessun server separato da installare). Al primo\n uso della chat scarica automaticamente i modelli (~2.3 GB) da <code>wuic-framework.com</code>.\n Con una GPU NVIDIA (CUDA 12.x + cuDNN 9.x) le risposte sono in ~1s; senza, fallback automatico\n su CPU. <strong>Nessun setup da fare qui.</strong>\n </small>\n <label for=\"first-run-anthropic-key\">\n Anthropic API Key (opzionale)\n <i class=\"pi pi-info-circle first-run-info-icon\"\n [pTooltip]=\"'firstrun.rag.apiKeyTooltip' | translate\"\n tooltipPosition=\"right\"\n [tooltipStyleClass]=\"'first-run-tooltip'\"\n [escape]=\"false\"></i>\n </label>\n <textarea id=\"first-run-anthropic-key\" class=\"first-run-input first-run-textarea\"\n [ngModel]=\"firstRunForm.anthropicApiKey\"\n (ngModelChange)=\"firstRunForm.anthropicApiKey = $event\"\n [disabled]=\"firstRunInstalling\"\n rows=\"2\" autocomplete=\"off\"\n placeholder=\"sk-ant-...\"></textarea>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Senza chiave il chatbot funziona solo in modalit\u00E0 retrieval (ricerca snippet).\n Con chiave abilita la chat con LLM (Claude) e le azioni proposte sul designer.\n Viene salvata in <code>appsettings.json</code>; puoi cambiarla anche dopo.\n </small>\n </div>\n </div>\n\n <!-- Crash reporting opt-in (skill crash-reporting Commit 8). Default OFF.\n Il consenso GDPR usa labels HARDCODED in `crashReportingLabels`\n dentro il componente (NON `wuic_translation`) perche' il\n first-run gira PRIMA che il DB metadati esista \u2014 niente DB,\n niente translation table. Vedi commento esteso nel componente.\n Al check del consenso si apre il popup col disclaimer\n dettagliato; l'utente conferma li' per attivare il flag. -->\n <div class=\"first-run-section-title first-run-section-title-crash-reporting\">{{ crashReportingLabels.title }}</div>\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.enableCrashReporting\"\n (ngModelChange)=\"onCrashReportingToggle($event)\"\n [disabled]=\"firstRunInstalling\" />\n {{ crashReportingLabels.checkbox_accept }}\n </label>\n <small style=\"display:block; margin-top:4px; opacity:0.85; font-size:0.85rem; line-height:1.45;\">\n {{ crashReportingLabels.intro_short }}\n <a href=\"javascript:void(0)\" (click)=\"openCrashReportingDisclaimer()\"\n style=\"margin-left:6px;\">{{ crashReportingLabels.read_full }}</a>\n </small>\n </div>\n </div>\n\n <!-- Disclaimer GDPR popup (apre al check + da link \"leggi tutto\"). -->\n <p-dialog [(visible)]=\"crashReportingDisclaimerVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [closeOnEscape]=\"true\"\n [header]=\"crashReportingLabels.title\"\n [style]=\"{ width: '600px', maxWidth: '90vw' }\"\n [contentStyle]=\"{ 'max-height': '70vh', 'overflow-y': 'auto' }\"\n [appendTo]=\"'body'\">\n <div style=\"line-height:1.55;\">\n <p>{{ crashReportingLabels.intro }}</p>\n <p><strong>{{ crashReportingLabels.what_we_send }}</strong></p>\n <ul style=\"margin:0 0 8px 18px; padding:0;\">\n <li>{{ crashReportingLabels.what_we_dont_send }}</li>\n <li>{{ crashReportingLabels.where_it_goes }}</li>\n <li>{{ crashReportingLabels.retention }}</li>\n <li>{{ crashReportingLabels.legal_basis }}</li>\n <li>{{ crashReportingLabels.how_to_disable }}</li>\n </ul>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button [label]=\"crashReportingLabels.btn_decline\"\n severity=\"secondary\"\n (onClick)=\"declineCrashReporting()\"></p-button>\n <p-button [label]=\"crashReportingLabels.btn_accept\"\n (onClick)=\"acceptCrashReporting()\"></p-button>\n </ng-template>\n </p-dialog>\n\n </div><!-- /.first-run-body -->\n\n <!-- FOOTER sticky: error (se presente) + riga progress|CTA sempre visibile. -->\n <div class=\"first-run-footer\">\n @if (firstRunError && !firstRunErrorDismissed) {\n <div class=\"first-run-error\" role=\"alert\">\n <button type=\"button\"\n class=\"first-run-error__close\"\n (click)=\"dismissFirstRunError()\"\n aria-label=\"Chiudi errore\"\n title=\"Chiudi\">\u00D7</button>\n <div class=\"first-run-error__body\">{{ firstRunError }}</div>\n </div>\n }\n\n <div class=\"first-run-footer-row\">\n @if (firstRunInstalling && firstRunProgress.active) {\n <div class=\"first-run-progress\">\n <div class=\"first-run-progress-label\">\n <strong>{{ firstRunProgress.phase }}</strong>\n @if (firstRunProgress.total > 0 && !firstRunProgress.phase.includes('.restore')) {\n <span class=\"first-run-progress-count\">\n \u2014 batch {{ firstRunProgress.current }} / {{ firstRunProgress.total }}\n </span>\n }\n @if (firstRunProgress.elapsedMs > 0) {\n <span class=\"first-run-progress-count\">\n \u00B7 {{ (firstRunProgress.elapsedMs / 1000) | number:'1.0-0' }}s\n </span>\n }\n </div>\n @if (firstRunProgress.phase.includes('.restore') && firstRunProgress.percent < 5) {\n <p-progressBar mode=\"indeterminate\" [style]=\"{'height': '1rem'}\"></p-progressBar>\n } @else {\n <p-progressBar [value]=\"firstRunProgress.percent\" [showValue]=\"true\" [style]=\"{'height': '1rem'}\"></p-progressBar>\n }\n @if (firstRunProgress.message) {\n <div class=\"first-run-progress-message\">{{ firstRunProgress.message }}</div>\n }\n </div>\n } @else {\n <div class=\"first-run-progress-placeholder\"></div>\n }\n\n <div class=\"first-run-actions\">\n <p-button label=\"Conferma e genera metadataDB\" [loading]=\"firstRunInstalling\"\n [disabled]=\"firstRunInstalling || firstRunLoading\" (onClick)=\"submitFirstRunInstall()\"></p-button>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".first-run-overlay{position:fixed;inset:0;z-index:900;display:flex;align-items:center;justify-content:center;padding:24px;background:linear-gradient(135deg,#081221d9,#16294acc)}.first-run-card-wide{width:min(1180px,100%)!important}.first-run-card{width:min(860px,100%);min-height:min(720px,100vh - 48px);max-height:calc(100vh - 48px);display:flex;flex-direction:column;overflow:hidden;border-radius:14px;padding:22px;background:var(--p-surface-0);box-shadow:0 18px 48px #00000059;border:1px solid var(--p-content-border-color)}.first-run-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding-right:4px;margin-right:-4px}.first-run-footer{flex:0 0 auto;margin-top:12px;padding-top:12px;border-top:1px solid var(--p-content-border-color);display:flex;flex-direction:column;gap:10px}.first-run-footer-row{display:flex;align-items:center;gap:16px}.first-run-title{font-size:1.25rem;font-weight:700}.first-run-subtitle{margin-top:6px;margin-bottom:18px;opacity:.8}.first-run-field{margin-bottom:14px}.first-run-field label{display:block;margin-bottom:6px;font-weight:600}.first-run-checkbox-row label{display:inline-flex;align-items:center;gap:.5rem;margin-bottom:0;font-weight:500}.first-run-input{width:100%;height:40px;border-radius:8px;border:1px solid var(--p-content-border-color);padding:8px 12px;font-size:.95rem;background:var(--p-surface-0);color:var(--p-text-color)}.first-run-textarea{height:auto;min-height:56px;resize:vertical;font-family:var(--p-font-family);line-height:1.4}.first-run-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:28px;row-gap:0}@media(max-width:860px){.first-run-grid{grid-template-columns:1fr}}.first-run-col{display:flex;flex-direction:column;min-width:0}.first-run-section-title{margin-top:4px;margin-bottom:12px;padding-bottom:6px;font-size:.95rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;opacity:.8;border-bottom:1px solid var(--p-content-border-color)}.first-run-section-title-rag{margin-top:18px}.first-run-python-warning{margin-top:8px;padding:10px 12px;background:#fef3c7;border:1px solid #fcd34d;border-radius:6px;color:#78350f;font-size:.85rem;line-height:1.4}.first-run-python-warning strong{color:#78350f}.first-run-python-warning code{background:#00000014;padding:1px 4px;border-radius:3px;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.82rem}.first-run-python-warning ol li+li{margin-top:4px}.first-run-python-warning-link{color:#92400e;text-decoration:underline;font-weight:600}.first-run-python-warning-link:hover{color:#78350f}.first-run-python-warning-link:visited{color:#92400e}.first-run-python-note{margin-top:8px;padding:10px 12px;background:#dbeafe;border:1px solid #93c5fd;border-radius:6px;color:#1e3a8a;font-size:.85rem;line-height:1.4}.first-run-python-note strong{color:#1e3a8a}.first-run-python-note code{background:#00000014;padding:1px 4px;border-radius:3px;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.82rem}.first-run-info-icon{margin-left:6px;font-size:.95rem;color:var(--p-primary-color, #3b82f6);cursor:help;vertical-align:middle;opacity:.85}.first-run-info-icon:hover{opacity:1}::ng-deep .p-tooltip.first-run-tooltip{max-width:440px}::ng-deep .p-tooltip.first-run-tooltip .p-tooltip-text{white-space:pre-line;font-size:.85rem;line-height:1.45}.first-run-input:focus{outline:2px solid rgba(59,130,246,.25);border-color:#3b82f6}.first-run-error{position:relative;margin:8px 0 14px;color:#7f1d1d;background:#fee2e2;border:1px solid #fca5a5;border-radius:8px;padding:10px 36px 10px 12px}.first-run-error__body{max-height:200px;overflow-y:auto;word-break:break-word;white-space:pre-wrap;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.85rem;line-height:1.4}.first-run-error__close{position:absolute;top:6px;right:8px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:transparent;border:0;border-radius:4px;color:inherit;font-size:1.25rem;line-height:1;cursor:pointer;opacity:.75;transition:background-color .12s ease,opacity .12s ease}.first-run-error__close:hover,.first-run-error__close:focus-visible{opacity:1;background:#7f1d1d1f;outline:none}.first-run-error__close:active{background:#7f1d1d33}.first-run-actions{flex:0 0 auto;display:flex;justify-content:flex-end}.first-run-progress{flex:1 1 auto;min-width:0;padding:8px 12px;background:var(--p-surface-50);border:1px solid var(--p-content-border-color);border-radius:8px;display:flex;flex-direction:column;gap:4px}.first-run-progress-placeholder{flex:1 1 auto;min-width:0}.first-run-progress-label{font-size:.9rem}.first-run-progress-label strong{font-weight:600}.first-run-progress-label .first-run-progress-count{opacity:.7;margin-left:4px}.first-run-progress-message{font-size:.8rem;opacity:.75;font-family:ui-monospace,Cascadia Code,Consolas,monospace}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i11.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "pipe", type: i1$2.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
1295
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WuicFirstRunWizardComponent, isStandalone: true, selector: "wuic-first-run-wizard-impl", outputs: { complete: "complete" }, ngImport: i0, template: "@if (showFirstRunInstall) {\n<div class=\"first-run-overlay\">\n <div class=\"first-run-card first-run-card-wide\">\n <div class=\"first-run-title\">Configurazione iniziale progetto</div>\n <div class=\"first-run-subtitle\">Seleziona DBMS, connessione dati e nome database metadati.</div>\n\n <!-- BODY scrollabile: header (title/subtitle) e footer (progress + CTA)\n restano sempre visibili, solo questo blocco scrolla quando il form\n e' piu' alto della viewport. -->\n <div class=\"first-run-body\">\n\n <!-- Grid 2 colonne: sx = connessione + scaffold / dx = admin + RAG.\n Su viewport stretti (< 720px) il grid collassa a 1 colonna. -->\n <div class=\"first-run-grid\">\n\n <!-- \u2500\u2500 COLONNA SINISTRA: Database + Setup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"first-run-col\">\n\n @if (firstRunSetupModeOptions.length > 1) {\n <div class=\"first-run-field\">\n <label for=\"first-run-mode\">Modalit\u00E0 setup</label>\n <p-select [options]=\"firstRunSetupModeOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.setupMode\" (ngModelChange)=\"onFirstRunSetupModeChanged($event)\"\n [disabled]=\"firstRunInstalling\" [style]=\"{ width: '100%' }\" inputId=\"first-run-mode\"></p-select>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-dbms\">DBMS</label>\n <p-select [options]=\"firstRunDbmsOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.dbms\" (ngModelChange)=\"onFirstRunDbmsChanged($event)\"\n [disabled]=\"firstRunInstalling\" [style]=\"{ width: '100%' }\" inputId=\"first-run-dbms\"></p-select>\n </div>\n\n @if (firstRunForm.setupMode === 'tutorial') {\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.createTutorialIfMissing\"\n (ngModelChange)=\"firstRunForm.createTutorialIfMissing = !!$event\" [disabled]=\"firstRunInstalling\" />\n Crea tutorial se manca\n </label>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-datasql\">DataSQLConnection</label>\n <input id=\"first-run-datasql\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.dataConnectionString\" (ngModelChange)=\"onFirstRunConnectionChanged($event)\"\n [disabled]=\"firstRunInstalling\"\n placeholder=\"es. data source=localhost\\sqlexpress;User ID=sa;Password=...;initial catalog=WideWorldImporters\" />\n </div>\n\n <div class=\"first-run-field\">\n <p-button label=\"Test connessione e carica DB\" severity=\"secondary\" [outlined]=\"true\"\n [loading]=\"firstRunConnectionTesting\"\n [disabled]=\"firstRunInstalling || firstRunLoading || !firstRunForm.dataConnectionString\"\n (onClick)=\"testFirstRunConnectionAndLoadDatabases()\"></p-button>\n </div>\n\n @if (firstRunForm.setupMode === 'tutorial') {\n <div class=\"first-run-field\">\n <label for=\"first-run-datadb\">Database dati tutorial</label>\n <input id=\"first-run-datadb\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.tutorialDataDbName\"\n (ngModelChange)=\"firstRunForm.tutorialDataDbName = $event; firstRunForm.dataDbName = $event\"\n [disabled]=\"firstRunInstalling || !firstRunConnectionValid\"\n placeholder=\"WideWorldImporters\" />\n </div>\n } @else {\n <div class=\"first-run-field\">\n <label for=\"first-run-datadb\">Database dati</label>\n <p-select [options]=\"firstRunDataDbOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.dataDbName\" (ngModelChange)=\"firstRunForm.dataDbName = $event\"\n [disabled]=\"firstRunInstalling || firstRunDbLoading || !firstRunConnectionValid\" [filter]=\"true\"\n [editable]=\"true\" [style]=\"{ width: '100%' }\" inputId=\"first-run-datadb\"\n placeholder=\"Seleziona o digita database\"></p-select>\n <div style=\"margin-top: 0.5rem;\">\n <p-button label=\"Aggiorna elenco DB\" severity=\"secondary\" [outlined]=\"true\" size=\"small\"\n [loading]=\"firstRunDbLoading\" [disabled]=\"firstRunInstalling || !firstRunConnectionValid\"\n (onClick)=\"testFirstRunConnectionAndLoadDatabases()\"></p-button>\n </div>\n </div>\n }\n\n <div class=\"first-run-field\">\n <label for=\"first-run-metadb\">@if (firstRunForm.setupMode === 'tutorial') {Nome DB metadati tutorial} @else {Nome DB metadati}</label>\n <input id=\"first-run-metadb\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.setupMode === 'tutorial' ? firstRunForm.tutorialMetadataDbName : firstRunForm.metadataDbName\"\n (ngModelChange)=\"firstRunForm.metadataDbName = $event; firstRunForm.tutorialMetadataDbName = $event\"\n [disabled]=\"firstRunInstalling\"\n placeholder=\"metadataDB\" />\n </div>\n\n @if (firstRunForm.setupMode !== 'tutorial') {\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.scaffoldExistingDatabase\"\n (ngModelChange)=\"firstRunForm.scaffoldExistingDatabase = !!$event\"\n [disabled]=\"firstRunInstalling\" />\n Esegui scaffold automatico delle tabelle del DB selezionato\n </label>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Popola <code>_metadati__tabelle</code> / <code>_metadati__colonne</code> al termine dell'installazione.\n Operazione potenzialmente lunga su DB con molte tabelle.\n </small>\n </div>\n }\n </div>\n\n <!-- \u2500\u2500 COLONNA DESTRA: Admin + RAG \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"first-run-col\">\n\n <div class=\"first-run-section-title\">Utente admin iniziale</div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-username\">Username admin iniziale</label>\n <input id=\"first-run-admin-username\" class=\"first-run-input\" type=\"text\"\n [ngModel]=\"firstRunForm.adminUsername\"\n (ngModelChange)=\"firstRunForm.adminUsername = $event\"\n [disabled]=\"firstRunInstalling\" autocomplete=\"off\"\n placeholder=\"admin\" />\n </div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-password\">Password admin iniziale</label>\n <input id=\"first-run-admin-password\" class=\"first-run-input\" type=\"password\"\n [ngModel]=\"firstRunForm.adminPassword\"\n (ngModelChange)=\"firstRunForm.adminPassword = $event\"\n [disabled]=\"firstRunInstalling\" autocomplete=\"new-password\"\n placeholder=\"(min 4 caratteri)\" />\n </div>\n\n <div class=\"first-run-field\">\n <label for=\"first-run-admin-language\">Lingua admin iniziale</label>\n <p-select [options]=\"firstRunAdminLanguageOptions\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"firstRunForm.adminLanguage\"\n (ngModelChange)=\"firstRunForm.adminLanguage = $event\"\n [disabled]=\"firstRunInstalling\"\n [style]=\"{ width: '100%' }\" inputId=\"first-run-admin-language\"></p-select>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Lingua applicata all'utente admin dopo il primo login. Puoi cambiarla in seguito dal profilo utente.\n </small>\n </div>\n\n <div class=\"first-run-section-title first-run-section-title-rag\">RAG Chatbot (opzionale)</div>\n\n <div class=\"first-run-field\">\n <small style=\"display:block; margin-bottom:8px; opacity:0.8; font-size:0.85rem; line-height:1.4;\">\n Il RAG Chatbot \u00E8 gi\u00E0 incluso e funziona <strong>out-of-the-box</strong>: l'engine \u00E8 nativo\n <strong>.NET/ONNX</strong> (nessun Python, nessun server separato da installare). Al primo\n uso della chat scarica automaticamente i modelli (~2.3 GB) da <code>wuic-framework.com</code>.\n Con una GPU NVIDIA (CUDA 12.x + cuDNN 9.x) le risposte sono in ~1s; senza, fallback automatico\n su CPU. <strong>Nessun setup da fare qui.</strong>\n </small>\n <label for=\"first-run-anthropic-key\">\n Anthropic API Key (opzionale)\n <i class=\"pi pi-info-circle first-run-info-icon\"\n [pTooltip]=\"'firstrun.rag.apiKeyTooltip' | translate\"\n tooltipPosition=\"right\"\n [tooltipStyleClass]=\"'first-run-tooltip'\"\n [escape]=\"false\"></i>\n </label>\n <textarea id=\"first-run-anthropic-key\" class=\"first-run-input first-run-textarea\"\n [ngModel]=\"firstRunForm.anthropicApiKey\"\n (ngModelChange)=\"firstRunForm.anthropicApiKey = $event\"\n [disabled]=\"firstRunInstalling\"\n rows=\"2\" autocomplete=\"off\"\n placeholder=\"sk-ant-...\"></textarea>\n <small style=\"display:block; margin-top:4px; opacity:0.75; font-size:0.8rem; line-height:1.35;\">\n Senza chiave il chatbot funziona solo in modalit\u00E0 retrieval (ricerca snippet).\n Con chiave abilita la chat con LLM (Claude) e le azioni proposte sul designer.\n Viene salvata in <code>appsettings.json</code>; puoi cambiarla anche dopo.\n </small>\n </div>\n </div>\n\n <!-- Crash reporting opt-in (skill crash-reporting Commit 8). Default OFF.\n Il consenso GDPR usa labels HARDCODED in `crashReportingLabels`\n dentro il componente (NON `wuic_translation`) perche' il\n first-run gira PRIMA che il DB metadati esista \u2014 niente DB,\n niente translation table. Vedi commento esteso nel componente.\n Al check del consenso si apre il popup col disclaimer\n dettagliato; l'utente conferma li' per attivare il flag. -->\n <div class=\"first-run-section-title first-run-section-title-crash-reporting\">{{ crashReportingLabels.title }}</div>\n <div class=\"first-run-field first-run-checkbox-row\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"firstRunForm.enableCrashReporting\"\n (ngModelChange)=\"onCrashReportingToggle($event)\"\n [disabled]=\"firstRunInstalling\" />\n {{ crashReportingLabels.checkbox_accept }}\n </label>\n <small style=\"display:block; margin-top:4px; opacity:0.85; font-size:0.85rem; line-height:1.45;\">\n {{ crashReportingLabels.intro_short }}\n <a href=\"javascript:void(0)\" (click)=\"openCrashReportingDisclaimer()\"\n style=\"margin-left:6px;\">{{ crashReportingLabels.read_full }}</a>\n </small>\n </div>\n </div>\n\n <!-- Disclaimer GDPR popup (apre al check + da link \"leggi tutto\"). -->\n <p-dialog [(visible)]=\"crashReportingDisclaimerVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [closeOnEscape]=\"true\"\n [header]=\"crashReportingLabels.title\"\n [style]=\"{ width: '600px', maxWidth: '90vw' }\"\n [contentStyle]=\"{ 'max-height': '70vh', 'overflow-y': 'auto' }\"\n [appendTo]=\"'body'\">\n <div style=\"line-height:1.55;\">\n <p>{{ crashReportingLabels.intro }}</p>\n <p><strong>{{ crashReportingLabels.what_we_send }}</strong></p>\n <ul style=\"margin:0 0 8px 18px; padding:0;\">\n <li>{{ crashReportingLabels.what_we_dont_send }}</li>\n <li>{{ crashReportingLabels.where_it_goes }}</li>\n <li>{{ crashReportingLabels.retention }}</li>\n <li>{{ crashReportingLabels.legal_basis }}</li>\n <li>{{ crashReportingLabels.how_to_disable }}</li>\n </ul>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button [label]=\"crashReportingLabels.btn_decline\"\n severity=\"secondary\"\n (onClick)=\"declineCrashReporting()\"></p-button>\n <p-button [label]=\"crashReportingLabels.btn_accept\"\n (onClick)=\"acceptCrashReporting()\"></p-button>\n </ng-template>\n </p-dialog>\n\n </div><!-- /.first-run-body -->\n\n <!-- FOOTER sticky: error (se presente) + riga progress|CTA sempre visibile. -->\n <div class=\"first-run-footer\">\n @if (firstRunError && !firstRunErrorDismissed) {\n <div class=\"first-run-error\" role=\"alert\">\n <button type=\"button\"\n class=\"first-run-error__close\"\n (click)=\"dismissFirstRunError()\"\n aria-label=\"Chiudi errore\"\n title=\"Chiudi\">\u00D7</button>\n <div class=\"first-run-error__body\">{{ firstRunError }}</div>\n </div>\n }\n\n <div class=\"first-run-footer-row\">\n @if (firstRunInstalling && firstRunProgress.active) {\n <div class=\"first-run-progress\">\n <div class=\"first-run-progress-label\">\n <strong>{{ firstRunProgress.phase }}</strong>\n @if (firstRunProgress.total > 0 && !firstRunProgress.phase.includes('.restore')) {\n <span class=\"first-run-progress-count\">\n \u2014 batch {{ firstRunProgress.current }} / {{ firstRunProgress.total }}\n </span>\n }\n @if (firstRunProgress.elapsedMs > 0) {\n <span class=\"first-run-progress-count\">\n \u00B7 {{ (firstRunProgress.elapsedMs / 1000) | number:'1.0-0' }}s\n </span>\n }\n </div>\n @if (firstRunProgress.phase.includes('.restore') && firstRunProgress.percent < 5) {\n <p-progressBar mode=\"indeterminate\" [style]=\"{'height': '1rem'}\"></p-progressBar>\n } @else {\n <p-progressBar [value]=\"firstRunProgress.percent\" [showValue]=\"true\" [style]=\"{'height': '1rem'}\"></p-progressBar>\n }\n @if (firstRunProgress.message) {\n <div class=\"first-run-progress-message\">{{ firstRunProgress.message }}</div>\n }\n </div>\n } @else {\n <div class=\"first-run-progress-placeholder\"></div>\n }\n\n <div class=\"first-run-actions\">\n <p-button label=\"Conferma e genera metadataDB\" [loading]=\"firstRunInstalling\"\n [disabled]=\"firstRunInstalling || firstRunLoading\" (onClick)=\"submitFirstRunInstall()\"></p-button>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".first-run-overlay{position:fixed;inset:0;z-index:900;display:flex;align-items:center;justify-content:center;padding:24px;background:linear-gradient(135deg,#081221d9,#16294acc)}.first-run-card-wide{width:min(1180px,100%)!important}.first-run-card{width:min(860px,100%);min-height:min(720px,100vh - 48px);max-height:calc(100vh - 48px);display:flex;flex-direction:column;overflow:hidden;border-radius:14px;padding:22px;background:var(--p-surface-0);box-shadow:0 18px 48px #00000059;border:1px solid var(--p-content-border-color)}.first-run-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding-right:4px;margin-right:-4px}.first-run-footer{flex:0 0 auto;margin-top:12px;padding-top:12px;border-top:1px solid var(--p-content-border-color);display:flex;flex-direction:column;gap:10px}.first-run-footer-row{display:flex;align-items:center;gap:16px}.first-run-title{font-size:1.25rem;font-weight:700}.first-run-subtitle{margin-top:6px;margin-bottom:18px;opacity:.8}.first-run-field{margin-bottom:14px}.first-run-field label{display:block;margin-bottom:6px;font-weight:600}.first-run-checkbox-row label{display:inline-flex;align-items:center;gap:.5rem;margin-bottom:0;font-weight:500}.first-run-input{width:100%;height:40px;border-radius:8px;border:1px solid var(--p-content-border-color);padding:8px 12px;font-size:.95rem;background:var(--p-surface-0);color:var(--p-text-color)}.first-run-textarea{height:auto;min-height:56px;resize:vertical;font-family:var(--p-font-family);line-height:1.4}.first-run-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:28px;row-gap:0}@media(max-width:860px){.first-run-grid{grid-template-columns:1fr}}.first-run-col{display:flex;flex-direction:column;min-width:0}.first-run-section-title{margin-top:4px;margin-bottom:12px;padding-bottom:6px;font-size:.95rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;opacity:.8;border-bottom:1px solid var(--p-content-border-color)}.first-run-section-title-rag{margin-top:18px}.first-run-python-warning{margin-top:8px;padding:10px 12px;background:#fef3c7;border:1px solid #fcd34d;border-radius:6px;color:#78350f;font-size:.85rem;line-height:1.4}.first-run-python-warning strong{color:#78350f}.first-run-python-warning code{background:#00000014;padding:1px 4px;border-radius:3px;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.82rem}.first-run-python-warning ol li+li{margin-top:4px}.first-run-python-warning-link{color:#92400e;text-decoration:underline;font-weight:600}.first-run-python-warning-link:hover{color:#78350f}.first-run-python-warning-link:visited{color:#92400e}.first-run-python-note{margin-top:8px;padding:10px 12px;background:#dbeafe;border:1px solid #93c5fd;border-radius:6px;color:#1e3a8a;font-size:.85rem;line-height:1.4}.first-run-python-note strong{color:#1e3a8a}.first-run-python-note code{background:#00000014;padding:1px 4px;border-radius:3px;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.82rem}.first-run-info-icon{margin-left:6px;font-size:.95rem;color:var(--p-primary-color, #3b82f6);cursor:help;vertical-align:middle;opacity:.85}.first-run-info-icon:hover{opacity:1}::ng-deep .p-tooltip.first-run-tooltip{max-width:440px}::ng-deep .p-tooltip.first-run-tooltip .p-tooltip-text{white-space:pre-line;font-size:.85rem;line-height:1.45}.first-run-input:focus{outline:2px solid rgba(59,130,246,.25);border-color:#3b82f6}.first-run-error{position:relative;margin:8px 0 14px;color:#7f1d1d;background:#fee2e2;border:1px solid #fca5a5;border-radius:8px;padding:10px 36px 10px 12px}.first-run-error__body{max-height:200px;overflow-y:auto;word-break:break-word;white-space:pre-wrap;font-family:ui-monospace,Cascadia Code,Consolas,monospace;font-size:.85rem;line-height:1.4}.first-run-error__close{position:absolute;top:6px;right:8px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:transparent;border:0;border-radius:4px;color:inherit;font-size:1.25rem;line-height:1;cursor:pointer;opacity:.75;transition:background-color .12s ease,opacity .12s ease}.first-run-error__close:hover,.first-run-error__close:focus-visible{opacity:1;background:#7f1d1d1f;outline:none}.first-run-error__close:active{background:#7f1d1d33}.first-run-actions{flex:0 0 auto;display:flex;justify-content:flex-end}.first-run-progress{flex:1 1 auto;min-width:0;padding:8px 12px;background:var(--p-surface-50);border:1px solid var(--p-content-border-color);border-radius:8px;display:flex;flex-direction:column;gap:4px}.first-run-progress-placeholder{flex:1 1 auto;min-width:0}.first-run-progress-label{font-size:.9rem}.first-run-progress-label strong{font-weight:600}.first-run-progress-label .first-run-progress-count{opacity:.7;margin-left:4px}.first-run-progress-message{font-size:.8rem;opacity:.75;font-family:ui-monospace,Cascadia Code,Consolas,monospace}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i6.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "pipe", type: i1$2.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
1298
1296
  }
1299
1297
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WuicFirstRunWizardComponent, decorators: [{
1300
1298
  type: Component,
@@ -1313,4 +1311,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1313
1311
  }] } });
1314
1312
 
1315
1313
  export { WuicFirstRunWizardComponent };
1316
- //# sourceMappingURL=wuic-framework-lib-first-run-wizard.component-BLrUrfZ9.mjs.map
1314
+ //# sourceMappingURL=wuic-framework-lib-first-run-wizard.component-NN6cWVHL.mjs.map