@esfaenza/flow-builder 20.3.7 → 20.3.8

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.
@@ -1259,12 +1259,74 @@ const BUCKET_BY_NAME = new Map([
1259
1259
  ['trace', 'Info'],
1260
1260
  ['verbose', 'Info'],
1261
1261
  ]);
1262
- /** Un livello sconosciuto e' una nota: si mostra, non si nasconde. */
1262
+ /**
1263
+ * L'enum serializzato come **numero**, nell'ordine di dichiarazione di
1264
+ * `FlowValidationSeverity` lato backend: `Info = 0, Warning = 1, Error = 2` — gravita'
1265
+ * crescente, non decrescente. L'ordine non e' intuibile e sbagliarlo e' silenzioso al
1266
+ * contrario (un errore mostrato come nota), quindi qui vale solo questo elenco.
1267
+ *
1268
+ * Il contratto vuole i **nomi** (§7): la libreria C# registra uno `StringEnumConverter`
1269
+ * proprio per questo. Un host che serializza con impostazioni proprie manda i numeri — questa
1270
+ * mappa e' la rete, non la strada giusta: la cura sta nel converter lato backend.
1271
+ */
1272
+ const BUCKET_BY_ORDINAL = ['Info', 'Warning', 'Error'];
1273
+ /**
1274
+ * Il valore inatteso si segnala **una volta per forma**, non a ogni rilievo: la validazione
1275
+ * ricalcola in continuazione e un warn per rilievo renderebbe la console illeggibile.
1276
+ */
1277
+ const REPORTED_UNEXPECTED = new Set();
1278
+ /**
1279
+ * Un livello sconosciuto e' una nota: si mostra, non si nasconde.
1280
+ *
1281
+ * Il parametro e' `unknown` di proposito: `FlowIssueSeverity` promette una stringa, ma il tipo
1282
+ * e' aperto perche' il backend decide i livelli (§13.11) e in un ambiente reale e' arrivato un
1283
+ * valore che **non** era una stringa — `severity.trim is not a function`. Un `TypeError` qui
1284
+ * uccide il `computed` dei conteggi e con esso l'intero pannello dei problemi, quindi la
1285
+ * normalizzazione accetta qualunque forma e non lancia mai.
1286
+ */
1263
1287
  function severityBucket(severity) {
1264
- if (!severity) {
1265
- return 'Info';
1288
+ return severityBucketOf(severity) ?? 'Info';
1289
+ }
1290
+ function severityBucketOf(severity, depth = 0) {
1291
+ if (severity === null || severity === undefined) {
1292
+ return null;
1266
1293
  }
1267
- return BUCKET_BY_NAME.get(severity?.trim().toLowerCase()) ?? 'Info';
1294
+ if (typeof severity === 'string') {
1295
+ const name = severity.trim().toLowerCase();
1296
+ if (!name) {
1297
+ return null;
1298
+ }
1299
+ // Anche una stringa puo' portare il numero dell'enum ("1"): si prova prima per nome. Un
1300
+ // nome nuovo non si segnala — il backend puo' aggiungerne (§13.11) e cadere in `Info` e'
1301
+ // il comportamento previsto, non un difetto da mostrare in console.
1302
+ return BUCKET_BY_NAME.get(name) ?? bucketByOrdinal(Number(name));
1303
+ }
1304
+ if (typeof severity === 'number' || typeof severity === 'bigint') {
1305
+ return bucketByOrdinal(Number(severity)) ?? unexpected(severity, `number:${severity}`);
1306
+ }
1307
+ // `{ name, value }`, `{ severity }`, `{ level }`: si scende una volta sola sul primo campo
1308
+ // riconoscibile — oltre non e' piu' normalizzazione, e' indovinare.
1309
+ if (typeof severity === 'object' && depth === 0) {
1310
+ const box = severity;
1311
+ for (const key of ['name', 'severity', 'level', 'label', 'code', 'value']) {
1312
+ const bucket = severityBucketOf(box[key], depth + 1);
1313
+ if (bucket) {
1314
+ return bucket;
1315
+ }
1316
+ }
1317
+ }
1318
+ return unexpected(severity, `${typeof severity}`);
1319
+ }
1320
+ function bucketByOrdinal(value) {
1321
+ return Number.isInteger(value) ? (BUCKET_BY_ORDINAL[value] ?? null) : null;
1322
+ }
1323
+ /** Nessun secchio riconosciuto: si dice **cosa** e' arrivato, poi si cade su `Info`. */
1324
+ function unexpected(severity, key) {
1325
+ if (!REPORTED_UNEXPECTED.has(key)) {
1326
+ REPORTED_UNEXPECTED.add(key);
1327
+ console.warn('[flow-builder] gravita’ di rilievo non riconosciuta, trattata come nota:', severity);
1328
+ }
1329
+ return null;
1268
1330
  }
1269
1331
  /** L'ordine in cui si presentano: prima cio' che blocca l'attivazione. */
1270
1332
  const SEVERITY_BUCKETS = ['Error', 'Warning', 'Info'];
@@ -4116,11 +4178,11 @@ class ObjectPickerComponent {
4116
4178
  return parts.join(' · ');
4117
4179
  }
4118
4180
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: ObjectPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4119
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: ObjectPickerComponent, isStandalone: true, selector: "fb-object-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra gli oggetti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Questo nome non e\u2019 fra gli oggetti disponibili: la validazione lo segnalerebbe.\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\r\n </p>\r\n }\r\n @for (object of options(); track object.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"object.name === value()\"\r\n (click)=\"choose(object)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ object.name }}</span>\r\n @if (describe(object)) {\r\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4181
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: ObjectPickerComponent, isStandalone: true, selector: "fb-object-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra gli oggetti disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Questo nome non e\u2019 fra gli oggetti disponibili: la validazione lo segnalerebbe.\n </p>\n } @else if (labelOfValue()) {\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\n </p>\n }\n @for (object of options(); track object.name) {\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"object.name === value()\"\n (click)=\"choose(object)\"\n >\n <span class=\"fb-pick__name\">{{ object.name }}</span>\n @if (describe(object)) {\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\n }\n </button>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4120
4182
  }
4121
4183
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: ObjectPickerComponent, decorators: [{
4122
4184
  type: Component,
4123
- args: [{ selector: 'fb-object-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra gli oggetti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Questo nome non e\u2019 fra gli oggetti disponibili: la validazione lo segnalerebbe.\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\r\n </p>\r\n }\r\n @for (object of options(); track object.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"object.name === value()\"\r\n (click)=\"choose(object)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ object.name }}</span>\r\n @if (describe(object)) {\r\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4185
+ args: [{ selector: 'fb-object-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra gli oggetti disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Questo nome non e\u2019 fra gli oggetti disponibili: la validazione lo segnalerebbe.\n </p>\n } @else if (labelOfValue()) {\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\n </p>\n }\n @for (object of options(); track object.name) {\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"object.name === value()\"\n (click)=\"choose(object)\"\n >\n <span class=\"fb-pick__name\">{{ object.name }}</span>\n @if (describe(object)) {\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\n }\n </button>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4124
4186
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
4125
4187
 
4126
4188
  /**
@@ -4286,11 +4348,11 @@ class FieldPickerComponent {
4286
4348
  return describePathEntry(entry);
4287
4349
  }
4288
4350
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: FieldPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4289
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: FieldPickerComponent, isStandalone: true, selector: "fb-field-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null }, usage: { classPropertyName: "usage", publicName: "usage", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i campi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\r\n } @else if (isNotVerifiable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (prefix()) {\r\n <p class=\"fb-pick__group\">Campi di {{ levelLabel() }}</p>\r\n }\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!object()) {\r\n Scegli prima un oggetto.\r\n } @else {\r\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\r\n }\r\n </p>\r\n }\r\n @for (entry of options(); track entry.name) {\r\n <div class=\"fb-pick__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\r\n (click)=\"choose(entry)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\r\n @if (describe(entry)) {\r\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\r\n }\r\n </button>\r\n @if (canDescend(entry)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__into\"\r\n [attr.aria-label]=\"'Entra in ' + entry.name\"\r\n title=\"Entra nella relazione\"\r\n (click)=\"descend(entry)\"\r\n >\r\n \u203A\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4351
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: FieldPickerComponent, isStandalone: true, selector: "fb-field-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null }, usage: { classPropertyName: "usage", publicName: "usage", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i campi disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\n } @else if (isNotVerifiable()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\n } @else if (describeValue()) {\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (prefix()) {\n <p class=\"fb-pick__group\">Campi di {{ levelLabel() }}</p>\n }\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n @if (!object()) {\n Scegli prima un oggetto.\n } @else {\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\n }\n </p>\n }\n @for (entry of options(); track entry.name) {\n <div class=\"fb-pick__row\">\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\n (click)=\"choose(entry)\"\n >\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\n @if (describe(entry)) {\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\n }\n </button>\n @if (canDescend(entry)) {\n <button\n type=\"button\"\n class=\"fb-pick__into\"\n [attr.aria-label]=\"'Entra in ' + entry.name\"\n title=\"Entra nella relazione\"\n (click)=\"descend(entry)\"\n >\n \u203A\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4290
4352
  }
4291
4353
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: FieldPickerComponent, decorators: [{
4292
4354
  type: Component,
4293
- args: [{ selector: 'fb-field-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i campi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\r\n } @else if (isNotVerifiable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (prefix()) {\r\n <p class=\"fb-pick__group\">Campi di {{ levelLabel() }}</p>\r\n }\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!object()) {\r\n Scegli prima un oggetto.\r\n } @else {\r\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\r\n }\r\n </p>\r\n }\r\n @for (entry of options(); track entry.name) {\r\n <div class=\"fb-pick__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\r\n (click)=\"choose(entry)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\r\n @if (describe(entry)) {\r\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\r\n }\r\n </button>\r\n @if (canDescend(entry)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__into\"\r\n [attr.aria-label]=\"'Entra in ' + entry.name\"\r\n title=\"Entra nella relazione\"\r\n (click)=\"descend(entry)\"\r\n >\r\n \u203A\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4355
+ args: [{ selector: 'fb-field-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i campi disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\n } @else if (isNotVerifiable()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\n } @else if (describeValue()) {\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (prefix()) {\n <p class=\"fb-pick__group\">Campi di {{ levelLabel() }}</p>\n }\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n @if (!object()) {\n Scegli prima un oggetto.\n } @else {\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\n }\n </p>\n }\n @for (entry of options(); track entry.name) {\n <div class=\"fb-pick__row\">\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\n (click)=\"choose(entry)\"\n >\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\n @if (describe(entry)) {\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\n }\n </button>\n @if (canDescend(entry)) {\n <button\n type=\"button\"\n class=\"fb-pick__into\"\n [attr.aria-label]=\"'Entra in ' + entry.name\"\n title=\"Entra nella relazione\"\n (click)=\"descend(entry)\"\n >\n \u203A\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4294
4356
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], object: [{ type: i0.Input, args: [{ isSignal: true, alias: "object", required: false }] }], usage: [{ type: i0.Input, args: [{ isSignal: true, alias: "usage", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
4295
4357
 
4296
4358
  /**
@@ -4396,11 +4458,11 @@ class NamePickerComponent {
4396
4458
  return parts.join(' · ');
4397
4459
  }
4398
4460
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: NamePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4399
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: NamePickerComponent, isStandalone: true, selector: "fb-name-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, unknownMessage: { classPropertyName: "unknownMessage", publicName: "unknownMessage", isSignal: true, isRequired: false, transformFunction: null }, unknownSeverity: { classPropertyName: "unknownSeverity", publicName: "unknownSeverity", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, isMono: { classPropertyName: "isMono", publicName: "isMono", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n [class.fb-pick__input--mono]=\"isMono()\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i nomi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p\r\n class=\"fb-pick__hint\"\r\n [class.fb-pick__hint--warn]=\"unknownSeverity() === 'warn'\"\r\n [class.fb-pick__hint--error]=\"unknownSeverity() === 'error'\"\r\n >\r\n {{ unknownMessage() }}\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (!hasOptions()) {\r\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (visibleOptions().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\r\n </p>\r\n }\r\n @for (option of visibleOptions(); track option.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"option.name === value()\"\r\n (click)=\"choose(option)\"\r\n >\r\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\r\n @if (describe(option)) {\r\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: NamePickerComponent, isStandalone: true, selector: "fb-name-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, unknownMessage: { classPropertyName: "unknownMessage", publicName: "unknownMessage", isSignal: true, isRequired: false, transformFunction: null }, unknownSeverity: { classPropertyName: "unknownSeverity", publicName: "unknownSeverity", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, isMono: { classPropertyName: "isMono", publicName: "isMono", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n [class.fb-pick__input--mono]=\"isMono()\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i nomi disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p\n class=\"fb-pick__hint\"\n [class.fb-pick__hint--warn]=\"unknownSeverity() === 'warn'\"\n [class.fb-pick__hint--error]=\"unknownSeverity() === 'error'\"\n >\n {{ unknownMessage() }}\n </p>\n } @else if (labelOfValue()) {\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\n } @else if (!hasOptions()) {\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (visibleOptions().length === 0) {\n <p class=\"fb-pick__empty\">\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\n </p>\n }\n @for (option of visibleOptions(); track option.name) {\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"option.name === value()\"\n (click)=\"choose(option)\"\n >\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\n @if (describe(option)) {\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\n }\n </button>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4400
4462
  }
4401
4463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: NamePickerComponent, decorators: [{
4402
4464
  type: Component,
4403
- args: [{ selector: 'fb-name-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n [class.fb-pick__input--mono]=\"isMono()\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i nomi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p\r\n class=\"fb-pick__hint\"\r\n [class.fb-pick__hint--warn]=\"unknownSeverity() === 'warn'\"\r\n [class.fb-pick__hint--error]=\"unknownSeverity() === 'error'\"\r\n >\r\n {{ unknownMessage() }}\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (!hasOptions()) {\r\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (visibleOptions().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\r\n </p>\r\n }\r\n @for (option of visibleOptions(); track option.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"option.name === value()\"\r\n (click)=\"choose(option)\"\r\n >\r\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\r\n @if (describe(option)) {\r\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4465
+ args: [{ selector: 'fb-name-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n [class.fb-pick__input--mono]=\"isMono()\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i nomi disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isUnknown()) {\n <p\n class=\"fb-pick__hint\"\n [class.fb-pick__hint--warn]=\"unknownSeverity() === 'warn'\"\n [class.fb-pick__hint--error]=\"unknownSeverity() === 'error'\"\n >\n {{ unknownMessage() }}\n </p>\n } @else if (labelOfValue()) {\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\n } @else if (!hasOptions()) {\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (visibleOptions().length === 0) {\n <p class=\"fb-pick__empty\">\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\n </p>\n }\n @for (option of visibleOptions(); track option.name) {\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"option.name === value()\"\n (click)=\"choose(option)\"\n >\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\n @if (describe(option)) {\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\n }\n </button>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4404
4466
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], unknownMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "unknownMessage", required: false }] }], unknownSeverity: [{ type: i0.Input, args: [{ isSignal: true, alias: "unknownSeverity", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], isMono: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMono", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
4405
4467
 
4406
4468
  /**
@@ -4438,18 +4500,18 @@ class StructurePickerComponent {
4438
4500
  description: entry.description ?? null,
4439
4501
  })), ...(ngDevMode ? [{ debugName: "options" }] : []));
4440
4502
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StructurePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4441
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.27", type: StructurePickerComponent, isStandalone: true, selector: "fb-structure-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
4442
- <fb-name-picker
4443
- [value]="value()"
4444
- [options]="options()"
4445
- [label]="label()"
4446
- [placeholder]="placeholder()"
4447
- [disabled]="disabled()"
4448
- unknownSeverity="error"
4449
- unknownMessage="Questa classe non e’ fra quelle utilizzabili (STRUCTURE_TYPE_UNKNOWN)."
4450
- emptyMessage="Elenco delle classi non disponibile: puoi scrivere il nome a mano."
4451
- (valueChange)="valueChange.emit($event)"
4452
- />
4503
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.27", type: StructurePickerComponent, isStandalone: true, selector: "fb-structure-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
4504
+ <fb-name-picker
4505
+ [value]="value()"
4506
+ [options]="options()"
4507
+ [label]="label()"
4508
+ [placeholder]="placeholder()"
4509
+ [disabled]="disabled()"
4510
+ unknownSeverity="error"
4511
+ unknownMessage="Questa classe non e’ fra quelle utilizzabili (STRUCTURE_TYPE_UNKNOWN)."
4512
+ emptyMessage="Elenco delle classi non disponibile: puoi scrivere il nome a mano."
4513
+ (valueChange)="valueChange.emit($event)"
4514
+ />
4453
4515
  `, isInline: true, dependencies: [{ kind: "component", type: NamePickerComponent, selector: "fb-name-picker", inputs: ["value", "options", "label", "placeholder", "disabled", "unknownMessage", "unknownSeverity", "emptyMessage", "isMono"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4454
4516
  }
4455
4517
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StructurePickerComponent, decorators: [{
@@ -4459,18 +4521,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImpo
4459
4521
  standalone: true,
4460
4522
  imports: [NamePickerComponent],
4461
4523
  changeDetection: ChangeDetectionStrategy.OnPush,
4462
- template: `
4463
- <fb-name-picker
4464
- [value]="value()"
4465
- [options]="options()"
4466
- [label]="label()"
4467
- [placeholder]="placeholder()"
4468
- [disabled]="disabled()"
4469
- unknownSeverity="error"
4470
- unknownMessage="Questa classe non e’ fra quelle utilizzabili (STRUCTURE_TYPE_UNKNOWN)."
4471
- emptyMessage="Elenco delle classi non disponibile: puoi scrivere il nome a mano."
4472
- (valueChange)="valueChange.emit($event)"
4473
- />
4524
+ template: `
4525
+ <fb-name-picker
4526
+ [value]="value()"
4527
+ [options]="options()"
4528
+ [label]="label()"
4529
+ [placeholder]="placeholder()"
4530
+ [disabled]="disabled()"
4531
+ unknownSeverity="error"
4532
+ unknownMessage="Questa classe non e’ fra quelle utilizzabili (STRUCTURE_TYPE_UNKNOWN)."
4533
+ emptyMessage="Elenco delle classi non disponibile: puoi scrivere il nome a mano."
4534
+ (valueChange)="valueChange.emit($event)"
4535
+ />
4474
4536
  `,
4475
4537
  }]
4476
4538
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
@@ -4669,11 +4731,11 @@ class StructureMemberPickerComponent {
4669
4731
  return describePathEntry(entry, { showWritability: this.usage() === 'writable' });
4670
4732
  }
4671
4733
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StructureMemberPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4672
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: StructureMemberPickerComponent, isStandalone: true, selector: "fb-structure-member-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, usage: { classPropertyName: "usage", publicName: "usage", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i membri disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isClassUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">\r\n La classe {{ className() }} non e\u2019 registrata (STRUCTURE_TYPE_UNKNOWN): correggi la classe,\r\n non il membro.\r\n </p>\r\n } @else if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ unknownMessage() }}</p>\r\n } @else if (isNotWritable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ notWritableMessage() }}</p>\r\n } @else if (isUndeclared()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n {{ classLabel() }} non dichiara i suoi membri: scrivi il nome a mano, non e\u2019 verificabile.\r\n </p>\r\n } @else if (isNotVerifiable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei membri non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (className()) {\r\n <p class=\"fb-pick__group\">\r\n {{ isObjectLevel() ? 'Campi di ' : 'Membri di ' }}{{ classLabel() }}\r\n </p>\r\n }\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!className()) {\r\n Scegli prima una classe.\r\n } @else if (hasCatalog()) {\r\n Nessun membro corrisponde.\r\n } @else if (isClassUnknown()) {\r\n Classe non registrata: nessun membro da proporre.\r\n } @else {\r\n Membri non dichiarati: scrivi il nome del membro.\r\n }\r\n </p>\r\n }\r\n @for (entry of options(); track entry.name) {\r\n <div class=\"fb-pick__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\r\n (click)=\"choose(entry)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\r\n @if (describe(entry)) {\r\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\r\n }\r\n </button>\r\n @if (canDescend(entry)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__into\"\r\n [attr.aria-label]=\"'Entra in ' + entry.name\"\r\n title=\"Entra nel membro composto\"\r\n (click)=\"descend(entry)\"\r\n >\r\n \u203A\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4734
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: StructureMemberPickerComponent, isStandalone: true, selector: "fb-structure-member-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, usage: { classPropertyName: "usage", publicName: "usage", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i membri disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isClassUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">\n La classe {{ className() }} non e\u2019 registrata (STRUCTURE_TYPE_UNKNOWN): correggi la classe,\n non il membro.\n </p>\n } @else if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ unknownMessage() }}</p>\n } @else if (isNotWritable()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ notWritableMessage() }}</p>\n } @else if (isUndeclared()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n {{ classLabel() }} non dichiara i suoi membri: scrivi il nome a mano, non e\u2019 verificabile.\n </p>\n } @else if (isNotVerifiable()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\n } @else if (describeValue()) {\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco dei membri non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (className()) {\n <p class=\"fb-pick__group\">\n {{ isObjectLevel() ? 'Campi di ' : 'Membri di ' }}{{ classLabel() }}\n </p>\n }\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n @if (!className()) {\n Scegli prima una classe.\n } @else if (hasCatalog()) {\n Nessun membro corrisponde.\n } @else if (isClassUnknown()) {\n Classe non registrata: nessun membro da proporre.\n } @else {\n Membri non dichiarati: scrivi il nome del membro.\n }\n </p>\n }\n @for (entry of options(); track entry.name) {\n <div class=\"fb-pick__row\">\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\n (click)=\"choose(entry)\"\n >\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\n @if (describe(entry)) {\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\n }\n </button>\n @if (canDescend(entry)) {\n <button\n type=\"button\"\n class=\"fb-pick__into\"\n [attr.aria-label]=\"'Entra in ' + entry.name\"\n title=\"Entra nel membro composto\"\n (click)=\"descend(entry)\"\n >\n \u203A\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4673
4735
  }
4674
4736
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StructureMemberPickerComponent, decorators: [{
4675
4737
  type: Component,
4676
- args: [{ selector: 'fb-structure-member-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i membri disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n \u25BE\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\r\n }\r\n </div>\r\n\r\n @if (isClassUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">\r\n La classe {{ className() }} non e\u2019 registrata (STRUCTURE_TYPE_UNKNOWN): correggi la classe,\r\n non il membro.\r\n </p>\r\n } @else if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ unknownMessage() }}</p>\r\n } @else if (isNotWritable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ notWritableMessage() }}</p>\r\n } @else if (isUndeclared()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n {{ classLabel() }} non dichiara i suoi membri: scrivi il nome a mano, non e\u2019 verificabile.\r\n </p>\r\n } @else if (isNotVerifiable()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei membri non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (className()) {\r\n <p class=\"fb-pick__group\">\r\n {{ isObjectLevel() ? 'Campi di ' : 'Membri di ' }}{{ classLabel() }}\r\n </p>\r\n }\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!className()) {\r\n Scegli prima una classe.\r\n } @else if (hasCatalog()) {\r\n Nessun membro corrisponde.\r\n } @else if (isClassUnknown()) {\r\n Classe non registrata: nessun membro da proporre.\r\n } @else {\r\n Membri non dichiarati: scrivi il nome del membro.\r\n }\r\n </p>\r\n }\r\n @for (entry of options(); track entry.name) {\r\n <div class=\"fb-pick__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\r\n (click)=\"choose(entry)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\r\n @if (describe(entry)) {\r\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\r\n }\r\n </button>\r\n @if (canDescend(entry)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__into\"\r\n [attr.aria-label]=\"'Entra in ' + entry.name\"\r\n title=\"Entra nel membro composto\"\r\n (click)=\"descend(entry)\"\r\n >\r\n \u203A\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4738
+ args: [{ selector: 'fb-structure-member-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\n <div class=\"fb-pick__control\">\n <input\n class=\"fb-pick__input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-expanded]=\"isOpen()\"\n (input)=\"onInput($any($event.target).value)\"\n (focus)=\"open()\"\n (keydown.escape)=\"close()\"\n />\n <button\n type=\"button\"\n class=\"fb-pick__toggle\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-label=\"Mostra i membri disponibili\"\n (click)=\"toggle()\"\n >\n \u25BE\n </button>\n @if (value()) {\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">\u00D7</button>\n }\n </div>\n\n @if (isClassUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">\n La classe {{ className() }} non e\u2019 registrata (STRUCTURE_TYPE_UNKNOWN): correggi la classe,\n non il membro.\n </p>\n } @else if (isUnknown()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ unknownMessage() }}</p>\n } @else if (isNotWritable()) {\n <p class=\"fb-pick__hint fb-pick__hint--error\">{{ notWritableMessage() }}</p>\n } @else if (isUndeclared()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n {{ classLabel() }} non dichiara i suoi membri: scrivi il nome a mano, non e\u2019 verificabile.\n </p>\n } @else if (isNotVerifiable()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ notVerifiableMessage() }}</p>\n } @else if (describeValue()) {\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\n } @else if (loadErrored()) {\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\n Elenco dei membri non disponibile: puoi scrivere il nome a mano.\n </p>\n }\n\n @if (isOpen()) {\n <div class=\"fb-pick__panel\" role=\"listbox\">\n @if (className()) {\n <p class=\"fb-pick__group\">\n {{ isObjectLevel() ? 'Campi di ' : 'Membri di ' }}{{ classLabel() }}\n </p>\n }\n @if (options().length === 0) {\n <p class=\"fb-pick__empty\">\n @if (!className()) {\n Scegli prima una classe.\n } @else if (hasCatalog()) {\n Nessun membro corrisponde.\n } @else if (isClassUnknown()) {\n Classe non registrata: nessun membro da proporre.\n } @else {\n Membri non dichiarati: scrivi il nome del membro.\n }\n </p>\n }\n @for (entry of options(); track entry.name) {\n <div class=\"fb-pick__row\">\n <button\n type=\"button\"\n class=\"fb-pick__option\"\n role=\"option\"\n [attr.aria-selected]=\"prefix() + entry.name === value()\"\n (click)=\"choose(entry)\"\n >\n <span class=\"fb-pick__name\">{{ entry.name }}</span>\n @if (describe(entry)) {\n <span class=\"fb-pick__meta\">{{ describe(entry) }}</span>\n }\n </button>\n @if (canDescend(entry)) {\n <button\n type=\"button\"\n class=\"fb-pick__into\"\n [attr.aria-label]=\"'Entra in ' + entry.name\"\n title=\"Entra nel membro composto\"\n (click)=\"descend(entry)\"\n >\n \u203A\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.fb-pick{position:relative}.fb-pick__control{display:flex;align-items:stretch;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);overflow:hidden}.fb-pick--open .fb-pick__control{border-color:var(--fb-accent, #2f6feb)}.fb-pick__input{flex:1;min-width:0;padding:5px 7px;border:0;background:transparent;color:var(--fb-text, #1d2939);font:inherit;font-size:12px}.fb-pick__input:focus-visible{outline:none}.fb-pick__input--mono,.fb-pick__name--mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.fb-pick__toggle,.fb-pick__clear{flex:0 0 auto;padding:0 7px;border:0;border-left:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:12px;cursor:pointer}.fb-pick__toggle:hover,.fb-pick__clear:hover{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__hint{margin:3px 0 0;font-size:10px;line-height:1.35;color:var(--fb-text-subtle, #98a2b3)}.fb-pick__hint--warn{color:var(--fb-warning, #b7791f)}.fb-pick__hint--error{color:var(--fb-error, #c9372c)}.fb-pick__panel{position:absolute;z-index:30;top:calc(100% + 3px);left:0;right:0;max-height:260px;overflow-y:auto;padding:6px;border:1px solid var(--fb-border, #d6dae1);border-radius:6px;background:var(--fb-surface, #fff);box-shadow:0 6px 18px #10182829}.fb-pick__option{display:flex;flex-direction:column;width:100%;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:var(--fb-text, #1d2939);font:inherit;text-align:left;cursor:pointer}.fb-pick__option:hover,.fb-pick__option[aria-selected=true]{background:var(--fb-surface-alt, #f8f9fb)}.fb-pick__row{display:flex;align-items:stretch;gap:2px}.fb-pick__row .fb-pick__option{flex:1;min-width:0}.fb-pick__into{flex:0 0 auto;padding:0 7px;border:0;border-radius:4px;background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:13px;cursor:pointer}.fb-pick__into:hover{background:var(--fb-surface-alt, #f8f9fb);color:var(--fb-accent, #2f6feb)}.fb-pick__name{font-size:12px}.fb-pick__meta{font-size:10px;color:var(--fb-text-muted, #667085)}.fb-pick__group{margin:2px 4px 4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--fb-text-muted, #667085)}.fb-pick__empty{margin:4px;font-size:11px;color:var(--fb-text-muted, #667085)}.fb-pick__close{width:100%;margin-top:4px;padding:4px;border:0;border-top:1px solid var(--fb-border-subtle, #e6e9ee);background:transparent;color:var(--fb-text-muted, #667085);font:inherit;font-size:11px;cursor:pointer}\n"] }]
4677
4739
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], usage: [{ type: i0.Input, args: [{ isSignal: true, alias: "usage", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
4678
4740
 
4679
4741
  /**
@@ -6866,7 +6928,7 @@ class OrchestratedStageInspectorComponent extends NodeInspectorBase {
6866
6928
  /** C'e' almeno uno step il cui rifiuto e' un esito previsto. */
6867
6929
  hasApprovalStep = computed(() => this.steps().some((step) => this.supportsRejection(step)), ...(ngDevMode ? [{ debugName: "hasApprovalStep" }] : []));
6868
6930
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: OrchestratedStageInspectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6869
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: OrchestratedStageInspectorComponent, isStandalone: true, selector: "fb-orchestrated-stage-inspector", usesInheritance: true, ngImport: i0, template: "<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Step dello stage</legend>\r\n <p class=\"fb-section__note\">\r\n Gli step <strong>non sono una sequenza</strong>: parte quello le cui condizioni d\u2019ingresso sono vere, e\r\n l\u2019ordine qui sotto e\u2019 solo l\u2019ordine in cui vengono esaminati.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n <!-- `stepIndex` esplicito: dentro l'elenco degli assegnatari `$index` e' quello dell'assegnatario. -->\r\n @for (step of steps(); track $index; let stepIndex = $index, isFirst = $first, isLast = $last) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <!-- Titolo, non indice: gli step non sono numerati perche' non sono una sequenza. -->\r\n <span class=\"fb-list__title\">{{ step.label || step.name || '\u2014' }}</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Esamina prima\"\r\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\r\n [disabled]=\"isFirst\"\r\n (click)=\"moveStep(stepIndex, -1)\"\r\n >\r\n \u2191\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Esamina dopo\"\r\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\r\n [disabled]=\"isLast\"\r\n (click)=\"moveStep(stepIndex, 1)\"\r\n >\r\n \u2193\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi lo step\"\r\n (click)=\"removeStep(stepIndex)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"step.label || ''\"\r\n placeholder=\"Approva la pratica\"\r\n (input)=\"setStepLabel(stepIndex, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Nome tecnico</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!stepNameError(step)\"\r\n [value]=\"step.name || ''\"\r\n (input)=\"setStepName(stepIndex, $any($event.target).value)\"\r\n />\r\n @if (stepNameError(step)) {\r\n <p class=\"fb-field__error\">{{ stepNameError(step) }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Sta nello stesso spazio dei nomi di elementi e risorse. Gli output dello step sono\r\n referenziabili come <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>.\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo di step</label>\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-input--invalid]=\"!step.actionType || isUnknownStepType(step)\"\r\n [fbValue]=\"step.actionType || ''\"\r\n (change)=\"setStepType(stepIndex, $any($event.target).value)\"\r\n >\r\n <option value=\"\">\u2014 scegli \u2014</option>\r\n @for (type of stepTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n @if (!step.actionType) {\r\n <p class=\"fb-field__error\">Senza tipo lo step non e\u2019 valido (STAGE_STEP_TYPE_MISSING).</p>\r\n } @else if (isUnknownStepType(step)) {\r\n <p class=\"fb-field__error\">\r\n \u00AB{{ step.actionType }}\u00BB non e\u2019 un tipo di step di questo sistema (STAGE_STEP_TYPE_UNKNOWN).\r\n </p>\r\n } @else if (stepTypeDescription(step)) {\r\n <p class=\"fb-field__hint\">{{ stepTypeDescription(step) }}</p>\r\n }\r\n </div>\r\n\r\n @if (requiresActionName(step)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Flow da eseguire</label>\r\n <!--\r\n Una lista di candidati vuota significa \"non lo so\", non \"nessuno\": il campo resta\r\n scrivibile a mano invece di bloccare l'utente (\u00A77).\r\n -->\r\n <fb-name-picker\r\n [value]=\"step.actionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Flow da eseguire\"\r\n placeholder=\"Preparazione_Pratica\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setStepActionName(stepIndex, $event ?? '')\"\r\n />\r\n @if (!step.actionName) {\r\n <p class=\"fb-field__error\">\r\n Uno step in background esegue un flow: senza, e\u2019 STAGE_STEP_FLOW_MISSING.\r\n </p>\r\n } @else {\r\n <p class=\"fb-field__hint\">Il motore lo esegue subito, senza coinvolgere nessuno.</p>\r\n }\r\n </div>\r\n }\r\n\r\n @if (requiresAssignees(step)) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Assegnatari</legend>\r\n <p class=\"fb-section__note\">\r\n Su questo step l\u2019interview si <strong>sospende</strong>: resta aperto un work item finche\u2019\r\n una persona non lo conclude.\r\n </p>\r\n <div class=\"fb-list\">\r\n @for (assignee of assigneesOf(step); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__index\">{{ $index + 1 }}</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi l\u2019assegnatario\"\r\n (click)=\"removeAssignee(stepIndex, $index)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"assignee.assigneeType || ''\"\r\n (change)=\"setAssigneeType(stepIndex, $index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">\u2014 scegli \u2014</option>\r\n @for (type of assigneeTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Chi</label>\r\n <fb-value-editor\r\n [value]=\"assignee.assignee\"\r\n label=\"Assegnatario\"\r\n dataType=\"String\"\r\n (valueChange)=\"setAssigneeValue(stepIndex, $index, $event)\"\r\n />\r\n </div>\r\n @if (isAssigneeIncomplete(assignee)) {\r\n <p class=\"fb-field__error\">Servono tipo e destinatario (STAGE_STEP_ASSIGNEE_INVALID).</p>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Senza assegnatari questo step non e\u2019 valido (STAGE_STEP_ASSIGNEES_MISSING).\r\n </p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAssignee(stepIndex)\">\r\n Aggiungi assegnatario\r\n </button>\r\n\r\n @if (supportsRejection(step)) {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isMultiMemberApproval(step)\"\r\n (change)=\"setMultiMemberApproval(stepIndex, $any($event.target).checked)\"\r\n />\r\n Serve l\u2019approvazione di tutti i membri\r\n </label>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!--\r\n Ingresso e uscita non sono simmetriche: se l'ingresso non si avvera lo step viene\r\n saltato, se l'uscita resta falsa lo stage va in stallo e l'esecuzione fallisce (\u00A75.13).\r\n -->\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].entry\"\r\n title=\"Condizioni d\u2019ingresso (se lo step si applica)\"\r\n [allowLogic]=\"false\"\r\n [allowFormula]=\"false\"\r\n (changed)=\"onEntryConditionsChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Se non si avverano, lo step viene <strong>saltato</strong> e lo stage prosegue.\r\n </p>\r\n\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].exit\"\r\n title=\"Condizioni d\u2019uscita (quando lo step libera lo stage)\"\r\n [allowLogic]=\"false\"\r\n [allowFormula]=\"false\"\r\n (changed)=\"onExitConditionsChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Se restano false quando non c\u2019e\u2019 piu\u2019 niente in esecuzione, lo stage e\u2019 in stallo e\r\n l\u2019esecuzione <strong>fallisce</strong>.\r\n </p>\r\n\r\n @if (stepOutputInConditions(step)) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Una condizione referenzia l\u2019output dello step \u00AB{{ stepOutputInConditions(step) }}\u00BB: finche\u2019\r\n quello step non ha girato il riferimento e\u2019 irrisolvibile, e a runtime e\u2019 un errore. Fai\r\n scrivere quel risultato in una variabile (parametro di uscita \u2192 destinazione) e condiziona su\r\n quella.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Evaluation flow per l\u2019ingresso</label>\r\n <fb-name-picker\r\n [value]=\"step.entryActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l\u2019ingresso\"\r\n placeholder=\"Valuta_Ingresso\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setEntryActionName(stepIndex, $event ?? '')\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Deve restituire l\u2019output booleano <code>{{ conditionOutputName }}</code>: e\u2019 l\u2019unico che il\r\n runtime legge, dichiararne altri e\u2019 STAGE_ACTION_INVALID.\r\n </p>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Evaluation flow per l\u2019uscita</label>\r\n <fb-name-picker\r\n [value]=\"step.exitActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l\u2019uscita\"\r\n placeholder=\"Valuta_Uscita\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setExitActionName(stepIndex, $event ?? '')\"\r\n />\r\n </div>\r\n\r\n <fb-parameter-editor\r\n [holder]=\"step\"\r\n inputTitle=\"Parametri dello step\"\r\n [showOutputs]=\"true\"\r\n outputTitle=\"Valori prodotti dallo step\"\r\n (changed)=\"onParametersChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n La destinazione e\u2019 <strong>facoltativa</strong>: l\u2019output e\u2019 gi\u00E0 referenziabile come\r\n <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>. Serve una variabile solo se un altro step\r\n deve condizionare su quel risultato.\r\n </p>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"hasSimulatedOutputs(step)\"\r\n (change)=\"setSimulateStep(stepIndex, $any($event.target).checked)\"\r\n />\r\n Simula lo step nella prova\r\n </label>\r\n @if (hasSimulatedOutputs(step)) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Con la simulazione lo step non viene eseguito ne\u2019 assegnato: si usano gli output finti di\r\n <code>outputConfigParams</code>. Non memorizzarci dati personali.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Descrizione</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"step.description || ''\"\r\n (input)=\"setStepDescription(stepIndex, $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Uno stage senza step non fa nulla ed e\u2019 un errore di validazione (STAGE_WITHOUT_STEPS).\r\n </p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addStep()\">Aggiungi step</button>\r\n</fieldset>\r\n\r\n@if (hasApprovalStep() && !hasRejectionBranch()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n C\u2019e\u2019 uno step di approvazione ma il ramo \u00ABStep rifiutato\u00BB non e\u2019 disegnato: senza, un rifiuto fa\r\n <strong>fallire</strong> l\u2019interview. Non e\u2019 un ramo di guasto, e\u2019 l\u2019esito previsto del rifiuto.\r\n </p>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Rami\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n", dependencies: [{ kind: "component", type: ConditionEditorComponent, selector: "fb-condition-editor", inputs: ["holder", "title", "allowFormula", "allowLogic", "issuePath"], outputs: ["changed"] }, { kind: "component", type: ConnectorEditorComponent, selector: "fb-connector-editor", inputs: ["nodeName", "node", "outlets", "title"], outputs: ["connectorChanged"] }, { kind: "component", type: NamePickerComponent, selector: "fb-name-picker", inputs: ["value", "options", "label", "placeholder", "disabled", "unknownMessage", "unknownSeverity", "emptyMessage", "isMono"], outputs: ["valueChange"] }, { kind: "component", type: ParameterEditorComponent, selector: "fb-parameter-editor", inputs: ["holder", "catalogParameters", "inputTitle", "outputTitle", "showInputs", "showOutputs", "outputsDisabledReason"], outputs: ["changed"] }, { kind: "component", type: ValueEditorComponent, selector: "fb-value-editor", inputs: ["value", "label", "dataType", "objectType", "isCollection", "disabled", "allowFormula"], outputs: ["valueChange"] }, { kind: "directive", type: SelectValueDirective, selector: "select[fbValue]", inputs: ["fbValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6931
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.27", type: OrchestratedStageInspectorComponent, isStandalone: true, selector: "fb-orchestrated-stage-inspector", usesInheritance: true, ngImport: i0, template: "<fieldset class=\"fb-section\">\n <legend class=\"fb-section__title\">Step dello stage</legend>\n <p class=\"fb-section__note\">\n Gli step <strong>non sono una sequenza</strong>: parte quello le cui condizioni d\u2019ingresso sono vere, e\n l\u2019ordine qui sotto e\u2019 solo l\u2019ordine in cui vengono esaminati.\n </p>\n\n <div class=\"fb-list\">\n <!-- `stepIndex` esplicito: dentro l'elenco degli assegnatari `$index` e' quello dell'assegnatario. -->\n @for (step of steps(); track $index; let stepIndex = $index, isFirst = $first, isLast = $last) {\n <div class=\"fb-list__item\">\n <div class=\"fb-list__header\">\n <!-- Titolo, non indice: gli step non sono numerati perche' non sono una sequenza. -->\n <span class=\"fb-list__title\">{{ step.label || step.name || '\u2014' }}</span>\n <span class=\"fb-list__spacer\"></span>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Esamina prima\"\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\n [disabled]=\"isFirst\"\n (click)=\"moveStep(stepIndex, -1)\"\n >\n \u2191\n </button>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Esamina dopo\"\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\n [disabled]=\"isLast\"\n (click)=\"moveStep(stepIndex, 1)\"\n >\n \u2193\n </button>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Rimuovi lo step\"\n (click)=\"removeStep(stepIndex)\"\n >\n \u00D7\n </button>\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Etichetta</label>\n <input\n class=\"fb-input\"\n [value]=\"step.label || ''\"\n placeholder=\"Approva la pratica\"\n (input)=\"setStepLabel(stepIndex, $any($event.target).value)\"\n />\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Nome tecnico</label>\n <input\n class=\"fb-input fb-input--mono\"\n [class.fb-input--invalid]=\"!!stepNameError(step)\"\n [value]=\"step.name || ''\"\n (input)=\"setStepName(stepIndex, $any($event.target).value)\"\n />\n @if (stepNameError(step)) {\n <p class=\"fb-field__error\">{{ stepNameError(step) }}</p>\n } @else {\n <p class=\"fb-field__hint\">\n Sta nello stesso spazio dei nomi di elementi e risorse. Gli output dello step sono\n referenziabili come <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>.\n </p>\n }\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Tipo di step</label>\n <select\n class=\"fb-select\"\n [class.fb-input--invalid]=\"!step.actionType || isUnknownStepType(step)\"\n [fbValue]=\"step.actionType || ''\"\n (change)=\"setStepType(stepIndex, $any($event.target).value)\"\n >\n <option value=\"\">\u2014 scegli \u2014</option>\n @for (type of stepTypes(); track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n @if (!step.actionType) {\n <p class=\"fb-field__error\">Senza tipo lo step non e\u2019 valido (STAGE_STEP_TYPE_MISSING).</p>\n } @else if (isUnknownStepType(step)) {\n <p class=\"fb-field__error\">\n \u00AB{{ step.actionType }}\u00BB non e\u2019 un tipo di step di questo sistema (STAGE_STEP_TYPE_UNKNOWN).\n </p>\n } @else if (stepTypeDescription(step)) {\n <p class=\"fb-field__hint\">{{ stepTypeDescription(step) }}</p>\n }\n </div>\n\n @if (requiresActionName(step)) {\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Flow da eseguire</label>\n <!--\n Una lista di candidati vuota significa \"non lo so\", non \"nessuno\": il campo resta\n scrivibile a mano invece di bloccare l'utente (\u00A77).\n -->\n <fb-name-picker\n [value]=\"step.actionName\"\n [options]=\"candidateOptions()\"\n label=\"Flow da eseguire\"\n placeholder=\"Preparazione_Pratica\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setStepActionName(stepIndex, $event ?? '')\"\n />\n @if (!step.actionName) {\n <p class=\"fb-field__error\">\n Uno step in background esegue un flow: senza, e\u2019 STAGE_STEP_FLOW_MISSING.\n </p>\n } @else {\n <p class=\"fb-field__hint\">Il motore lo esegue subito, senza coinvolgere nessuno.</p>\n }\n </div>\n }\n\n @if (requiresAssignees(step)) {\n <fieldset class=\"fb-section\">\n <legend class=\"fb-section__title\">Assegnatari</legend>\n <p class=\"fb-section__note\">\n Su questo step l\u2019interview si <strong>sospende</strong>: resta aperto un work item finche\u2019\n una persona non lo conclude.\n </p>\n <div class=\"fb-list\">\n @for (assignee of assigneesOf(step); track $index) {\n <div class=\"fb-list__item\">\n <div class=\"fb-list__header\">\n <span class=\"fb-list__index\">{{ $index + 1 }}</span>\n <span class=\"fb-list__spacer\"></span>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Rimuovi l\u2019assegnatario\"\n (click)=\"removeAssignee(stepIndex, $index)\"\n >\n \u00D7\n </button>\n </div>\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Tipo</label>\n <select\n class=\"fb-select\"\n [fbValue]=\"assignee.assigneeType || ''\"\n (change)=\"setAssigneeType(stepIndex, $index, $any($event.target).value)\"\n >\n <option value=\"\">\u2014 scegli \u2014</option>\n @for (type of assigneeTypes(); track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n </div>\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Chi</label>\n <fb-value-editor\n [value]=\"assignee.assignee\"\n label=\"Assegnatario\"\n dataType=\"String\"\n (valueChange)=\"setAssigneeValue(stepIndex, $index, $event)\"\n />\n </div>\n @if (isAssigneeIncomplete(assignee)) {\n <p class=\"fb-field__error\">Servono tipo e destinatario (STAGE_STEP_ASSIGNEE_INVALID).</p>\n }\n </div>\n } @empty {\n <p class=\"fb-empty\">\n Senza assegnatari questo step non e\u2019 valido (STAGE_STEP_ASSIGNEES_MISSING).\n </p>\n }\n </div>\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAssignee(stepIndex)\">\n Aggiungi assegnatario\n </button>\n\n @if (supportsRejection(step)) {\n <label class=\"fb-check\">\n <input\n type=\"checkbox\"\n [checked]=\"isMultiMemberApproval(step)\"\n (change)=\"setMultiMemberApproval(stepIndex, $any($event.target).checked)\"\n />\n Serve l\u2019approvazione di tutti i membri\n </label>\n }\n </fieldset>\n }\n\n <!--\n Ingresso e uscita non sono simmetriche: se l'ingresso non si avvera lo step viene\n saltato, se l'uscita resta falsa lo stage va in stallo e l'esecuzione fallisce (\u00A75.13).\n -->\n <fb-condition-editor\n [holder]=\"conditionHolders()[stepIndex].entry\"\n title=\"Condizioni d\u2019ingresso (se lo step si applica)\"\n [allowLogic]=\"false\"\n [allowFormula]=\"false\"\n (changed)=\"onEntryConditionsChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint\">\n Se non si avverano, lo step viene <strong>saltato</strong> e lo stage prosegue.\n </p>\n\n <fb-condition-editor\n [holder]=\"conditionHolders()[stepIndex].exit\"\n title=\"Condizioni d\u2019uscita (quando lo step libera lo stage)\"\n [allowLogic]=\"false\"\n [allowFormula]=\"false\"\n (changed)=\"onExitConditionsChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint fb-field__hint--warn\">\n Se restano false quando non c\u2019e\u2019 piu\u2019 niente in esecuzione, lo stage e\u2019 in stallo e\n l\u2019esecuzione <strong>fallisce</strong>.\n </p>\n\n @if (stepOutputInConditions(step)) {\n <p class=\"fb-callout fb-callout--error\">\n Una condizione referenzia l\u2019output dello step \u00AB{{ stepOutputInConditions(step) }}\u00BB: finche\u2019\n quello step non ha girato il riferimento e\u2019 irrisolvibile, e a runtime e\u2019 un errore. Fai\n scrivere quel risultato in una variabile (parametro di uscita \u2192 destinazione) e condiziona su\n quella.\n </p>\n }\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Evaluation flow per l\u2019ingresso</label>\n <fb-name-picker\n [value]=\"step.entryActionName\"\n [options]=\"candidateOptions()\"\n label=\"Evaluation flow per l\u2019ingresso\"\n placeholder=\"Valuta_Ingresso\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setEntryActionName(stepIndex, $event ?? '')\"\n />\n <p class=\"fb-field__hint\">\n Deve restituire l\u2019output booleano <code>{{ conditionOutputName }}</code>: e\u2019 l\u2019unico che il\n runtime legge, dichiararne altri e\u2019 STAGE_ACTION_INVALID.\n </p>\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Evaluation flow per l\u2019uscita</label>\n <fb-name-picker\n [value]=\"step.exitActionName\"\n [options]=\"candidateOptions()\"\n label=\"Evaluation flow per l\u2019uscita\"\n placeholder=\"Valuta_Uscita\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setExitActionName(stepIndex, $event ?? '')\"\n />\n </div>\n\n <fb-parameter-editor\n [holder]=\"step\"\n inputTitle=\"Parametri dello step\"\n [showOutputs]=\"true\"\n outputTitle=\"Valori prodotti dallo step\"\n (changed)=\"onParametersChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint\">\n La destinazione e\u2019 <strong>facoltativa</strong>: l\u2019output e\u2019 gi\u00E0 referenziabile come\n <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>. Serve una variabile solo se un altro step\n deve condizionare su quel risultato.\n </p>\n\n <label class=\"fb-check\">\n <input\n type=\"checkbox\"\n [checked]=\"hasSimulatedOutputs(step)\"\n (change)=\"setSimulateStep(stepIndex, $any($event.target).checked)\"\n />\n Simula lo step nella prova\n </label>\n @if (hasSimulatedOutputs(step)) {\n <p class=\"fb-callout fb-callout--warn\">\n Con la simulazione lo step non viene eseguito ne\u2019 assegnato: si usano gli output finti di\n <code>outputConfigParams</code>. Non memorizzarci dati personali.\n </p>\n }\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Descrizione</label>\n <textarea\n class=\"fb-textarea\"\n [value]=\"step.description || ''\"\n (input)=\"setStepDescription(stepIndex, $any($event.target).value)\"\n ></textarea>\n </div>\n </div>\n } @empty {\n <p class=\"fb-empty\">\n Uno stage senza step non fa nulla ed e\u2019 un errore di validazione (STAGE_WITHOUT_STEPS).\n </p>\n }\n </div>\n\n <button type=\"button\" class=\"fb-btn\" (click)=\"addStep()\">Aggiungi step</button>\n</fieldset>\n\n@if (hasApprovalStep() && !hasRejectionBranch()) {\n <p class=\"fb-callout fb-callout--warn\">\n C\u2019e\u2019 uno step di approvazione ma il ramo \u00ABStep rifiutato\u00BB non e\u2019 disegnato: senza, un rifiuto fa\n <strong>fallire</strong> l\u2019interview. Non e\u2019 un ramo di guasto, e\u2019 l\u2019esito previsto del rifiuto.\n </p>\n}\n\n<fb-connector-editor\n [nodeName]=\"name()\"\n [node]=\"node()\"\n [outlets]=\"outlets()\"\n title=\"Rami\"\n (connectorChanged)=\"onConnectorChanged($event)\"\n/>\n", dependencies: [{ kind: "component", type: ConditionEditorComponent, selector: "fb-condition-editor", inputs: ["holder", "title", "allowFormula", "allowLogic", "issuePath"], outputs: ["changed"] }, { kind: "component", type: ConnectorEditorComponent, selector: "fb-connector-editor", inputs: ["nodeName", "node", "outlets", "title"], outputs: ["connectorChanged"] }, { kind: "component", type: NamePickerComponent, selector: "fb-name-picker", inputs: ["value", "options", "label", "placeholder", "disabled", "unknownMessage", "unknownSeverity", "emptyMessage", "isMono"], outputs: ["valueChange"] }, { kind: "component", type: ParameterEditorComponent, selector: "fb-parameter-editor", inputs: ["holder", "catalogParameters", "inputTitle", "outputTitle", "showInputs", "showOutputs", "outputsDisabledReason"], outputs: ["changed"] }, { kind: "component", type: ValueEditorComponent, selector: "fb-value-editor", inputs: ["value", "label", "dataType", "objectType", "isCollection", "disabled", "allowFormula"], outputs: ["valueChange"] }, { kind: "directive", type: SelectValueDirective, selector: "select[fbValue]", inputs: ["fbValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6870
6932
  }
6871
6933
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: OrchestratedStageInspectorComponent, decorators: [{
6872
6934
  type: Component,
@@ -6877,7 +6939,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImpo
6877
6939
  ParameterEditorComponent,
6878
6940
  ValueEditorComponent,
6879
6941
  SelectValueDirective,
6880
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Step dello stage</legend>\r\n <p class=\"fb-section__note\">\r\n Gli step <strong>non sono una sequenza</strong>: parte quello le cui condizioni d\u2019ingresso sono vere, e\r\n l\u2019ordine qui sotto e\u2019 solo l\u2019ordine in cui vengono esaminati.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n <!-- `stepIndex` esplicito: dentro l'elenco degli assegnatari `$index` e' quello dell'assegnatario. -->\r\n @for (step of steps(); track $index; let stepIndex = $index, isFirst = $first, isLast = $last) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <!-- Titolo, non indice: gli step non sono numerati perche' non sono una sequenza. -->\r\n <span class=\"fb-list__title\">{{ step.label || step.name || '\u2014' }}</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Esamina prima\"\r\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\r\n [disabled]=\"isFirst\"\r\n (click)=\"moveStep(stepIndex, -1)\"\r\n >\r\n \u2191\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Esamina dopo\"\r\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\r\n [disabled]=\"isLast\"\r\n (click)=\"moveStep(stepIndex, 1)\"\r\n >\r\n \u2193\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi lo step\"\r\n (click)=\"removeStep(stepIndex)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"step.label || ''\"\r\n placeholder=\"Approva la pratica\"\r\n (input)=\"setStepLabel(stepIndex, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Nome tecnico</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!stepNameError(step)\"\r\n [value]=\"step.name || ''\"\r\n (input)=\"setStepName(stepIndex, $any($event.target).value)\"\r\n />\r\n @if (stepNameError(step)) {\r\n <p class=\"fb-field__error\">{{ stepNameError(step) }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Sta nello stesso spazio dei nomi di elementi e risorse. Gli output dello step sono\r\n referenziabili come <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>.\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo di step</label>\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-input--invalid]=\"!step.actionType || isUnknownStepType(step)\"\r\n [fbValue]=\"step.actionType || ''\"\r\n (change)=\"setStepType(stepIndex, $any($event.target).value)\"\r\n >\r\n <option value=\"\">\u2014 scegli \u2014</option>\r\n @for (type of stepTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n @if (!step.actionType) {\r\n <p class=\"fb-field__error\">Senza tipo lo step non e\u2019 valido (STAGE_STEP_TYPE_MISSING).</p>\r\n } @else if (isUnknownStepType(step)) {\r\n <p class=\"fb-field__error\">\r\n \u00AB{{ step.actionType }}\u00BB non e\u2019 un tipo di step di questo sistema (STAGE_STEP_TYPE_UNKNOWN).\r\n </p>\r\n } @else if (stepTypeDescription(step)) {\r\n <p class=\"fb-field__hint\">{{ stepTypeDescription(step) }}</p>\r\n }\r\n </div>\r\n\r\n @if (requiresActionName(step)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Flow da eseguire</label>\r\n <!--\r\n Una lista di candidati vuota significa \"non lo so\", non \"nessuno\": il campo resta\r\n scrivibile a mano invece di bloccare l'utente (\u00A77).\r\n -->\r\n <fb-name-picker\r\n [value]=\"step.actionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Flow da eseguire\"\r\n placeholder=\"Preparazione_Pratica\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setStepActionName(stepIndex, $event ?? '')\"\r\n />\r\n @if (!step.actionName) {\r\n <p class=\"fb-field__error\">\r\n Uno step in background esegue un flow: senza, e\u2019 STAGE_STEP_FLOW_MISSING.\r\n </p>\r\n } @else {\r\n <p class=\"fb-field__hint\">Il motore lo esegue subito, senza coinvolgere nessuno.</p>\r\n }\r\n </div>\r\n }\r\n\r\n @if (requiresAssignees(step)) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Assegnatari</legend>\r\n <p class=\"fb-section__note\">\r\n Su questo step l\u2019interview si <strong>sospende</strong>: resta aperto un work item finche\u2019\r\n una persona non lo conclude.\r\n </p>\r\n <div class=\"fb-list\">\r\n @for (assignee of assigneesOf(step); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__index\">{{ $index + 1 }}</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi l\u2019assegnatario\"\r\n (click)=\"removeAssignee(stepIndex, $index)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"assignee.assigneeType || ''\"\r\n (change)=\"setAssigneeType(stepIndex, $index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">\u2014 scegli \u2014</option>\r\n @for (type of assigneeTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Chi</label>\r\n <fb-value-editor\r\n [value]=\"assignee.assignee\"\r\n label=\"Assegnatario\"\r\n dataType=\"String\"\r\n (valueChange)=\"setAssigneeValue(stepIndex, $index, $event)\"\r\n />\r\n </div>\r\n @if (isAssigneeIncomplete(assignee)) {\r\n <p class=\"fb-field__error\">Servono tipo e destinatario (STAGE_STEP_ASSIGNEE_INVALID).</p>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Senza assegnatari questo step non e\u2019 valido (STAGE_STEP_ASSIGNEES_MISSING).\r\n </p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAssignee(stepIndex)\">\r\n Aggiungi assegnatario\r\n </button>\r\n\r\n @if (supportsRejection(step)) {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isMultiMemberApproval(step)\"\r\n (change)=\"setMultiMemberApproval(stepIndex, $any($event.target).checked)\"\r\n />\r\n Serve l\u2019approvazione di tutti i membri\r\n </label>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!--\r\n Ingresso e uscita non sono simmetriche: se l'ingresso non si avvera lo step viene\r\n saltato, se l'uscita resta falsa lo stage va in stallo e l'esecuzione fallisce (\u00A75.13).\r\n -->\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].entry\"\r\n title=\"Condizioni d\u2019ingresso (se lo step si applica)\"\r\n [allowLogic]=\"false\"\r\n [allowFormula]=\"false\"\r\n (changed)=\"onEntryConditionsChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Se non si avverano, lo step viene <strong>saltato</strong> e lo stage prosegue.\r\n </p>\r\n\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].exit\"\r\n title=\"Condizioni d\u2019uscita (quando lo step libera lo stage)\"\r\n [allowLogic]=\"false\"\r\n [allowFormula]=\"false\"\r\n (changed)=\"onExitConditionsChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Se restano false quando non c\u2019e\u2019 piu\u2019 niente in esecuzione, lo stage e\u2019 in stallo e\r\n l\u2019esecuzione <strong>fallisce</strong>.\r\n </p>\r\n\r\n @if (stepOutputInConditions(step)) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Una condizione referenzia l\u2019output dello step \u00AB{{ stepOutputInConditions(step) }}\u00BB: finche\u2019\r\n quello step non ha girato il riferimento e\u2019 irrisolvibile, e a runtime e\u2019 un errore. Fai\r\n scrivere quel risultato in una variabile (parametro di uscita \u2192 destinazione) e condiziona su\r\n quella.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Evaluation flow per l\u2019ingresso</label>\r\n <fb-name-picker\r\n [value]=\"step.entryActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l\u2019ingresso\"\r\n placeholder=\"Valuta_Ingresso\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setEntryActionName(stepIndex, $event ?? '')\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Deve restituire l\u2019output booleano <code>{{ conditionOutputName }}</code>: e\u2019 l\u2019unico che il\r\n runtime legge, dichiararne altri e\u2019 STAGE_ACTION_INVALID.\r\n </p>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Evaluation flow per l\u2019uscita</label>\r\n <fb-name-picker\r\n [value]=\"step.exitActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l\u2019uscita\"\r\n placeholder=\"Valuta_Uscita\"\r\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\r\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setExitActionName(stepIndex, $event ?? '')\"\r\n />\r\n </div>\r\n\r\n <fb-parameter-editor\r\n [holder]=\"step\"\r\n inputTitle=\"Parametri dello step\"\r\n [showOutputs]=\"true\"\r\n outputTitle=\"Valori prodotti dallo step\"\r\n (changed)=\"onParametersChanged(stepIndex, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n La destinazione e\u2019 <strong>facoltativa</strong>: l\u2019output e\u2019 gi\u00E0 referenziabile come\r\n <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>. Serve una variabile solo se un altro step\r\n deve condizionare su quel risultato.\r\n </p>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"hasSimulatedOutputs(step)\"\r\n (change)=\"setSimulateStep(stepIndex, $any($event.target).checked)\"\r\n />\r\n Simula lo step nella prova\r\n </label>\r\n @if (hasSimulatedOutputs(step)) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Con la simulazione lo step non viene eseguito ne\u2019 assegnato: si usano gli output finti di\r\n <code>outputConfigParams</code>. Non memorizzarci dati personali.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Descrizione</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"step.description || ''\"\r\n (input)=\"setStepDescription(stepIndex, $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Uno stage senza step non fa nulla ed e\u2019 un errore di validazione (STAGE_WITHOUT_STEPS).\r\n </p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addStep()\">Aggiungi step</button>\r\n</fieldset>\r\n\r\n@if (hasApprovalStep() && !hasRejectionBranch()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n C\u2019e\u2019 uno step di approvazione ma il ramo \u00ABStep rifiutato\u00BB non e\u2019 disegnato: senza, un rifiuto fa\r\n <strong>fallire</strong> l\u2019interview. Non e\u2019 un ramo di guasto, e\u2019 l\u2019esito previsto del rifiuto.\r\n </p>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Rami\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n" }]
6942
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<fieldset class=\"fb-section\">\n <legend class=\"fb-section__title\">Step dello stage</legend>\n <p class=\"fb-section__note\">\n Gli step <strong>non sono una sequenza</strong>: parte quello le cui condizioni d\u2019ingresso sono vere, e\n l\u2019ordine qui sotto e\u2019 solo l\u2019ordine in cui vengono esaminati.\n </p>\n\n <div class=\"fb-list\">\n <!-- `stepIndex` esplicito: dentro l'elenco degli assegnatari `$index` e' quello dell'assegnatario. -->\n @for (step of steps(); track $index; let stepIndex = $index, isFirst = $first, isLast = $last) {\n <div class=\"fb-list__item\">\n <div class=\"fb-list__header\">\n <!-- Titolo, non indice: gli step non sono numerati perche' non sono una sequenza. -->\n <span class=\"fb-list__title\">{{ step.label || step.name || '\u2014' }}</span>\n <span class=\"fb-list__spacer\"></span>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Esamina prima\"\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\n [disabled]=\"isFirst\"\n (click)=\"moveStep(stepIndex, -1)\"\n >\n \u2191\n </button>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Esamina dopo\"\n title=\"Cambia l\u2019ordine d\u2019esame, non l\u2019ordine di esecuzione\"\n [disabled]=\"isLast\"\n (click)=\"moveStep(stepIndex, 1)\"\n >\n \u2193\n </button>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Rimuovi lo step\"\n (click)=\"removeStep(stepIndex)\"\n >\n \u00D7\n </button>\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Etichetta</label>\n <input\n class=\"fb-input\"\n [value]=\"step.label || ''\"\n placeholder=\"Approva la pratica\"\n (input)=\"setStepLabel(stepIndex, $any($event.target).value)\"\n />\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Nome tecnico</label>\n <input\n class=\"fb-input fb-input--mono\"\n [class.fb-input--invalid]=\"!!stepNameError(step)\"\n [value]=\"step.name || ''\"\n (input)=\"setStepName(stepIndex, $any($event.target).value)\"\n />\n @if (stepNameError(step)) {\n <p class=\"fb-field__error\">{{ stepNameError(step) }}</p>\n } @else {\n <p class=\"fb-field__hint\">\n Sta nello stesso spazio dei nomi di elementi e risorse. Gli output dello step sono\n referenziabili come <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>.\n </p>\n }\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Tipo di step</label>\n <select\n class=\"fb-select\"\n [class.fb-input--invalid]=\"!step.actionType || isUnknownStepType(step)\"\n [fbValue]=\"step.actionType || ''\"\n (change)=\"setStepType(stepIndex, $any($event.target).value)\"\n >\n <option value=\"\">\u2014 scegli \u2014</option>\n @for (type of stepTypes(); track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n @if (!step.actionType) {\n <p class=\"fb-field__error\">Senza tipo lo step non e\u2019 valido (STAGE_STEP_TYPE_MISSING).</p>\n } @else if (isUnknownStepType(step)) {\n <p class=\"fb-field__error\">\n \u00AB{{ step.actionType }}\u00BB non e\u2019 un tipo di step di questo sistema (STAGE_STEP_TYPE_UNKNOWN).\n </p>\n } @else if (stepTypeDescription(step)) {\n <p class=\"fb-field__hint\">{{ stepTypeDescription(step) }}</p>\n }\n </div>\n\n @if (requiresActionName(step)) {\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Flow da eseguire</label>\n <!--\n Una lista di candidati vuota significa \"non lo so\", non \"nessuno\": il campo resta\n scrivibile a mano invece di bloccare l'utente (\u00A77).\n -->\n <fb-name-picker\n [value]=\"step.actionName\"\n [options]=\"candidateOptions()\"\n label=\"Flow da eseguire\"\n placeholder=\"Preparazione_Pratica\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setStepActionName(stepIndex, $event ?? '')\"\n />\n @if (!step.actionName) {\n <p class=\"fb-field__error\">\n Uno step in background esegue un flow: senza, e\u2019 STAGE_STEP_FLOW_MISSING.\n </p>\n } @else {\n <p class=\"fb-field__hint\">Il motore lo esegue subito, senza coinvolgere nessuno.</p>\n }\n </div>\n }\n\n @if (requiresAssignees(step)) {\n <fieldset class=\"fb-section\">\n <legend class=\"fb-section__title\">Assegnatari</legend>\n <p class=\"fb-section__note\">\n Su questo step l\u2019interview si <strong>sospende</strong>: resta aperto un work item finche\u2019\n una persona non lo conclude.\n </p>\n <div class=\"fb-list\">\n @for (assignee of assigneesOf(step); track $index) {\n <div class=\"fb-list__item\">\n <div class=\"fb-list__header\">\n <span class=\"fb-list__index\">{{ $index + 1 }}</span>\n <span class=\"fb-list__spacer\"></span>\n <button\n type=\"button\"\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\n aria-label=\"Rimuovi l\u2019assegnatario\"\n (click)=\"removeAssignee(stepIndex, $index)\"\n >\n \u00D7\n </button>\n </div>\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Tipo</label>\n <select\n class=\"fb-select\"\n [fbValue]=\"assignee.assigneeType || ''\"\n (change)=\"setAssigneeType(stepIndex, $index, $any($event.target).value)\"\n >\n <option value=\"\">\u2014 scegli \u2014</option>\n @for (type of assigneeTypes(); track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n </div>\n <div class=\"fb-field\">\n <label class=\"fb-field__label fb-field__label--required\">Chi</label>\n <fb-value-editor\n [value]=\"assignee.assignee\"\n label=\"Assegnatario\"\n dataType=\"String\"\n (valueChange)=\"setAssigneeValue(stepIndex, $index, $event)\"\n />\n </div>\n @if (isAssigneeIncomplete(assignee)) {\n <p class=\"fb-field__error\">Servono tipo e destinatario (STAGE_STEP_ASSIGNEE_INVALID).</p>\n }\n </div>\n } @empty {\n <p class=\"fb-empty\">\n Senza assegnatari questo step non e\u2019 valido (STAGE_STEP_ASSIGNEES_MISSING).\n </p>\n }\n </div>\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAssignee(stepIndex)\">\n Aggiungi assegnatario\n </button>\n\n @if (supportsRejection(step)) {\n <label class=\"fb-check\">\n <input\n type=\"checkbox\"\n [checked]=\"isMultiMemberApproval(step)\"\n (change)=\"setMultiMemberApproval(stepIndex, $any($event.target).checked)\"\n />\n Serve l\u2019approvazione di tutti i membri\n </label>\n }\n </fieldset>\n }\n\n <!--\n Ingresso e uscita non sono simmetriche: se l'ingresso non si avvera lo step viene\n saltato, se l'uscita resta falsa lo stage va in stallo e l'esecuzione fallisce (\u00A75.13).\n -->\n <fb-condition-editor\n [holder]=\"conditionHolders()[stepIndex].entry\"\n title=\"Condizioni d\u2019ingresso (se lo step si applica)\"\n [allowLogic]=\"false\"\n [allowFormula]=\"false\"\n (changed)=\"onEntryConditionsChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint\">\n Se non si avverano, lo step viene <strong>saltato</strong> e lo stage prosegue.\n </p>\n\n <fb-condition-editor\n [holder]=\"conditionHolders()[stepIndex].exit\"\n title=\"Condizioni d\u2019uscita (quando lo step libera lo stage)\"\n [allowLogic]=\"false\"\n [allowFormula]=\"false\"\n (changed)=\"onExitConditionsChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint fb-field__hint--warn\">\n Se restano false quando non c\u2019e\u2019 piu\u2019 niente in esecuzione, lo stage e\u2019 in stallo e\n l\u2019esecuzione <strong>fallisce</strong>.\n </p>\n\n @if (stepOutputInConditions(step)) {\n <p class=\"fb-callout fb-callout--error\">\n Una condizione referenzia l\u2019output dello step \u00AB{{ stepOutputInConditions(step) }}\u00BB: finche\u2019\n quello step non ha girato il riferimento e\u2019 irrisolvibile, e a runtime e\u2019 un errore. Fai\n scrivere quel risultato in una variabile (parametro di uscita \u2192 destinazione) e condiziona su\n quella.\n </p>\n }\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Evaluation flow per l\u2019ingresso</label>\n <fb-name-picker\n [value]=\"step.entryActionName\"\n [options]=\"candidateOptions()\"\n label=\"Evaluation flow per l\u2019ingresso\"\n placeholder=\"Valuta_Ingresso\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setEntryActionName(stepIndex, $event ?? '')\"\n />\n <p class=\"fb-field__hint\">\n Deve restituire l\u2019output booleano <code>{{ conditionOutputName }}</code>: e\u2019 l\u2019unico che il\n runtime legge, dichiararne altri e\u2019 STAGE_ACTION_INVALID.\n </p>\n </div>\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Evaluation flow per l\u2019uscita</label>\n <fb-name-picker\n [value]=\"step.exitActionName\"\n [options]=\"candidateOptions()\"\n label=\"Evaluation flow per l\u2019uscita\"\n placeholder=\"Valuta_Uscita\"\n unknownMessage=\"Questo flow non e\u2019 fra quelli invocabili: senza una versione attiva il motore non lo trova.\"\n emptyMessage=\"Elenco dei flow non disponibile: puoi scrivere il nome a mano.\"\n (valueChange)=\"setExitActionName(stepIndex, $event ?? '')\"\n />\n </div>\n\n <fb-parameter-editor\n [holder]=\"step\"\n inputTitle=\"Parametri dello step\"\n [showOutputs]=\"true\"\n outputTitle=\"Valori prodotti dallo step\"\n (changed)=\"onParametersChanged(stepIndex, $event)\"\n />\n <p class=\"fb-field__hint\">\n La destinazione e\u2019 <strong>facoltativa</strong>: l\u2019output e\u2019 gi\u00E0 referenziabile come\n <code>{{ step.name || 'NomeStep' }}.NomeOutput</code>. Serve una variabile solo se un altro step\n deve condizionare su quel risultato.\n </p>\n\n <label class=\"fb-check\">\n <input\n type=\"checkbox\"\n [checked]=\"hasSimulatedOutputs(step)\"\n (change)=\"setSimulateStep(stepIndex, $any($event.target).checked)\"\n />\n Simula lo step nella prova\n </label>\n @if (hasSimulatedOutputs(step)) {\n <p class=\"fb-callout fb-callout--warn\">\n Con la simulazione lo step non viene eseguito ne\u2019 assegnato: si usano gli output finti di\n <code>outputConfigParams</code>. Non memorizzarci dati personali.\n </p>\n }\n\n <div class=\"fb-field\">\n <label class=\"fb-field__label\">Descrizione</label>\n <textarea\n class=\"fb-textarea\"\n [value]=\"step.description || ''\"\n (input)=\"setStepDescription(stepIndex, $any($event.target).value)\"\n ></textarea>\n </div>\n </div>\n } @empty {\n <p class=\"fb-empty\">\n Uno stage senza step non fa nulla ed e\u2019 un errore di validazione (STAGE_WITHOUT_STEPS).\n </p>\n }\n </div>\n\n <button type=\"button\" class=\"fb-btn\" (click)=\"addStep()\">Aggiungi step</button>\n</fieldset>\n\n@if (hasApprovalStep() && !hasRejectionBranch()) {\n <p class=\"fb-callout fb-callout--warn\">\n C\u2019e\u2019 uno step di approvazione ma il ramo \u00ABStep rifiutato\u00BB non e\u2019 disegnato: senza, un rifiuto fa\n <strong>fallire</strong> l\u2019interview. Non e\u2019 un ramo di guasto, e\u2019 l\u2019esito previsto del rifiuto.\n </p>\n}\n\n<fb-connector-editor\n [nodeName]=\"name()\"\n [node]=\"node()\"\n [outlets]=\"outlets()\"\n title=\"Rami\"\n (connectorChanged)=\"onConnectorChanged($event)\"\n/>\n" }]
6881
6943
  }], ctorParameters: () => [] });
6882
6944
 
6883
6945
  /**