@esfaenza/flow-builder 20.3.6 → 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.
|
@@ -800,7 +800,7 @@ function elementIcon(type, label, variant) {
|
|
|
800
800
|
if (icon) {
|
|
801
801
|
return icon;
|
|
802
802
|
}
|
|
803
|
-
const fallback = (label || type)
|
|
803
|
+
const fallback = (label || type)?.trim().charAt(0).toUpperCase();
|
|
804
804
|
return fallback || '•';
|
|
805
805
|
}
|
|
806
806
|
|
|
@@ -865,7 +865,7 @@ function isValidFlowName(name) {
|
|
|
865
865
|
* `currentName` esclude se stesso dal controllo, per non segnalare un elemento in modifica.
|
|
866
866
|
*/
|
|
867
867
|
function checkFlowName(name, usedNames, currentName) {
|
|
868
|
-
const trimmed = (name ?? '')
|
|
868
|
+
const trimmed = (name ?? '')?.trim();
|
|
869
869
|
if (!trimmed) {
|
|
870
870
|
return { isValid: false, problem: 'empty', message: 'Il nome tecnico e’ obbligatorio.' };
|
|
871
871
|
}
|
|
@@ -896,7 +896,7 @@ function checkFlowName(name, usedNames, currentName) {
|
|
|
896
896
|
* Va lasciato modificabile finche' l'elemento e' nuovo.
|
|
897
897
|
*/
|
|
898
898
|
function slugifyFlowName(label) {
|
|
899
|
-
const source = (label ?? '')
|
|
899
|
+
const source = (label ?? '')?.trim();
|
|
900
900
|
if (!source) {
|
|
901
901
|
return '';
|
|
902
902
|
}
|
|
@@ -938,7 +938,7 @@ function uniqueFlowName(base, usedNames) {
|
|
|
938
938
|
* `Cliente.Email` → `Cliente`; `$Record.Stato` → `$Record`; `Importo` → `Importo`.
|
|
939
939
|
*/
|
|
940
940
|
function referenceRoot(reference) {
|
|
941
|
-
const value = (reference ?? '')
|
|
941
|
+
const value = (reference ?? '')?.trim();
|
|
942
942
|
const dot = value.indexOf('.');
|
|
943
943
|
return dot < 0 ? value : value.slice(0, dot);
|
|
944
944
|
}
|
|
@@ -960,7 +960,7 @@ function isCustomConditionLogic(logic) {
|
|
|
960
960
|
if (!logic) {
|
|
961
961
|
return false;
|
|
962
962
|
}
|
|
963
|
-
const normalized = logic
|
|
963
|
+
const normalized = logic?.trim().toLowerCase();
|
|
964
964
|
return normalized !== 'and' && normalized !== 'or' && normalized !== 'formula';
|
|
965
965
|
}
|
|
966
966
|
/**
|
|
@@ -1047,7 +1047,7 @@ function moveCondition(holder, from, to) {
|
|
|
1047
1047
|
* del backend (`CONDITION_LOGIC_INVALID`).
|
|
1048
1048
|
*/
|
|
1049
1049
|
function checkConditionLogic(logic, conditionCount) {
|
|
1050
|
-
const trimmed = logic
|
|
1050
|
+
const trimmed = logic?.trim();
|
|
1051
1051
|
if (!trimmed) {
|
|
1052
1052
|
return null;
|
|
1053
1053
|
}
|
|
@@ -1154,7 +1154,7 @@ function areTypesComparable(left, right) {
|
|
|
1154
1154
|
* scrive — e la traduce, invece di lasciare che `parseFloat` tronchi silenziosamente a `1`.
|
|
1155
1155
|
*/
|
|
1156
1156
|
function parseInvariantNumber(raw) {
|
|
1157
|
-
const trimmed = raw
|
|
1157
|
+
const trimmed = raw?.trim();
|
|
1158
1158
|
if (!trimmed) {
|
|
1159
1159
|
return undefined;
|
|
1160
1160
|
}
|
|
@@ -1209,7 +1209,7 @@ function stageStepOutputReferenced(reference, steps) {
|
|
|
1209
1209
|
if (!reference) {
|
|
1210
1210
|
return undefined;
|
|
1211
1211
|
}
|
|
1212
|
-
const root = referenceRoot(reference
|
|
1212
|
+
const root = referenceRoot(reference?.trim());
|
|
1213
1213
|
return steps.find((step) => !!step.name && step.name === root)?.name;
|
|
1214
1214
|
}
|
|
1215
1215
|
/**
|
|
@@ -1259,12 +1259,74 @@ const BUCKET_BY_NAME = new Map([
|
|
|
1259
1259
|
['trace', 'Info'],
|
|
1260
1260
|
['verbose', 'Info'],
|
|
1261
1261
|
]);
|
|
1262
|
-
/**
|
|
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
|
-
|
|
1265
|
-
|
|
1288
|
+
return severityBucketOf(severity) ?? 'Info';
|
|
1289
|
+
}
|
|
1290
|
+
function severityBucketOf(severity, depth = 0) {
|
|
1291
|
+
if (severity === null || severity === undefined) {
|
|
1292
|
+
return null;
|
|
1266
1293
|
}
|
|
1267
|
-
|
|
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'];
|
|
@@ -1387,8 +1449,8 @@ function reasonOf(status) {
|
|
|
1387
1449
|
* e' un esito (`unverifiable`), non un errore da gestire in ogni chiamante.
|
|
1388
1450
|
*/
|
|
1389
1451
|
async function resolvePath(catalog, root, path, options) {
|
|
1390
|
-
const trimmed = (path ?? '')
|
|
1391
|
-
const segments = trimmed.split('.').map((segment) => segment
|
|
1452
|
+
const trimmed = (path ?? '')?.trim();
|
|
1453
|
+
const segments = trimmed.split('.').map((segment) => segment?.trim());
|
|
1392
1454
|
const levels = [];
|
|
1393
1455
|
const resolved = [];
|
|
1394
1456
|
const base = { root, path: trimmed, segments, levels, resolved };
|
|
@@ -3541,7 +3603,7 @@ class ElementPaletteComponent {
|
|
|
3541
3603
|
return items;
|
|
3542
3604
|
}, ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
3543
3605
|
groups = computed(() => {
|
|
3544
|
-
const needle = this.filter()
|
|
3606
|
+
const needle = this.filter()?.trim().toLowerCase();
|
|
3545
3607
|
const groups = [];
|
|
3546
3608
|
for (const item of this.items()) {
|
|
3547
3609
|
// La ricerca guarda anche l'etichetta del tipo: cercando «ordina o filtra» si trovano
|
|
@@ -3735,7 +3797,7 @@ class ReferencePickerComponent {
|
|
|
3735
3797
|
* l'editor non deve accusare cio' che il backend non verifica.
|
|
3736
3798
|
*/
|
|
3737
3799
|
navigableRoot = computed(() => {
|
|
3738
|
-
const root = referenceRoot((this.value() ?? '')
|
|
3800
|
+
const root = referenceRoot((this.value() ?? '')?.trim());
|
|
3739
3801
|
if (!root) {
|
|
3740
3802
|
return undefined;
|
|
3741
3803
|
}
|
|
@@ -3753,7 +3815,7 @@ class ReferencePickerComponent {
|
|
|
3753
3815
|
/** Il percorso dopo la radice: `Cliente.Email` di `Richiesta.Cliente.Email`. */
|
|
3754
3816
|
navigatedPath = computed(() => {
|
|
3755
3817
|
const root = this.navigableRoot()?.reference.name;
|
|
3756
|
-
const value = (this.value() ?? '')
|
|
3818
|
+
const value = (this.value() ?? '')?.trim();
|
|
3757
3819
|
return root && value.length > root.length ? value.slice(root.length + 1) : '';
|
|
3758
3820
|
}, ...(ngDevMode ? [{ debugName: "navigatedPath" }] : []));
|
|
3759
3821
|
navigation = navigatePath(this.catalog, () => {
|
|
@@ -3790,7 +3852,7 @@ class ReferencePickerComponent {
|
|
|
3790
3852
|
}));
|
|
3791
3853
|
}, ...(ngDevMode ? [{ debugName: "pathReferences" }] : []));
|
|
3792
3854
|
options = computed(() => {
|
|
3793
|
-
const needle = this.query()
|
|
3855
|
+
const needle = this.query()?.trim().toLowerCase();
|
|
3794
3856
|
// Le globali assegnabili — `$Flow.CurrentStage`, `$Flow.ActiveStages` e quelle che l'host
|
|
3795
3857
|
// dichiara scrivibili — le comprende già `POST /flows/references/writable`: aggiungerle
|
|
3796
3858
|
// qui le duplicherebbe (§5.2, §6.4).
|
|
@@ -3861,7 +3923,7 @@ class ReferencePickerComponent {
|
|
|
3861
3923
|
* risponderebbe `GLOBAL_UNKNOWN`.
|
|
3862
3924
|
*/
|
|
3863
3925
|
valueState = computed(() => {
|
|
3864
|
-
const value = (this.value() ?? '')
|
|
3926
|
+
const value = (this.value() ?? '')?.trim();
|
|
3865
3927
|
if (!value) {
|
|
3866
3928
|
return 'empty';
|
|
3867
3929
|
}
|
|
@@ -3978,7 +4040,7 @@ class ReferencePickerComponent {
|
|
|
3978
4040
|
}
|
|
3979
4041
|
/** Scrittura libera: indispensabile per gli scope dell'host e per i percorsi non enumerabili. */
|
|
3980
4042
|
onManualInput(value) {
|
|
3981
|
-
this.valueChange.emit(value
|
|
4043
|
+
this.valueChange.emit(value?.trim() ? value?.trim() : undefined);
|
|
3982
4044
|
}
|
|
3983
4045
|
clear() {
|
|
3984
4046
|
this.valueChange.emit(undefined);
|
|
@@ -4044,8 +4106,8 @@ class ObjectPickerComponent {
|
|
|
4044
4106
|
* resterebbe nella casella pur non essendo piu' il valore del documento.
|
|
4045
4107
|
*/
|
|
4046
4108
|
effect(() => {
|
|
4047
|
-
const value = (this.value() ?? '')
|
|
4048
|
-
if (value !== (untracked(this.query) ?? '')
|
|
4109
|
+
const value = (this.value() ?? '')?.trim();
|
|
4110
|
+
if (value !== (untracked(this.query) ?? '')?.trim()) {
|
|
4049
4111
|
this.query.set(null);
|
|
4050
4112
|
}
|
|
4051
4113
|
});
|
|
@@ -4053,7 +4115,7 @@ class ObjectPickerComponent {
|
|
|
4053
4115
|
/** Quel che si vede nella casella: il filtro se si sta digitando, il valore altrimenti. */
|
|
4054
4116
|
text = computed(() => this.query() ?? this.value() ?? '', ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
4055
4117
|
options = computed(() => {
|
|
4056
|
-
const needle = (this.query() ?? '')
|
|
4118
|
+
const needle = (this.query() ?? '')?.trim().toLowerCase();
|
|
4057
4119
|
const all = this.objects();
|
|
4058
4120
|
if (!needle) {
|
|
4059
4121
|
return all;
|
|
@@ -4066,14 +4128,14 @@ class ObjectPickerComponent {
|
|
|
4066
4128
|
* "non lo so" non e' "non esiste".
|
|
4067
4129
|
*/
|
|
4068
4130
|
isUnknown = computed(() => {
|
|
4069
|
-
const value = (this.value() ?? '')
|
|
4131
|
+
const value = (this.value() ?? '')?.trim();
|
|
4070
4132
|
if (!value || !this.hasCatalog()) {
|
|
4071
4133
|
return false;
|
|
4072
4134
|
}
|
|
4073
4135
|
return !this.objects().some((object) => object.name === value);
|
|
4074
4136
|
}, ...(ngDevMode ? [{ debugName: "isUnknown" }] : []));
|
|
4075
4137
|
labelOfValue = computed(() => {
|
|
4076
|
-
const value = (this.value() ?? '')
|
|
4138
|
+
const value = (this.value() ?? '')?.trim();
|
|
4077
4139
|
const found = this.objects().find((object) => object.name === value);
|
|
4078
4140
|
return found?.label && found.label !== found.name ? found.label : null;
|
|
4079
4141
|
}, ...(ngDevMode ? [{ debugName: "labelOfValue" }] : []));
|
|
@@ -4095,7 +4157,7 @@ class ObjectPickerComponent {
|
|
|
4095
4157
|
onInput(text) {
|
|
4096
4158
|
this.query.set(text);
|
|
4097
4159
|
this.open();
|
|
4098
|
-
this.valueChange.emit(text
|
|
4160
|
+
this.valueChange.emit(text?.trim() ? text?.trim() : undefined);
|
|
4099
4161
|
}
|
|
4100
4162
|
choose(object) {
|
|
4101
4163
|
this.valueChange.emit(object.name);
|
|
@@ -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()\">\
|
|
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()\">\
|
|
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
|
/**
|
|
@@ -4170,8 +4232,8 @@ class FieldPickerComponent {
|
|
|
4170
4232
|
// Vedi ObjectPickerComponent: il filtro sopravvive alla propria scrittura, non a un
|
|
4171
4233
|
// valore che arriva da fuori (un'altra riga della lista, un altro elemento).
|
|
4172
4234
|
effect(() => {
|
|
4173
|
-
const value = (this.value() ?? '')
|
|
4174
|
-
if (value !== (untracked(this.query) ?? '')
|
|
4235
|
+
const value = (this.value() ?? '')?.trim();
|
|
4236
|
+
if (value !== (untracked(this.query) ?? '')?.trim()) {
|
|
4175
4237
|
this.query.set(null);
|
|
4176
4238
|
}
|
|
4177
4239
|
});
|
|
@@ -4189,7 +4251,7 @@ class FieldPickerComponent {
|
|
|
4189
4251
|
if (!tail) {
|
|
4190
4252
|
return [];
|
|
4191
4253
|
}
|
|
4192
|
-
const needle = tail.segment
|
|
4254
|
+
const needle = tail.segment?.trim().toLowerCase();
|
|
4193
4255
|
if (!needle) {
|
|
4194
4256
|
return tail.level.entries;
|
|
4195
4257
|
}
|
|
@@ -4257,7 +4319,7 @@ class FieldPickerComponent {
|
|
|
4257
4319
|
onInput(text) {
|
|
4258
4320
|
this.query.set(text);
|
|
4259
4321
|
this.open();
|
|
4260
|
-
this.valueChange.emit(text
|
|
4322
|
+
this.valueChange.emit(text?.trim() ? text?.trim() : undefined);
|
|
4261
4323
|
}
|
|
4262
4324
|
choose(entry) {
|
|
4263
4325
|
this.valueChange.emit(`${this.prefix()}${entry.name}`);
|
|
@@ -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()\">\
|
|
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()\">\
|
|
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
|
/**
|
|
@@ -4331,15 +4393,15 @@ class NamePickerComponent {
|
|
|
4331
4393
|
constructor() {
|
|
4332
4394
|
// Vedi ObjectPickerComponent: il filtro non sopravvive a un valore che arriva da fuori.
|
|
4333
4395
|
effect(() => {
|
|
4334
|
-
const value = (this.value() ?? '')
|
|
4335
|
-
if (value !== (untracked(this.query) ?? '')
|
|
4396
|
+
const value = (this.value() ?? '')?.trim();
|
|
4397
|
+
if (value !== (untracked(this.query) ?? '')?.trim()) {
|
|
4336
4398
|
this.query.set(null);
|
|
4337
4399
|
}
|
|
4338
4400
|
});
|
|
4339
4401
|
}
|
|
4340
4402
|
text = computed(() => this.query() ?? this.value() ?? '', ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
4341
4403
|
visibleOptions = computed(() => {
|
|
4342
|
-
const needle = (this.query() ?? '')
|
|
4404
|
+
const needle = (this.query() ?? '')?.trim().toLowerCase();
|
|
4343
4405
|
const all = this.options();
|
|
4344
4406
|
if (!needle) {
|
|
4345
4407
|
return all;
|
|
@@ -4348,14 +4410,14 @@ class NamePickerComponent {
|
|
|
4348
4410
|
}, ...(ngDevMode ? [{ debugName: "visibleOptions" }] : []));
|
|
4349
4411
|
hasOptions = computed(() => this.options().length > 0, ...(ngDevMode ? [{ debugName: "hasOptions" }] : []));
|
|
4350
4412
|
isUnknown = computed(() => {
|
|
4351
|
-
const value = (this.value() ?? '')
|
|
4413
|
+
const value = (this.value() ?? '')?.trim();
|
|
4352
4414
|
if (!value || !this.hasOptions()) {
|
|
4353
4415
|
return false;
|
|
4354
4416
|
}
|
|
4355
4417
|
return !this.options().some((option) => option.name === value);
|
|
4356
4418
|
}, ...(ngDevMode ? [{ debugName: "isUnknown" }] : []));
|
|
4357
4419
|
labelOfValue = computed(() => {
|
|
4358
|
-
const value = (this.value() ?? '')
|
|
4420
|
+
const value = (this.value() ?? '')?.trim();
|
|
4359
4421
|
const found = this.options().find((option) => option.name === value);
|
|
4360
4422
|
return found ? this.describe(found) || null : null;
|
|
4361
4423
|
}, ...(ngDevMode ? [{ debugName: "labelOfValue" }] : []));
|
|
@@ -4375,7 +4437,7 @@ class NamePickerComponent {
|
|
|
4375
4437
|
onInput(text) {
|
|
4376
4438
|
this.query.set(text);
|
|
4377
4439
|
this.open();
|
|
4378
|
-
this.valueChange.emit(text
|
|
4440
|
+
this.valueChange.emit(text?.trim() ? text?.trim() : undefined);
|
|
4379
4441
|
}
|
|
4380
4442
|
choose(option) {
|
|
4381
4443
|
this.valueChange.emit(option.name);
|
|
@@ -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()\">\
|
|
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()\">\
|
|
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"] }] } });
|
|
@@ -4527,8 +4589,8 @@ class StructureMemberPickerComponent {
|
|
|
4527
4589
|
// Vedi ObjectPickerComponent: il filtro sopravvive alla propria scrittura, non a un valore
|
|
4528
4590
|
// che arriva da fuori (un'altra riga della lista, un altro elemento).
|
|
4529
4591
|
effect(() => {
|
|
4530
|
-
const value = (this.value() ?? '')
|
|
4531
|
-
if (value !== (untracked(this.query) ?? '')
|
|
4592
|
+
const value = (this.value() ?? '')?.trim();
|
|
4593
|
+
if (value !== (untracked(this.query) ?? '')?.trim()) {
|
|
4532
4594
|
this.query.set(null);
|
|
4533
4595
|
}
|
|
4534
4596
|
});
|
|
@@ -4554,7 +4616,7 @@ class StructureMemberPickerComponent {
|
|
|
4554
4616
|
return entries.filter((entry) => entry.isWritable || !!entry.next);
|
|
4555
4617
|
}, ...(ngDevMode ? [{ debugName: "available" }] : []));
|
|
4556
4618
|
options = computed(() => {
|
|
4557
|
-
const needle = (this.tail()?.segment ?? '')
|
|
4619
|
+
const needle = (this.tail()?.segment ?? '')?.trim().toLowerCase();
|
|
4558
4620
|
const all = this.available();
|
|
4559
4621
|
if (!needle) {
|
|
4560
4622
|
return all;
|
|
@@ -4641,7 +4703,7 @@ class StructureMemberPickerComponent {
|
|
|
4641
4703
|
onInput(text) {
|
|
4642
4704
|
this.query.set(text);
|
|
4643
4705
|
this.open();
|
|
4644
|
-
this.valueChange.emit(text
|
|
4706
|
+
this.valueChange.emit(text?.trim() ? text?.trim() : undefined);
|
|
4645
4707
|
}
|
|
4646
4708
|
choose(entry) {
|
|
4647
4709
|
this.valueChange.emit(`${this.prefix()}${entry.name}`);
|
|
@@ -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()\">\
|
|
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()\">\
|
|
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
|
/**
|
|
@@ -5148,7 +5210,7 @@ class ConditionEditorComponent {
|
|
|
5148
5210
|
// Assente = tutte le condizioni devono essere vere (§4.3).
|
|
5149
5211
|
return 'and';
|
|
5150
5212
|
}
|
|
5151
|
-
const normalized = logic
|
|
5213
|
+
const normalized = logic?.trim().toLowerCase();
|
|
5152
5214
|
if (normalized === 'and') {
|
|
5153
5215
|
return 'and';
|
|
5154
5216
|
}
|
|
@@ -5413,7 +5475,7 @@ class RecordFilterEditorComponent {
|
|
|
5413
5475
|
if (!logic) {
|
|
5414
5476
|
return 'and';
|
|
5415
5477
|
}
|
|
5416
|
-
const normalized = logic
|
|
5478
|
+
const normalized = logic?.trim().toLowerCase();
|
|
5417
5479
|
if (normalized === 'and') {
|
|
5418
5480
|
return 'and';
|
|
5419
5481
|
}
|
|
@@ -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
|
/**
|