@esfaenza/flow-builder 20.3.39 → 20.3.41

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 CHANGED
@@ -349,7 +349,11 @@ Tre cose che il modello non mostra e il form dice:
349
349
  - le regole di visibilita' si rivalutano **sui valori appena inviati**, i campi nascosti vengono
350
350
  **azzerati** e solo i visibili vengono validati;
351
351
  - `choiceReferences` accetta **solo** `Choice` e `DynamicChoiceSet`, e gli output automatici di un
352
- `ComponentInstance` sono esclusivi con i suoi `outputParameters`.
352
+ `ComponentInstance` sono esclusivi con i suoi `outputParameters`;
353
+ - `autoSelectSingleChoice` fa prendere al campo l'**unica** opzione risolta, quando e' una sola: e'
354
+ la tendina che dipende da un'altra tendina — i CAP di un comune — dove chiedere di scegliere non
355
+ decide niente. La spunta compare solo dove il tipo `acceptsChoices`, e altrove e'
356
+ `SCREEN_FIELD_CONFIGURATION_INVALID` (avviso).
353
357
 
354
358
  Il riordino e l'annidamento si fanno trascinando (`@angular/cdk/drag-drop`, senza drop list: il
355
359
  bersaglio si calcola dal DOM) oppure con i comandi «su / giu' / porta fuori».
@@ -400,7 +404,9 @@ Le tre cose che riguardano l'editor, e non il runtime:
400
404
  - **un trigger senza campo e senza `initBehavior` non scattera' mai**
401
405
  (`SCREEN_TRIGGER_WITHOUT_CAUSE`), e l'unico `initBehavior` ammesso e' `runOnLoad` — il
402
406
  `runOnRevisit` della specifica Salesforce e' `SCREEN_TRIGGER_INIT_BEHAVIOR_UNKNOWN`, e vale la
403
- pena saperlo perche' chi arriva da quella specifica lo scrive per abitudine.
407
+ pena saperlo perche' chi arriva da quella specifica lo scrive per abitudine. Dove il campo
408
+ osservato ha un `defaultValue` il form dice che `runOnLoad` **non serve**: un campo precompilato
409
+ dal flow conta come un campo che ha preso un valore, e l'action gira comunque all'arrivo.
404
410
 
405
411
  Le action si aprono **una alla volta**: i cataloghi delle action e dei loro parametri dipendono da
406
412
  `actionType`/`actionName`, e tenerne N in volo sarebbe N volte la corsa fra risposte che l'inspector
@@ -489,6 +495,16 @@ sapere: le globali sono di sola lettura, membri compresi — le assegnabili sono
489
495
  `$Flow.ActiveStages` e i campi di `$Record` — e il picker lo dice con `TARGET_NOT_WRITABLE` invece
490
496
  di far sembrare il nome inesistente (§5.2).
491
497
 
498
+ **Uno scope puo' nominarsi da solo.** `$Profile` senza percorso e' un riferimento valido se — e solo
499
+ se — l'host lo dichiara così, con una voce **senza punto** che porta il suo `dataType` e il suo
500
+ `objectType` (§4.1): e' come un host espone l'utente corrente come un'unica istanza invece di
501
+ elencarne i campi, e da lì la navigazione riparte, quindi `$Profile.Livello` si verifica sui membri
502
+ della classe senza che il catalogo dichiari un percorso per ognuno. Il prefisso dichiarato piu' lungo
503
+ e' la stessa regola di prima: la voce senza punto e' il prefisso **vuoto**, cioe' quello che vince
504
+ solo quando nessun altro corrisponde. Dove lo scope dichiara percorsi ma non la voce senza punto,
505
+ `$Profile` da solo resta `GLOBAL_UNKNOWN`: nella demo e' la differenza fra `$Profile` (dichiarato
506
+ così) e `$User` (che dichiara i suoi campi).
507
+
492
508
  Su una destinazione la colonna che decide non e' la stessa nei due mondi: un membro porta il proprio
493
509
  `isWritable`, un campo no. Fuori da un Create o da un Update il contesto non c'e' — un Assignment su
494
510
  `Cliente.Codice` non sa se quel record verra' creato o aggiornato — quindi lì basta `isCreateable`
@@ -575,6 +591,19 @@ aggiunte. Tre esiti restano distinti e nessuno dei tre e' «formula valida»: pr
575
591
  stata controllata), `isValid` (verificata davvero, ed e' l'unico caso con la spunta verde) — una
576
592
  spunta su un'espressione mai controllata e' peggio di nessuna spunta.
577
593
 
594
+ **Testo con merge field (§5.12).** Il messaggio di un Custom Error non e' una casella di testo
595
+ qualunque: supporta i segnaposto `{!...}` come il testo di un text template e le scritte di uno screen
596
+ dinamico, e lì servono piu' che altrove — *«L'ordine e' già stato evaso»* senza il numero dell'ordine e'
597
+ meta' messaggio. Lo monta `<fb-merge-text-editor>`, ed e' un componente diverso dall'editor di formule
598
+ perche' il contenuto e' diverso: qui c'e' una **frase**, con dentro delle isole. Tre conseguenze. Offre
599
+ l'**inserimento** di un riferimento (un bottone con l'elenco, piu' i suggerimenti mentre si scrive dentro
600
+ un `{!` aperto), e scrive l'isola intera, graffe comprese: la sintassi non deve stare a memoria. Manda il
601
+ testo al motore **solo se contiene `{!`**, perche' una frase in italiano mandata a un motore di
602
+ espressioni si farebbe accusare parola per parola. E gli esiti restano i tre delle formule, con la stessa
603
+ regola: nessuna spunta su un testo che nessuno ha guardato. Lo stesso controllo avviene nella validazione
604
+ del documento, con `usage: "Text"` e il rilievo sul path `customErrorMessages[n].errorMessage`: un refuso
605
+ dentro una graffa non si scopre davanti a chi sta usando il flow.
606
+
578
607
  **Un campo a `null` e' assente.** Il valore ha un campo per tipo e va valorizzato **uno e un solo**
579
608
  campo (§4.2); la §2 dice che cio' che non c'e' si omette, ma un backend che serializza tutte le
580
609
  proprieta' — `System.Text.Json` senza `IgnoreNullValues` lo fa di default — manda
@@ -849,7 +878,7 @@ distribuire e nessuna dipendenza da un font di icone dell'applicazione ospite.
849
878
  | 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 |
850
879
  | 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** |
851
880
  | 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 |
852
- | 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 percorso **fino in fondo** con `core/path-navigation.ts`, con `PATH_NOT_VERIFIABLE` dove la catena si interrompe; 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) |
881
+ | 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` **soltanto** con `usage="writable"`, cioe' dove serve una destinazione: un membro calcolato si legge — in una condizione, in una formula, in un valore — e filtrarlo ovunque renderebbe invisibili proprio i membri derivati (§13.16). 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 percorso **fino in fondo** con `core/path-navigation.ts`, con `PATH_NOT_VERIFIABLE` dove la catena si interrompe; 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) |
853
882
  | 17 | **Due body diversi per due famiglie di primitive** | `HttpFlowBuilderApi`: le primitive che **analizzano** il documento — `validate`, `parse`, `references`, `references/writable`, `connector-targets`, `outline` — lo mandano **nudo alla radice**; l'involucro `{definition, flowName, …}` resta alle sole primitive di scrittura della §6.2. Sbagliare involucro non da' nessun errore: il backend legge un flow vuoto e risponde `200`. Per lo stesso motivo `getReferences`/`getWritableReferences` prendono la `FlowDefinition` e non un oggetto query: non c'e' nessun campo di filtro nel body, e il filtro di tipo lo applica l'editor con `core/reference-filter.util.ts` |
854
883
  | 18 | **Gli enum si scrivono come stringhe** | Il modello e' fatto di unioni di stringhe letterali (`FlowDataType`, `FlowVersionStatus`, …) e non di enum numerici: `JSON.stringify` non ha modo di produrre un ordinale. Conta perche' `"status": 3` non e' `Draft` ma `InvalidDraft` e `"dataType": 0` e' `String`, non "non specificato" — nessun errore lo segnalerebbe. Chi scrive un'altra implementazione di `FlowBuilderApi` non traduca i valori in numeri |
855
884
  | 19 | **Un campo di screen dinamico e' una risorsa, ma di sola lettura** | Lo restituisce `POST /flows/references` con `kind: "ScreenField"`, e il reference picker lo propone in un gruppo suo; nei selettori di **destinazione** non compare, perche' `references/writable` lo esclude. L'unica eccezione e' l'`assignToReference` di una **screen action**, dove il campo di *quella* schermata e' una destinazione e l'elenco lo passa il chiamante (`extraReferences`). Il nome entra in `FlowDocumentStore.usedNames`, quindi un campo omonimo di una variabile e' `NAME_DUPLICATED`, e `renameScreenField` riscrive i riferimenti come `renameNode` |