@esfaenza/flow-builder 20.3.23 → 20.3.25
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 +30 -4
- package/fesm2022/esfaenza-flow-builder.mjs +357 -24
- package/fesm2022/esfaenza-flow-builder.mjs.map +1 -1
- package/index.d.ts +194 -9
- package/package.json +1 -1
- package/styles/flow-builder.css +96 -0
package/README.md
CHANGED
|
@@ -142,7 +142,8 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
|
|
|
142
142
|
| `listScripts` / `listScriptParameters` | astratti |
|
|
143
143
|
| `listForms(kind?)` / `listFormParameters` | astratti — **un catalogo, due ruoli** (§5.1, §5.2): le schermate intere di uno Screen (`formName`) e i componenti di uno screen dinamico (`extensionName`) stanno nello stesso elenco e si distinguono per `formKind`. `kind` vale `Form`, `Component` o assente per tutto; una voce **senza** `formKind` vale `Any` e resta proponibile in entrambi i posti, perche' un catalogo che il ruolo non lo dichiara non deve vietare tutto. Usare l'uno al posto dell'altro e' `FORM_KIND_MISMATCH`, che e' un errore **diverso** da «il nome non esiste». I parametri si chiedono per nome, uguali per i due ruoli |
|
|
144
144
|
| `listEnumTypes`, `listEvents`, `listSubflowCandidates` | astratti |
|
|
145
|
-
| `describeObject
|
|
145
|
+
| `describeObject` | opzionale |
|
|
146
|
+
| `listFieldValues(object, field)` | opzionale — i valori ammessi di un campo a **scelta chiusa** (`hasClosedValueSet`, §6.4), cioe' l'altra meta' degli insiemi chiusi: quelli di un `Enum` sono del **tipo** (`listEnumValues`), questi della **colonna** — `Ordine.Stato` e `Attivita.Stato` possono ammettere valori diversi pur essendo due `String`, ed e' perche' serve la coppia. Lista vuota = "non lo so": il valore si scrive a mano |
|
|
146
147
|
| `listEnumValues(enumType)` | opzionale — i **valori** di un tipo di enumerazione, cioe' i nomi scrivibili in `enumValue` (§4.2, §4.6). `listEnumTypes` e' l'altra meta' e non basta: quella dice quali tipi esistono, questa quali valori ha un tipo. `enumType` e' esattamente l'`objectType` della risorsa, del parametro o del **membro** di una classe (§4.7.1): la risposta e' del tipo, non del punto di uso, e la cache e' per nome del tipo. Lista vuota = "non lo so" — il valore si scrive a mano, e un tipo sconosciuto risponde vuoto, non 404 |
|
|
147
148
|
| `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**) |
|
|
148
149
|
|
|
@@ -163,7 +164,7 @@ throw new FlowApiError('VersionConflict', 'Ha salvato mrossi.', undefined, 'mros
|
|
|
163
164
|
```
|
|
164
165
|
|
|
165
166
|
Un'implementazione completa e commentata sta in
|
|
166
|
-
[`projects/
|
|
167
|
+
[`projects/flow-builder-example/src/app/backend/in-memory-flow-builder-api.ts`](../flow-builder-example/src/app/backend/in-memory-flow-builder-api.ts):
|
|
167
168
|
copre tutte le primitive, il ciclo di vita, la concorrenza ottimistica e un esecutore finto,
|
|
168
169
|
senza una sola richiesta di rete.
|
|
169
170
|
|
|
@@ -324,6 +325,19 @@ con la via d'uscita: scrivere quel risultato in una variabile.
|
|
|
324
325
|
`Object` / `Enum` / `Structure`, `scale` solo sui numerici, costanti che non possono referenziare
|
|
325
326
|
risorse, `stageOrder` distinti.
|
|
326
327
|
|
|
328
|
+
**Dynamic choice set.** Le sorgenti sono **tre e si escludono a vicenda** (§5.2): una collection
|
|
329
|
+
del flow, una query su un'entita', i valori di un **tipo enum**. Nel form sono tre pulsanti e non
|
|
330
|
+
tre campi da riempire a caso: sceglierne una cancella le altre — dichiararne due e'
|
|
331
|
+
`CHOICE_SET_SOURCE_AMBIGUOUS` — e cancella anche i campi citati, perche' `Label` non e' un campo
|
|
332
|
+
di un'entita' e `Ragione_Sociale` non e' una proprieta' di un valore di enum. Sulla sorgente enum
|
|
333
|
+
cambiano due cose: il tipo si sceglie da `listEnumTypes` e fuori catalogo e' un **errore**
|
|
334
|
+
(`ENUM_TYPE_UNKNOWN`, l'elenco qui e' autorevole quando non e' vuoto), e i campi citabili sono le
|
|
335
|
+
tre proprieta' di un valore — `Name`, `Label`, `NumericValue` — che arrivano dal dizionario
|
|
336
|
+
(`enumChoiceSetFields`) e non da un catalogo di campi. Le sa `core/enum-choice-set.util.ts`,
|
|
337
|
+
compreso il **tipo** di ciascuna: senza, il valore di un filtro su `NumericValue` sarebbe una
|
|
338
|
+
casella di testo. `displayField` e `valueField` hanno un default (`Label` e `Name`) e il form li
|
|
339
|
+
mostra come tali, cosi' non finiscono nel documento senza motivo.
|
|
340
|
+
|
|
327
341
|
**Classi (`Structure`).** L'ottavo tipo di dato non e' un doppione di `Object` (§4.7): di
|
|
328
342
|
un'istanza di classe il flow legge e scrive i **membri**. Cambia quindi il form: la classe si
|
|
329
343
|
scoglie con `<fb-structure-picker>` e la sua assenza e' un **errore** — senza classe il runtime
|
|
@@ -428,6 +442,18 @@ vuoto resta "non lo so" — primitiva non esposta, tipo senza valori dichiarati,
|
|
|
428
442
|
da scegliere — e allora il valore si digita; con l'elenco popolato un valore fuori elenco e' un
|
|
429
443
|
**avviso**, perche' nessun codice della §7 lo blocca ed e' l'editor ad accorgersene prima del runtime.
|
|
430
444
|
|
|
445
|
+
**Valori di un campo a scelta chiusa.** È lo stesso problema degli enum sull'altra meta' dello
|
|
446
|
+
schema: un campo che dichiara `hasClosedValueSet` ammette pochi valori e nessun tipo li porta con
|
|
447
|
+
se', quindi si chiedono con `listFieldValues(object, field)` (§4.4, §6.4). Li propone
|
|
448
|
+
`<fb-field-value-picker>`, che il `<fb-value-editor>` monta al posto della casella di testo quando
|
|
449
|
+
chi lo usa gli passa `[valueSet]`: oggi lo fa il **filtro sui record**, dove il campo e la sua
|
|
450
|
+
entita' si sanno — anche in fondo a un percorso di relazione, perche' il tipo dell'ultimo segmento lo
|
|
451
|
+
naviga `core/reference-path` e con lui arriva l'insieme chiuso. Nel documento va il **valore**, non
|
|
452
|
+
l'etichetta: «Da approvare» aiuta a riconoscere `DaApprovare` ma non e' cio' che il motore confronta.
|
|
453
|
+
Elenco vuoto = "non lo so" (primitiva non esposta, campo senza insieme dichiarato) e valore fuori
|
|
454
|
+
elenco = **avviso**, come per gli enum: la §7 non ha un codice per questo, e un filtro con un valore
|
|
455
|
+
inesistente non trova nessun record senza che niente lo segnali.
|
|
456
|
+
|
|
431
457
|
**Formule.** L'espressione va al motore di regole e la sua sintassi resta del motore: la libreria
|
|
432
458
|
non ha nessun parser. Cio' che ha e' il **controllo**, `validateFormula` (`POST /flows/validate-formula`,
|
|
433
459
|
§6.3), chiesto con debounce mentre si digita: risponde lo stesso motore, e i suoi rilievi portano la
|
|
@@ -525,7 +551,7 @@ questo pannello non ci sarebbe **nessun** posto in cui vedere cosa e' successo.
|
|
|
525
551
|
dati personali compresi: l'avviso e' in chiaro. Il pannello non conduce niente: guarda, e basta.
|
|
526
552
|
|
|
527
553
|
Come si implementa l'altra metà si vede nella demo
|
|
528
|
-
(`projects/
|
|
554
|
+
(`projects/flow-builder-example/src/app/runner`), e la scelta interessante e' **quando** aprire una finestra: un
|
|
529
555
|
flow che non ha niente da chiedere finisce da solo e l'esito torna subito all'editor, mentre uno
|
|
530
556
|
interattivo apre il runner e restituisce l'ultimo risultato alla chiusura — così la traccia resta
|
|
531
557
|
comunque lì dove si stava lavorando. Il runner guida l'interview con le primitive della §6.5,
|
|
@@ -655,7 +681,7 @@ distribuire e nessuna dipendenza da un font di icone dell'applicazione ospite.
|
|
|
655
681
|
| 9 | `Step` ed `Experiment` non sono supportati; `OrchestratedStage` lo e' | I due non supportati sono filtrati dalla palette via `isSupported` e, se arrivano da un import, l'inspector li mostra in sola lettura spiegando perche'. Lo stage ha il suo form: step non presentati come sequenza, e la condizione che referenzia l'output di un altro step segnalata con la via d'uscita |
|
|
656
682
|
| 10 | Un `Delete` senza filtri e' un **errore**, un `Update` senza filtri un **avviso** | `RecordWriteInspectorComponent`: severita' diverse, e l'update di massa chiede una conferma esplicita |
|
|
657
683
|
| 11 | Non cablare enum e operatori | Ogni tendina legge da `getDictionaries()`; le mappe locali intervengono solo come fallback quando il dizionario non e' disponibile |
|
|
658
|
-
| 12 | Il **token di continuazione e' opaco** | Non lo tocca nessuno nella libreria: l'editor non esegue, quindi il token nasce e muore nel runner dell'ospite. Quello della demo (`projects/
|
|
684
|
+
| 12 | Il **token di continuazione e' opaco** | Non lo tocca nessuno nella libreria: l'editor non esegue, quindi il token nasce e muore nel runner dell'ospite. Quello della demo (`projects/flow-builder-example/src/app/runner/interview-runner.component.ts`) lo rimanda tale e quale, non lo legge e non lo mette in nessun URL |
|
|
659
685
|
| 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 |
|
|
660
686
|
| 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** |
|
|
661
687
|
| 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 |
|