@esfaenza/flow-builder 20.3.2 → 20.3.4
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.
- package/README.md +59 -14
- package/fesm2022/esfaenza-flow-builder.mjs +917 -154
- package/fesm2022/esfaenza-flow-builder.mjs.map +1 -1
- package/index.d.ts +466 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,6 +142,7 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
|
|
|
142
142
|
| `listForms` / `listFormParameters` | astratti |
|
|
143
143
|
| `listEnumTypes`, `listEvents`, `listSubflowCandidates` | astratti |
|
|
144
144
|
| `describeObject`, `listFieldValues` | opzionali |
|
|
145
|
+
| `listStructures`, `describeStructure(className)` | opzionali — le classi e i loro membri per le risorse `Structure` (§4.7). `listStructures` e' l'**elenco delle classi** senza membri; `describeStructure` restituisce la **descrizione** di una classe (`className`, `label`, `members`), non un array nudo (§4.7.1). Senza, le classi non sono verificabili e il nome si scrive a mano: "non lo so", non "non esiste". I tre esiti sono distinti: `members` popolato = elenco autorevole, `members: []` = membri non dichiarati (si digita, nessuna accusa), rifiuto `StructureNotFound` = classe non registrata (si segnala la **classe**) |
|
|
145
146
|
|
|
146
147
|
| §6.5 Esecuzione | |
|
|
147
148
|
|---|---|
|
|
@@ -202,6 +203,15 @@ qualsiasi.
|
|
|
202
203
|
dalla mappa delle uscite invece di essere «ramo di errore» per tutti: su uno stage di
|
|
203
204
|
orchestrazione quel ramo e' lo **step rifiutato**, non un guasto.
|
|
204
205
|
|
|
206
|
+
Un tipo con un **discriminatore** compare come piu' voci, una per valore: il Collection
|
|
207
|
+
Processor e' «Ordina» e «Filtra», non «ordina o filtra». Sono due gesti diversi — un `Sort`
|
|
208
|
+
vuole `sortOptions`, un `Filter` vuole condizioni (§5.5) — e sceglierli dalla palette evita di
|
|
209
|
+
sceglierli dopo, dentro il form. L'elemento nasce con il discriminatore già scritto, con la
|
|
210
|
+
label della variante (da cui viene anche il nome tecnico) e con il glifo della variante, lo
|
|
211
|
+
stesso che avra' sul canvas. `core/element-variants.ts` tiene la mappa tipo → campo del
|
|
212
|
+
discriminatore; i valori restano nel dizionario del backend (`collectionProcessorTypes`), e
|
|
213
|
+
senza quel dizionario il tipo torna a essere una voce sola.
|
|
214
|
+
|
|
205
215
|
**Inspector.** Un form per ogni tipo supportato: Start, Screen, Assignment, Decision, Loop,
|
|
206
216
|
Collection Processor, Get / Create / Update / Delete / Rollback Records, Action, Script,
|
|
207
217
|
Subflow, Wait, Custom Error, Transform, Orchestrated Stage. Più l'intestazione comune con la
|
|
@@ -215,8 +225,29 @@ fa fallire l'interview. Una condizione che referenzia l'output di un altro step
|
|
|
215
225
|
con la via d'uscita: scrivere quel risultato in una variabile.
|
|
216
226
|
|
|
217
227
|
**Risorse.** I sette tipi, con i vincoli visibili: `dataType` obbligatorio, `objectType` per
|
|
218
|
-
`Object` / `Enum`, `scale` solo sui numerici, costanti che non possono referenziare
|
|
219
|
-
`stageOrder` distinti.
|
|
228
|
+
`Object` / `Enum` / `Structure`, `scale` solo sui numerici, costanti che non possono referenziare
|
|
229
|
+
risorse, `stageOrder` distinti.
|
|
230
|
+
|
|
231
|
+
**Classi (`Structure`).** L'ottavo tipo di dato non e' un doppione di `Object` (§4.7): di
|
|
232
|
+
un'istanza di classe il flow legge e scrive i **membri**. Cambia quindi il form: la classe si
|
|
233
|
+
scoglie con `<fb-structure-picker>` e la sua assenza e' un **errore** — senza classe il runtime
|
|
234
|
+
non ha nulla da istanziare — mentre il campo «valore iniziale» non c'e' affatto, perche' non
|
|
235
|
+
esiste un `structureValue` e la variabile parte con un'istanza vuota. I membri si scelgono con
|
|
236
|
+
`<fb-structure-member-picker>`, e nelle destinazioni si propongono **solo** quelli scrivibili: un
|
|
237
|
+
membro calcolato si legge in una condizione ma assegnarlo e' `TARGET_NOT_WRITABLE`. Lo stesso
|
|
238
|
+
vale dentro `<fb-reference-picker>`, dove i membri di una variabile `Structure` sono l'unica
|
|
239
|
+
eccezione ai percorsi non verificati: `Richiesta.Ragione` si propone e il **primo** segmento si
|
|
240
|
+
verifica (`STRUCTURE_MEMBER_UNKNOWN`), oltre quello si torna a "non lo so" — la descrizione della
|
|
241
|
+
classe e' piatta, e i membri di una classe annidata sono una seconda chiamata (§4.7.1). Un
|
|
242
|
+
Transform con target `Structure` compone l'istanza intera in un elemento solo: lì
|
|
243
|
+
`outputFieldApiName` e' il nome di un membro, e il form lo dice invece di far indovinare (§5.12).
|
|
244
|
+
|
|
245
|
+
Dei tre esiti di `describeStructure` il picker mostra tre messaggi diversi, perche' portano a
|
|
246
|
+
gesti opposti: con l'elenco autorevole un nome fuori elenco e' un errore; con `members: []` la
|
|
247
|
+
classe e' valida ma i membri non sono dichiarati e il nome si **digita**, senza accuse; con un
|
|
248
|
+
404 (`StructureNotFound`) e' la **classe** a essere sbagliata, e il messaggio manda a correggere
|
|
249
|
+
quella invece del membro. L'intestazione dell'elenco usa la `label` della classe, che e' la
|
|
250
|
+
ragione per cui la risposta ha un involucro invece di essere un array.
|
|
220
251
|
|
|
221
252
|
**Oggetti e campi.** Ogni punto che chiede un'entita' o un suo campo usa lo stesso controllo:
|
|
222
253
|
`<fb-object-picker>` e `<fb-field-picker>`, una casella con autocomplete che filtra il catalogo
|
|
@@ -226,18 +257,31 @@ campo di testo cieco. La scrittura libera e' voluta — i percorsi di relazione
|
|
|
226
257
|
(`Cliente.Citta`) non sono enumerabili e il catalogo dell'host puo' essere incompleto — ma un
|
|
227
258
|
nome fuori catalogo viene segnalato subito, prima che il backend risponda `OBJECT_UNKNOWN` o
|
|
228
259
|
`FIELD_UNKNOWN`. Il campo si chiede sempre con l'uso giusto (`filterable`, `sortable`,
|
|
229
|
-
`updateable`), che decide sia l'elenco sia il testo dell'avviso: "non filtrabile"
|
|
230
|
-
aggiornabile"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
260
|
+
`updateable`, `createable`), che decide sia l'elenco sia il testo dell'avviso: "non filtrabile",
|
|
261
|
+
"non aggiornabile" e "non valorizzabile alla creazione" sono errori diversi. In particolare
|
|
262
|
+
`createable` e `updateable` **non** sono sinonimi (§5.7): un Create propone i primi, un Update i
|
|
263
|
+
secondi, e il validatore usa il codice giusto per l'elemento (`FIELD_NOT_CREATEABLE` /
|
|
264
|
+
`FIELD_NOT_UPDATEABLE`). Per lo stesso motivo l'editor non da' per scontato che `Id` sia
|
|
265
|
+
filtrabile: su una chiave composta porta la forma canonica della chiave e non e' filtrabile,
|
|
266
|
+
quindi l'editor dice di filtrare per le colonne della chiave invece di far cercare un campo che
|
|
267
|
+
nell'elenco non c'e'. Restano `<select>` i dizionari chiusi — tipi di dato, operatori,
|
|
268
|
+
enumerazioni — dove non c'e' niente da scrivere a mano.
|
|
269
|
+
|
|
270
|
+
Lo stesso controllo, nella variante `<fb-name-picker>`, vale per **ogni altro nome che il flow
|
|
271
|
+
prende da fuori**: tipo di action e action, script, form, i nomi dei loro parametri di ingresso
|
|
272
|
+
e di uscita, il flow di uno step in background e dei suoi evaluation flow, il flow invocato da
|
|
273
|
+
un Subflow e le variabili di input e output **del flow invocato**. Qui l'elenco arriva da chi
|
|
274
|
+
ospita il picker — il catalogo già caricato per altri motivi, `listSubflowCandidates`, le
|
|
275
|
+
variabili della definizione caricata — perche' dipende dal contesto: le action dipendono dal
|
|
276
|
+
tipo scelto, i parametri dall'action, le variabili dal subflow.
|
|
277
|
+
|
|
278
|
+
Un elenco vuoto resta "non lo so": il campo si scrive a mano e non si accusa nessun nome. Con
|
|
279
|
+
l'elenco popolato, un nome che non c'e' e' segnalato, e con la **gravita' giusta**: un'action,
|
|
280
|
+
un form, uno script o un parametro inesistenti sono errori che bloccano l'attivazione
|
|
281
|
+
(`ACTION_UNKNOWN`, `FORM_UNKNOWN`, `PARAMETER_UNKNOWN`) e si mostrano in rosso; un flow senza
|
|
282
|
+
versione attiva e' un avviso. Prima questi campi erano `<select>` con un'opzione sintetica
|
|
283
|
+
«(non nel catalogo)» per non perdere il valore, oppure un `datalist` che accettava qualunque
|
|
284
|
+
cosa in silenzio: il primo non si poteva cercare, il secondo non diceva niente.
|
|
241
285
|
|
|
242
286
|
**Problemi.** Pannello con filtro per gravita', navigazione all'elemento con un clic,
|
|
243
287
|
validazione su pausa di digitazione (debounce 400 ms) e l'avvertenza che l'assenza di rilievi
|
|
@@ -367,6 +411,7 @@ distribuire e nessuna dipendenza da un font di icone dell'applicazione ospite.
|
|
|
367
411
|
| 13 | **Testo e numero non si confrontano** (`CONDITION_TYPE_MISMATCH`) | `ConditionEditorComponent` conosce il tipo del lato sinistro da `POST /flows/references`: filtra gli operatori applicabili, guida il campo del letterale del secondo operando e segnala la coppia vietata. La regola sta in `core/condition-types.util.ts`, che salta gli operatori con semantica propria (`Contains`, `In`, …). I numeri si scrivono in cultura invariante: `1234,50` viene tradotto in `1234.50`, non troncato |
|
|
368
412
|
| 14 | **`None` non e' un operatore, e' un "da completare"** | Condizione evidenziata come incompleta, con il conteggio in testa alla sezione e la frase «la bozza si salva, l'attivazione no»; il validatore della demo lo emette come **errore** |
|
|
369
413
|
| 15 | **Un valore data senza `Z` significa ora locale** | `ValueEditorComponent` ha un selettore «Ora locale / UTC (Z)», dice che cambiare fuso riscrive l'orario e non lo converte, e toglie il suffisso solo per il controllo `datetime-local`, che con il fuso resterebbe vuoto |
|
|
414
|
+
| 16 | **`Structure` e `Object` non sono intercambiabili** | `StructurePickerComponent` per la classe (fuori catalogo = **errore**, `STRUCTURE_TYPE_UNKNOWN`) e `StructureMemberPickerComponent` per i membri, filtrati su `isWritable` dove serve una destinazione. Il pannello risorse mostra la classe come obbligatoria con severita' di errore e **non** mostra il valore iniziale, perche' un `structureValue` non esiste; `ReferencePickerComponent` propone `Variabile.Membro` e verifica il primo segmento; il Transform con target classe chiede un membro invece di un campo. `FlowDictionaryStore.isStructure` legge il flag dal dizionario, non dal nome del tipo. La risposta dei membri e' la **descrizione della classe** (`{className, label, members}`), e i suoi tre esiti restano distinti fino alla UI: `FlowCatalogStore.describeStructure` li traduce in `declared` / `undeclared` / `unknown-class` / `unknown-catalog`, e solo `declared` autorizza a dire che un membro non esiste (§4.7.1) |
|
|
370
415
|
|
|
371
416
|
Altre regole del contratto rispettate: liste vuote omesse invece di scritte come `[]` (§2),
|
|
372
417
|
`filterLogic` mostrato **solo** dove il modello lo prevede (§4.4), `fullName` / `status` mai
|