wuic-framework-lib 1.3.0 → 1.3.2

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-C02jeFGy.mjs → wuic-framework-lib-chart-list.component-DAP-TPJR.mjs} +2 -2
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-BZNLr0Jj.mjs → wuic-framework-lib-code-editor.component-CLMDvOWs.mjs} +2 -2
  3. package/fesm2022/{wuic-framework-lib-designer.component-N_CfbGnr.mjs → wuic-framework-lib-designer.component-DA7abiLW.mjs} +79 -3
  4. package/fesm2022/{wuic-framework-lib-first-run-wizard.component-lW7-xMm3.mjs → wuic-framework-lib-first-run-wizard.component-BLrUrfZ9.mjs} +78 -38
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-CGQbmSkv.mjs → wuic-framework-lib-framework-docs.component-DphKhTef.mjs} +38 -18
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-0gJz9RWr.mjs → wuic-framework-lib-pivot-builder.component-BqUUwrJM.mjs} +2 -2
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-C9LvmFsL.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DZrhwMH5.mjs} +2 -2
  8. package/fesm2022/{wuic-framework-lib-report-designer.component-DcpdzFjh.mjs → wuic-framework-lib-report-designer.component-D_qbefud.mjs} +2 -2
  9. package/fesm2022/{wuic-framework-lib-report-viewer.component-BHpbGpp9.mjs → wuic-framework-lib-report-viewer.component-CIN2fY0P.mjs} +2 -2
  10. package/fesm2022/{wuic-framework-lib-scheduler-list.component-DHoukjf-.mjs → wuic-framework-lib-scheduler-list.component-CdcI1Uor.mjs} +2 -2
  11. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-VsaXepUC.mjs → wuic-framework-lib-spreadsheet-list-sf.component-j1HTRI_P.mjs} +2 -2
  12. package/fesm2022/{wuic-framework-lib-workflow-designer.component-epj3oKq3.mjs → wuic-framework-lib-workflow-designer.component-SE_7ZogW.mjs} +2 -2
  13. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-Deudd4MY.mjs → wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs} +87 -33
  14. package/fesm2022/wuic-framework-lib.mjs +1 -1
  15. package/package.json +1 -1
  16. package/types/wuic-framework-lib.d.ts +23 -2
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { EventEmitter, ViewChild, Output, Input, Component } from '@angular/core';
3
3
  import { BehaviorSubject } from 'rxjs';
4
- import { W as WtoolboxService, k as WuicClientException, l as WuicErrorCodes, G as GlobalHandler, M as MetadataProviderService, T as TranslationManagerService, U as UserInfoService, A as ArchetypeConfiguratorComponent } from './wuic-framework-lib-wuic-framework-lib-Deudd4MY.mjs';
4
+ import { W as WtoolboxService, k as WuicClientException, l as WuicErrorCodes, G as GlobalHandler, M as MetadataProviderService, T as TranslationManagerService, U as UserInfoService, A as ArchetypeConfiguratorComponent } from './wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs';
5
5
  import * as i5 from 'primeng/chart';
6
6
  import { ChartModule } from 'primeng/chart';
7
7
  import * as i8 from '@ngx-translate/core';
@@ -1377,4 +1377,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1377
1377
  }] } });
1378
1378
 
1379
1379
  export { ChartListComponent };
1380
- //# sourceMappingURL=wuic-framework-lib-chart-list.component-C02jeFGy.mjs.map
1380
+ //# sourceMappingURL=wuic-framework-lib-chart-list.component-DAP-TPJR.mjs.map
@@ -6,7 +6,7 @@ import * as i1 from '@materia-ui/ngx-monaco-editor';
6
6
  import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
7
7
  import { filter, take } from 'rxjs/operators';
8
8
  import { Emitter } from 'monaco-editor/esm/vs/base/common/event';
9
- import { W as WtoolboxService, M as MetadataProviderService, e as MetadatiColonna, m as MetaInfo, U as UserInfoService, f as DataProviderService } from './wuic-framework-lib-wuic-framework-lib-Deudd4MY.mjs';
9
+ import { W as WtoolboxService, M as MetadataProviderService, e as MetadatiColonna, m as MetaInfo, U as UserInfoService, f as DataProviderService } from './wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs';
10
10
  import { NgClass, NgStyle } from '@angular/common';
11
11
  import * as i14 from 'primeng/contextmenu';
12
12
  import { ContextMenuModule } from 'primeng/contextmenu';
@@ -3996,4 +3996,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3996
3996
  }] } });
3997
3997
 
3998
3998
  export { CodeEditorComponent };
3999
- //# sourceMappingURL=wuic-framework-lib-code-editor.component-BZNLr0Jj.mjs.map
3999
+ //# sourceMappingURL=wuic-framework-lib-code-editor.component-CLMDvOWs.mjs.map
@@ -5,7 +5,7 @@ import { SplitterModule } from 'primeng/splitter';
5
5
  import * as i12 from 'primeng/dragdrop';
6
6
  import { DragDropModule } from 'primeng/dragdrop';
7
7
  import { NgClass, NgStyle, NgTemplateOutlet, AsyncPipe, JsonPipe, NgFor, NgIf, NgComponentOutlet } from '@angular/common';
8
- import { W as WtoolboxService, D as DynamicGenericTemplateComponent, a as DynamicCompilerService, b as DataSourceComponent, c as DataRepeaterComponent, F as FilterBarComponent, L as LazyParametricDialogComponent, P as PagerComponent, M as MetadataProviderService, d as ParametricDialogComponent, e as MetadatiColonna, f as DataProviderService, U as UserInfoService, T as TranslationManagerService, g as MetadataEditorService, C as ChatbotHostRegistryService, h as WorkflowRuntimeMetadataService, i as FieldEditorComponent, j as MetadataEditorComponent, A as ArchetypeConfiguratorComponent } from './wuic-framework-lib-wuic-framework-lib-Deudd4MY.mjs';
8
+ import { W as WtoolboxService, D as DynamicGenericTemplateComponent, a as DynamicCompilerService, b as DataSourceComponent, c as DataRepeaterComponent, F as FilterBarComponent, L as LazyParametricDialogComponent, P as PagerComponent, M as MetadataProviderService, d as ParametricDialogComponent, e as MetadatiColonna, f as DataProviderService, U as UserInfoService, T as TranslationManagerService, g as MetadataEditorService, C as ChatbotHostRegistryService, h as WorkflowRuntimeMetadataService, i as FieldEditorComponent, j as MetadataEditorComponent, A as ArchetypeConfiguratorComponent } from './wuic-framework-lib-wuic-framework-lib-BRujEwpR.mjs';
9
9
  import { fromEvent, BehaviorSubject, merge, filter, Observable, switchMap, take, map, takeUntil, tap, timeInterval, scan, mergeMap, of, delay, repeat, Subject, startWith, pairwise, skipWhile, combineLatest } from 'rxjs';
10
10
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
11
  import { CdkAccordionModule, CdkAccordion, CdkAccordionItem } from '@angular/cdk/accordion';
@@ -6092,6 +6092,48 @@ class DesignerComponent {
6092
6092
  *
6093
6093
  * Ritorna il numero di elementi creati (1 + somma dei children).
6094
6094
  */
6095
+ /**
6096
+ * Inietta la config di archetipo (`md_props_bag.archetypes.<action>`) nel
6097
+ * `metaInfo.tableMetadata` del DATASOURCE bindato a un DATAREPEATER appena
6098
+ * droppato. NESSUNA chiamata server: muta solo lo stato in-memory del
6099
+ * datasource (md_props_bag + extraProps.archetypes) e ri-emette `fetchInfo$`
6100
+ * cosi' il DATAREPEATER reagisce e renderizza l'archetipo configurato. La
6101
+ * config viene poi serializzata insieme al datasource quando l'utente salva
6102
+ * la dashboard (boardcontent), coerente con AGENTS regola 7 (md_props_bag e'
6103
+ * la fonte di verita', extraProps e' la proiezione runtime).
6104
+ * @param dsBinding il binding gia' idratato (`{uniqueName, component: BehaviorSubject<DataSourceComponent>}`)
6105
+ * @param action l'archetipo (chart/map/scheduler/kanban/tree/carousel/spreadsheet/...)
6106
+ * @param config oggetto config = contenuto di archetypes.<action>
6107
+ */
6108
+ /**
6109
+ * Applica `archetype_config` (dal nodo designer_inject) a un DATAREPEATER tool
6110
+ * APPENA droppato, posticipando finche' il DataSourceComponent bindato e'
6111
+ * materializzato (`fetchData` disponibile). Poi delega ad
6112
+ * {@link applyArchetypeConfigToTool} — il path proven del configuratore.
6113
+ */
6114
+ deferApplyArchetypeConfig(tool, action, config) {
6115
+ if (!tool || !action || !config || typeof config !== 'object')
6116
+ return;
6117
+ let tries = 0;
6118
+ const attempt = () => {
6119
+ const ds = tool.inputs?.['datasource']?.component?.value;
6120
+ if (ds && typeof ds.fetchData === 'function') {
6121
+ try {
6122
+ this.applyArchetypeConfigToTool(tool, action, config);
6123
+ }
6124
+ catch (e) {
6125
+ try {
6126
+ console.warn('[deferApplyArchetypeConfig] apply failed', e);
6127
+ }
6128
+ catch { /* */ }
6129
+ }
6130
+ return;
6131
+ }
6132
+ if (tries++ < 60)
6133
+ setTimeout(attempt, 200); // ~12s max per la materializzazione del ds
6134
+ };
6135
+ attempt();
6136
+ }
6095
6137
  async injectLayoutNode(node, parentUniqueName) {
6096
6138
  const toolName = String(node?.tool_name || '').trim();
6097
6139
  if (!toolName)
@@ -6365,6 +6407,25 @@ class DesignerComponent {
6365
6407
  }
6366
6408
  catch { /* ignore */ }
6367
6409
  }
6410
+ // CONFIG ARCHETIPO INLINE: il nodo puo' portare `archetype_config`
6411
+ // (= md_props_bag.archetypes.<action> JSON, es. chart {type,options,
6412
+ // dataOptions}, map {zoom,center,...}, scheduler {fromField,...},
6413
+ // kanban {statusField,statusColumns,...}). NESSUNA chiamata server: la
6414
+ // config viene scritta nel metaInfo.tableMetadata del DATASOURCE bindato
6415
+ // (md_props_bag + extraProps.archetypes); il DATAREPEATER reagisce via
6416
+ // fetchInfo$ e renderizza l'archetipo configurato. Persiste alla
6417
+ // serializzazione del datasource quando si salva la dashboard.
6418
+ const archCfg = (node && (node.archetype_config || node.archetypeConfig))
6419
+ || (node?.inputs && (node.inputs.archetype_config || node.inputs.archetypeConfig))
6420
+ || null;
6421
+ if (archCfg && typeof archCfg === 'object') {
6422
+ // Defer: il DataSourceComponent bindato (e l'archetipo renderizzato) si
6423
+ // materializzano async dopo il drop. Aspetta che il ds sia pronto
6424
+ // (fetchData disponibile), poi applica via il path PROVEN del configuratore
6425
+ // (`applyArchetypeConfigToTool`: customProps_<action> + metaInfo + ds.fetchData
6426
+ // + propertyTreeBuilder) — lo STESSO usato da "Configura chart".
6427
+ this.deferApplyArchetypeConfig(justInjected, String(action), archCfg);
6428
+ }
6368
6429
  }
6369
6430
  }
6370
6431
  let count = 1;
@@ -9230,6 +9291,22 @@ class DesignerComponent {
9230
9291
  this.closeArchetypeConfigurator();
9231
9292
  return;
9232
9293
  }
9294
+ this.applyArchetypeConfigToTool(tool, action, nextConfig);
9295
+ this.closeArchetypeConfigurator();
9296
+ }
9297
+ /**
9298
+ * Core riusabile di {@link onArchetypeConfigApply}: applica la config di
9299
+ * archetipo a un DATAREPEATER tool. Scrive `customProps_<action>` sulle
9300
+ * proprietà del tool (= ciò che il chatbot designer_inject persiste e l'archetipo
9301
+ * legge), aggiorna `metaInfo.tableMetadata.extraProps`+`md_props_bag`, e RIGENERA
9302
+ * il render chiamando `ds.fetchData()` (re-emit `fetchInfo$` → l'archetipo
9303
+ * ri-legge type/opzioni) + `propertyTreeBuilder`. NESSUNA chiamata server.
9304
+ * Usato sia dal configuratore UI ("Configura chart") sia dall'injection del
9305
+ * chatbot (drop di un DATAREPEATER con `archetype_config`).
9306
+ */
9307
+ applyArchetypeConfigToTool(tool, action, nextConfig) {
9308
+ if (!tool || !action || !nextConfig)
9309
+ return;
9233
9310
  const customKey = 'customProps_' + action;
9234
9311
  tool.inputs[customKey] = this.toBehaviorSubjectsObject(nextConfig);
9235
9312
  const metaInfo = this.getDesignerDatasourceMetaInfo(tool);
@@ -9246,7 +9323,6 @@ class DesignerComponent {
9246
9323
  ds.fetchData();
9247
9324
  }
9248
9325
  this.propertyTreeBuilder(action, tool.inputs);
9249
- this.closeArchetypeConfigurator();
9250
9326
  }
9251
9327
  /**
9252
9328
  * Espone i metadati datasource al popup configuratore archetype.
@@ -11857,4 +11933,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
11857
11933
  }] } });
11858
11934
 
11859
11935
  export { DesignerComponent };
11860
- //# sourceMappingURL=wuic-framework-lib-designer.component-N_CfbGnr.mjs.map
11936
+ //# sourceMappingURL=wuic-framework-lib-designer.component-DA7abiLW.mjs.map
@@ -4,6 +4,9 @@ import * as i1$2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/forms';
6
6
  import { FormsModule } from '@angular/forms';
7
+ import * as i1 from '@angular/common/http';
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';
7
10
  import { firstValueFrom } from 'rxjs';
8
11
  import * as i8 from '@ngx-translate/core';
9
12
  import { TranslateModule } from '@ngx-translate/core';
@@ -17,8 +20,6 @@ import * as i6$1 from 'primeng/tooltip';
17
20
  import { TooltipModule } from 'primeng/tooltip';
18
21
  import * as i2 from 'primeng/dialog';
19
22
  import { DialogModule } from 'primeng/dialog';
20
- import { G as GlobalHandler, W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-Deudd4MY.mjs';
21
- import * as i1 from '@angular/common/http';
22
23
  import * as i3 from 'primeng/api';
23
24
 
24
25
  /**
@@ -412,13 +413,12 @@ class WuicFirstRunWizardComponent {
412
413
  const apiBase = WtoolboxService.appSettings?.api_url || '';
413
414
  const globalRoot = WtoolboxService.appSettings?.global_root_url || '';
414
415
  try {
415
- const authenticated = await this.isAuthenticatedQuickly();
416
- if (authenticated) {
417
- this.showFirstRunInstall = false;
418
- this.complete.emit();
419
- return;
420
- }
421
- const publicStatus = await firstValueFrom(this.http.get(`${apiBase}Meta/FirstRunStatus`));
416
+ // firstRun VINCE sull'auth: su una prima installazione genuina il (nuovo) DB
417
+ // metadati non ha utenti legittimi, quindi un cookie/sessione residua
418
+ // (`Auth/Me` -> authenticated=true) NON deve dirottare l'app sul login saltando
419
+ // il wizard. La decisione si basa SOLO su FirstRunStatus; l'eventuale stato di
420
+ // auth e' irrilevante (quando firstRun=false il wizard si salta comunque sotto).
421
+ const publicStatus = await firstValueFrom(this.http.get(`${apiBase}Meta/FirstRunStatus`, this.suppressGlobalErrorOpts()));
422
422
  const settings = this.parseDictionaryResponse(publicStatus);
423
423
  const firstRunSetting = settings['firstRun'] ?? settings['first-run'] ?? settings['firstrun'];
424
424
  const isFirstRun = this.toBoolean(firstRunSetting);
@@ -440,7 +440,7 @@ class WuicFirstRunWizardComponent {
440
440
  }
441
441
  // Filter DBMS dropdown to providers actually deployed.
442
442
  try {
443
- const availableResp = await firstValueFrom(this.http.get(`${apiBase}Meta/AvailableDbms`));
443
+ const availableResp = await firstValueFrom(this.http.get(`${apiBase}Meta/AvailableDbms`, this.suppressGlobalErrorOpts()));
444
444
  const availableList = availableResp?.dbms || [];
445
445
  if (Array.isArray(availableList) && availableList.length > 0) {
446
446
  const filtered = availableList.map(entry => {
@@ -466,7 +466,7 @@ class WuicFirstRunWizardComponent {
466
466
  catch {
467
467
  // Legacy fallback for environments where Meta/FirstRunStatus is unavailable.
468
468
  try {
469
- const appSettingsResponse = await firstValueFrom(this.http.post(`${globalRoot}MetaService.getAppSettings`, {}));
469
+ const appSettingsResponse = await firstValueFrom(this.http.post(`${globalRoot}MetaService.getAppSettings`, {}, this.suppressGlobalErrorOpts()));
470
470
  const settings = this.parseDictionaryResponse(appSettingsResponse);
471
471
  const firstRunSetting = settings['firstRun'] ?? settings['first-run'] ?? settings['firstrun'];
472
472
  const isFirstRun = this.toBoolean(firstRunSetting);
@@ -492,19 +492,6 @@ class WuicFirstRunWizardComponent {
492
492
  this.firstRunLoading = false;
493
493
  }
494
494
  }
495
- async isAuthenticatedQuickly() {
496
- const apiBase = WtoolboxService.appSettings?.api_url || '';
497
- try {
498
- const me = await Promise.race([
499
- firstValueFrom(this.http.get(`${apiBase}Auth/Me`, { withCredentials: true })),
500
- new Promise((resolve) => setTimeout(() => resolve(null), 750))
501
- ]);
502
- return !!me?.authenticated;
503
- }
504
- catch {
505
- return false;
506
- }
507
- }
508
495
  async loadDefaultConnectionString(settings) {
509
496
  const fallbackConn = String(settings['connection'] || '').trim();
510
497
  const fallbackDb = String(settings['DataDBName'] || settings['datadbname'] || '').trim();
@@ -622,20 +609,30 @@ class WuicFirstRunWizardComponent {
622
609
  this.firstRunConnectionValid = false;
623
610
  this.firstRunDataDbOptions = [];
624
611
  this.firstRunError = detail;
625
- this.messageService.add({ severity: 'error', summary: 'Connessione non valida', detail });
612
+ // Errore mostrato SOLO inline nel form (firstRunError): niente toast ne
613
+ // dialog globale (le chiamate usano suppressGlobalErrorOpts()).
626
614
  }
627
615
  finally {
628
616
  this.firstRunDbLoading = false;
629
617
  this.firstRunConnectionTesting = false;
630
618
  }
631
619
  }
620
+ /**
621
+ * Opzioni HTTP che sopprimono il dialog/handler globale (`GlobalHandler`)
622
+ * per le chiamate del first-run wizard. Gli errori dell'installer vengono
623
+ * mostrati SOLO inline nel form (`firstRunError`) — niente popup dialog
624
+ * (interceptor) ne toast. Vedi WUIC_SUPPRESS_GLOBAL_ERROR.
625
+ */
626
+ suppressGlobalErrorOpts() {
627
+ return { context: new HttpContext().set(WUIC_SUPPRESS_GLOBAL_ERROR, true) };
628
+ }
632
629
  async fetchDatabaseNames(dbms, baseConnection) {
633
630
  const globalRoot = WtoolboxService.appSettings?.global_root_url || '';
634
631
  const endpoint = `${globalRoot}MetaService.get_database_names`;
635
632
  const payload = await firstValueFrom(this.http.post(endpoint, {
636
633
  rdbDBMS: dbms,
637
634
  connectionString: baseConnection
638
- }));
635
+ }, this.suppressGlobalErrorOpts()));
639
636
  return this.parseStringArrayResponse(payload)
640
637
  .map(x => String(x || '').trim())
641
638
  .filter(x => !!x);
@@ -741,7 +738,7 @@ class WuicFirstRunWizardComponent {
741
738
  // sezione resta a Enabled=false e l'utente potra' attivarla in
742
739
  // seguito dall'appsettings-editor (Commit 9).
743
740
  enableCrashReporting: this.firstRunForm.enableCrashReporting ? 'true' : 'false'
744
- }));
741
+ }, this.suppressGlobalErrorOpts()));
745
742
  // STOP polling FirstRunProgress NOW — `configure_wuic` ha appena riscritto
746
743
  // `appsettings.json` (firstRun=false + nuove ConnectionStrings). IIS rileva
747
744
  // il file change via FileSystemWatcher e recyclia l'app pool. Se il polling
@@ -753,6 +750,11 @@ class WuicFirstRunWizardComponent {
753
750
  // esattamente la finestra di shutdown→restart pool).
754
751
  this.stopFirstRunProgressPolling();
755
752
  await this.clearClientStateForFirstRunLogin();
753
+ // I servizi notifiche (WS `/ws/notifications` + watcher) sono registrati SEMPRE
754
+ // dal backend (anche durante il first-run) e partono in polling resiliente che
755
+ // rilegge la connection FRESH -> nessun restart necessario qui: appena
756
+ // configure_wuic scrive la connection reale + crea lo schema, il push si aggancia.
757
+ // Vedi Startup.cs (registrazione sempre attiva) e NotificationSqlDependencyWatcher.
756
758
  await this.waitForBackendReady();
757
759
  const scaffoldRoute = '/scaffolding/dialog/1556';
758
760
  const loginRedirectUrl = `/?redirect=${encodeURIComponent(scaffoldRoute)}&firstRunLogin=1`;
@@ -762,14 +764,18 @@ class WuicFirstRunWizardComponent {
762
764
  }
763
765
  catch (error) {
764
766
  this.firstRunError = this.extractErrorMessage(error);
765
- // Branch METADATA_DB_EXISTS gestito dal delegate registrato in ngOnInit
766
- // (`metadataDbExistsDelegateDisposer`): mostra prompt + ri-chiama
767
- // `submitFirstRunInstallInternal(true)`. Qui sotto saltiamo solo il toast
768
- // generico in quel caso specifico, per evitare duplicati col prompt.
767
+ // Branch METADATA_DB_EXISTS: il server chiede conferma di drop+recreate del
768
+ // metadata DB esistente. Le chiamate del wizard sopprimono il GlobalHandler
769
+ // (errore solo inline), quindi il delegate registrato in ngOnInit NON scatta
770
+ // piu' -> mostriamo il prompt di conferma DIRETTAMENTE qui. La guard
771
+ // `metadataDbExistsPromptInFlight` dentro handleMetadataDbExistsPrompt evita
772
+ // doppi prompt se il delegate dovesse comunque scattare.
769
773
  if (!confirmDropExistingMetadataDb && this.firstRunError.includes('METADATA_DB_EXISTS_CONFIRM_REQUIRED')) {
774
+ void this.handleMetadataDbExistsPrompt({ message: this.firstRunError });
770
775
  return;
771
776
  }
772
- this.messageService.add({ severity: 'error', summary: 'Installazione fallita', detail: this.firstRunError });
777
+ // Errore mostrato SOLO inline nel form (firstRunError): niente toast ne
778
+ // dialog globale (configure_wuic usa suppressGlobalErrorOpts()).
773
779
  }
774
780
  finally {
775
781
  this.firstRunInstalling = false;
@@ -796,7 +802,7 @@ class WuicFirstRunWizardComponent {
796
802
  const apiBase = WtoolboxService.appSettings?.api_url || '';
797
803
  this.firstRunProgressTimer = setInterval(async () => {
798
804
  try {
799
- const resp = await firstValueFrom(this.http.get(`${apiBase}Meta/FirstRunProgress`));
805
+ const resp = await firstValueFrom(this.http.get(`${apiBase}Meta/FirstRunProgress`, this.suppressGlobalErrorOpts()));
800
806
  if (resp && typeof resp === 'object') {
801
807
  this.firstRunProgress = {
802
808
  active: !!resp.active,
@@ -847,7 +853,7 @@ class WuicFirstRunWizardComponent {
847
853
  await new Promise((resolve) => setTimeout(resolve, 500));
848
854
  while (Date.now() - startedAt < timeoutMs) {
849
855
  try {
850
- await firstValueFrom(this.http.get(sentinelUrl));
856
+ await firstValueFrom(this.http.get(sentinelUrl, this.suppressGlobalErrorOpts()));
851
857
  return;
852
858
  }
853
859
  catch {
@@ -1076,7 +1082,7 @@ class WuicFirstRunWizardComponent {
1076
1082
  extractErrorMessage(error) {
1077
1083
  const fromBackend = error?.error;
1078
1084
  if (typeof fromBackend === 'string' && fromBackend.trim())
1079
- return fromBackend;
1085
+ return this.cleanServerErrorMessage(fromBackend);
1080
1086
  if (fromBackend && typeof fromBackend === 'object') {
1081
1087
  const parts = [];
1082
1088
  const detail = fromBackend.message || fromBackend.error || fromBackend.title;
@@ -1102,9 +1108,43 @@ class WuicFirstRunWizardComponent {
1102
1108
  parts.push(String(fallbackMsg));
1103
1109
  }
1104
1110
  if (parts.length > 0)
1105
- return parts.join(' | ');
1111
+ return this.cleanServerErrorMessage(parts.join(' | '));
1112
+ }
1113
+ return this.cleanServerErrorMessage(String(error?.message || 'Errore sconosciuto durante il first-run setup.'));
1114
+ }
1115
+ /**
1116
+ * Ripulisce il wrapper grezzo dell'AsmxProxy dispatcher mostrando SOLO il
1117
+ * messaggio dell'eccezione interna piu' profonda. Il backend, quando una
1118
+ * invocazione `MetaService.*` fallisce, rilancia un messaggio verboso del
1119
+ * tipo:
1120
+ * AsmxProxy invocation failed. Requested='MetaService.get_database_names',
1121
+ * Current='ok', ... Methods='...', Parameters='...'.
1122
+ * Inner='System.InvalidOperationException: Errore test connessione/lista
1123
+ * database: Errore dell'istanza.'
1124
+ * Di tutto questo l'utente vuole solo la parte utile -> qui estraiamo il
1125
+ * contenuto dell'ultimo `Inner='...'` e togliamo il prefisso del tipo
1126
+ * eccezione .NET (es. `System.InvalidOperationException: `). Se il messaggio
1127
+ * non e' un dump AsmxProxy lo lasciamo invariato. Preserva eventuali marker
1128
+ * (es. METADATA_DB_EXISTS_CONFIRM_REQUIRED) che cosi' diventano anzi piu'
1129
+ * facili da matchare (non piu' sepolti nel dump).
1130
+ */
1131
+ cleanServerErrorMessage(raw) {
1132
+ const original = String(raw || '').trim();
1133
+ let msg = original;
1134
+ if (!msg)
1135
+ return msg;
1136
+ // Scarta progressivamente i wrapper `Inner='...'` fino all'eccezione piu'
1137
+ // interna (guard anti-loop). Greedy: l'apostrofo dentro al messaggio (es.
1138
+ // "dell'istanza") resta incluso, la cattura arriva fino all'ultima quote.
1139
+ let m;
1140
+ let guard = 0;
1141
+ while ((m = msg.match(/Inner='([\s\S]*)'/)) !== null && guard++ < 6) {
1142
+ msg = m[1].trim();
1106
1143
  }
1107
- return String(error?.message || 'Errore sconosciuto durante il first-run setup.');
1144
+ // Togli il prefisso fully-qualified del tipo eccezione .NET
1145
+ // (es. "System.InvalidOperationException: " / "System.Data.SqlClient.SqlException: ").
1146
+ msg = msg.replace(/^(?:[A-Za-z_][\w]*\.)+[A-Za-z_]\w*(?:Exception|Error)\s*:\s*/, '').trim();
1147
+ return msg || original;
1108
1148
  }
1109
1149
  // ════════════════════════════════════════════════════════════════════════
1110
1150
  // I18N BUNDLES (firstrun.* keys)
@@ -1273,4 +1313,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1273
1313
  }] } });
1274
1314
 
1275
1315
  export { WuicFirstRunWizardComponent };
1276
- //# sourceMappingURL=wuic-framework-lib-first-run-wizard.component-lW7-xMm3.mjs.map
1316
+ //# sourceMappingURL=wuic-framework-lib-first-run-wizard.component-BLrUrfZ9.mjs.map