@esfaenza/flow-builder 20.3.2 → 20.3.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"esfaenza-flow-builder.mjs","sources":["../../../projects/flow-builder/src/lib/model/flow.model.ts","../../../projects/flow-builder/src/lib/model/dictionary.model.ts","../../../projects/flow-builder/src/lib/model/api.model.ts","../../../projects/flow-builder/src/lib/model/error.model.ts","../../../projects/flow-builder/src/lib/api/flow-builder-api.ts","../../../projects/flow-builder/src/lib/api/http-flow-builder-api.ts","../../../projects/flow-builder/src/lib/core/element-outlets.ts","../../../projects/flow-builder/src/lib/core/element-icons.ts","../../../projects/flow-builder/src/lib/core/flow-name.util.ts","../../../projects/flow-builder/src/lib/core/condition-logic.util.ts","../../../projects/flow-builder/src/lib/core/condition-types.util.ts","../../../projects/flow-builder/src/lib/core/stage-step.util.ts","../../../projects/flow-builder/src/lib/core/flow-document.store.ts","../../../projects/flow-builder/src/lib/core/flow-dictionary.store.ts","../../../projects/flow-builder/src/lib/core/flow-validation.store.ts","../../../projects/flow-builder/src/lib/core/flow-layout.service.ts","../../../projects/flow-builder/src/lib/core/flow-editor-session.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.model.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.component.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.component.html","../../../projects/flow-builder/src/lib/ui/palette/element-palette.component.ts","../../../projects/flow-builder/src/lib/ui/palette/element-palette.component.html","../../../projects/flow-builder/src/lib/ui/shared/reference-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/reference-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/object-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/object-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/field-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/field-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/name-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/name-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/select-value.directive.ts","../../../projects/flow-builder/src/lib/ui/shared/value-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/value-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/condition-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/condition-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/record-filter-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/record-filter-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/parameter-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/parameter-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/field-assignment-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/field-assignment-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/connector-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/connector-editor.component.html","../../../projects/flow-builder/src/lib/ui/inspector/node-inspector-base.ts","../../../projects/flow-builder/src/lib/ui/inspector/action-call-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/action-call-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/assignment-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/assignment-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/collection-processor-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/collection-processor-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/custom-error-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/custom-error-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/decision-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/decision-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/loop-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/loop-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/orchestrated-stage-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/orchestrated-stage-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-lookup-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-lookup-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-rollback-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-rollback-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-write-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-write-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/screen-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/screen-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/script-call-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/script-call-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/start-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/start-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/subflow-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/subflow-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/transform-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/transform-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/wait-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/wait-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/element-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/element-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/element-dialog.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/element-dialog.component.html","../../../projects/flow-builder/src/lib/ui/resources/resource-panel.component.ts","../../../projects/flow-builder/src/lib/ui/resources/resource-panel.component.html","../../../projects/flow-builder/src/lib/ui/problems/problems-panel.component.ts","../../../projects/flow-builder/src/lib/ui/problems/problems-panel.component.html","../../../projects/flow-builder/src/lib/ui/versions/version-panel.component.ts","../../../projects/flow-builder/src/lib/ui/versions/version-panel.component.html","../../../projects/flow-builder/src/lib/ui/debug/debug-panel.component.ts","../../../projects/flow-builder/src/lib/ui/debug/debug-panel.component.html","../../../projects/flow-builder/src/lib/ui/flow-builder.component.ts","../../../projects/flow-builder/src/lib/ui/flow-builder.component.html","../../../projects/flow-builder/src/esfaenza-flow-builder.ts"],"sourcesContent":["/**\r\n * Modello del documento Flow — FRONTEND.md §3, §4, §5.\r\n *\r\n * Regole del contratto rispettate qui:\r\n * - camelCase su ogni proprieta';\r\n * - ogni campo e' opzionale (una definizione incompleta e' salvabile);\r\n * - nessun `$type`: il tipo di un node e' la collection in cui sta (§3.1);\r\n * - gli enum sono stringhe, ma i tipi sono aperti (`| string`) perche' gli elenchi\r\n * autoritativi arrivano da `GET /flows/dictionaries` e possono crescere (§13.11).\r\n */\r\n\r\n/** §4.2 — i sette tipi del sistema. Aperto: il dizionario `dataTypes` e' autoritativo. */\r\nexport type FlowDataType = 'String' | 'Integer' | 'Number' | 'Date' | 'Boolean' | 'Enum' | 'Object' | string;\r\n\r\nexport type FlowProcessType = 'Screen' | 'AutoLaunched' | 'Evaluation' | 'Orchestration' | string;\r\n\r\nexport type FlowVersionStatus = 'Draft' | 'InvalidDraft' | 'UnderReview' | 'Active' | 'Obsolete' | string;\r\n\r\nexport type FlowTriggerType =\r\n | 'None'\r\n | 'RecordBeforeSave'\r\n | 'RecordAfterSave'\r\n | 'RecordBeforeDelete'\r\n | 'Scheduled'\r\n | 'Event'\r\n | string;\r\n\r\nexport type FlowRecordTriggerType = 'Create' | 'Update' | 'CreateAndUpdate' | 'Delete' | string;\r\n\r\nexport type FlowSortOrder = 'Asc' | 'Desc' | string;\r\n\r\nexport type FlowOffsetUnit = 'Minutes' | 'Hours' | 'Days' | 'Months' | string;\r\n\r\nexport type FlowCollectionProcessorType = 'Sort' | 'Filter' | string;\r\n\r\nexport type FlowTransformType = 'Map' | 'Sum' | 'Count' | string;\r\n\r\nexport type FlowTransactionModel = 'Automatic' | 'CurrentTransaction' | 'NewTransaction' | string;\r\n\r\n/**\r\n * §4.2 — un riferimento **oppure** un valore letterale.\r\n * Va valorizzato **uno e un solo** campo; `formulaExpression` e' l'unica eccezione\r\n * (espressione + tipo atteso). Piu' campi insieme = `VALUE_AMBIGUOUS`.\r\n */\r\nexport interface FlowValue {\r\n elementReference?: string;\r\n stringValue?: string;\r\n integerValue?: number;\r\n numberValue?: number;\r\n /**\r\n * `2026-08-15T09:00:00Z` sono le 9 UTC, `2026-08-15T09:00:00` le 9 nel fuso\r\n * dell'applicazione: sono **due istanti diversi**, e il motore converte prima di\r\n * confrontare. Scrivere il fuso quando lo si conosce e' una scelta, non un dettaglio (§4.2).\r\n */\r\n dateValue?: string;\r\n booleanValue?: boolean;\r\n enumValue?: string;\r\n formulaExpression?: string;\r\n formulaDataType?: FlowDataType;\r\n}\r\n\r\n/** §3.5 — un connector e' sempre la stessa forma; cambia solo il campo in cui vive. */\r\nexport interface FlowConnector {\r\n targetReference?: string;\r\n /** Solo suggerimento di disegno: la semantica di esecuzione e' identica (§3.5). */\r\n isGoTo?: boolean;\r\n}\r\n\r\n/** §4.3 — condizione su risorse. Per gli operatori unari `rightValue` e' l'esito atteso. */\r\nexport interface FlowCondition {\r\n leftValueReference?: string;\r\n operator?: FlowComparisonOperator;\r\n rightValue?: FlowValue;\r\n}\r\n\r\nexport type FlowComparisonOperator =\r\n | 'EqualTo'\r\n | 'NotEqualTo'\r\n | 'GreaterThan'\r\n | 'GreaterThanOrEqualTo'\r\n | 'LessThan'\r\n | 'LessThanOrEqualTo'\r\n | 'Contains'\r\n | 'StartsWith'\r\n | 'EndsWith'\r\n | 'In'\r\n | 'NotIn'\r\n | 'IsNull'\r\n | 'IsBlank'\r\n | 'IsEmpty'\r\n | 'IsChanged'\r\n | 'WasSet'\r\n | 'WasVisited'\r\n | 'HasError'\r\n | 'None'\r\n | string;\r\n\r\n/** §4.4 — filtro su campi di un'entita': struttura **diversa** dalle condizioni. */\r\nexport interface FlowRecordFilter {\r\n field?: string;\r\n operator?: FlowRecordFilterOperator;\r\n value?: FlowValue;\r\n}\r\n\r\nexport type FlowRecordFilterOperator =\r\n | 'EqualTo'\r\n | 'NotEqualTo'\r\n | 'GreaterThan'\r\n | 'GreaterThanOrEqualTo'\r\n | 'LessThan'\r\n | 'LessThanOrEqualTo'\r\n | 'StartsWith'\r\n | 'EndsWith'\r\n | 'Contains'\r\n | 'IsNull'\r\n | string;\r\n\r\n/** §4.3 — `and` | `or` | espressione sugli indici 1-based | `Formula`. */\r\nexport type FlowConditionLogic = 'and' | 'or' | 'Formula' | string;\r\n\r\n/** Blocco condizioni riusato da Decision rule, Wait event, Collection Processor, Start. */\r\nexport interface FlowConditionHolder {\r\n conditionLogic?: FlowConditionLogic;\r\n conditions?: FlowCondition[];\r\n /** Usato quando `conditionLogic === 'Formula'`; in quel caso `conditions` e' ignorato. */\r\n formula?: string;\r\n}\r\n\r\n/** Parametro di input verso form / action / script / wait event. */\r\nexport interface FlowInputParameter {\r\n name?: string;\r\n value?: FlowValue;\r\n}\r\n\r\n/** Parametro di output: `assignToReference` deve essere una destinazione scrivibile (§4.6). */\r\nexport interface FlowOutputParameter {\r\n name?: string;\r\n assignToReference?: string;\r\n}\r\n\r\n/** Campo di un record → valore (Create/Update). */\r\nexport interface FlowInputFieldAssignment {\r\n field?: string;\r\n value?: FlowValue;\r\n}\r\n\r\n/** Campo di un record → variabile (Get Records con output esplicito). */\r\nexport interface FlowOutputFieldAssignment {\r\n field?: string;\r\n assignToReference?: string;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Risorse (§4.6)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowVariable {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n /** Obbligatorio per `Object` ed `Enum`: nome dell'entita' o del tipo di enum. */\r\n objectType?: string;\r\n isCollection?: boolean;\r\n isInput?: boolean;\r\n isOutput?: boolean;\r\n /** Solo per `Number` e `Integer`; altrove e' `SCALE_NOT_APPLICABLE`. */\r\n scale?: number;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowConstant {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n /** Non puo' referenziare altre risorse: `CONSTANT_REFERENCES_RESOURCE`. */\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowFormula {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n scale?: number;\r\n /** Passata verbatim al motore di regole: il backend non la valida (§4.6). */\r\n expression?: string;\r\n}\r\n\r\nexport interface FlowTextTemplate {\r\n name?: string;\r\n description?: string;\r\n text?: string;\r\n isViewedAsPlainText?: boolean;\r\n}\r\n\r\nexport interface FlowChoice {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n choiceText?: string;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowDynamicChoiceSet {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n object?: string;\r\n displayField?: string;\r\n valueField?: string;\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n limit?: number;\r\n /** Sempre in AND: nessun `filterLogic` qui (§4.4). */\r\n filters?: FlowRecordFilter[];\r\n}\r\n\r\nexport interface FlowStage {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n /** Devono essere distinti: `STAGE_ORDER_DUPLICATED`. */\r\n stageOrder?: number;\r\n isActive?: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Node (§5)\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Campi comuni a ogni node. `locationX`/`locationY` sono l'unico layout persistito (§3.5). */\r\nexport interface FlowNodeBase {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n locationX?: number;\r\n locationY?: number;\r\n}\r\n\r\n/** §5.1 — lo screen dichiara *quale* form mostrare, non i suoi campi. */\r\nexport interface FlowScreen extends FlowNodeBase {\r\n formName?: string;\r\n helpText?: string;\r\n allowBack?: boolean;\r\n allowFinish?: boolean;\r\n allowPause?: boolean;\r\n pausedText?: string;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport type FlowAssignmentOperator =\r\n | 'Assign'\r\n | 'Add'\r\n | 'Subtract'\r\n | 'AddAtStart'\r\n | 'AssignCount'\r\n | 'RemoveFirst'\r\n | 'RemoveAll'\r\n | 'RemovePosition'\r\n | 'RemoveAfterFirst'\r\n | 'RemoveBeforeFirst'\r\n | 'RemoveUncommon'\r\n | string;\r\n\r\nexport interface FlowAssignmentItem {\r\n assignToReference?: string;\r\n operator?: FlowAssignmentOperator;\r\n value?: FlowValue;\r\n}\r\n\r\n/** §5.2 — le operazioni sono eseguite nell'ordine dichiarato. */\r\nexport interface FlowAssignment extends FlowNodeBase {\r\n assignmentItems?: FlowAssignmentItem[];\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.3 — una regola per ramo; l'ordine e' semantico. */\r\nexport interface FlowDecisionRule extends FlowConditionHolder {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowDecision extends FlowNodeBase {\r\n rules?: FlowDecisionRule[];\r\n defaultConnector?: FlowConnector;\r\n defaultConnectorLabel?: string;\r\n}\r\n\r\n/** §5.4 */\r\nexport interface FlowLoop extends FlowNodeBase {\r\n collectionReference?: string;\r\n assignNextValueToReference?: string;\r\n iterationOrder?: FlowSortOrder;\r\n nextValueConnector?: FlowConnector;\r\n noMoreValuesConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowSortOption {\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n doesPutEmptyStringAndNullFirst?: boolean;\r\n}\r\n\r\n/** §5.5 — `assignNextValueToReference` e' l'elemento in esame, non la destinazione. */\r\nexport interface FlowCollectionProcessor extends FlowNodeBase, FlowConditionHolder {\r\n collectionProcessorType?: FlowCollectionProcessorType;\r\n collectionReference?: string;\r\n assignNextValueToReference?: string;\r\n limit?: number;\r\n sortOptions?: FlowSortOption[];\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.6 */\r\nexport interface FlowRecordLookup extends FlowNodeBase {\r\n object?: string;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n getFirstRecordOnly?: boolean;\r\n queriedFields?: string[];\r\n limit?: number;\r\n /** Alternativo a `outputReference`/`outputAssignments`: `OUTPUT_CONFIGURATION_CONFLICT`. */\r\n storeOutputAutomatically?: boolean;\r\n outputReference?: string;\r\n outputAssignments?: FlowOutputFieldAssignment[];\r\n /** Modellato ma non tradotto in query (§5.6). */\r\n relatedRecords?: unknown[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.7 */\r\nexport interface FlowRecordCreate extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n doesUpsert?: boolean;\r\n upsertExternalIdField?: string;\r\n upsertStandardIdField?: string;\r\n storeOutputAutomatically?: boolean;\r\n assignRecordIdToReference?: string;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordUpdate extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n /** Nessun `filterLogic` qui: i filtri sono sempre in AND (§4.4). */\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordDelete extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n /** Senza filtri e' un **errore**, non un avviso (§5.7). */\r\n filters?: FlowRecordFilter[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordRollback extends FlowNodeBase {\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.8 */\r\nexport interface FlowActionCall extends FlowNodeBase {\r\n actionType?: string;\r\n actionName?: string;\r\n flowTransactionModel?: FlowTransactionModel;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n storeOutputAutomatically?: boolean;\r\n isWaitUntilCompleted?: boolean;\r\n offset?: number;\r\n offsetUnit?: FlowOffsetUnit;\r\n /** Il ramo di timeout esiste solo con `EnableTimeoutPath`. */\r\n timeoutPathUsage?: 'EnableTimeoutPath' | 'NoTimeoutPath' | string;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n timeoutConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowScriptPluginCall extends FlowNodeBase {\r\n scriptName?: string;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n storeOutputAutomatically?: boolean;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.9 — i `name` sono le variabili isInput/isOutput del flow **invocato**. */\r\nexport interface FlowSubflowInputAssignment {\r\n name?: string;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowSubflowOutputAssignment {\r\n name?: string;\r\n assignToReference?: string;\r\n}\r\n\r\nexport interface FlowSubflow extends FlowNodeBase {\r\n flowName?: string;\r\n inputAssignments?: FlowSubflowInputAssignment[];\r\n outputAssignments?: FlowSubflowOutputAssignment[];\r\n storeOutputAutomatically?: boolean;\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.10 */\r\nexport interface FlowWaitEvent extends FlowConditionHolder {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n eventType?: string;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowWait extends FlowNodeBase {\r\n waitEvents?: FlowWaitEvent[];\r\n defaultConnector?: FlowConnector;\r\n defaultConnectorLabel?: string;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.11 */\r\nexport interface FlowCustomErrorMessage {\r\n errorMessage?: string;\r\n isFieldError?: boolean;\r\n fieldSelection?: string;\r\n}\r\n\r\nexport interface FlowCustomError extends FlowNodeBase {\r\n customErrorMessages?: FlowCustomErrorMessage[];\r\n}\r\n\r\n/** §5.12 */\r\nexport interface FlowTransformValueAction {\r\n transformType?: FlowTransformType;\r\n outputFieldApiName?: string;\r\n value?: FlowValue;\r\n inputParameters?: FlowInputParameter[];\r\n}\r\n\r\nexport interface FlowTransformValue {\r\n transformValueActions?: FlowTransformValueAction[];\r\n}\r\n\r\nexport interface FlowTransform extends FlowNodeBase {\r\n dataType?: FlowDataType;\r\n objectType?: string;\r\n isCollection?: boolean;\r\n transformValues?: FlowTransformValue[];\r\n /** **Array** per fedelta' storica: usa il primo (§3.5). */\r\n connector?: FlowConnector[];\r\n}\r\n\r\n/** Non supportati dal motore: nascosti dalla palette (§3.2, §13.9). */\r\nexport interface FlowUnsupportedNode extends FlowNodeBase {\r\n connector?: FlowConnector;\r\n [key: string]: unknown;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Orchestrated Stage (§5.13)\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * §5.13 — i tre tipi di step. `stepMuleSoft` non esiste in questo sistema\r\n * (`ELEMENT_NOT_SUPPORTED`); l'elenco autoritativo e' il dizionario `stageStepTypes`.\r\n */\r\nexport type FlowStageStepActionType = 'stepBackground' | 'stepInteractive' | 'stepApproval' | string;\r\n\r\n/** A chi e' assegnato uno step interattivo. `assigneeTypes` e' il dizionario (§6.4). */\r\nexport interface FlowStageStepAssignee {\r\n assigneeType?: string;\r\n assignee?: FlowValue;\r\n}\r\n\r\n/** Il nome di un *evaluation flow* che decide una condizione di ingresso o di uscita. */\r\nexport type FlowStageStepConditionActionType = 'EvaluationFlow' | string;\r\n\r\n/**\r\n * §5.13 — uno step di uno stage.\r\n *\r\n * Due cose che non si vedono dal tipo:\r\n * - gli step **non hanno un ordine di esecuzione**: parte quello le cui `entryConditions`\r\n * sono vere, e l'ordine nell'array e' solo l'ordine d'esame;\r\n * - `name` sta nello **stesso spazio dei nomi** di node e risorse (§3.3), e l'output di uno\r\n * step e' sempre referenziabile come `<NomeStep>.<NomeOutput>`.\r\n *\r\n * I campi riservati (`runAsUser`, ignorato dal runtime, `canAssigneeEdit`, `shouldLock`,\r\n * `requiresAsyncProcessing`) non sono modellati di proposito: non vanno esposti. Sopravvivono\r\n * comunque al round-trip, perche' il documento viaggia come JSON.\r\n */\r\nexport interface FlowStageStep {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n actionType?: FlowStageStepActionType;\r\n /** Obbligatorio su `stepBackground`: il flow che il motore esegue subito. */\r\n actionName?: string;\r\n /** Obbligatori su `stepInteractive` e `stepApproval`. */\r\n assignees?: FlowStageStepAssignee[];\r\n /** `\"0\"` o `\"1\"`: il modello lo porta come stringa. */\r\n requiresMultiMemberApproval?: string;\r\n /** *Se* lo step si applica: se non si avverano, viene saltato (§5.13). */\r\n entryConditions?: FlowCondition[];\r\n /** *Quando* lo step libera lo stage: se restano false, lo stage va in stallo (§5.13). */\r\n exitConditions?: FlowCondition[];\r\n /** Evaluation flow che decide l'ingresso: deve restituire `isOrchestrationConditionMet`. */\r\n entryActionName?: string;\r\n entryActionType?: FlowStageStepConditionActionType;\r\n exitActionName?: string;\r\n exitActionType?: FlowStageStepConditionActionType;\r\n inputParameters?: FlowInputParameter[];\r\n /** `assignToReference` e' facoltativo: l'output e' già referenziabile (§5.13). */\r\n outputParameters?: FlowOutputParameter[];\r\n /** `true` → usa `outputConfigParams` come output finti, senza eseguire lo step. */\r\n debugSimulateStep?: boolean;\r\n outputConfigParams?: FlowInputParameter[];\r\n}\r\n\r\nexport interface FlowOrchestratedStage extends FlowNodeBase {\r\n stageSteps?: FlowStageStep[];\r\n connector?: FlowConnector;\r\n /**\r\n * **Non** e' un ramo di guasto: e' il ramo percorso quando uno step viene rifiutato.\r\n * Senza, un rifiuto fa fallire l'interview (§5.13).\r\n */\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Start (§3.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowSchedule {\r\n frequency?: 'Once' | 'Daily' | 'Weekly' | 'Monthly' | string;\r\n /** Data senza fuso: `2026-08-01T00:00:00`. */\r\n startDate?: string;\r\n /** `08:00:00`. */\r\n startTime?: string;\r\n}\r\n\r\nexport interface FlowScheduledPath {\r\n name?: string;\r\n label?: string;\r\n offsetNumber?: number;\r\n offsetUnit?: FlowOffsetUnit;\r\n timeSource?: string;\r\n recordField?: string;\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowStart {\r\n locationX?: number;\r\n locationY?: number;\r\n /** Sempre necessario: senza, `START_NO_ENTRY_POINT`. */\r\n connector?: FlowConnector;\r\n triggerType?: FlowTriggerType;\r\n object?: string;\r\n recordTriggerType?: FlowRecordTriggerType;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n doesRequireRecordChangedToMeetCriteria?: boolean;\r\n schedule?: FlowSchedule;\r\n scheduledPaths?: FlowScheduledPath[];\r\n inputs?: FlowInputParameter[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Documento radice (§3.1)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowCustomProperty {\r\n name?: string;\r\n value?: string;\r\n}\r\n\r\n/**\r\n * §3.1 — i node non stanno in un'unica lista: c'e' una collection per tipo.\r\n * Il tipo di un node **e'** la collection in cui sta.\r\n */\r\nexport interface FlowDefinition {\r\n /** Identificatore. Rinominare passa da una primitiva dedicata, non dal JSON (§2). */\r\n fullName?: string;\r\n label?: string;\r\n description?: string;\r\n processType?: FlowProcessType;\r\n /** Sola lettura per l'editor: lo governa il ciclo di vita (§8). */\r\n status?: FlowVersionStatus;\r\n interviewLabel?: string;\r\n\r\n /** Array di uno per fedelta' storica: usa sempre il primo (§3.4). */\r\n start?: FlowStart[];\r\n\r\n variables?: FlowVariable[];\r\n constants?: FlowConstant[];\r\n formulas?: FlowFormula[];\r\n textTemplates?: FlowTextTemplate[];\r\n choices?: FlowChoice[];\r\n dynamicChoiceSets?: FlowDynamicChoiceSet[];\r\n stages?: FlowStage[];\r\n\r\n screens?: FlowScreen[];\r\n assignments?: FlowAssignment[];\r\n decisions?: FlowDecision[];\r\n loops?: FlowLoop[];\r\n collectionProcessors?: FlowCollectionProcessor[];\r\n recordLookups?: FlowRecordLookup[];\r\n recordCreates?: FlowRecordCreate[];\r\n recordUpdates?: FlowRecordUpdate[];\r\n recordDeletes?: FlowRecordDelete[];\r\n recordRollbacks?: FlowRecordRollback[];\r\n actionCalls?: FlowActionCall[];\r\n scriptPluginCalls?: FlowScriptPluginCall[];\r\n subflows?: FlowSubflow[];\r\n transforms?: FlowTransform[];\r\n waits?: FlowWait[];\r\n customErrors?: FlowCustomError[];\r\n orchestratedStages?: FlowOrchestratedStage[];\r\n\r\n /** Non supportati: conservati nel round-trip ma non creabili dalla palette. */\r\n steps?: FlowUnsupportedNode[];\r\n experiments?: FlowUnsupportedNode[];\r\n\r\n apiVersion?: string;\r\n timeZoneSidKey?: string;\r\n triggerOrder?: number;\r\n isTemplate?: boolean;\r\n customProperties?: FlowCustomProperty[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Chiavi delle collection\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Le collection di node: `metadataProperty` del dizionario `elementTypes` (§3.2). */\r\nexport const FLOW_NODE_COLLECTIONS = [\r\n 'screens',\r\n 'assignments',\r\n 'decisions',\r\n 'loops',\r\n 'collectionProcessors',\r\n 'recordLookups',\r\n 'recordCreates',\r\n 'recordUpdates',\r\n 'recordDeletes',\r\n 'recordRollbacks',\r\n 'actionCalls',\r\n 'scriptPluginCalls',\r\n 'subflows',\r\n 'transforms',\r\n 'waits',\r\n 'customErrors',\r\n 'orchestratedStages',\r\n 'steps',\r\n 'experiments',\r\n] as const;\r\n\r\nexport type FlowNodeCollection = (typeof FLOW_NODE_COLLECTIONS)[number];\r\n\r\n/** Le collection di risorse (§4.6). Condividono lo spazio dei nomi con i node (§3.3). */\r\nexport const FLOW_RESOURCE_COLLECTIONS = [\r\n 'variables',\r\n 'constants',\r\n 'formulas',\r\n 'textTemplates',\r\n 'choices',\r\n 'dynamicChoiceSets',\r\n 'stages',\r\n] as const;\r\n\r\nexport type FlowResourceCollection = (typeof FLOW_RESOURCE_COLLECTIONS)[number];\r\n\r\n/** Il discriminatore `value` del dizionario `elementTypes`. */\r\nexport type FlowElementType =\r\n | 'Screen'\r\n | 'Assignment'\r\n | 'Decision'\r\n | 'Loop'\r\n | 'CollectionProcessor'\r\n | 'CustomError'\r\n | 'Wait'\r\n | 'RecordLookup'\r\n | 'RecordCreate'\r\n | 'RecordUpdate'\r\n | 'RecordDelete'\r\n | 'RecordRollback'\r\n | 'ActionCall'\r\n | 'ScriptCall'\r\n | 'Subflow'\r\n | 'Transform'\r\n | 'OrchestratedStage'\r\n | 'Step'\r\n | 'Experiment'\r\n | string;\r\n\r\n/** Un node qualunque, come lo vede il canvas. */\r\nexport type FlowAnyNode = FlowNodeBase & Record<string, unknown>;\r\n","/**\r\n * Dizionari — FRONTEND.md §6.4.\r\n *\r\n * Sono statici: si caricano una volta e si tengono in cache. Nessun elenco di enum\r\n * o di operatori va cablato nel frontend (§13.11): tutte le tendine leggono da qui.\r\n */\r\n\r\nimport { FlowDataType, FlowElementType, FlowNodeCollection } from './flow.model';\r\n\r\n/** Ogni voce di dizionario ha almeno `value` (da scrivere) e `label` (da mostrare). */\r\nexport interface FlowDictionaryEntry {\r\n value: string;\r\n label: string;\r\n description?: string | null;\r\n}\r\n\r\nexport interface FlowDataTypeEntry extends FlowDictionaryEntry {\r\n value: FlowDataType;\r\n /** `Object` ed `Enum` richiedono `objectType` (§4.6). */\r\n requiresObjectType?: boolean;\r\n /** `scale` si applica solo ai numerici (§4.6). */\r\n supportsScale?: boolean;\r\n}\r\n\r\n/** §3.2 — la voce che descrive un tipo di elemento. */\r\nexport interface FlowElementTypeEntry extends FlowDictionaryEntry {\r\n value: FlowElementType;\r\n /** Categoria per raggruppare la palette: Interazione, Logica, Dati, Azione, Flow. */\r\n category?: string | null;\r\n /** La collection in cui scrivere il node (§3.1). */\r\n metadataProperty?: FlowNodeCollection | string;\r\n /** `false` → va nascosto dalla palette (§13.9). */\r\n isSupported?: boolean;\r\n hasFaultConnector?: boolean;\r\n hasAutomaticOutput?: boolean;\r\n}\r\n\r\n/** §4.3 — operatore di confronto per le condizioni su risorse. */\r\nexport interface FlowComparisonOperatorEntry extends FlowDictionaryEntry {\r\n /**\r\n * Trappola numero uno (§13.1): per gli unari `rightValue` e' l'**esito atteso**,\r\n * non il termine di confronto.\r\n */\r\n isUnary?: boolean;\r\n /** A sinistra vuole il nome di un **node**, non di una risorsa (`WasVisited`, `HasError`). */\r\n appliesToElements?: boolean;\r\n /** Tipi a cui l'operatore si applica; vuoto o assente = qualunque tipo. */\r\n appliesTo?: FlowDataType[] | null;\r\n}\r\n\r\n/** §5.2 — operatore di assegnazione. */\r\nexport interface FlowAssignmentOperatorEntry extends FlowDictionaryEntry {\r\n /** Ha senso solo su destinazioni collection; altrove e' un avviso. */\r\n expectsCollection?: boolean;\r\n}\r\n\r\n/**\r\n * §4.1 — variabile globale proponibile invece di farla digitare.\r\n *\r\n * La verificabilita' e' **per scope**: se `paths` porta almeno una voce, un percorso che non\r\n * c'e' e' `GLOBAL_UNKNOWN`; se `paths` e' vuoto, lo scope resta non verificabile — che\r\n * significa \"non lo so\", non \"non esiste\".\r\n */\r\nexport interface FlowGlobalVariableEntry extends FlowDictionaryEntry {\r\n /** `$Flow`, `$GlobalConstant`, `$Record`, `$User`, … */\r\n scope?: string;\r\n /** Percorsi noti dello scope. Vuoto → lo scope non e' verificabile (§4.1). */\r\n paths?: string[] | null;\r\n /** `true` → i percorsi li dichiara il sistema ospite, e solo quelli che dichiara. */\r\n isResolvedByHost?: boolean;\r\n /** Disponibile solo con un trigger su record (`$Record`, `$Record__Prior`). */\r\n requiresRecordTrigger?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — i tipi di step di uno stage di orchestrazione (`stageStepTypes`).\r\n * Le colonne dicono cosa il tipo pretende: senza, l'editor dovrebbe cablare i tre nomi.\r\n */\r\nexport interface FlowStageStepTypeEntry extends FlowDictionaryEntry {\r\n /** `stepBackground`: il flow eseguito subito e' obbligatorio. */\r\n requiresActionName?: boolean;\r\n /** `stepInteractive` / `stepApproval`: gli assegnatari sono obbligatori. */\r\n requiresAssignees?: boolean;\r\n /** `true` → l'interview si **sospende** su questo step, in attesa di una persona. */\r\n suspendsInterview?: boolean;\r\n /** `true` → il rifiuto e' un esito previsto, e prende il `faultConnector` dello stage. */\r\n supportsRejection?: boolean;\r\n}\r\n\r\nexport interface FlowResourceKindEntry extends FlowDictionaryEntry {\r\n /** Solo le variabili sono scrivibili (§4.6). */\r\n isWritable?: boolean;\r\n /** La collection del documento in cui vive la risorsa. */\r\n metadataProperty?: string;\r\n}\r\n\r\n/**\r\n * §6.4 — le tendine in una risposta.\r\n * I campi sono opzionali: un backend che non popola un dizionario non deve far\r\n * crollare l'editor, che degrada mostrando il valore grezzo.\r\n *\r\n * Sono **quasi** statici: `globalVariables` dipende dal `processType` con cui si sono\r\n * chiesti, perche' `$Record` non esiste in uno screen flow (§4.1). Chi lavora su piu' tipi di\r\n * flow ne tiene una copia per tipo — se ne occupa {@link FlowDictionaryStore}.\r\n */\r\nexport interface FlowDictionaries {\r\n dataTypes?: FlowDataTypeEntry[];\r\n comparisonOperators?: FlowComparisonOperatorEntry[];\r\n assignmentOperators?: FlowAssignmentOperatorEntry[];\r\n recordFilterOperators?: FlowDictionaryEntry[];\r\n elementTypes?: FlowElementTypeEntry[];\r\n resourceKinds?: FlowResourceKindEntry[];\r\n globalVariables?: FlowGlobalVariableEntry[];\r\n processTypes?: FlowDictionaryEntry[];\r\n versionStatuses?: FlowDictionaryEntry[];\r\n triggerTypes?: FlowDictionaryEntry[];\r\n recordTriggerTypes?: FlowDictionaryEntry[];\r\n startFrequencies?: FlowDictionaryEntry[];\r\n offsetUnits?: FlowDictionaryEntry[];\r\n sortOrders?: FlowDictionaryEntry[];\r\n collectionProcessorTypes?: FlowDictionaryEntry[];\r\n transformTypes?: FlowDictionaryEntry[];\r\n transactionModels?: FlowDictionaryEntry[];\r\n waitEventTypes?: FlowDictionaryEntry[];\r\n stageStepTypes?: FlowStageStepTypeEntry[];\r\n assigneeTypes?: FlowDictionaryEntry[];\r\n conditionLogicModes?: FlowDictionaryEntry[];\r\n screenNavigations?: FlowDictionaryEntry[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cataloghi (§6.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowObjectSummary {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\nexport interface FlowObjectDescription {\r\n name: string;\r\n label?: string | null;\r\n fields?: FlowFieldDescription[];\r\n}\r\n\r\nexport interface FlowFieldDescription {\r\n name: string;\r\n label?: string | null;\r\n dataType?: FlowDataType;\r\n objectType?: string | null;\r\n isFilterable?: boolean;\r\n isSortable?: boolean;\r\n isUpdateable?: boolean;\r\n isRequired?: boolean;\r\n /** `true` → i valori ammessi si chiedono a `.../fields/{field}/values`. */\r\n hasClosedValueSet?: boolean;\r\n}\r\n\r\n/** `any` | `filterable` | `sortable` | `updateable` (§6.4). */\r\nexport type FlowFieldUsage = 'any' | 'filterable' | 'sortable' | 'updateable';\r\n\r\nexport interface FlowFieldValue {\r\n value: string;\r\n label?: string | null;\r\n}\r\n\r\n/** Voce di catalogo per action, script, form, eventi, tipi di enum. */\r\nexport interface FlowCatalogEntry {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\n/**\r\n * Parametro dichiarato da un'action, uno script o un form.\r\n * Con il catalogo popolato un parametro inesistente e' un **errore** (§5.8).\r\n */\r\nexport interface FlowCatalogParameter {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n dataType?: FlowDataType;\r\n objectType?: string | null;\r\n isCollection?: boolean;\r\n isInput?: boolean;\r\n isOutput?: boolean;\r\n isRequired?: boolean;\r\n}\r\n","/**\r\n * Payload delle primitive — FRONTEND.md §6, §7, §8, §10.\r\n */\r\n\r\nimport { FlowDataType, FlowDefinition, FlowProcessType, FlowVersionStatus } from './flow.model';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Elenchi (§6.1)\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Una riga per **nome**, non per versione (§6.1). */\r\nexport interface FlowSummary {\r\n flowName: string;\r\n label?: string | null;\r\n description?: string | null;\r\n processType?: FlowProcessType;\r\n activeVersion?: number | null;\r\n latestVersion?: number;\r\n versionCount?: number;\r\n hasDraft?: boolean;\r\n updatedAt?: string;\r\n /** Esiste una versione attiva. Non ricalcolarlo lato client (§6.1). */\r\n isRunnable?: boolean;\r\n}\r\n\r\nexport interface FlowVersionSummary {\r\n flowName: string;\r\n version: number;\r\n status?: FlowVersionStatus;\r\n label?: string | null;\r\n description?: string | null;\r\n processType?: FlowProcessType;\r\n createdAt?: string;\r\n /** Da conservare e rimandare come `expectedUpdatedAt` al salvataggio (§9). */\r\n updatedAt?: string;\r\n updatedBy?: string | null;\r\n isActive?: boolean;\r\n /** La versione e' una bozza. Non ricalcolarlo lato client (§6.1). */\r\n isEditable?: boolean;\r\n}\r\n\r\nexport interface FlowListQuery {\r\n search?: string;\r\n processType?: FlowProcessType;\r\n onlyActive?: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Validazione (§7)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowIssueSeverity = 'Error' | 'Warning' | 'Info' | string;\r\n\r\nexport interface FlowValidationIssue {\r\n /** Stabile: usalo per decidere il comportamento. Non interpretare `message` (§7). */\r\n code: string;\r\n severity: FlowIssueSeverity;\r\n message: string;\r\n /** Ancora per portare l'utente sull'elemento con un clic. */\r\n elementName?: string | null;\r\n /** Campo dentro l'elemento, es. `rules[Approvato].connector.targetReference`. */\r\n path?: string | null;\r\n}\r\n\r\nexport interface FlowValidationResult {\r\n /** Ordinati per gravita' decrescente (§7). */\r\n issues: FlowValidationIssue[];\r\n errorCount: number;\r\n warningCount: number;\r\n isValid: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Scrittura (§6.2)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowCreateRequest {\r\n definition: FlowDefinition;\r\n flowName?: string;\r\n author?: string;\r\n}\r\n\r\nexport interface FlowSaveRequest {\r\n definition: FlowDefinition;\r\n /** Se indicato **vince** sul `fullName` del documento: e' cosi' che si rinomina (§6.2). */\r\n flowName?: string;\r\n /** Mandare sempre la versione che si sta editando rende il risultato prevedibile (§8). */\r\n version?: number;\r\n /** Concorrenza ottimistica: facoltativo ma raccomandato (§9). */\r\n expectedUpdatedAt?: string;\r\n author?: string;\r\n /** Salva **e** attiva. Fallisce senza scrivere nulla se ci sono errori. */\r\n activate?: boolean;\r\n}\r\n\r\nexport interface FlowSaveResult {\r\n flowName: string;\r\n version: number;\r\n status: FlowVersionStatus;\r\n isNewVersion: boolean;\r\n /** Da conservare per il salvataggio successivo (§9). */\r\n updatedAt: string;\r\n /** Il salvataggio riesce anche con errori: guarda qui, non l'esito HTTP (§6.2). */\r\n validation?: FlowValidationResult;\r\n}\r\n\r\nexport interface FlowCloneRequest {\r\n targetFlowName: string;\r\n label?: string;\r\n fromVersion?: number;\r\n author?: string;\r\n}\r\n\r\nexport interface FlowNewVersionRequest {\r\n /** Versione da copiare; se omessa, l'ultima. */\r\n from?: number;\r\n author?: string;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Riferimenti e struttura (§6.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowReferenceKind =\r\n | 'Variable'\r\n | 'Constant'\r\n | 'Formula'\r\n | 'TextTemplate'\r\n | 'Choice'\r\n | 'DynamicChoiceSet'\r\n | 'Stage'\r\n /** Output automatico di un elemento: valido pur non essendo dichiarato (§4.5, §13.3). */\r\n | 'ElementOutput'\r\n | 'Global'\r\n | string;\r\n\r\nexport interface FlowReference {\r\n name: string;\r\n label?: string | null;\r\n kind: FlowReferenceKind;\r\n dataType?: FlowDataType | null;\r\n isCollection?: boolean;\r\n objectType?: string | null;\r\n /**\r\n * Per i campi di destinazione. Scrivibili sono le variabili, `$Flow.CurrentStage`,\r\n * `$Flow.ActiveStages` e le globali che il sistema ospite dichiara tali: la primitiva\r\n * `POST /flows/references/writable` le comprende già, non vanno aggiunte lato client (§5.2).\r\n */\r\n isWritable?: boolean;\r\n description?: string | null;\r\n}\r\n\r\n/** Filtro opzionale per non trasferire riferimenti che il campo non accetta. */\r\nexport interface FlowReferenceQuery {\r\n definition: FlowDefinition;\r\n dataType?: FlowDataType;\r\n isCollection?: boolean;\r\n objectType?: string;\r\n}\r\n\r\nexport interface FlowConnectorTarget {\r\n name: string;\r\n label?: string | null;\r\n kind?: string;\r\n}\r\n\r\nexport type FlowConnectionKind =\r\n | 'Start'\r\n | 'ScheduledPath'\r\n | 'Next'\r\n | 'Rule'\r\n | 'Default'\r\n | 'LoopNext'\r\n | 'LoopEnd'\r\n | 'WaitEvent'\r\n | 'Fault'\r\n | 'Timeout'\r\n | string;\r\n\r\nexport interface FlowOutlineNode {\r\n name: string;\r\n label?: string | null;\r\n kind: string;\r\n description?: string | null;\r\n locationX?: number;\r\n locationY?: number;\r\n /** `false` → nessun percorso lo raggiunge dallo Start: va reso \"scollegato\" (§6.4). */\r\n isReachable?: boolean;\r\n}\r\n\r\nexport interface FlowOutlineConnection {\r\n /** `null` identifica gli archi uscenti dallo Start, che non ha nome (§6.4). */\r\n from?: string | null;\r\n /** `null` → il connector esiste ma non ha destinazione: ramo incompleto (§6.4). */\r\n to?: string | null;\r\n kind: FlowConnectionKind;\r\n label?: string | null;\r\n isGoTo?: boolean;\r\n}\r\n\r\nexport interface FlowOutline {\r\n flowName?: string | null;\r\n label?: string | null;\r\n processType?: FlowProcessType;\r\n triggerType?: string | null;\r\n entryElementName?: string | null;\r\n nodes: FlowOutlineNode[];\r\n connections: FlowOutlineConnection[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Esecuzione (§6.5)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowInterviewStatus =\r\n | 'Completed'\r\n | 'WaitingForScreen'\r\n | 'Paused'\r\n | 'Suspended'\r\n /** **Non** e' un errore HTTP: la richiesta e' riuscita, il flow e' fallito (§6.5). */\r\n | 'Failed'\r\n /** I criteri dello Start non erano soddisfatti: non e' un errore (§6.5). */\r\n | 'NotStarted'\r\n | string;\r\n\r\nexport type FlowScreenNavigation = 'Next' | 'Previous' | 'Pause' | 'Finish' | string;\r\n\r\n/** Il tipo dichiarato **vince** in lettura: distingue `Integer` da `Number` (§6.5). */\r\nexport interface FlowTypedValue {\r\n type?: FlowDataType;\r\n value?: unknown;\r\n}\r\n\r\nexport interface FlowPendingScreen {\r\n elementName?: string;\r\n formName?: string;\r\n label?: string | null;\r\n helpText?: string | null;\r\n inputs?: Record<string, FlowTypedValue>;\r\n /** Piu' precisi dei flag del metadata: sono la verita' su cosa abilitare (§6.5). */\r\n canGoBack?: boolean;\r\n canFinish?: boolean;\r\n canPause?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — lo stato che un assegnatario comunica concludendo uno step.\r\n * `Pending` non e' accettato in scrittura: e' `INVALID_REQUEST`.\r\n */\r\nexport type FlowStageStepStatus = 'Completed' | 'Rejected' | 'Cancelled' | 'Pending' | string;\r\n\r\n/** Lo stato di uno step, come lo riporta l'ispezione di una sospesa (§5.13, §6.5). */\r\nexport interface FlowStageStepState {\r\n stepName?: string;\r\n label?: string | null;\r\n actionType?: string;\r\n status?: FlowStageStepStatus;\r\n /** `true` → c'e' un work item aperto: e' questo step a tenere sospesa l'interview. */\r\n isWaiting?: boolean;\r\n assignees?: string[];\r\n outputs?: Record<string, FlowTypedValue>;\r\n}\r\n\r\nexport interface FlowTraceEntry {\r\n sequence?: number;\r\n level?: string;\r\n message?: string;\r\n elementName?: string | null;\r\n}\r\n\r\nexport interface FlowInterviewResult {\r\n interviewId?: string;\r\n flowName?: string;\r\n status: FlowInterviewStatus;\r\n /** Opaco: da rimandare tale e quale (§6.5, §13.12). */\r\n continuationToken?: string | null;\r\n interviewKey?: string | null;\r\n pendingScreen?: FlowPendingScreen | null;\r\n outputs?: Record<string, FlowTypedValue>;\r\n errors?: string[];\r\n fault?: string | null;\r\n currentElementName?: string | null;\r\n steps?: number;\r\n /** Popolato solo con `debug: true`. Puo' contenere dati personali (§6.5). */\r\n trace?: FlowTraceEntry[];\r\n /** Con `debug: true`: i valori di **tutte** le risorse, non solo gli output. */\r\n resources?: Record<string, FlowTypedValue>;\r\n /**\r\n * `Suspended` copre due attese diverse, e questi due flag le distinguono: un evento\r\n * oppure uno step di orchestrazione (§6.5).\r\n */\r\n isWaitingForEvent?: boolean;\r\n isWaitingForStageStep?: boolean;\r\n /** Con `isWaitingForStageStep`: lo stato di ogni step dello stage corrente (§5.13). */\r\n stageSteps?: FlowStageStepState[];\r\n isSuccess?: boolean;\r\n}\r\n\r\nexport interface FlowStartInterviewRequest {\r\n flowName: string;\r\n version?: number;\r\n inputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowScreenResponseRequest {\r\n continuationToken: string;\r\n screenElementName?: string;\r\n navigation?: FlowScreenNavigation;\r\n outputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowResumeRequest {\r\n interviewKey: string;\r\n debug?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — `POST /interviews/{key}/stage-step`: un assegnatario conclude uno step.\r\n * Se lo stage si sospende di nuovo, la risposta porta una `interviewKey` **nuova** e la\r\n * vecchia non e' piu' valida.\r\n */\r\nexport interface FlowStageStepRequest {\r\n interviewKey: string;\r\n stepName: string;\r\n /** `Pending` viene rifiutato come `INVALID_REQUEST`. */\r\n status: FlowStageStepStatus;\r\n stepOutputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowExportQuery {\r\n version?: number;\r\n indented?: boolean;\r\n}\r\n","/**\r\n * Errori categorizzati — FRONTEND.md §10.\r\n *\r\n * La UI si comporta in base alla **categoria**, non al messaggio. L'implementazione\r\n * dell'interfaccia backend ha il compito di tradurre l'errore di trasporto\r\n * (status HTTP, payload) in un `FlowApiError`: da lì in poi l'editor non conosce HTTP.\r\n */\r\n\r\nimport { FlowValidationResult } from './api.model';\r\n\r\n/** Categorie di authoring (§10). */\r\nexport type FlowErrorCategory =\r\n /** Bug del client: la richiesta e' incompleta. */\r\n | 'InvalidRequest'\r\n /** Il documento non e' leggibile: tipicamente l'import di un file sbagliato. */\r\n | 'InvalidDefinition'\r\n /** Apri il pannello dei problemi: il payload contiene `validation`. */\r\n | 'ValidationFailed'\r\n | 'FlowNotFound'\r\n | 'VersionNotFound'\r\n /** Nome già usato: chiedi un altro nome. */\r\n | 'AlreadyExists'\r\n /** Versione non modificabile: proponi \"Nuova versione\" (§8.1). */\r\n | 'NotEditable'\r\n /** Qualcun altro ha salvato: proponi ricarica (§9). */\r\n | 'VersionConflict'\r\n /** Funzione non configurata su questo ambiente: disabilita il comando. */\r\n | 'MissingService'\r\n // Categorie dell'esecuzione (§10, secondo capoverso)\r\n | 'InvalidToken'\r\n | 'InterviewNotFound'\r\n /** Fallback per un errore di trasporto non categorizzato. */\r\n | 'Unknown'\r\n | string;\r\n\r\n/** L'errore che ogni primitiva puo' rifiutare (§6, §10). */\r\nexport class FlowApiError extends Error {\r\n constructor(\r\n readonly category: FlowErrorCategory,\r\n message: string,\r\n /** Presente con `ValidationFailed`: l'elenco da aprire nel pannello (§8.3). */\r\n readonly validation?: FlowValidationResult,\r\n /** Con `VersionConflict`: chi ha modificato nel frattempo (§9). */\r\n readonly conflictingAuthor?: string,\r\n readonly details?: unknown,\r\n ) {\r\n super(message);\r\n this.name = 'FlowApiError';\r\n }\r\n\r\n static is(value: unknown): value is FlowApiError {\r\n return value instanceof FlowApiError;\r\n }\r\n}\r\n\r\n/** Mappatura HTTP suggerita (§10). Usata dall'implementazione HTTP dell'interfaccia. */\r\nexport const FLOW_ERROR_HTTP_STATUS: Record<string, number> = {\r\n InvalidRequest: 400,\r\n InvalidDefinition: 400,\r\n ValidationFailed: 422,\r\n FlowNotFound: 404,\r\n VersionNotFound: 404,\r\n InterviewNotFound: 404,\r\n AlreadyExists: 409,\r\n NotEditable: 409,\r\n VersionConflict: 409,\r\n InvalidToken: 400,\r\n MissingService: 501,\r\n};\r\n\r\n/** Messaggi di fallback: `message` del backend, quando c'e', ha la precedenza. */\r\nexport const FLOW_ERROR_FALLBACK_MESSAGE: Record<string, string> = {\r\n InvalidRequest: 'La richiesta non e’ valida.',\r\n InvalidDefinition: 'Il documento non e’ leggibile come definizione di flow.',\r\n ValidationFailed: 'La definizione contiene errori che impediscono l’attivazione.',\r\n FlowNotFound: 'Il flow non esiste piu’.',\r\n VersionNotFound: 'La versione richiesta non esiste.',\r\n AlreadyExists: 'Esiste già un flow con questo nome.',\r\n NotEditable: 'Questa versione non e’ modificabile: creane una nuova.',\r\n VersionConflict: 'Qualcun altro ha salvato questa versione nel frattempo.',\r\n MissingService: 'Funzione non configurata su questo ambiente.',\r\n InvalidToken: 'La sessione di prova non e’ piu’ valida: riavvia l’esecuzione.',\r\n InterviewNotFound: 'L’esecuzione sospesa non esiste piu’.',\r\n Unknown: 'Errore inatteso.',\r\n};\r\n","/**\r\n * L'unica porta verso il backend.\r\n *\r\n * **Tutto** il traffico di dati da e verso il backend passa da qui: nessun componente\r\n * e nessun servizio della libreria conosce HTTP, URL o formati di trasporto. Chi integra\r\n * il builder fornisce una implementazione di questa classe astratta e la registra come\r\n * provider — `FlowBuilderApi` e' anche il token di dependency injection.\r\n *\r\n * Contratto di errore: ogni metodo, in caso di rifiuto, deve fallire con un\r\n * {@link FlowApiError} categorizzato (§10). L'editor si comporta in base alla categoria,\r\n * mai leggendo il messaggio.\r\n *\r\n * Contratto di forma: i metodi restituiscono `Promise`. Le primitive marcate\r\n * \"prende il documento in lavorazione\" ricevono la definizione non ancora salvata,\r\n * perche' la risposta dipende da cio' che l'utente sta scrivendo (§6.4).\r\n *\r\n * I metodi con implementazione di default che lancia `MissingService` sono opzionali:\r\n * un ambiente che non li espone lascia l'editor funzionante, con il comando corrispondente\r\n * disabilitato (§10, categoria `MissingService`).\r\n */\r\n\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowDictionaries,\r\n FlowFieldUsage,\r\n FlowFieldValue,\r\n FlowObjectDescription,\r\n FlowObjectSummary,\r\n} from '../model/dictionary.model';\r\nimport {\r\n FlowCloneRequest,\r\n FlowConnectorTarget,\r\n FlowCreateRequest,\r\n FlowExportQuery,\r\n FlowInterviewResult,\r\n FlowListQuery,\r\n FlowNewVersionRequest,\r\n FlowOutline,\r\n FlowReference,\r\n FlowReferenceQuery,\r\n FlowResumeRequest,\r\n FlowSaveRequest,\r\n FlowSaveResult,\r\n FlowScreenResponseRequest,\r\n FlowStageStepRequest,\r\n FlowStartInterviewRequest,\r\n FlowSummary,\r\n FlowValidationResult,\r\n FlowVersionSummary,\r\n} from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\n\r\n/** Helper per i metodi opzionali non implementati. */\r\nfunction missing(primitive: string): Promise<never> {\r\n return Promise.reject(\r\n new FlowApiError('MissingService', `Primitiva non disponibile su questo ambiente: ${primitive}.`),\r\n );\r\n}\r\n\r\nexport abstract class FlowBuilderApi {\r\n // -------------------------------------------------------------------------\r\n // §6.1 Catalogo e lettura\r\n // -------------------------------------------------------------------------\r\n\r\n /** `GET /flows` — una riga per nome, non per versione. */\r\n abstract listFlows(query?: FlowListQuery): Promise<FlowSummary[]>;\r\n\r\n /** `GET /flows/{name}/versions` — dalla piu' recente. */\r\n abstract listVersions(flowName: string): Promise<FlowVersionSummary[]>;\r\n\r\n /**\r\n * `GET /flows/{name}?version=` — senza `version` restituisce la versione attiva,\r\n * altrimenti l'ultima.\r\n */\r\n abstract loadFlow(flowName: string, version?: number): Promise<FlowDefinition>;\r\n\r\n /** `GET /flows/{name}/export` — il documento come stringa indentata. */\r\n exportFlow(flowName: string, query?: FlowExportQuery): Promise<string> {\r\n void flowName;\r\n void query;\r\n return missing('exportFlow');\r\n }\r\n\r\n /**\r\n * `POST /flows/parse` — normalizza un documento senza salvarlo.\r\n * Serve all'import di un file: rifiuta con `InvalidDefinition` se non e' leggibile.\r\n */\r\n parseFlow(definition: unknown): Promise<FlowDefinition> {\r\n void definition;\r\n return missing('parseFlow');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.2 Scrittura e versionamento\r\n // -------------------------------------------------------------------------\r\n\r\n /** `POST /flows` — crea la versione 1. `AlreadyExists` se il nome e' già usato. */\r\n abstract createFlow(request: FlowCreateRequest): Promise<FlowSaveResult>;\r\n\r\n /**\r\n * `PUT /flows/{name}` — salva sulla bozza esistente o ne crea una nuova versione.\r\n * Riesce **anche con errori** di validazione: l'esito sano si legge in\r\n * `FlowSaveResult.validation`, non nell'assenza di eccezione (§6.2).\r\n */\r\n abstract saveFlow(flowName: string, request: FlowSaveRequest): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/versions?from=` — copia una versione in una nuova bozza. */\r\n abstract createVersion(flowName: string, request?: FlowNewVersionRequest): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/clone` — copia il flow sotto un altro nome, versione 1. */\r\n cloneFlow(flowName: string, request: FlowCloneRequest): Promise<FlowSaveResult> {\r\n void flowName;\r\n void request;\r\n return missing('cloneFlow');\r\n }\r\n\r\n /**\r\n * `POST /flows/{name}/versions/{v}/activate` — valida e attiva; la precedente\r\n * diventa `Obsolete`. Con errori fallisce con `ValidationFailed` e il payload\r\n * contiene l'elenco (§8.3).\r\n */\r\n abstract activateVersion(flowName: string, version: number): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/deactivate` — il flow non e' piu' eseguibile. */\r\n abstract deactivateFlow(flowName: string): Promise<void>;\r\n\r\n /** `DELETE /flows/{name}/versions/{v}` — rifiutata sulla versione attiva. */\r\n deleteVersion(flowName: string, version: number): Promise<void> {\r\n void flowName;\r\n void version;\r\n return missing('deleteVersion');\r\n }\r\n\r\n /** `DELETE /flows/{name}` — rifiutata se esiste una versione attiva. */\r\n deleteFlow(flowName: string): Promise<void> {\r\n void flowName;\r\n return missing('deleteFlow');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.3 Validazione\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `POST /flows/validate` — non scrive nulla. È la primitiva del pannello dei\r\n * problemi, richiamabile a ogni pausa di digitazione (§11, debounce 300–500 ms).\r\n */\r\n abstract validateDefinition(definition: FlowDefinition): Promise<FlowValidationResult>;\r\n\r\n /** `GET /flows/{name}/versions/{v}/validate` — valida una versione già salvata. */\r\n validateVersion(flowName: string, version: number): Promise<FlowValidationResult> {\r\n void flowName;\r\n void version;\r\n return missing('validateVersion');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.4 Dizionari, cataloghi e strumenti per l'interfaccia\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `GET /flows/dictionaries?processType=` — le tendine in una risposta.\r\n *\r\n * Quasi statiche: si caricano una volta e si tengono in cache (§6.4, §13.11). L'eccezione e'\r\n * `globalVariables`, che dipende dal `processType`: `$Record` non esiste in uno screen flow,\r\n * e referenziarlo lì e' un errore, non un avviso (§4.1). Chi lavora su piu' tipi di flow\r\n * tiene una copia di dizionari per tipo.\r\n */\r\n abstract getDictionaries(processType?: string): Promise<FlowDictionaries>;\r\n\r\n /**\r\n * `POST /flows/references` — i valori proponibili in un campo che accetta una risorsa.\r\n * Include gli **output automatici** degli elementi, che non sono dichiarati in nessuna\r\n * collection: e' il motivo per cui non va ricostruita lato client (§4.5, §13.3).\r\n */\r\n abstract getReferences(query: FlowReferenceQuery): Promise<FlowReference[]>;\r\n\r\n /**\r\n * `POST /flows/references/writable` — le variabili **piu' le globali assegnabili**, per i\r\n * campi di destinazione: `$Flow.CurrentStage`, `$Flow.ActiveStages` e quelle che il sistema\r\n * ospite dichiara `isWritable`. La primitiva le comprende già, l'editor non le aggiunge\r\n * (§5.2). Restano fuori i campi di `$Record`, che dipendono dallo schema: quelli arrivano da\r\n * `listFields(object, 'updateable')` (§6.4).\r\n */\r\n abstract getWritableReferences(query: FlowReferenceQuery): Promise<FlowReference[]>;\r\n\r\n /** `POST /flows/connector-targets?excluding=` — i node a cui un arco puo' puntare. */\r\n abstract getConnectorTargets(definition: FlowDefinition, excluding?: string): Promise<FlowConnectorTarget[]>;\r\n\r\n /**\r\n * `POST /flows/outline` — node, archi e raggiungibilita' per il canvas.\r\n * `isReachable` e' la fonte autoritativa dei node scollegati (§6.4).\r\n */\r\n abstract getOutline(definition: FlowDefinition): Promise<FlowOutline>;\r\n\r\n /** `GET /catalog/objects` — le entita' su cui i flow possono operare. */\r\n abstract listObjects(): Promise<FlowObjectSummary[]>;\r\n\r\n /** `GET /schema/{object}` — label e campi. */\r\n describeObject(object: string): Promise<FlowObjectDescription> {\r\n void object;\r\n return missing('describeObject');\r\n }\r\n\r\n /** `GET /schema/{object}/fields?usage=` — proponi solo i campi validi per l'uso (§4.4). */\r\n abstract listFields(object: string, usage?: FlowFieldUsage): Promise<FlowObjectDescription['fields']>;\r\n\r\n /** `GET /schema/{object}/fields/{field}/values` — per non far digitare i valori. */\r\n listFieldValues(object: string, field: string): Promise<FlowFieldValue[]> {\r\n void object;\r\n void field;\r\n return missing('listFieldValues');\r\n }\r\n\r\n /** `GET /catalog/action-types` */\r\n abstract listActionTypes(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/actions?type=` */\r\n abstract listActions(actionType?: string): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/actions/{type}/{name}/parameters` */\r\n abstract listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/scripts` */\r\n abstract listScripts(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/scripts/{name}/parameters` */\r\n abstract listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/forms` — i form realizzati a mano nel frontend applicativo (§5.1). */\r\n abstract listForms(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/forms/{name}/parameters` */\r\n abstract listFormParameters(formName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/enum-types` — per `objectType` delle risorse `Enum`. */\r\n abstract listEnumTypes(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/events` — per gli eventi di un Wait. */\r\n abstract listEvents(): Promise<FlowCatalogEntry[]>;\r\n\r\n /**\r\n * `GET /flows/subflow-candidates?excluding=` — solo i flow con una versione attiva,\r\n * escluso quello corrente (§5.9).\r\n */\r\n abstract listSubflowCandidates(excluding?: string): Promise<FlowSummary[]>;\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.5 Provare un flow dall'editor\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `POST /interviews` — avvia. Ricorda: `status: 'Failed'` **non** e' un errore\r\n * di trasporto, e `debug: true` popola `trace` e `resources` con dati che\r\n * possono essere personali (§6.5).\r\n */\r\n startInterview(request: FlowStartInterviewRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('startInterview');\r\n }\r\n\r\n /** `POST /interviews/screen` — il `continuationToken` va rimandato tale e quale (§13.12). */\r\n respondToScreen(request: FlowScreenResponseRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('respondToScreen');\r\n }\r\n\r\n /** `POST /interviews/resume` — riprende un'esecuzione in pausa. */\r\n resumeInterview(request: FlowResumeRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('resumeInterview');\r\n }\r\n\r\n /**\r\n * `POST /interviews/{key}/stage-step` — un assegnatario conclude uno step (§5.13).\r\n * Se lo stage si sospende di nuovo, la risposta porta una `interviewKey` **nuova**: la\r\n * vecchia non e' piu' valida e va sostituita, non conservata.\r\n */\r\n completeStageStep(request: FlowStageStepRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('completeStageStep');\r\n }\r\n\r\n /**\r\n * `GET /interviews/{key}` — ispeziona una sospesa senza consumarla.\r\n * Con `isWaitingForStageStep` porta `stageSteps` con lo stato di ognuno (§5.13).\r\n */\r\n inspectInterview(interviewKey: string): Promise<FlowInterviewResult> {\r\n void interviewKey;\r\n return missing('inspectInterview');\r\n }\r\n\r\n /** `DELETE /interviews/{key}` — abbandona. */\r\n abandonInterview(interviewKey: string): Promise<void> {\r\n void interviewKey;\r\n return missing('abandonInterview');\r\n }\r\n}\r\n","/**\r\n * Implementazione HTTP dell'interfaccia {@link FlowBuilderApi}, sulle rotte proposte\r\n * dalla §6 di FRONTEND.md.\r\n *\r\n * I percorsi HTTP della specifica sono **una proposta**: le rotte definitive le decide\r\n * chi scrive i controller. Se le vostre differiscono, ci sono due strade e nessuna\r\n * tocca l'editor:\r\n * 1. estendere questa classe e sovrascrivere i soli metodi con rotta diversa;\r\n * 2. scrivere un'altra implementazione di `FlowBuilderApi` da zero.\r\n *\r\n * Qui vive l'unica conoscenza di HTTP della libreria, incluso il compito di tradurre\r\n * status e payload in {@link FlowApiError} categorizzati (§10).\r\n */\r\n\r\nimport { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';\r\nimport { InjectionToken, inject } from '@angular/core';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { FlowBuilderApi } from './flow-builder-api';\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowDictionaries,\r\n FlowFieldUsage,\r\n FlowFieldValue,\r\n FlowObjectDescription,\r\n FlowObjectSummary,\r\n} from '../model/dictionary.model';\r\nimport {\r\n FlowCloneRequest,\r\n FlowConnectorTarget,\r\n FlowCreateRequest,\r\n FlowExportQuery,\r\n FlowInterviewResult,\r\n FlowListQuery,\r\n FlowNewVersionRequest,\r\n FlowOutline,\r\n FlowReference,\r\n FlowReferenceQuery,\r\n FlowResumeRequest,\r\n FlowSaveRequest,\r\n FlowSaveResult,\r\n FlowScreenResponseRequest,\r\n FlowStageStepRequest,\r\n FlowStartInterviewRequest,\r\n FlowSummary,\r\n FlowValidationResult,\r\n FlowVersionSummary,\r\n} from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FLOW_ERROR_FALLBACK_MESSAGE, FlowApiError, FlowErrorCategory } from '../model/error.model';\r\n\r\nexport interface FlowBuilderHttpConfig {\r\n /** Prefisso comune, es. `/api` o `https://host/api`. Senza slash finale. */\r\n baseUrl?: string;\r\n}\r\n\r\nexport const FLOW_BUILDER_HTTP_CONFIG = new InjectionToken<FlowBuilderHttpConfig>('FLOW_BUILDER_HTTP_CONFIG', {\r\n factory: () => ({ baseUrl: '/api' }),\r\n});\r\n\r\n/** Forma attesa del corpo di errore del backend. */\r\ninterface FlowErrorBody {\r\n category?: string;\r\n message?: string;\r\n validation?: FlowValidationResult;\r\n conflictingAuthor?: string;\r\n updatedBy?: string;\r\n}\r\n\r\n/** Ricava la categoria dallo status quando il corpo non la dichiara (§10). */\r\nfunction categoryFromStatus(status: number): FlowErrorCategory {\r\n switch (status) {\r\n case 400:\r\n return 'InvalidRequest';\r\n case 404:\r\n return 'FlowNotFound';\r\n case 409:\r\n return 'VersionConflict';\r\n case 422:\r\n return 'ValidationFailed';\r\n case 501:\r\n return 'MissingService';\r\n default:\r\n return 'Unknown';\r\n }\r\n}\r\n\r\nexport class HttpFlowBuilderApi extends FlowBuilderApi {\r\n private readonly http = inject(HttpClient);\r\n private readonly config = inject(FLOW_BUILDER_HTTP_CONFIG);\r\n\r\n protected url(path: string): string {\r\n return `${this.config.baseUrl ?? ''}${path}`;\r\n }\r\n\r\n /** Punto unico in cui un errore di trasporto diventa un errore di dominio. */\r\n protected async request<T>(call: Promise<T>): Promise<T> {\r\n try {\r\n return await call;\r\n } catch (error) {\r\n throw this.toApiError(error);\r\n }\r\n }\r\n\r\n protected toApiError(error: unknown): FlowApiError {\r\n if (FlowApiError.is(error)) {\r\n return error;\r\n }\r\n if (error instanceof HttpErrorResponse) {\r\n const body: FlowErrorBody = (error.error ?? {}) as FlowErrorBody;\r\n const category: FlowErrorCategory = body.category ?? categoryFromStatus(error.status);\r\n const message = body.message ?? FLOW_ERROR_FALLBACK_MESSAGE[category] ?? error.message;\r\n return new FlowApiError(\r\n category,\r\n message,\r\n body.validation,\r\n body.conflictingAuthor ?? body.updatedBy,\r\n error.error,\r\n );\r\n }\r\n const message = error instanceof Error ? error.message : String(error);\r\n return new FlowApiError('Unknown', message, undefined, undefined, error);\r\n }\r\n\r\n private get<T>(path: string, params?: HttpParams): Promise<T> {\r\n return this.request(firstValueFrom(this.http.get<T>(this.url(path), { params })));\r\n }\r\n\r\n private post<T>(path: string, body?: unknown, params?: HttpParams): Promise<T> {\r\n return this.request(firstValueFrom(this.http.post<T>(this.url(path), body ?? {}, { params })));\r\n }\r\n\r\n private put<T>(path: string, body?: unknown): Promise<T> {\r\n return this.request(firstValueFrom(this.http.put<T>(this.url(path), body ?? {})));\r\n }\r\n\r\n private del<T>(path: string): Promise<T> {\r\n return this.request(firstValueFrom(this.http.delete<T>(this.url(path))));\r\n }\r\n\r\n private static params(values: Record<string, string | number | boolean | undefined>): HttpParams {\r\n let params = new HttpParams();\r\n for (const [key, value] of Object.entries(values)) {\r\n if (value !== undefined && value !== null && value !== '') {\r\n params = params.set(key, String(value));\r\n }\r\n }\r\n return params;\r\n }\r\n\r\n private static segment(value: string): string {\r\n return encodeURIComponent(value);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.1\r\n\r\n listFlows(query?: FlowListQuery): Promise<FlowSummary[]> {\r\n return this.get<FlowSummary[]>('/flows/editor/list', HttpFlowBuilderApi.params({ ...query }));\r\n }\r\n\r\n listVersions(flowName: string): Promise<FlowVersionSummary[]> {\r\n return this.get<FlowVersionSummary[]>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/versions`);\r\n }\r\n\r\n loadFlow(flowName: string, version?: number): Promise<FlowDefinition> {\r\n return this.get<FlowDefinition>(\r\n `/flows/editor/${HttpFlowBuilderApi.segment(flowName)}`,\r\n HttpFlowBuilderApi.params({ version }),\r\n );\r\n }\r\n\r\n override exportFlow(flowName: string, query?: FlowExportQuery): Promise<string> {\r\n return this.request(\r\n firstValueFrom(\r\n this.http.get(this.url(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/export`), {\r\n params: HttpFlowBuilderApi.params({ ...query }),\r\n responseType: 'text',\r\n }),\r\n ),\r\n );\r\n }\r\n\r\n override parseFlow(definition: unknown): Promise<FlowDefinition> {\r\n return this.post<FlowDefinition>('/flows/editor/parse', definition);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.2\r\n\r\n createFlow(request: FlowCreateRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>('/flows/editor/create', request);\r\n }\r\n\r\n saveFlow(flowName: string, request: FlowSaveRequest): Promise<FlowSaveResult> {\r\n return this.put<FlowSaveResult>(`/flows/editor/save`, request);\r\n }\r\n\r\n createVersion(flowName: string, request?: FlowNewVersionRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/new-version`, { author: request?.author }, HttpFlowBuilderApi.params({ from: request?.from }));\r\n }\r\n\r\n override cloneFlow(flowName: string, request: FlowCloneRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/clone`, request);\r\n }\r\n\r\n activateVersion(flowName: string, version: number): Promise<FlowSaveResult> {\r\n return this.put<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/activate/${version}`);\r\n }\r\n\r\n deactivateFlow(flowName: string): Promise<void> {\r\n return this.put<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/deactivate`);\r\n }\r\n\r\n override deleteVersion(flowName: string, version: number): Promise<void> {\r\n return this.del<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/versions/${version}`);\r\n }\r\n\r\n override deleteFlow(flowName: string): Promise<void> {\r\n return this.del<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}`);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.3\r\n\r\n validateDefinition(definition: FlowDefinition): Promise<FlowValidationResult> {\r\n return this.post<FlowValidationResult>(`/flows/editor/${HttpFlowBuilderApi.segment(definition.fullName!.toString())}/validate`, definition);\r\n }\r\n\r\n override validateVersion(flowName: string, version: number): Promise<FlowValidationResult> {\r\n return this.get<FlowValidationResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/validate`, HttpFlowBuilderApi.params({ version: version }));\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.4\r\n\r\n getDictionaries(processType?: string): Promise<FlowDictionaries> {\r\n // `processType` filtra le globali: `$Record` non esiste in uno screen flow (§4.1).\r\n return this.get<FlowDictionaries>('/flows/editor/dictionaries', HttpFlowBuilderApi.params({ processType }));\r\n }\r\n\r\n getReferences(query: FlowReferenceQuery): Promise<FlowReference[]> {\r\n return this.post<FlowReference[]>('/flows/editor/references', query);\r\n }\r\n\r\n getWritableReferences(query: FlowReferenceQuery): Promise<FlowReference[]> {\r\n return this.post<FlowReference[]>('/flows/editor/writable-references', query);\r\n }\r\n\r\n getConnectorTargets(definition: FlowDefinition, excluding?: string): Promise<FlowConnectorTarget[]> {\r\n return this.post<FlowConnectorTarget[]>('/flows/editor/connector-targets', definition, HttpFlowBuilderApi.params({ excluding }));\r\n }\r\n\r\n getOutline(definition: FlowDefinition): Promise<FlowOutline> {\r\n return this.post<FlowOutline>('/flows/editor/outline', definition);\r\n }\r\n\r\n listObjects(): Promise<FlowObjectSummary[]> {\r\n return this.get<FlowObjectSummary[]>('/flows/objects');\r\n }\r\n\r\n override describeObject(object: string): Promise<FlowObjectDescription> {\r\n return this.get<FlowObjectDescription>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}`);\r\n }\r\n\r\n listFields(object: string, usage?: FlowFieldUsage): Promise<FlowObjectDescription['fields']> {\r\n return this.get<FlowObjectDescription['fields']>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}/fields`, HttpFlowBuilderApi.params({ usage }));\r\n }\r\n\r\n override listFieldValues(object: string, field: string): Promise<FlowFieldValue[]> {\r\n return this.get<FlowFieldValue[]>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}/fields/${HttpFlowBuilderApi.segment(field)}/picklist`);\r\n }\r\n\r\n listActionTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/action-types');\r\n }\r\n\r\n listActions(actionType?: string): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/actions', HttpFlowBuilderApi.params({ type: actionType }));\r\n }\r\n\r\n listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/actions/${HttpFlowBuilderApi.segment(actionType)}/${HttpFlowBuilderApi.segment(actionName)}/parameters`);\r\n }\r\n\r\n listScripts(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/scripts');\r\n }\r\n\r\n listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/editor/scripts/${HttpFlowBuilderApi.segment(scriptName)}/parameters`);\r\n }\r\n\r\n listForms(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/forms');\r\n }\r\n\r\n listFormParameters(formName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/editor/forms/${HttpFlowBuilderApi.segment(formName)}/parameters`);\r\n }\r\n\r\n listEnumTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/enum-types');\r\n }\r\n\r\n listEvents(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/events');\r\n }\r\n\r\n listSubflowCandidates(excluding?: string): Promise<FlowSummary[]> {\r\n return this.get<FlowSummary[]>('/flows/editor/subflows', HttpFlowBuilderApi.params({ excluding }));\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.5\r\n\r\n override startInterview(request: FlowStartInterviewRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/start', request);\r\n }\r\n\r\n override respondToScreen(request: FlowScreenResponseRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/submit-screen', request);\r\n }\r\n\r\n override resumeInterview(request: FlowResumeRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/resume-wait', request);\r\n }\r\n\r\n override completeStageStep(request: FlowStageStepRequest): Promise<FlowInterviewResult> {\r\n // La chiave sta nell'URL, il resto nel corpo: la risposta puo' portarne una nuova (§5.13).\r\n let body = { stepName: request.stepName, status: request.status, stepOutputs: request.stepOutputs, debug: request.debug };\r\n return this.post<FlowInterviewResult>(`/flows/${HttpFlowBuilderApi.segment(request.interviewKey)}/resume-stage-step`, body);\r\n }\r\n\r\n override inspectInterview(interviewKey: string): Promise<FlowInterviewResult> {\r\n return this.get<FlowInterviewResult>(`/flows/${HttpFlowBuilderApi.segment(interviewKey)}`);\r\n }\r\n\r\n override abandonInterview(interviewKey: string): Promise<void> {\r\n return this.del<void>(`/flows/${HttpFlowBuilderApi.segment(interviewKey)}`);\r\n }\r\n}\r\n","/**\r\n * Le uscite di ogni tipo di elemento — FRONTEND.md §3.5.\r\n *\r\n * Un connector e' sempre `{ targetReference, isGoTo }`. Quello che cambia e' **in quale\r\n * campo** vive, e il campo dipende dal tipo di elemento. Questo file e' l'unica sede di\r\n * quella mappa: canvas, inspector e outline locale la leggono da qui, invece di ripetere\r\n * `node['faultConnector']` in venti punti.\r\n *\r\n * Ogni uscita e' descritta da una chiave stabile piu' due accessori. La chiave finisce\r\n * nell'id del connettore sul canvas (`out:<node>:<key>`), quindi deve restare uguale fra\r\n * un render e l'altro: per i rami indicizzati (regole, eventi, scheduled path) usa\r\n * l'**indice** dentro la chiave.\r\n *\r\n * Nota: `Transform.connector` e' un array e `start` e' un array di uno, entrambi per\r\n * fedelta' storica; gli accessori qui sotto lo nascondono al resto della libreria.\r\n */\r\n\r\nimport {\r\n FlowAnyNode,\r\n FlowConnector,\r\n FlowDecision,\r\n FlowElementType,\r\n FlowNodeCollection,\r\n FlowStart,\r\n FlowTransform,\r\n FlowWait,\r\n} from '../model/flow.model';\r\nimport { FlowConnectionKind } from '../model/api.model';\r\n\r\n/** Nome fittizio dello Start sul canvas: nel documento non ha `name` (§6.4, `from: null`). */\r\nexport const START_NODE_NAME = '$start';\r\n\r\nexport interface FlowOutlet {\r\n /** Stabile fra i render: entra nell'id del connettore del canvas. */\r\n key: string;\r\n /** Determina lo stile dell'arco: `Fault` rosso, `Rule` etichettato, … (§6.4). */\r\n kind: FlowConnectionKind;\r\n /** Etichetta mostrata sul connettore e nel form. */\r\n label: string;\r\n /** Etichetta di ramo definita dall'autore (label della regola, dell'evento). */\r\n branchLabel?: string | null;\r\n /**\r\n * `true` → l'assenza del connector e' un problema strutturale, non la fine legittima\r\n * di un percorso: il corpo di un Loop (§3.5).\r\n */\r\n isStructural?: boolean;\r\n read(node: FlowAnyNode): FlowConnector | undefined;\r\n write(node: FlowAnyNode, connector: FlowConnector | undefined): void;\r\n}\r\n\r\n/** Accessore per un connector che vive in un campo diretto del node. */\r\nfunction field(\r\n key: string,\r\n kind: FlowConnectionKind,\r\n label: string,\r\n property: string,\r\n extra?: Partial<FlowOutlet>,\r\n): FlowOutlet {\r\n return {\r\n key,\r\n kind,\r\n label,\r\n read: (node) => node[property] as FlowConnector | undefined,\r\n write: (node, connector) => {\r\n if (connector) {\r\n node[property] = connector;\r\n } else {\r\n delete node[property];\r\n }\r\n },\r\n ...extra,\r\n };\r\n}\r\n\r\n/** Accessore per un connector dentro un elemento di array (`rules[i].connector`). */\r\nfunction nested(\r\n key: string,\r\n kind: FlowConnectionKind,\r\n label: string,\r\n arrayProperty: string,\r\n index: number,\r\n branchLabel?: string | null,\r\n): FlowOutlet {\r\n return {\r\n key,\r\n kind,\r\n label,\r\n branchLabel,\r\n read: (node) => {\r\n const list = node[arrayProperty] as Array<{ connector?: FlowConnector }> | undefined;\r\n return list?.[index]?.connector;\r\n },\r\n write: (node, connector) => {\r\n const list = node[arrayProperty] as Array<{ connector?: FlowConnector }> | undefined;\r\n const item = list?.[index];\r\n if (!item) {\r\n return;\r\n }\r\n if (connector) {\r\n item.connector = connector;\r\n } else {\r\n delete item.connector;\r\n }\r\n },\r\n };\r\n}\r\n\r\n/** `Transform.connector` e' un array: usa il primo (§3.5). */\r\nfunction transformOutlet(): FlowOutlet {\r\n return {\r\n key: 'next',\r\n kind: 'Next',\r\n label: 'Successivo',\r\n read: (node) => (node as FlowTransform).connector?.[0],\r\n write: (node, connector) => {\r\n const transform = node as FlowTransform;\r\n if (connector) {\r\n transform.connector = [connector];\r\n } else {\r\n delete transform.connector;\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Le uscite di un node, nell'ordine in cui vanno mostrate.\r\n * `type` e' il discriminatore di `elementTypes`; per lo Start passa `'Start'`.\r\n */\r\nexport function outletsOf(type: FlowElementType, node: FlowAnyNode): FlowOutlet[] {\r\n switch (type) {\r\n case 'Start': {\r\n const start = node as FlowStart;\r\n const outlets: FlowOutlet[] = [\r\n field('next', 'Start', 'Inizio', 'connector', {\r\n // Senza, `START_NO_ENTRY_POINT`: e' strutturale (§3.4).\r\n isStructural: true,\r\n }),\r\n ];\r\n (start.scheduledPaths ?? []).forEach((path, index) => {\r\n outlets.push(\r\n nested(\r\n `scheduledPath:${index}`,\r\n 'ScheduledPath',\r\n path.label || path.name || `Percorso differito ${index + 1}`,\r\n 'scheduledPaths',\r\n index,\r\n path.label ?? path.name ?? null,\r\n ),\r\n );\r\n });\r\n return outlets;\r\n }\r\n\r\n case 'Decision': {\r\n const decision = node as FlowDecision;\r\n const outlets: FlowOutlet[] = (decision.rules ?? []).map((rule, index) =>\r\n nested(\r\n `rule:${index}`,\r\n 'Rule',\r\n rule.label || rule.name || `Regola ${index + 1}`,\r\n 'rules',\r\n index,\r\n rule.label ?? rule.name ?? null,\r\n ),\r\n );\r\n outlets.push(\r\n field('default', 'Default', decision.defaultConnectorLabel || 'Nessuna regola vera', 'defaultConnector', {\r\n branchLabel: decision.defaultConnectorLabel ?? null,\r\n }),\r\n );\r\n return outlets;\r\n }\r\n\r\n case 'Loop':\r\n return [\r\n // Senza corpo il ciclo non ha senso: la validazione lo segnala come errore (§3.5).\r\n field('loopNext', 'LoopNext', 'Per ogni valore', 'nextValueConnector', { isStructural: true }),\r\n field('loopEnd', 'LoopEnd', 'Nessun valore rimasto', 'noMoreValuesConnector'),\r\n ];\r\n\r\n case 'Wait': {\r\n const wait = node as FlowWait;\r\n const outlets: FlowOutlet[] = (wait.waitEvents ?? []).map((event, index) =>\r\n nested(\r\n `waitEvent:${index}`,\r\n 'WaitEvent',\r\n event.label || event.name || `Evento ${index + 1}`,\r\n 'waitEvents',\r\n index,\r\n event.label ?? event.name ?? null,\r\n ),\r\n );\r\n outlets.push(\r\n field('default', 'Default', wait.defaultConnectorLabel || 'Nessun evento verificato', 'defaultConnector', {\r\n branchLabel: wait.defaultConnectorLabel ?? null,\r\n }),\r\n );\r\n outlets.push(field('fault', 'Fault', 'Errore', 'faultConnector'));\r\n return outlets;\r\n }\r\n\r\n case 'ActionCall': {\r\n const outlets: FlowOutlet[] = [\r\n field('next', 'Next', 'Successivo', 'connector'),\r\n field('fault', 'Fault', 'Errore', 'faultConnector'),\r\n ];\r\n // Il ramo di timeout esiste solo con `timeoutPathUsage: 'EnableTimeoutPath'` (§5.8).\r\n if (node['timeoutPathUsage'] === 'EnableTimeoutPath' || node['timeoutConnector']) {\r\n outlets.push(field('timeout', 'Timeout', 'Timeout', 'timeoutConnector'));\r\n }\r\n return outlets;\r\n }\r\n\r\n // Lo `faultConnector` di uno stage **non** e' un ramo di guasto: e' il ramo dello step\r\n // rifiutato, e senza di esso un rifiuto fa fallire l'interview (§5.13). L'etichetta lo\r\n // dice, altrimenti chi disegna un'approvazione lo lascia vuoto credendo di rinunciare\r\n // solo alla gestione degli errori.\r\n case 'OrchestratedStage':\r\n return [\r\n field('next', 'Next', 'Stage concluso', 'connector'),\r\n field('fault', 'Fault', 'Step rifiutato', 'faultConnector'),\r\n ];\r\n\r\n case 'ScriptCall':\r\n case 'RecordLookup':\r\n case 'RecordCreate':\r\n case 'RecordUpdate':\r\n case 'RecordDelete':\r\n return [\r\n field('next', 'Next', 'Successivo', 'connector'),\r\n field('fault', 'Fault', 'Errore', 'faultConnector'),\r\n ];\r\n\r\n case 'Transform':\r\n return [transformOutlet()];\r\n\r\n // Il Custom Error interrompe l'esecuzione: non ha uscite (§5.11).\r\n case 'CustomError':\r\n return [];\r\n\r\n case 'Screen':\r\n case 'Assignment':\r\n case 'CollectionProcessor':\r\n case 'RecordRollback':\r\n case 'Subflow':\r\n return [field('next', 'Next', 'Successivo', 'connector')];\r\n\r\n default:\r\n // Tipo sconosciuto o non supportato: se ha un `connector`, mostralo comunque,\r\n // altrimenti nessuna uscita. Non inventare rami.\r\n return node['connector'] ? [field('next', 'Next', 'Successivo', 'connector')] : [];\r\n }\r\n}\r\n\r\n/** Trova un'uscita per chiave. */\r\nexport function outletByKey(type: FlowElementType, node: FlowAnyNode, key: string): FlowOutlet | undefined {\r\n return outletsOf(type, node).find((outlet) => outlet.key === key);\r\n}\r\n\r\n/**\r\n * Mappa di fallback tipo → collection, usata quando il dizionario `elementTypes` non e'\r\n * disponibile. La fonte autoritativa resta `metadataProperty` del dizionario (§3.2).\r\n */\r\nexport const FALLBACK_COLLECTION_BY_TYPE: Record<string, FlowNodeCollection> = {\r\n Screen: 'screens',\r\n Assignment: 'assignments',\r\n Decision: 'decisions',\r\n Loop: 'loops',\r\n CollectionProcessor: 'collectionProcessors',\r\n CustomError: 'customErrors',\r\n Wait: 'waits',\r\n RecordLookup: 'recordLookups',\r\n RecordCreate: 'recordCreates',\r\n RecordUpdate: 'recordUpdates',\r\n RecordDelete: 'recordDeletes',\r\n RecordRollback: 'recordRollbacks',\r\n ActionCall: 'actionCalls',\r\n ScriptCall: 'scriptPluginCalls',\r\n Subflow: 'subflows',\r\n Transform: 'transforms',\r\n Step: 'steps',\r\n Experiment: 'experiments',\r\n OrchestratedStage: 'orchestratedStages',\r\n};\r\n\r\n/** Inverso della mappa: serve al flatten in lettura (§3.1). */\r\nexport const TYPE_BY_COLLECTION: Record<string, FlowElementType> = Object.fromEntries(\r\n Object.entries(FALLBACK_COLLECTION_BY_TYPE).map(([type, collection]) => [collection, type]),\r\n);\r\n\r\n/** Etichette di fallback, se il dizionario non e' caricato. */\r\nexport const FALLBACK_TYPE_LABEL: Record<string, string> = {\r\n Screen: 'Screen',\r\n Assignment: 'Assegnazione',\r\n Decision: 'Decisione',\r\n Loop: 'Ciclo',\r\n CollectionProcessor: 'Ordina o filtra',\r\n CustomError: 'Errore custom',\r\n Wait: 'Attesa',\r\n RecordLookup: 'Get Records',\r\n RecordCreate: 'Create Records',\r\n RecordUpdate: 'Update Records',\r\n RecordDelete: 'Delete Records',\r\n RecordRollback: 'Roll Back Records',\r\n ActionCall: 'Action',\r\n ScriptCall: 'Script',\r\n Subflow: 'Subflow',\r\n Transform: 'Trasformazione',\r\n Step: 'Segnaposto',\r\n Experiment: 'Esperimento',\r\n OrchestratedStage: 'Stage di orchestrazione',\r\n};\r\n\r\n/** I due tipi che il motore rifiuta: nascosti dalla palette (§3.2, §13.9). */\r\nexport const UNSUPPORTED_TYPES: ReadonlySet<string> = new Set(['Step', 'Experiment']);\r\n\r\n/** Elementi che espongono il proprio risultato sotto il nome dell'elemento (§4.5). */\r\nexport const TYPES_WITH_AUTOMATIC_OUTPUT: ReadonlySet<string> = new Set([\r\n 'RecordLookup',\r\n 'RecordCreate',\r\n 'CollectionProcessor',\r\n 'Transform',\r\n 'ActionCall',\r\n 'Subflow',\r\n]);\r\n","/**\r\n * Il glifo di ogni tipo di elemento.\r\n *\r\n * Sono caratteri Unicode, non icone: la libreria non porta asset e non dipende da un font di\r\n * icone dell'applicazione ospite. Sta in `core` e non nel canvas perche' lo stesso glifo deve\r\n * comparire sulla palette e sul node: se divergessero, l'elemento trascinato non\r\n * assomiglierebbe a quello che compare sul canvas.\r\n */\r\n\r\nexport const FLOW_ELEMENT_ICONS: Record<string, string> = {\r\n Start: '▶',\r\n Screen: '▤',\r\n Decision: '◆',\r\n Assignment: '=',\r\n Loop: '↻',\r\n CollectionProcessor: '⇅',\r\n RecordLookup: '⌕',\r\n RecordCreate: '+',\r\n RecordUpdate: '✎',\r\n RecordDelete: '×',\r\n RecordRollback: '↺',\r\n ActionCall: '⚡',\r\n ScriptCall: '⟨⟩',\r\n Subflow: '⤵',\r\n Transform: '⇄',\r\n Wait: '◷',\r\n CustomError: '!',\r\n OrchestratedStage: '☰',\r\n};\r\n\r\n/**\r\n * Il glifo del tipo. Per un tipo che il dizionario del backend aggiunge e questa mappa non\r\n * conosce, l'iniziale dell'etichetta e' un segnaposto migliore di un simbolo generico.\r\n */\r\nexport function elementIcon(type: string, label?: string): string {\r\n const icon = FLOW_ELEMENT_ICONS[type];\r\n if (icon) {\r\n return icon;\r\n }\r\n const fallback = (label || type).trim().charAt(0).toUpperCase();\r\n return fallback || '•';\r\n}\r\n","/**\r\n * Nomi — FRONTEND.md §3.3, §13.5.\r\n *\r\n * Tre regole, tutte e tre implementate qui:\r\n * 1. `^[A-Za-z][A-Za-z0-9_]*$` — niente punti (i riferimenti si spezzano sul punto),\r\n * niente spazi, niente `$`;\r\n * 2. node e risorse condividono **un unico** spazio di nomi;\r\n * 3. il confronto e' **case-insensitive**.\r\n */\r\n\r\nexport const FLOW_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*$/;\r\n\r\nexport type FlowNameProblem = 'empty' | 'pattern' | 'duplicate';\r\n\r\nexport interface FlowNameCheck {\r\n isValid: boolean;\r\n problem?: FlowNameProblem;\r\n message?: string;\r\n}\r\n\r\n/** Verifica solo la forma. */\r\nexport function isValidFlowName(name: string | undefined | null): boolean {\r\n return !!name && FLOW_NAME_PATTERN.test(name);\r\n}\r\n\r\n/**\r\n * Verifica forma **e** unicita' contro l'insieme dei nomi già usati.\r\n * `currentName` esclude se stesso dal controllo, per non segnalare un elemento in modifica.\r\n */\r\nexport function checkFlowName(\r\n name: string | undefined | null,\r\n usedNames: Iterable<string>,\r\n currentName?: string | null,\r\n): FlowNameCheck {\r\n const trimmed = (name ?? '').trim();\r\n if (!trimmed) {\r\n return { isValid: false, problem: 'empty', message: 'Il nome tecnico e’ obbligatorio.' };\r\n }\r\n if (!FLOW_NAME_PATTERN.test(trimmed)) {\r\n return {\r\n isValid: false,\r\n problem: 'pattern',\r\n message: 'Deve iniziare con una lettera e contenere solo lettere, cifre e underscore.',\r\n };\r\n }\r\n const lower = trimmed.toLowerCase();\r\n const currentLower = currentName?.trim().toLowerCase();\r\n for (const used of usedNames) {\r\n const usedLower = used.toLowerCase();\r\n if (usedLower === lower && usedLower !== currentLower) {\r\n // Il confronto e' case-insensitive: `Importo` e `importo` sono lo stesso nome.\r\n return {\r\n isValid: false,\r\n problem: 'duplicate',\r\n message: 'Questo nome e’ già usato da un altro elemento o da una risorsa.',\r\n };\r\n }\r\n }\r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Genera il nome tecnico da una label: `\"Approva ordine\"` → `Approva_Ordine` (§3.3).\r\n * Va lasciato modificabile finche' l'elemento e' nuovo.\r\n */\r\nexport function slugifyFlowName(label: string | undefined | null): string {\r\n const source = (label ?? '').trim();\r\n if (!source) {\r\n return '';\r\n }\r\n const words = source\r\n // Toglie i diacritici: `Città` → `Citta`.\r\n .normalize('NFD')\r\n .replace(/\\p{Diacritic}/gu, '')\r\n .split(/[^A-Za-z0-9]+/)\r\n .filter(Boolean)\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1));\r\n let name = words.join('_');\r\n if (!name) {\r\n return '';\r\n }\r\n // Deve iniziare con una lettera.\r\n if (!/^[A-Za-z]/.test(name)) {\r\n name = `X_${name}`;\r\n }\r\n return name;\r\n}\r\n\r\n/**\r\n * Genera un nome libero a partire da una base, aggiungendo un suffisso numerico.\r\n * `Decisione`, `Decisione_1`, `Decisione_2`, …\r\n */\r\nexport function uniqueFlowName(base: string, usedNames: Iterable<string>): string {\r\n const used = new Set(Array.from(usedNames, (name) => name.toLowerCase()));\r\n const root = slugifyFlowName(base) || 'Elemento';\r\n if (!used.has(root.toLowerCase())) {\r\n return root;\r\n }\r\n let index = 1;\r\n while (used.has(`${root}_${index}`.toLowerCase())) {\r\n index += 1;\r\n }\r\n return `${root}_${index}`;\r\n}\r\n\r\n/**\r\n * La prima parte di un riferimento, cioe' il nome che deve esistere.\r\n * `Cliente.Email` → `Cliente`; `$Record.Stato` → `$Record`; `Importo` → `Importo`.\r\n */\r\nexport function referenceRoot(reference: string | undefined | null): string {\r\n const value = (reference ?? '').trim();\r\n const dot = value.indexOf('.');\r\n return dot < 0 ? value : value.slice(0, dot);\r\n}\r\n\r\n/** `true` se il riferimento e' una variabile globale (`$Record`, `$Flow`, `$User`, …). */\r\nexport function isGlobalReference(reference: string | undefined | null): boolean {\r\n return (reference ?? '').trimStart().startsWith('$');\r\n}\r\n","/**\r\n * `conditionLogic` — FRONTEND.md §4.3 e trappola §13.4.\r\n *\r\n * L'espressione custom referenzia gli **indici 1-based** delle condizioni. Se l'editor\r\n * cancella o riordina una condizione, gli indici scalano e l'espressione va riscritta:\r\n * senza, si ottiene un `CONDITION_LOGIC_INVALID` o — peggio — un'espressione valida che\r\n * punta alla condizione sbagliata.\r\n */\r\n\r\nimport { FlowConditionHolder, FlowConditionLogic } from '../model/flow.model';\r\n\r\n/** Le tre forme non-espressione. `and` e' anche il default quando il campo e' assente. */\r\nexport function isCustomConditionLogic(logic: FlowConditionLogic | undefined): boolean {\r\n if (!logic) {\r\n return false;\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n return normalized !== 'and' && normalized !== 'or' && normalized !== 'formula';\r\n}\r\n\r\n/**\r\n * Riscrive un'espressione custom dopo che le condizioni sono state rimappate.\r\n *\r\n * `mapping[oldIndex0Based]` = nuovo indice 0-based, oppure `-1` se la condizione e' stata\r\n * cancellata. Un indice cancellato non puo' essere rimpiazzato da niente di sensato: il\r\n * termine viene sostituito da un segnaposto e la funzione lo segnala, così la UI puo'\r\n * avvisare che l'espressione va rivista.\r\n */\r\nexport function remapConditionLogic(\r\n logic: string,\r\n mapping: number[],\r\n): { logic: string; hasDroppedTerms: boolean } {\r\n let hasDroppedTerms = false;\r\n const rewritten = logic.replace(/\\d+/g, (match) => {\r\n const oldIndex = Number(match) - 1;\r\n const newIndex = mapping[oldIndex];\r\n if (newIndex === undefined || newIndex < 0) {\r\n hasDroppedTerms = true;\r\n // Segnaposto riconoscibile: la UI lo evidenzia e chiede di correggere.\r\n return '?';\r\n }\r\n return String(newIndex + 1);\r\n });\r\n return { logic: rewritten, hasDroppedTerms };\r\n}\r\n\r\n/**\r\n * Rimuove la condizione all'indice indicato e aggiorna `conditionLogic` di conseguenza.\r\n * Muta l'oggetto passato (che nello store e' già una copia di lavoro).\r\n */\r\nexport function removeCondition(holder: FlowConditionHolder, index: number): { hasDroppedTerms: boolean } {\r\n const conditions = holder.conditions ?? [];\r\n if (index < 0 || index >= conditions.length) {\r\n return { hasDroppedTerms: false };\r\n }\r\n conditions.splice(index, 1);\r\n\r\n if (!isCustomConditionLogic(holder.conditionLogic)) {\r\n return { hasDroppedTerms: false };\r\n }\r\n // Le condizioni dopo quella cancellata scalano di uno; quella cancellata → -1.\r\n const mapping: number[] = [];\r\n for (let position = 0; position <= conditions.length; position += 1) {\r\n if (position < index) {\r\n mapping.push(position);\r\n } else if (position === index) {\r\n mapping.push(-1);\r\n } else {\r\n mapping.push(position - 1);\r\n }\r\n }\r\n const result = remapConditionLogic(holder.conditionLogic as string, mapping);\r\n holder.conditionLogic = result.logic;\r\n return { hasDroppedTerms: result.hasDroppedTerms };\r\n}\r\n\r\n/** Sposta una condizione e riscrive l'espressione perche' punti agli stessi termini. */\r\nexport function moveCondition(holder: FlowConditionHolder, from: number, to: number): void {\r\n const conditions = holder.conditions ?? [];\r\n if (from === to || from < 0 || to < 0 || from >= conditions.length || to >= conditions.length) {\r\n return;\r\n }\r\n const [moved] = conditions.splice(from, 1);\r\n conditions.splice(to, 0, moved);\r\n\r\n if (!isCustomConditionLogic(holder.conditionLogic)) {\r\n return;\r\n }\r\n // Ricostruisce dove e' finito ogni vecchio indice.\r\n const order: number[] = [];\r\n for (let index = 0; index < conditions.length; index += 1) {\r\n order.push(index);\r\n }\r\n const oldOrder = order.slice();\r\n const [movedIndex] = oldOrder.splice(to, 1);\r\n oldOrder.splice(from, 0, movedIndex);\r\n // `oldOrder[oldIndex] = newIndex`\r\n const mapping: number[] = [];\r\n oldOrder.forEach((newIndex, oldIndex) => {\r\n mapping[oldIndex] = newIndex;\r\n });\r\n holder.conditionLogic = remapConditionLogic(holder.conditionLogic as string, mapping).logic;\r\n}\r\n\r\n/**\r\n * Verifica che un'espressione custom sia sintatticamente accettabile e che ogni indice\r\n * esista. Serve al feedback immediato nel form: la verita' resta della validazione\r\n * del backend (`CONDITION_LOGIC_INVALID`).\r\n */\r\nexport function checkConditionLogic(logic: string, conditionCount: number): string | null {\r\n const trimmed = logic.trim();\r\n if (!trimmed) {\r\n return null;\r\n }\r\n if (!isCustomConditionLogic(trimmed)) {\r\n return null;\r\n }\r\n // Caratteri ammessi: indici, AND, OR, NOT, parentesi, spazi.\r\n const stripped = trimmed.replace(/\\b(AND|OR|NOT)\\b/gi, ' ').replace(/[()\\s]/g, '');\r\n if (/[^0-9]/.test(stripped)) {\r\n return 'Ammessi solo indici, AND, OR, NOT e parentesi.';\r\n }\r\n let depth = 0;\r\n for (const character of trimmed) {\r\n if (character === '(') {\r\n depth += 1;\r\n } else if (character === ')') {\r\n depth -= 1;\r\n if (depth < 0) {\r\n return 'Parentesi non bilanciate.';\r\n }\r\n }\r\n }\r\n if (depth !== 0) {\r\n return 'Parentesi non bilanciate.';\r\n }\r\n const indexes = trimmed.match(/\\d+/g) ?? [];\r\n if (indexes.length === 0) {\r\n return 'L’espressione non referenzia nessuna condizione.';\r\n }\r\n for (const raw of indexes) {\r\n const index = Number(raw);\r\n if (index < 1 || index > conditionCount) {\r\n return `La condizione ${index} non esiste: sono definite ${conditionCount} condizioni.`;\r\n }\r\n }\r\n return null;\r\n}\r\n","/**\r\n * Testo e numero non si confrontano — FRONTEND.md §4.3, §13.13.\r\n *\r\n * `Importo > \"1000\"` con `Importo` numerico e' `CONDITION_TYPE_MISMATCH`, un **errore** che\r\n * blocca l'attivazione: la conversione implicita renderebbe l'esito dipendente dal formato\r\n * del testo, e chi disegna il flow non ha modo di accorgersene.\r\n *\r\n * Il backend segnala solo quando conosce **entrambi** i tipi, e su un campo di un record o\r\n * sull'output automatico di un elemento non li conosce: il posto giusto in cui fermare\r\n * l'utente e' il picker, cioe' l'editor delle condizioni. Questo file e' la regola, in un\r\n * posto solo.\r\n *\r\n * Vale per i soli operatori di uguaglianza e ordine. `Contains`, `StartsWith`, `EndsWith`,\r\n * `In` e `NotIn` hanno una semantica propria e non sono soggetti alla regola; gli unari non\r\n * hanno un secondo operando.\r\n */\r\n\r\nimport { FlowDataType } from '../model/flow.model';\r\n\r\n/** Gli operatori con una semantica propria: la regola non li riguarda (§4.3). */\r\nconst OPERATORS_WITHOUT_TYPE_CHECK: ReadonlySet<string> = new Set([\r\n 'Contains',\r\n 'StartsWith',\r\n 'EndsWith',\r\n 'In',\r\n 'NotIn',\r\n 'None',\r\n]);\r\n\r\n/** `Integer` e `Number` sono intercambiabili fra loro. */\r\nconst NUMERIC_TYPES: ReadonlySet<string> = new Set(['Integer', 'Number']);\r\n\r\n/**\r\n * `true` → per questo operatore i due lati devono essere compatibili.\r\n * `isUnary` arriva dal dizionario: un unario non ha un termine di confronto.\r\n */\r\nexport function isTypeCheckedOperator(operator: string | undefined | null, isUnary: boolean): boolean {\r\n if (!operator || isUnary) {\r\n return false;\r\n }\r\n return !OPERATORS_WITHOUT_TYPE_CHECK.has(operator);\r\n}\r\n\r\nexport function isNumericType(dataType: FlowDataType | undefined | null): boolean {\r\n return !!dataType && NUMERIC_TYPES.has(dataType);\r\n}\r\n\r\n/**\r\n * `false` solo per la coppia vietata: testo con numero.\r\n *\r\n * È l'**unica** coppia vietata. Un `Enum` confrontato con un testo resta lecito, perche' un\r\n * enum si confronta anche per nome; e con un tipo ignoto da un lato non si segnala nulla,\r\n * perche' non sapere non e' sapere che e' sbagliato.\r\n */\r\nexport function areTypesComparable(\r\n left: FlowDataType | undefined | null,\r\n right: FlowDataType | undefined | null,\r\n): boolean {\r\n if (!left || !right) {\r\n return true;\r\n }\r\n if (isNumericType(left) && right === 'String') {\r\n return false;\r\n }\r\n if (left === 'String' && isNumericType(right)) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * I numeri viaggiano in **cultura invariante**: il separatore decimale e' il punto, la virgola\r\n * non e' accettata (§4.3). Un campo che mostra `1.234,50` deve scrivere `1234.50`.\r\n *\r\n * Accetta la virgola come separatore decimale digitato — e' quello che un utente italiano\r\n * scrive — e la traduce, invece di lasciare che `parseFloat` tronchi silenziosamente a `1`.\r\n */\r\nexport function parseInvariantNumber(raw: string): number | undefined {\r\n const trimmed = raw.trim();\r\n if (!trimmed) {\r\n return undefined;\r\n }\r\n // Una sola virgola e nessun punto: e' il separatore decimale.\r\n const normalized =\r\n !trimmed.includes('.') && (trimmed.match(/,/g) ?? []).length === 1\r\n ? trimmed.replace(',', '.')\r\n : trimmed;\r\n if (!/^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?$/.test(normalized)) {\r\n return undefined;\r\n }\r\n const parsed = Number(normalized);\r\n return Number.isFinite(parsed) ? parsed : undefined;\r\n}\r\n","/**\r\n * Gli step di uno stage di orchestrazione — FRONTEND.md §5.13.\r\n *\r\n * Tre regole del contratto che non si vedono guardando il tipo, e che qui stanno in un posto\r\n * solo perche' le usano l'inspector, lo spazio dei nomi del documento e la validazione locale:\r\n *\r\n * 1. il `name` di uno step vive nello **stesso spazio dei nomi** di node e risorse (§3.3):\r\n * uno step omonimo di una variabile e' `NAME_DUPLICATED`;\r\n * 2. l'output di uno step e' sempre referenziabile come `<NomeStep>.<NomeOutput>`, ma una\r\n * condizione **non** puo' referenziarlo: finche' lo step non ha girato il riferimento e'\r\n * irrisolvibile, e a runtime un riferimento irrisolvibile e' un errore;\r\n * 3. gli step non sono una sequenza: l'ordine nell'array e' solo l'ordine d'esame.\r\n */\r\n\r\nimport { FlowDefinition, FlowOrchestratedStage, FlowStageStep } from '../model/flow.model';\r\nimport { referenceRoot } from './flow-name.util';\r\n\r\n/** I nomi di tutti gli step del documento: entrano nello spazio dei nomi comune (§3.3). */\r\nexport function stageStepNames(definition: FlowDefinition): string[] {\r\n const names: string[] = [];\r\n for (const stage of definition.orchestratedStages ?? []) {\r\n for (const step of stage.stageSteps ?? []) {\r\n if (step.name) {\r\n names.push(step.name);\r\n }\r\n }\r\n }\r\n return names;\r\n}\r\n\r\n/** Gli step di uno stage, con l'array assente trattato come vuoto. */\r\nexport function stepsOf(stage: FlowOrchestratedStage | undefined): FlowStageStep[] {\r\n return stage?.stageSteps ?? [];\r\n}\r\n\r\n/**\r\n * Il nome dello step il cui output un riferimento sta leggendo, se e' uno degli step passati.\r\n * `undefined` quando il riferimento e' legittimo. Serve a impedire nell'editor la condizione\r\n * che referenzia l'output di un altro step (§5.13, punto 4): la strada corretta e' scrivere\r\n * quel risultato in una variabile con `outputParameters.assignToReference` e condizionare\r\n * su quella.\r\n */\r\nexport function stageStepOutputReferenced(\r\n reference: string | undefined,\r\n steps: FlowStageStep[],\r\n): string | undefined {\r\n if (!reference) {\r\n return undefined;\r\n }\r\n const root = referenceRoot(reference.trim());\r\n return steps.find((step) => !!step.name && step.name === root)?.name;\r\n}\r\n\r\n/**\r\n * L'unico output che il runtime legge da un evaluation flow di condizione. Dichiararne altri\r\n * e' `STAGE_ACTION_INVALID` (§5.13, punto 7).\r\n */\r\nexport const ORCHESTRATION_CONDITION_OUTPUT = 'isOrchestrationConditionMet';\r\n","/**\r\n * Lo store del documento in lavorazione.\r\n *\r\n * Il documento `FlowDefinition` e' la fonte di verita' unica: canvas, inspector e pannelli\r\n * leggono da qui e scrivono qui. Le primitive del backend non vengono chiamate da questo\r\n * store — se ne occupano i pannelli tramite {@link FlowBuilderApi} — così l'editing resta\r\n * sincrono e reattivo anche mentre una validazione e' in volo.\r\n *\r\n * Il flatten delle collection (§3.1) e la mappa delle uscite (§3.5) sono esposti come\r\n * signal derivati: e' cio' che rende il canvas una funzione del documento.\r\n */\r\n\r\nimport { Injectable, computed, signal } from '@angular/core';\r\n\r\nimport {\r\n FLOW_NODE_COLLECTIONS,\r\n FLOW_RESOURCE_COLLECTIONS,\r\n FlowAnyNode,\r\n FlowConnector,\r\n FlowDefinition,\r\n FlowElementType,\r\n FlowNodeCollection,\r\n FlowResourceCollection,\r\n FlowStart,\r\n} from '../model/flow.model';\r\nimport { FlowConnectionKind } from '../model/api.model';\r\nimport { FlowOutlet, START_NODE_NAME, TYPE_BY_COLLECTION, outletsOf } from './element-outlets';\r\nimport { stageStepNames } from './stage-step.util';\r\n\r\n/** Un node come lo vede l'editor: il node piu' da dove viene. */\r\nexport interface FlowNodeRef {\r\n name: string;\r\n type: FlowElementType;\r\n collection: FlowNodeCollection;\r\n index: number;\r\n node: FlowAnyNode;\r\n}\r\n\r\n/** Un arco derivato dal documento, con la sua origine precisa. */\r\nexport interface FlowEdge {\r\n /** Id stabile: `<sorgente>|<chiave uscita>`. */\r\n id: string;\r\n /** `$start` per gli archi uscenti dallo Start. */\r\n from: string;\r\n /** `undefined` → il connector esiste ma non ha destinazione: ramo incompleto (§6.4). */\r\n to?: string;\r\n outletKey: string;\r\n kind: FlowConnectionKind;\r\n label?: string | null;\r\n isGoTo?: boolean;\r\n}\r\n\r\n/** Una risorsa come la vede l'editor. */\r\nexport interface FlowResourceRef {\r\n name: string;\r\n collection: FlowResourceCollection;\r\n index: number;\r\n resource: Record<string, unknown>;\r\n}\r\n\r\n/** Documento minimo per un flow nuovo (§11, \"Creare un flow\"). */\r\nexport function emptyFlowDefinition(fullName: string, label: string, processType: string): FlowDefinition {\r\n return {\r\n fullName,\r\n label,\r\n processType,\r\n // `start` con connector vuoto: il flow appena creato ha errori, ed e' normale (§11).\r\n start: [{ locationX: 60, locationY: 60 }],\r\n };\r\n}\r\n\r\n/** Copia profonda via JSON: il documento e' JSON per contratto (§2). */\r\nfunction clone<T>(value: T): T {\r\n return JSON.parse(JSON.stringify(value)) as T;\r\n}\r\n\r\nconst HISTORY_LIMIT = 100;\r\n\r\n@Injectable()\r\nexport class FlowDocumentStore {\r\n private readonly _document = signal<FlowDefinition>(emptyFlowDefinition('', '', 'Screen'));\r\n private readonly _isDirty = signal(false);\r\n private readonly _undoStack = signal<string[]>([]);\r\n private readonly _redoStack = signal<string[]>([]);\r\n\r\n /** Il documento in lavorazione. Sola lettura: si modifica con i metodi di questo store. */\r\n readonly document = this._document.asReadonly();\r\n readonly isDirty = this._isDirty.asReadonly();\r\n readonly canUndo = computed(() => this._undoStack().length > 0);\r\n readonly canRedo = computed(() => this._redoStack().length > 0);\r\n\r\n /** §3.4 — l'elemento Start: array di uno, usa sempre il primo. */\r\n readonly start = computed<FlowStart>(() => this._document().start?.[0] ?? {});\r\n\r\n /** §3.1 — tutte le collection appiattite in un'unica lista di node. */\r\n readonly nodes = computed<FlowNodeRef[]>(() => {\r\n const document = this._document();\r\n const result: FlowNodeRef[] = [];\r\n for (const collection of FLOW_NODE_COLLECTIONS) {\r\n const list = document[collection] as FlowAnyNode[] | undefined;\r\n list?.forEach((node, index) => {\r\n result.push({\r\n name: node.name ?? '',\r\n type: TYPE_BY_COLLECTION[collection] ?? collection,\r\n collection,\r\n index,\r\n node,\r\n });\r\n });\r\n }\r\n return result;\r\n });\r\n\r\n readonly nodeByName = computed<Map<string, FlowNodeRef>>(\r\n () => new Map(this.nodes().map((reference) => [reference.name, reference])),\r\n );\r\n\r\n readonly resources = computed<FlowResourceRef[]>(() => {\r\n const document = this._document();\r\n const result: FlowResourceRef[] = [];\r\n for (const collection of FLOW_RESOURCE_COLLECTIONS) {\r\n const list = document[collection] as Array<Record<string, unknown>> | undefined;\r\n list?.forEach((resource, index) => {\r\n result.push({\r\n name: (resource['name'] as string) ?? '',\r\n collection,\r\n index,\r\n resource,\r\n });\r\n });\r\n }\r\n return result;\r\n });\r\n\r\n /**\r\n * §3.3 — l'insieme dei nomi già usati: node, risorse **e** step di orchestrazione, un unico\r\n * spazio di nomi. Il controllo di unicita' che guarda solo le variabili lascia passare una\r\n * variabile omonima di un node (§13.5); quello che dimentica gli step lascia passare uno\r\n * step omonimo di una variabile, che e' `NAME_DUPLICATED` allo stesso modo (§5.13).\r\n */\r\n readonly usedNames = computed<string[]>(() => [\r\n ...this.nodes().map((reference) => reference.name),\r\n ...this.resources().map((reference) => reference.name),\r\n ...stageStepNames(this._document()),\r\n ]);\r\n\r\n /** Gli archi derivati dal documento, Start incluso. */\r\n readonly edges = computed<FlowEdge[]>(() => {\r\n const edges: FlowEdge[] = [];\r\n const push = (from: string, node: FlowAnyNode, outlet: FlowOutlet) => {\r\n const connector = outlet.read(node);\r\n if (!connector) {\r\n return;\r\n }\r\n edges.push({\r\n id: `${from}|${outlet.key}`,\r\n from,\r\n to: connector.targetReference || undefined,\r\n outletKey: outlet.key,\r\n kind: outlet.kind,\r\n label: outlet.branchLabel ?? null,\r\n isGoTo: connector.isGoTo,\r\n });\r\n };\r\n\r\n const start = this.start() as FlowAnyNode;\r\n for (const outlet of outletsOf('Start', start)) {\r\n push(START_NODE_NAME, start, outlet);\r\n }\r\n for (const reference of this.nodes()) {\r\n for (const outlet of outletsOf(reference.type, reference.node)) {\r\n push(reference.name, reference.node, outlet);\r\n }\r\n }\r\n return edges;\r\n });\r\n\r\n /**\r\n * Raggiungibilita' calcolata localmente, per un feedback immediato mentre si disegna.\r\n * La fonte autoritativa resta `isReachable` di `POST /flows/outline` (§6.4): questa e'\r\n * un'anticipazione, non un sostituto.\r\n */\r\n readonly reachableNames = computed<ReadonlySet<string>>(() => {\r\n const adjacency = new Map<string, string[]>();\r\n for (const edge of this.edges()) {\r\n if (!edge.to) {\r\n continue;\r\n }\r\n const list = adjacency.get(edge.from) ?? [];\r\n list.push(edge.to);\r\n adjacency.set(edge.from, list);\r\n }\r\n const visited = new Set<string>();\r\n const queue = [START_NODE_NAME];\r\n while (queue.length) {\r\n const current = queue.shift() as string;\r\n for (const next of adjacency.get(current) ?? []) {\r\n if (!visited.has(next)) {\r\n visited.add(next);\r\n queue.push(next);\r\n }\r\n }\r\n }\r\n return visited;\r\n });\r\n\r\n // -------------------------------------------------------------------------\r\n // Caricamento e storico\r\n // -------------------------------------------------------------------------\r\n\r\n /** Carica un documento dal backend: azzera storico e flag di modifica. */\r\n load(definition: FlowDefinition): void {\r\n this._document.set(clone(definition));\r\n this._undoStack.set([]);\r\n this._redoStack.set([]);\r\n this._isDirty.set(false);\r\n }\r\n\r\n /** Dopo un salvataggio riuscito: il documento resta, la modifica non e' piu' pendente. */\r\n markSaved(): void {\r\n this._isDirty.set(false);\r\n }\r\n\r\n /**\r\n * Applica una modifica al documento.\r\n * Il mutatore riceve una **copia** e la modifica liberamente; lo store si occupa di\r\n * storico e di sostituire il riferimento (nuovo oggetto → i signal derivati ricalcolano).\r\n */\r\n update(mutate: (draft: FlowDefinition) => void, options?: { silent?: boolean }): void {\r\n const current = this._document();\r\n if (!options?.silent) {\r\n this.pushHistory(current);\r\n }\r\n const draft = clone(current);\r\n mutate(draft);\r\n this._document.set(draft);\r\n this._isDirty.set(true);\r\n }\r\n\r\n private pushHistory(snapshot: FlowDefinition): void {\r\n const serialized = JSON.stringify(snapshot);\r\n const stack = [...this._undoStack(), serialized];\r\n if (stack.length > HISTORY_LIMIT) {\r\n stack.shift();\r\n }\r\n this._undoStack.set(stack);\r\n this._redoStack.set([]);\r\n }\r\n\r\n undo(): void {\r\n const stack = [...this._undoStack()];\r\n const previous = stack.pop();\r\n if (!previous) {\r\n return;\r\n }\r\n this._redoStack.set([...this._redoStack(), JSON.stringify(this._document())]);\r\n this._undoStack.set(stack);\r\n this._document.set(JSON.parse(previous) as FlowDefinition);\r\n this._isDirty.set(true);\r\n }\r\n\r\n redo(): void {\r\n const stack = [...this._redoStack()];\r\n const next = stack.pop();\r\n if (!next) {\r\n return;\r\n }\r\n this._undoStack.set([...this._undoStack(), JSON.stringify(this._document())]);\r\n this._redoStack.set(stack);\r\n this._document.set(JSON.parse(next) as FlowDefinition);\r\n this._isDirty.set(true);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Node\r\n // -------------------------------------------------------------------------\r\n\r\n /** Inserisce un node nella collection indicata dal dizionario (`metadataProperty`). */\r\n addNode(collection: FlowNodeCollection, node: FlowAnyNode): void {\r\n this.update((draft) => {\r\n const list = (draft[collection] as FlowAnyNode[] | undefined) ?? [];\r\n list.push(node);\r\n (draft as Record<string, unknown>)[collection] = list;\r\n });\r\n }\r\n\r\n /** Modifica un node per nome. Il mutatore riceve la copia di lavoro. */\r\n updateNode(name: string, mutate: (node: FlowAnyNode) => void, options?: { silent?: boolean }): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n const node = list?.[reference.index];\r\n if (node) {\r\n mutate(node);\r\n }\r\n }, options);\r\n }\r\n\r\n /** Modifica lo Start. */\r\n updateStart(mutate: (start: FlowStart) => void, options?: { silent?: boolean }): void {\r\n this.update((draft) => {\r\n const list = draft.start ?? [{}];\r\n mutate(list[0]);\r\n draft.start = list;\r\n }, options);\r\n }\r\n\r\n /**\r\n * Sposta un node sul canvas. `silent` per non riempire lo storico durante il drag:\r\n * il chiamante registra un solo passo alla fine del gesto.\r\n */\r\n moveNode(name: string, x: number, y: number, options?: { silent?: boolean }): void {\r\n const rounded = { x: Math.round(x), y: Math.round(y) };\r\n if (name === START_NODE_NAME) {\r\n this.updateStart((start) => {\r\n start.locationX = rounded.x;\r\n start.locationY = rounded.y;\r\n }, options);\r\n return;\r\n }\r\n this.updateNode(\r\n name,\r\n (node) => {\r\n node.locationX = rounded.x;\r\n node.locationY = rounded.y;\r\n },\r\n options,\r\n );\r\n }\r\n\r\n /**\r\n * Rimuove un node **e** ogni connector che lo referenzia: un `targetReference` orfano\r\n * e' `CONNECTOR_TARGET_UNKNOWN`, cioe' un errore che blocca l'attivazione (§7).\r\n */\r\n removeNode(name: string): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n list?.splice(reference.index, 1);\r\n if (list && list.length === 0) {\r\n delete (draft as Record<string, unknown>)[reference.collection];\r\n }\r\n FlowDocumentStore.clearReferencesTo(draft, name);\r\n });\r\n }\r\n\r\n /** Azzera i connector che puntano a un node scomparso, Start compreso. */\r\n private static clearReferencesTo(draft: FlowDefinition, removedName: string): void {\r\n const visit = (type: FlowElementType, node: FlowAnyNode) => {\r\n for (const outlet of outletsOf(type, node)) {\r\n const connector = outlet.read(node);\r\n if (connector?.targetReference === removedName) {\r\n // Il ramo resta, senza destinazione: e' un ramo incompleto, non un errore\r\n // di riferimento. La UI lo mostra come tale (§6.4, `to: null`).\r\n outlet.write(node, { ...connector, targetReference: undefined });\r\n }\r\n }\r\n };\r\n const start = draft.start?.[0];\r\n if (start) {\r\n visit('Start', start as FlowAnyNode);\r\n }\r\n for (const collection of FLOW_NODE_COLLECTIONS) {\r\n const list = draft[collection] as FlowAnyNode[] | undefined;\r\n const type = TYPE_BY_COLLECTION[collection] ?? collection;\r\n list?.forEach((node) => visit(type, node));\r\n }\r\n }\r\n\r\n /**\r\n * Rinomina un node riscrivendo **tutti** i riferimenti che lo raggiungono.\r\n * Nessuna primitiva del backend lo fa (§13.8): se l'editor offre la rinomina, la\r\n * riscrittura la deve fare lui. Copre `targetReference`, i riferimenti a risorsa e i\r\n * riferimenti a output automatico (`Vecchio.Campo` → `Nuovo.Campo`).\r\n */\r\n renameNode(oldName: string, newName: string): void {\r\n if (!oldName || !newName || oldName === newName) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const reference = this.nodeByName().get(oldName);\r\n if (reference) {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n const node = list?.[reference.index];\r\n if (node) {\r\n node.name = newName;\r\n }\r\n }\r\n FlowDocumentStore.rewriteReferences(draft, oldName, newName);\r\n });\r\n }\r\n\r\n /** Rinomina una risorsa, riscrivendo i riferimenti che la usano. */\r\n renameResource(collection: FlowResourceCollection, index: number, newName: string): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n const resource = list?.[index];\r\n if (!resource) {\r\n return;\r\n }\r\n const oldName = resource['name'] as string;\r\n resource['name'] = newName;\r\n if (oldName) {\r\n FlowDocumentStore.rewriteReferences(draft, oldName, newName);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Riscrive ogni occorrenza di un nome nei campi che contengono riferimenti.\r\n * Cammina l'intero documento: e' l'unico modo per non dimenticare un campo, dato che\r\n * i riferimenti compaiono in una ventina di posti diversi (§4).\r\n */\r\n private static rewriteReferences(draft: FlowDefinition, oldName: string, newName: string): void {\r\n /** Campi il cui valore e' un riferimento a risorsa o a node. */\r\n const referenceFields = new Set([\r\n 'targetReference',\r\n 'elementReference',\r\n 'assignToReference',\r\n 'leftValueReference',\r\n 'collectionReference',\r\n 'assignNextValueToReference',\r\n 'outputReference',\r\n 'inputReference',\r\n 'assignRecordIdToReference',\r\n ]);\r\n\r\n const rewrite = (value: string): string => {\r\n if (value === oldName) {\r\n return newName;\r\n }\r\n // Riferimento navigato: `Vecchio.Campo` → `Nuovo.Campo`.\r\n if (value.startsWith(`${oldName}.`)) {\r\n return `${newName}${value.slice(oldName.length)}`;\r\n }\r\n return value;\r\n };\r\n\r\n const walk = (value: unknown): void => {\r\n if (Array.isArray(value)) {\r\n value.forEach(walk);\r\n return;\r\n }\r\n if (!value || typeof value !== 'object') {\r\n return;\r\n }\r\n const record = value as Record<string, unknown>;\r\n for (const [key, child] of Object.entries(record)) {\r\n if (typeof child === 'string' && referenceFields.has(key)) {\r\n record[key] = rewrite(child);\r\n } else {\r\n walk(child);\r\n }\r\n }\r\n };\r\n\r\n walk(draft);\r\n }\r\n\r\n /** Duplica un node con un nome nuovo, senza copiarne le uscite. */\r\n duplicateNode(name: string, newName: string, offset = { x: 40, y: 40 }): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n const copy = clone(reference.node);\r\n copy.name = newName;\r\n copy.locationX = (copy.locationX ?? 0) + offset.x;\r\n copy.locationY = (copy.locationY ?? 0) + offset.y;\r\n // Le uscite non si copiano: duplicherebbero rami che l'utente non ha disegnato.\r\n for (const outlet of outletsOf(reference.type, copy)) {\r\n outlet.write(copy, undefined);\r\n }\r\n this.addNode(reference.collection, copy);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Connector\r\n // -------------------------------------------------------------------------\r\n\r\n /** Scrive la destinazione di un'uscita. `target` assente → il ramo resta incompleto. */\r\n setConnector(fromName: string, outletKey: string, target: string | undefined, isGoTo?: boolean): void {\r\n const write = (type: FlowElementType, node: FlowAnyNode) => {\r\n const outlet = outletsOf(type, node).find((candidate) => candidate.key === outletKey);\r\n if (!outlet) {\r\n return;\r\n }\r\n const existing = outlet.read(node) ?? {};\r\n const connector: FlowConnector = { ...existing, targetReference: target };\r\n if (isGoTo !== undefined) {\r\n connector.isGoTo = isGoTo;\r\n }\r\n if (!connector.targetReference && !connector.isGoTo) {\r\n // Nessuna destinazione e nessun flag: meglio omettere il connector che scrivere\r\n // un oggetto vuoto (§2, \"proprieta' nulle omesse\").\r\n outlet.write(node, undefined);\r\n return;\r\n }\r\n outlet.write(node, connector);\r\n };\r\n\r\n if (fromName === START_NODE_NAME) {\r\n this.updateStart((start) => write('Start', start as FlowAnyNode));\r\n return;\r\n }\r\n this.updateNode(fromName, (node) => {\r\n const reference = this.nodeByName().get(fromName);\r\n write(reference?.type ?? '', node);\r\n });\r\n }\r\n\r\n /** Rimuove un arco: il percorso finisce lì, che e' legittimo (§3.5). */\r\n removeConnector(fromName: string, outletKey: string): void {\r\n this.setConnector(fromName, outletKey, undefined);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Risorse\r\n // -------------------------------------------------------------------------\r\n\r\n addResource(collection: FlowResourceCollection, resource: Record<string, unknown>): void {\r\n this.update((draft) => {\r\n const list = (draft[collection] as Array<Record<string, unknown>> | undefined) ?? [];\r\n list.push(resource);\r\n (draft as Record<string, unknown>)[collection] = list;\r\n });\r\n }\r\n\r\n updateResource(\r\n collection: FlowResourceCollection,\r\n index: number,\r\n mutate: (resource: Record<string, unknown>) => void,\r\n ): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n const resource = list?.[index];\r\n if (resource) {\r\n mutate(resource);\r\n }\r\n });\r\n }\r\n\r\n removeResource(collection: FlowResourceCollection, index: number): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n list?.splice(index, 1);\r\n if (list && list.length === 0) {\r\n delete (draft as Record<string, unknown>)[collection];\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Radice\r\n // -------------------------------------------------------------------------\r\n\r\n /** Modifica i campi del documento radice (label, description, processType, …). */\r\n updateHeader(mutate: (definition: FlowDefinition) => void, options?: { silent?: boolean }): void {\r\n this.update(mutate, options);\r\n }\r\n}\r\n","/**\r\n * Cache dei dizionari e dei cataloghi — FRONTEND.md §6.4.\r\n *\r\n * I dizionari sono **quasi** statici: si caricano una volta all'avvio dell'editor e si tengono\r\n * in cache, con un'eccezione — `globalVariables` dipende dal `processType` con cui li si e'\r\n * chiesti, perche' `$Record` non esiste in uno screen flow (§4.1). Qui la cache e' quindi per\r\n * tipo di flow: cambiare `processType` nell'editor ricarica le globali, non tutto il resto\r\n * dell'esperienza.\r\n *\r\n * I cataloghi (oggetti, campi, action, form, script, eventi) cambiano raramente: sono\r\n * memoizzati per chiave, in modo che aprire dieci volte lo stesso inspector non produca dieci\r\n * richieste.\r\n *\r\n * Nessun elenco di enum e' cablato: se il backend aggiunge un operatore, appare nelle\r\n * tendine senza toccare il frontend (§13.11).\r\n */\r\n\r\nimport { Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowComparisonOperatorEntry,\r\n FlowDataTypeEntry,\r\n FlowDictionaries,\r\n FlowDictionaryEntry,\r\n FlowElementTypeEntry,\r\n FlowFieldDescription,\r\n FlowFieldUsage,\r\n FlowGlobalVariableEntry,\r\n FlowObjectSummary,\r\n FlowStageStepTypeEntry,\r\n} from '../model/dictionary.model';\r\nimport { FlowDataType, FlowNodeCollection } from '../model/flow.model';\r\nimport {\r\n FALLBACK_COLLECTION_BY_TYPE,\r\n FALLBACK_TYPE_LABEL,\r\n UNSUPPORTED_TYPES,\r\n} from './element-outlets';\r\n\r\n@Injectable()\r\nexport class FlowDictionaryStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n private readonly _dictionaries = signal<FlowDictionaries>({});\r\n private readonly _isLoaded = signal(false);\r\n private readonly _processType = signal<string | undefined>(undefined);\r\n /** Una copia per tipo di flow: le globali dipendono dal `processType` (§4.1, §6.4). */\r\n private readonly cache = new Map<string, Promise<FlowDictionaries>>();\r\n /** Cresce a ogni `load`: scarta la risposta di un caricamento superato. */\r\n private sequence = 0;\r\n\r\n readonly dictionaries = this._dictionaries.asReadonly();\r\n readonly isLoaded = this._isLoaded.asReadonly();\r\n /** Il `processType` dei dizionari attualmente in uso. */\r\n readonly processType = this._processType.asReadonly();\r\n\r\n /**\r\n * Idempotente: chiamabile da ogni componente che ne ha bisogno.\r\n * Con un `processType` diverso da quello in uso ricarica — dalla cache se c'e' già —\r\n * perche' cambiare tipo di flow cambia quali globali sono proponibili.\r\n */\r\n async load(processType?: string): Promise<void> {\r\n if (this._isLoaded() && processType === this._processType()) {\r\n return;\r\n }\r\n const key = processType ?? '';\r\n const token = ++this.sequence;\r\n let entry = this.cache.get(key);\r\n if (!entry) {\r\n entry = this.api.getDictionaries(processType).then((dictionaries) => dictionaries ?? {});\r\n // Un errore non va memoizzato: al prossimo tentativo si riprova.\r\n entry.catch(() => this.cache.delete(key));\r\n this.cache.set(key, entry);\r\n }\r\n const dictionaries = await entry;\r\n if (token !== this.sequence) {\r\n // Un caricamento piu' recente ha già applicato un altro tipo: questo e' superato.\r\n return;\r\n }\r\n this._dictionaries.set(dictionaries);\r\n this._processType.set(processType);\r\n this._isLoaded.set(true);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Accessori tipizzati\r\n // -------------------------------------------------------------------------\r\n\r\n readonly dataTypes = computed<FlowDataTypeEntry[]>(() => this._dictionaries().dataTypes ?? []);\r\n readonly comparisonOperators = computed<FlowComparisonOperatorEntry[]>(\r\n () => this._dictionaries().comparisonOperators ?? [],\r\n );\r\n readonly assignmentOperators = computed(() => this._dictionaries().assignmentOperators ?? []);\r\n readonly recordFilterOperators = computed(() => this._dictionaries().recordFilterOperators ?? []);\r\n readonly resourceKinds = computed(() => this._dictionaries().resourceKinds ?? []);\r\n readonly globalVariables = computed<FlowGlobalVariableEntry[]>(\r\n () => this._dictionaries().globalVariables ?? [],\r\n );\r\n readonly processTypes = computed(() => this._dictionaries().processTypes ?? []);\r\n readonly triggerTypes = computed(() => this._dictionaries().triggerTypes ?? []);\r\n readonly recordTriggerTypes = computed(() => this._dictionaries().recordTriggerTypes ?? []);\r\n readonly startFrequencies = computed(() => this._dictionaries().startFrequencies ?? []);\r\n readonly offsetUnits = computed(() => this._dictionaries().offsetUnits ?? []);\r\n readonly sortOrders = computed(() => this._dictionaries().sortOrders ?? []);\r\n readonly collectionProcessorTypes = computed(() => this._dictionaries().collectionProcessorTypes ?? []);\r\n readonly transformTypes = computed(() => this._dictionaries().transformTypes ?? []);\r\n readonly transactionModels = computed(() => this._dictionaries().transactionModels ?? []);\r\n readonly waitEventTypes = computed(() => this._dictionaries().waitEventTypes ?? []);\r\n readonly stageStepTypes = computed<FlowStageStepTypeEntry[]>(\r\n () => this._dictionaries().stageStepTypes ?? [],\r\n );\r\n readonly assigneeTypes = computed(() => this._dictionaries().assigneeTypes ?? []);\r\n readonly conditionLogicModes = computed(() => this._dictionaries().conditionLogicModes ?? []);\r\n\r\n readonly elementTypes = computed<FlowElementTypeEntry[]>(() => this._dictionaries().elementTypes ?? []);\r\n\r\n /**\r\n * I tipi mostrabili nella palette: `isSupported: false` va nascosto (§3.2, §13.9).\r\n * Il filtro passa per la colonna del dizionario, non per una lista cablata; l'insieme\r\n * locale {@link UNSUPPORTED_TYPES} interviene solo se il dizionario non dichiara il flag.\r\n */\r\n readonly paletteTypes = computed<FlowElementTypeEntry[]>(() =>\r\n this.elementTypes().filter((entry) => {\r\n if (entry.isSupported === false) {\r\n return false;\r\n }\r\n if (entry.isSupported === undefined && UNSUPPORTED_TYPES.has(entry.value)) {\r\n return false;\r\n }\r\n return true;\r\n }),\r\n );\r\n\r\n /** Le categorie della palette, nell'ordine di prima apparizione nel dizionario. */\r\n readonly paletteCategories = computed<string[]>(() => {\r\n const categories: string[] = [];\r\n for (const entry of this.paletteTypes()) {\r\n const category = entry.category ?? 'Altro';\r\n if (!categories.includes(category)) {\r\n categories.push(category);\r\n }\r\n }\r\n return categories;\r\n });\r\n\r\n elementType(value: string): FlowElementTypeEntry | undefined {\r\n return this.elementTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /** La collection in cui scrivere un node: `metadataProperty`, con fallback locale (§3.2). */\r\n collectionOf(type: string): FlowNodeCollection | undefined {\r\n const fromDictionary = this.elementType(type)?.metadataProperty;\r\n return (fromDictionary as FlowNodeCollection | undefined) ?? FALLBACK_COLLECTION_BY_TYPE[type];\r\n }\r\n\r\n /** Etichetta di un tipo, con fallback: un tipo sconosciuto mostra il proprio `value`. */\r\n labelOf(type: string): string {\r\n return this.elementType(type)?.label ?? FALLBACK_TYPE_LABEL[type] ?? type;\r\n }\r\n\r\n hasFaultConnector(type: string): boolean {\r\n return this.elementType(type)?.hasFaultConnector ?? false;\r\n }\r\n\r\n hasAutomaticOutput(type: string): boolean {\r\n return this.elementType(type)?.hasAutomaticOutput ?? false;\r\n }\r\n\r\n /** Etichetta di una voce di dizionario, con fallback sul valore grezzo. */\r\n static labelIn(entries: FlowDictionaryEntry[], value: string | undefined | null): string {\r\n if (!value) {\r\n return '';\r\n }\r\n return entries.find((entry) => entry.value === value)?.label ?? value;\r\n }\r\n\r\n operator(value: string | undefined | null): FlowComparisonOperatorEntry | undefined {\r\n if (!value) {\r\n return undefined;\r\n }\r\n return this.comparisonOperators().find((entry) => entry.value === value);\r\n }\r\n\r\n /**\r\n * §13.1 — per gli operatori unari `rightValue` e' l'esito atteso, non un termine di\r\n * confronto. Il flag arriva dal dizionario (`isUnary`).\r\n */\r\n isUnaryOperator(value: string | undefined | null): boolean {\r\n return this.operator(value)?.isUnary ?? false;\r\n }\r\n\r\n /** §4.3 — `WasVisited` e `HasError` vogliono a sinistra il nome di un **node**. */\r\n operatorAppliesToElements(value: string | undefined | null): boolean {\r\n return this.operator(value)?.appliesToElements ?? false;\r\n }\r\n\r\n /** §5.2 — operatore che ha senso solo su destinazioni collection. */\r\n assignmentExpectsCollection(value: string | undefined | null): boolean {\r\n return this.assignmentOperators().find((entry) => entry.value === value)?.expectsCollection ?? false;\r\n }\r\n\r\n /**\r\n * Operatori applicabili al tipo del lato sinistro: `appliesTo` vuoto = qualunque tipo (§4.3).\r\n */\r\n operatorsFor(dataType: FlowDataType | undefined): FlowComparisonOperatorEntry[] {\r\n const operators = this.comparisonOperators();\r\n if (!dataType) {\r\n return operators;\r\n }\r\n return operators.filter(\r\n (entry) => !entry.appliesTo || entry.appliesTo.length === 0 || entry.appliesTo.includes(dataType),\r\n );\r\n }\r\n\r\n /** La voce di `globalVariables` di uno scope: `$User`, `$Flow`, … (§4.1). */\r\n globalScope(scope: string | undefined | null): FlowGlobalVariableEntry | undefined {\r\n if (!scope) {\r\n return undefined;\r\n }\r\n return this.globalVariables().find((entry) => entry.scope === scope || entry.value === scope);\r\n }\r\n\r\n /**\r\n * §4.1 — la verificabilita' e' **per scope**: se lo scope dichiara almeno un percorso, uno\r\n * che non c'e' e' `GLOBAL_UNKNOWN`; se non ne dichiara nessuno, resta non verificabile, che\r\n * significa \"non lo so\", non \"non esiste\".\r\n */\r\n isGlobalScopeVerifiable(scope: string | undefined | null): boolean {\r\n return (this.globalScope(scope)?.paths?.length ?? 0) > 0;\r\n }\r\n\r\n /** I percorsi noti di uno scope, già prefissati: `$User.Email`. */\r\n globalPathsOf(scope: string | undefined | null): string[] {\r\n const entry = this.globalScope(scope);\r\n if (!entry) {\r\n return [];\r\n }\r\n const prefix = entry.scope ?? entry.value;\r\n return (entry.paths ?? []).map((path) => `${prefix}.${path}`);\r\n }\r\n\r\n /** §5.13 — la voce di `stageStepTypes` di un `actionType`. */\r\n stageStepType(value: string | undefined | null): FlowStageStepTypeEntry | undefined {\r\n if (!value) {\r\n return undefined;\r\n }\r\n return this.stageStepTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /** `stepBackground` vuole `actionName`; il fallback serve se il dizionario non lo dichiara. */\r\n stageStepRequiresActionName(actionType: string | undefined | null): boolean {\r\n const entry = this.stageStepType(actionType);\r\n return entry?.requiresActionName ?? actionType === 'stepBackground';\r\n }\r\n\r\n /** `stepInteractive` e `stepApproval` vogliono gli assegnatari (§5.13). */\r\n stageStepRequiresAssignees(actionType: string | undefined | null): boolean {\r\n const entry = this.stageStepType(actionType);\r\n if (entry?.requiresAssignees !== undefined) {\r\n return entry.requiresAssignees;\r\n }\r\n return actionType === 'stepInteractive' || actionType === 'stepApproval';\r\n }\r\n\r\n dataType(value: string | undefined | null): FlowDataTypeEntry | undefined {\r\n return this.dataTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /** §4.6 — `Object` ed `Enum` richiedono `objectType`. */\r\n requiresObjectType(dataType: string | undefined | null): boolean {\r\n const entry = this.dataType(dataType);\r\n if (entry?.requiresObjectType !== undefined) {\r\n return entry.requiresObjectType;\r\n }\r\n return dataType === 'Object' || dataType === 'Enum';\r\n }\r\n\r\n /** §4.6 — `scale` si applica solo ai numerici. */\r\n supportsScale(dataType: string | undefined | null): boolean {\r\n const entry = this.dataType(dataType);\r\n if (entry?.supportsScale !== undefined) {\r\n return entry.supportsScale;\r\n }\r\n return dataType === 'Number' || dataType === 'Integer';\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cataloghi\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Memoizza per chiave le richieste di catalogo, condividendo la promise in volo. */\r\nclass AsyncCache<T> {\r\n private readonly entries = new Map<string, Promise<T>>();\r\n\r\n get(key: string, load: () => Promise<T>): Promise<T> {\r\n let entry = this.entries.get(key);\r\n if (!entry) {\r\n entry = load().catch((error) => {\r\n // Un errore non va memoizzato: al prossimo tentativo si riprova.\r\n this.entries.delete(key);\r\n throw error;\r\n });\r\n this.entries.set(key, entry);\r\n }\r\n return entry;\r\n }\r\n\r\n clear(): void {\r\n this.entries.clear();\r\n }\r\n}\r\n\r\n@Injectable()\r\nexport class FlowCatalogStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n private readonly objectsCache = new AsyncCache<FlowObjectSummary[]>();\r\n private readonly fieldsCache = new AsyncCache<FlowFieldDescription[]>();\r\n private readonly fieldValuesCache = new AsyncCache<Array<{ value: string; label?: string | null }>>();\r\n private readonly entriesCache = new AsyncCache<FlowCatalogEntry[]>();\r\n private readonly parametersCache = new AsyncCache<FlowCatalogParameter[]>();\r\n\r\n /**\r\n * Una lista vuota significa \"non lo so\", non \"nessuno\": con il catalogo non popolato la\r\n * validazione salta i controlli invece di produrre falsi allarmi (§7). L'editor fa lo\r\n * stesso: se la lista e' vuota, lascia il campo libero invece di bloccarlo.\r\n */\r\n listObjects(): Promise<FlowObjectSummary[]> {\r\n return this.objectsCache.get('objects', () => this.api.listObjects().then((list) => list ?? []));\r\n }\r\n\r\n listFields(object: string, usage: FlowFieldUsage = 'any'): Promise<FlowFieldDescription[]> {\r\n if (!object) {\r\n return Promise.resolve([]);\r\n }\r\n return this.fieldsCache.get(`${object}|${usage}`, () =>\r\n this.api.listFields(object, usage).then((list) => list ?? []),\r\n );\r\n }\r\n\r\n listFieldValues(object: string, field: string): Promise<Array<{ value: string; label?: string | null }>> {\r\n if (!object || !field) {\r\n return Promise.resolve([]);\r\n }\r\n return this.fieldValuesCache.get(`${object}|${field}`, () =>\r\n this.api.listFieldValues(object, field).catch(() => []),\r\n );\r\n }\r\n\r\n listActionTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('action-types', () => this.api.listActionTypes().then((list) => list ?? []));\r\n }\r\n\r\n listActions(actionType?: string): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get(`actions|${actionType ?? ''}`, () =>\r\n this.api.listActions(actionType).then((list) => list ?? []),\r\n );\r\n }\r\n\r\n listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]> {\r\n if (!actionType || !actionName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`action|${actionType}|${actionName}`, () =>\r\n this.api.listActionParameters(actionType, actionName).catch(() => []),\r\n );\r\n }\r\n\r\n listScripts(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('scripts', () => this.api.listScripts().then((list) => list ?? []));\r\n }\r\n\r\n listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]> {\r\n if (!scriptName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`script|${scriptName}`, () =>\r\n this.api.listScriptParameters(scriptName).catch(() => []),\r\n );\r\n }\r\n\r\n listForms(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('forms', () => this.api.listForms().then((list) => list ?? []));\r\n }\r\n\r\n listFormParameters(formName: string): Promise<FlowCatalogParameter[]> {\r\n if (!formName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`form|${formName}`, () =>\r\n this.api.listFormParameters(formName).catch(() => []),\r\n );\r\n }\r\n\r\n listEnumTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('enum-types', () => this.api.listEnumTypes().then((list) => list ?? []));\r\n }\r\n\r\n listEvents(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('events', () => this.api.listEvents().then((list) => list ?? []));\r\n }\r\n\r\n /** Da chiamare se lo schema cambia sotto i piedi (raro, ma il comando esiste). */\r\n clear(): void {\r\n this.objectsCache.clear();\r\n this.fieldsCache.clear();\r\n this.fieldValuesCache.clear();\r\n this.entriesCache.clear();\r\n this.parametersCache.clear();\r\n }\r\n}\r\n","/**\r\n * Il pannello dei problemi — FRONTEND.md §7, §11.\r\n *\r\n * La validazione e' un servizio separato dal salvataggio, e questo e' deliberato: si\r\n * salva quando si vuole, i problemi si guardano a parte. Qui vive il debounce (300–500 ms\r\n * su pausa di digitazione, §11.4) e l'indicizzazione dei rilievi per `elementName` e\r\n * `path`, che e' cio' che permette di evidenziare l'elemento sul canvas e il campo\r\n * dentro l'inspector.\r\n *\r\n * `code` e' stabile e si usa per decidere il comportamento; `message` e' testo per\r\n * l'utente e non va interpretato (§7).\r\n */\r\n\r\nimport { DestroyRef, Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowValidationIssue, FlowValidationResult } from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\n\r\nconst DEBOUNCE_MS = 400;\r\n\r\n@Injectable()\r\nexport class FlowValidationStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n private readonly _result = signal<FlowValidationResult | null>(null);\r\n private readonly _isRunning = signal(false);\r\n private readonly _lastError = signal<string | null>(null);\r\n\r\n private timer?: ReturnType<typeof setTimeout>;\r\n /** Cresce a ogni richiesta: scarta le risposte di validazioni superate. */\r\n private sequence = 0;\r\n\r\n readonly result = this._result.asReadonly();\r\n readonly isRunning = this._isRunning.asReadonly();\r\n readonly lastError = this._lastError.asReadonly();\r\n\r\n readonly issues = computed<FlowValidationIssue[]>(() => this._result()?.issues ?? []);\r\n readonly errorCount = computed(() => this._result()?.errorCount ?? 0);\r\n readonly warningCount = computed(() => this._result()?.warningCount ?? 0);\r\n readonly infoCount = computed(\r\n () => this.issues().filter((issue) => issue.severity === 'Info').length,\r\n );\r\n\r\n /**\r\n * `false` finche' non e' arrivata una validazione: non presentare l'assenza di rilievi\r\n * come garanzia di correttezza (§7, ultimo capoverso).\r\n */\r\n readonly hasResult = computed(() => this._result() !== null);\r\n\r\n /** Zero errori: e' la condizione che l'attivazione esige (§8.3). */\r\n readonly canActivate = computed(() => this.hasResult() && this.errorCount() === 0);\r\n\r\n /** Rilievi raggruppati per elemento, per l'evidenziazione sul canvas. */\r\n readonly issuesByElement = computed<Map<string, FlowValidationIssue[]>>(() => {\r\n const map = new Map<string, FlowValidationIssue[]>();\r\n for (const issue of this.issues()) {\r\n const key = issue.elementName ?? '';\r\n const list = map.get(key) ?? [];\r\n list.push(issue);\r\n map.set(key, list);\r\n }\r\n return map;\r\n });\r\n\r\n /** I rilievi non ancorati a un elemento: riguardano il documento (§7, famiglia Definizione). */\r\n readonly documentIssues = computed(() => this.issuesByElement().get('') ?? []);\r\n\r\n constructor() {\r\n this.destroyRef.onDestroy(() => this.cancel());\r\n }\r\n\r\n /** La gravita' peggiore su un elemento, per decidere il colore del node sul canvas. */\r\n severityOf(elementName: string): 'Error' | 'Warning' | 'Info' | null {\r\n const issues = this.issuesByElement().get(elementName);\r\n if (!issues?.length) {\r\n return null;\r\n }\r\n if (issues.some((issue) => issue.severity === 'Error')) {\r\n return 'Error';\r\n }\r\n if (issues.some((issue) => issue.severity === 'Warning')) {\r\n return 'Warning';\r\n }\r\n return 'Info';\r\n }\r\n\r\n /**\r\n * I rilievi che riguardano un campo dentro un elemento.\r\n * `path` e' del tipo `rules[Approvato].connector.targetReference`: il confronto e' per\r\n * prefisso, così `rules[Approvato]` cattura anche i rilievi piu' profondi.\r\n */\r\n issuesAt(elementName: string | null, pathPrefix: string): FlowValidationIssue[] {\r\n const issues = this.issuesByElement().get(elementName ?? '') ?? [];\r\n return issues.filter((issue) => issue.path?.startsWith(pathPrefix));\r\n }\r\n\r\n /** Programma una validazione dopo la pausa di digitazione (§11.4). */\r\n schedule(definition: FlowDefinition): void {\r\n this.cancel();\r\n this.timer = setTimeout(() => {\r\n this.timer = undefined;\r\n void this.run(definition);\r\n }, DEBOUNCE_MS);\r\n }\r\n\r\n /** Valida subito, saltando il debounce: prima di attivare, o su richiesta esplicita. */\r\n async run(definition: FlowDefinition): Promise<FlowValidationResult | null> {\r\n const token = ++this.sequence;\r\n this._isRunning.set(true);\r\n this._lastError.set(null);\r\n try {\r\n const result = await this.api.validateDefinition(definition);\r\n if (token !== this.sequence) {\r\n // Una validazione piu' recente e' già partita: questa risposta e' superata.\r\n return null;\r\n }\r\n this._result.set(result);\r\n return result;\r\n } catch (error) {\r\n if (token !== this.sequence) {\r\n return null;\r\n }\r\n const message = FlowApiError.is(error) ? error.message : String(error);\r\n this._lastError.set(message);\r\n return null;\r\n } finally {\r\n if (token === this.sequence) {\r\n this._isRunning.set(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sostituisce il risultato con quello arrivato da un'altra primitiva: il salvataggio\r\n * restituisce `validation` (§6.2) e l'attivazione fallita lo porta nel payload\r\n * dell'errore (§8.3). In entrambi i casi e' il risultato piu' fresco che esista.\r\n */\r\n adopt(result: FlowValidationResult | undefined | null): void {\r\n if (!result) {\r\n return;\r\n }\r\n this.sequence += 1;\r\n this._result.set(result);\r\n this._isRunning.set(false);\r\n }\r\n\r\n clear(): void {\r\n this.cancel();\r\n this.sequence += 1;\r\n this._result.set(null);\r\n this._lastError.set(null);\r\n this._isRunning.set(false);\r\n }\r\n\r\n private cancel(): void {\r\n if (this.timer) {\r\n clearTimeout(this.timer);\r\n this.timer = undefined;\r\n }\r\n }\r\n}\r\n","/**\r\n * Auto-layout con dagre.\r\n *\r\n * Il modello conserva soltanto `locationX`/`locationY` (§3.5): non c'e' nessuna nozione di\r\n * layout automatico da persistere. Il comando \"riordina\" calcola un layout gerarchico e\r\n * **scrive le coordinate risultanti** nel documento, come chiede la specifica (\"se usi un\r\n * auto-layout, scrivi comunque valori coerenti\").\r\n *\r\n * L'ordine delle uscite conta: i rami di una Decision escono nell'ordine delle regole, e\r\n * il ramo di fault viene tenuto a destra, così la lettura del grafo rispecchia la\r\n * semantica invece dell'ordine di inserimento nel JSON.\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport dagre from 'dagre';\r\n\r\nimport { FlowEdge } from './flow-document.store';\r\nimport { START_NODE_NAME } from './element-outlets';\r\n\r\nexport interface FlowLayoutNodeInput {\r\n name: string;\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface FlowLayoutResult {\r\n positions: Map<string, { x: number; y: number }>;\r\n}\r\n\r\nexport type FlowLayoutDirection = 'TB' | 'LR';\r\n\r\nexport interface FlowLayoutOptions {\r\n direction?: FlowLayoutDirection;\r\n /** Distanza fra i livelli. */\r\n rankSeparation?: number;\r\n /** Distanza fra i node dello stesso livello. */\r\n nodeSeparation?: number;\r\n origin?: { x: number; y: number };\r\n}\r\n\r\n@Injectable()\r\nexport class FlowLayoutService {\r\n /**\r\n * Calcola le posizioni. Restituisce l'angolo in alto a sinistra di ogni node, perche'\r\n * e' cio' che `locationX`/`locationY` significano nel modello, mentre dagre ragiona in\r\n * centri.\r\n */\r\n layout(\r\n nodes: FlowLayoutNodeInput[],\r\n edges: FlowEdge[],\r\n options?: FlowLayoutOptions,\r\n ): FlowLayoutResult {\r\n const direction = options?.direction ?? 'TB';\r\n const origin = options?.origin ?? { x: 60, y: 60 };\r\n\r\n const graph = new dagre.graphlib.Graph({ multigraph: true, compound: false });\r\n graph.setGraph({\r\n rankdir: direction,\r\n ranksep: options?.rankSeparation ?? 90,\r\n nodesep: options?.nodeSeparation ?? 60,\r\n marginx: 0,\r\n marginy: 0,\r\n });\r\n graph.setDefaultEdgeLabel(() => ({}));\r\n\r\n const known = new Set<string>();\r\n for (const node of nodes) {\r\n graph.setNode(node.name, { width: node.width, height: node.height });\r\n known.add(node.name);\r\n }\r\n\r\n for (const edge of edges) {\r\n // Un ramo senza destinazione non vincola il layout.\r\n if (!edge.to || !known.has(edge.from) || !known.has(edge.to)) {\r\n continue;\r\n }\r\n // `isGoTo` marca gli archi di ritorno: includerli creerebbe un ciclo che dagre\r\n // spezzerebbe arbitrariamente, allungando il grafo. Il corpo di un Loop si richiude\r\n // sul Loop, quindi questo caso e' la norma, non l'eccezione (§5.4).\r\n if (edge.isGoTo) {\r\n continue;\r\n }\r\n graph.setEdge(edge.from, edge.to, { weight: FlowLayoutService.weightOf(edge) }, edge.id);\r\n }\r\n\r\n dagre.layout(graph);\r\n\r\n const positions = new Map<string, { x: number; y: number }>();\r\n let minX = Number.POSITIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n\r\n for (const node of nodes) {\r\n const laid = graph.node(node.name) as { x?: number; y?: number } | undefined;\r\n if (!laid || laid.x === undefined || laid.y === undefined) {\r\n continue;\r\n }\r\n const x = laid.x - node.width / 2;\r\n const y = laid.y - node.height / 2;\r\n positions.set(node.name, { x, y });\r\n minX = Math.min(minX, x);\r\n minY = Math.min(minY, y);\r\n }\r\n\r\n // Trasla in modo che il grafo cominci dall'origine scelta, con coordinate positive.\r\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\r\n const deltaX = origin.x - minX;\r\n const deltaY = origin.y - minY;\r\n for (const [name, position] of positions) {\r\n positions.set(name, {\r\n x: Math.round(position.x + deltaX),\r\n y: Math.round(position.y + deltaY),\r\n });\r\n }\r\n }\r\n\r\n return { positions };\r\n }\r\n\r\n /**\r\n * Peso dell'arco: piu' alto = piu' dritto. Il percorso principale resta in colonna,\r\n * i rami di errore e di timeout si spostano di lato.\r\n */\r\n private static weightOf(edge: FlowEdge): number {\r\n switch (edge.kind) {\r\n case 'Start':\r\n case 'Next':\r\n case 'LoopNext':\r\n return 10;\r\n case 'Rule':\r\n case 'WaitEvent':\r\n case 'LoopEnd':\r\n case 'Default':\r\n return 4;\r\n case 'Fault':\r\n case 'Timeout':\r\n case 'ScheduledPath':\r\n return 1;\r\n default:\r\n return 3;\r\n }\r\n }\r\n\r\n /** Lo Start apre sempre il grafo: utile per ordinare i node prima del layout. */\r\n static isStart(name: string): boolean {\r\n return name === START_NODE_NAME;\r\n }\r\n}\r\n","/**\r\n * La sessione di editing: quale flow, quale versione, cosa e' permesso farci.\r\n * FRONTEND.md §6.2, §8, §9, §11.\r\n *\r\n * Tre responsabilita' che stanno bene insieme perche' condividono lo stesso stato:\r\n * - il ciclo di vita: si modifica una bozza; su una versione non modificabile il comando\r\n * e' \"Nuova versione\", non \"Salva\" (§8.1);\r\n * - la concorrenza ottimistica: `updatedAt` conservato al caricamento e rimandato come\r\n * `expectedUpdatedAt` al salvataggio (§9);\r\n * - la distinzione fra \"salvato\" e \"sano\": il salvataggio riesce anche con errori, e\r\n * l'esito si legge in `validation` (§6.2).\r\n */\r\n\r\nimport { Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowSaveResult, FlowValidationResult, FlowVersionSummary } from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\nimport { FlowDocumentStore, emptyFlowDefinition } from './flow-document.store';\r\nimport { FlowValidationStore } from './flow-validation.store';\r\n\r\n/** Cosa mostrare quando il salvataggio incontra una versione modificata da altri (§9). */\r\nexport interface FlowConflictState {\r\n message: string;\r\n conflictingAuthor?: string;\r\n}\r\n\r\n@Injectable()\r\nexport class FlowEditorSession {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly documentStore = inject(FlowDocumentStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n private readonly _flowName = signal<string | null>(null);\r\n private readonly _version = signal<number | null>(null);\r\n private readonly _versions = signal<FlowVersionSummary[]>([]);\r\n /** Conservato al caricamento, rimandato al salvataggio (§9.1, §9.2). */\r\n private readonly _expectedUpdatedAt = signal<string | undefined>(undefined);\r\n private readonly _isBusy = signal(false);\r\n private readonly _lastSaveResult = signal<FlowSaveResult | null>(null);\r\n private readonly _conflict = signal<FlowConflictState | null>(null);\r\n private readonly _author = signal<string | undefined>(undefined);\r\n\r\n readonly flowName = this._flowName.asReadonly();\r\n readonly version = this._version.asReadonly();\r\n readonly versions = this._versions.asReadonly();\r\n readonly isBusy = this._isBusy.asReadonly();\r\n readonly lastSaveResult = this._lastSaveResult.asReadonly();\r\n readonly conflict = this._conflict.asReadonly();\r\n readonly expectedUpdatedAt = this._expectedUpdatedAt.asReadonly();\r\n\r\n /** `true` finche' il flow non e' mai stato salvato: il comando e' \"Crea\", non \"Salva\". */\r\n readonly isNew = computed(() => this._version() === null);\r\n\r\n readonly currentVersionSummary = computed<FlowVersionSummary | undefined>(() => {\r\n const version = this._version();\r\n return version === null ? undefined : this._versions().find((entry) => entry.version === version);\r\n });\r\n\r\n /**\r\n * `isEditable` arriva dal backend e non va ricalcolato lato client (§6.1). Un flow nuovo,\r\n * non ancora salvato, e' modificabile per definizione.\r\n */\r\n readonly isEditable = computed(() => {\r\n if (this.isNew()) {\r\n return true;\r\n }\r\n return this.currentVersionSummary()?.isEditable ?? false;\r\n });\r\n\r\n /** Su una versione non modificabile il comando primario diventa \"Nuova versione\" (§8.1). */\r\n readonly primaryCommand = computed<'create' | 'save' | 'newVersion'>(() => {\r\n if (this.isNew()) {\r\n return 'create';\r\n }\r\n return this.isEditable() ? 'save' : 'newVersion';\r\n });\r\n\r\n readonly isActiveVersion = computed(() => this.currentVersionSummary()?.isActive ?? false);\r\n\r\n /** Attivare esige zero errori (§8.3): il comando resta disabilitato finche' ce ne sono. */\r\n readonly canActivate = computed(\r\n () => !this.isNew() && !this.isActiveVersion() && this.validation.canActivate(),\r\n );\r\n\r\n setAuthor(author: string | undefined): void {\r\n this._author.set(author);\r\n }\r\n\r\n /** Prepara un flow nuovo, non ancora salvato (§11, \"Creare un flow\"). */\r\n startNew(fullName: string, label: string, processType: string): void {\r\n this.documentStore.load(emptyFlowDefinition(fullName, label, processType));\r\n this._flowName.set(fullName || null);\r\n this._version.set(null);\r\n this._versions.set([]);\r\n this._expectedUpdatedAt.set(undefined);\r\n this._lastSaveResult.set(null);\r\n this._conflict.set(null);\r\n this.validation.clear();\r\n }\r\n\r\n /**\r\n * Carica una versione e conserva il suo `updatedAt` (§11, \"Modificare\", passo 1).\r\n * `version` assente → la versione attiva se c'e', altrimenti l'ultima.\r\n */\r\n async open(flowName: string, version?: number): Promise<void> {\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const [definition, versions] = await Promise.all([\r\n this.api.loadFlow(flowName, version),\r\n this.api.listVersions(flowName).catch(() => [] as FlowVersionSummary[]),\r\n ]);\r\n this.documentStore.load(definition);\r\n this._flowName.set(flowName);\r\n this._versions.set(versions);\r\n\r\n // La versione effettivamente caricata: il documento porta `status` ma non il numero,\r\n // quindi si deduce dal parametro o dall'elenco versioni.\r\n const resolved = version ?? FlowEditorSession.pickVersion(versions);\r\n this._version.set(resolved ?? null);\r\n this._expectedUpdatedAt.set(versions.find((entry) => entry.version === resolved)?.updatedAt);\r\n this._lastSaveResult.set(null);\r\n this.validation.clear();\r\n await this.validation.run(this.documentStore.document());\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /** Senza `version` il backend restituisce la versione attiva, altrimenti l'ultima (§6.1). */\r\n private static pickVersion(versions: FlowVersionSummary[]): number | undefined {\r\n const active = versions.find((entry) => entry.isActive);\r\n if (active) {\r\n return active.version;\r\n }\r\n return versions[0]?.version;\r\n }\r\n\r\n /** Ricarica l'elenco versioni: dopo un'attivazione la precedente e' `Obsolete` (§8.4). */\r\n async refreshVersions(): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n const versions = await this.api.listVersions(flowName);\r\n this._versions.set(versions);\r\n const current = this._version();\r\n if (current !== null) {\r\n this._expectedUpdatedAt.set(versions.find((entry) => entry.version === current)?.updatedAt);\r\n }\r\n }\r\n\r\n /**\r\n * Crea o salva, a seconda dello stato. Non lancia su definizione invalida: il\r\n * salvataggio riesce anche con errori e il chiamante legge `validation` (§8.2).\r\n *\r\n * Rilancia `VersionConflict` dopo aver popolato {@link conflict}, perche' la UI deve\r\n * offrire \"ricarica\" o \"salva come nuova versione\" (§9.3).\r\n */\r\n async save(options?: { activate?: boolean; flowName?: string }): Promise<FlowSaveResult> {\r\n const definition = this.documentStore.document();\r\n const targetName = options?.flowName ?? this._flowName() ?? definition.fullName ?? '';\r\n if (!targetName) {\r\n throw new FlowApiError('InvalidRequest', 'Il flow non ha un nome tecnico.');\r\n }\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const result = this.isNew()\r\n ? await this.api.createFlow({\r\n definition,\r\n flowName: targetName,\r\n author: this._author(),\r\n })\r\n : await this.api.saveFlow(this._flowName() as string, {\r\n definition,\r\n // Se indicato vince sul `fullName` del documento: e' così che si rinomina (§6.2).\r\n flowName: options?.flowName,\r\n // Mandare sempre la versione caricata rende prevedibile cosa viene toccato (§8).\r\n version: this._version() ?? undefined,\r\n expectedUpdatedAt: this._expectedUpdatedAt(),\r\n author: this._author(),\r\n activate: options?.activate,\r\n });\r\n this.applySaveResult(result);\r\n return result;\r\n } catch (error) {\r\n if (FlowApiError.is(error) && error.category === 'VersionConflict') {\r\n this._conflict.set({\r\n message: error.message,\r\n conflictingAuthor: error.conflictingAuthor,\r\n });\r\n }\r\n if (FlowApiError.is(error) && error.validation) {\r\n // `activate: true` fallisce senza scrivere nulla se ci sono errori (§6.2).\r\n this.validation.adopt(error.validation);\r\n }\r\n throw error;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n private applySaveResult(result: FlowSaveResult): void {\r\n this._flowName.set(result.flowName);\r\n this._version.set(result.version);\r\n // Da conservare per il salvataggio successivo (§6.2, ultimo capoverso).\r\n this._expectedUpdatedAt.set(result.updatedAt);\r\n this._lastSaveResult.set(result);\r\n // Riflette nel documento cio' che il backend ha deciso, senza sporcare lo storico:\r\n // `fullName` e `status` sono riempiti dal record di versione, non dall'editor (§2).\r\n this.documentStore.updateHeader((definition) => {\r\n definition.fullName = result.flowName;\r\n definition.status = result.status;\r\n }, { silent: true });\r\n this.documentStore.markSaved();\r\n this.validation.adopt(result.validation);\r\n void this.refreshVersions();\r\n }\r\n\r\n /** Copia la versione corrente in una nuova bozza (§8.1): il comando delle versioni chiuse. */\r\n async createNewVersion(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n throw new FlowApiError('InvalidRequest', 'Nessun flow aperto.');\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n const result = await this.api.createVersion(flowName, {\r\n from: this._version() ?? undefined,\r\n author: this._author(),\r\n });\r\n await this.open(flowName, result.version);\r\n return result;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Attiva la versione corrente (§11, \"Attivare\").\r\n * Valida prima in locale per un feedback immediato: se ci sono errori non chiama\r\n * l'attivazione, perche' fallirebbe comunque.\r\n */\r\n async activate(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n const version = this._version();\r\n if (!flowName || version === null) {\r\n throw new FlowApiError('InvalidRequest', 'Salva il flow prima di attivarlo.');\r\n }\r\n const local = await this.validation.run(this.documentStore.document());\r\n if (local && local.errorCount > 0) {\r\n throw new FlowApiError(\r\n 'ValidationFailed',\r\n 'La definizione contiene errori: correggili prima di attivare.',\r\n local,\r\n );\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n const result = await this.api.activateVersion(flowName, version);\r\n this.applySaveResult(result);\r\n return result;\r\n } catch (error) {\r\n // Qualcosa e' cambiato nel frattempo (per esempio un oggetto rinominato nello\r\n // schema): il payload porta l'elenco, che va aperto nel pannello (§11, passo 3).\r\n if (FlowApiError.is(error) && error.validation) {\r\n this.validation.adopt(error.validation);\r\n }\r\n throw error;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n async deactivate(): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n await this.api.deactivateFlow(flowName);\r\n await this.refreshVersions();\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Elimina una versione. Da mettere dietro una conferma esplicita: il numero della versione\r\n * piu' alta viene riassegnato dopo un'eliminazione, e un'esecuzione sospesa nata su quel\r\n * numero riprenderebbe su una definizione diversa (§8, ultimo capoverso).\r\n */\r\n async deleteVersion(version: number): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n await this.api.deleteVersion(flowName, version);\r\n await this.refreshVersions();\r\n // Se e' stata eliminata la versione aperta, si riapre quella piu' recente.\r\n if (this._version() === version) {\r\n const next = this._versions()[0]?.version;\r\n if (next !== undefined) {\r\n await this.open(flowName, next);\r\n } else {\r\n this._version.set(null);\r\n }\r\n }\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /** Risoluzione del conflitto, prima opzione: ricarica e perde le modifiche locali (§9.3). */\r\n async reloadAfterConflict(): Promise<void> {\r\n const flowName = this._flowName();\r\n const version = this._version();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._conflict.set(null);\r\n await this.open(flowName, version ?? undefined);\r\n }\r\n\r\n /**\r\n * Risoluzione del conflitto, seconda opzione: salva come nuova versione, conservando\r\n * le modifiche locali (§9.3). Il salvataggio senza `expectedUpdatedAt` e senza `version`\r\n * lascia scegliere al backend, che crea una nuova versione se l'ultima non e' toccabile.\r\n */\r\n async saveAsNewVersionAfterConflict(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n throw new FlowApiError('InvalidRequest', 'Nessun flow aperto.');\r\n }\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const created = await this.api.createVersion(flowName, { author: this._author() });\r\n const result = await this.api.saveFlow(flowName, {\r\n definition: this.documentStore.document(),\r\n version: created.version,\r\n expectedUpdatedAt: created.updatedAt,\r\n author: this._author(),\r\n });\r\n this.applySaveResult(result);\r\n return result;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n dismissConflict(): void {\r\n this._conflict.set(null);\r\n }\r\n\r\n /** L'ultima validazione conosciuta, da qualunque primitiva arrivi. */\r\n get validationResult(): FlowValidationResult | null {\r\n return this.validation.result();\r\n }\r\n\r\n /** Il documento corrente, per chi deve mandarlo a una primitiva. */\r\n get definition(): FlowDefinition {\r\n return this.documentStore.document();\r\n }\r\n}\r\n","/**\r\n * Il view model del canvas.\r\n *\r\n * Gli id dei connettori sono stringhe costruite qui e in nessun altro posto: un mismatch\r\n * fra l'id dichiarato su un connettore e quello usato da una connessione fa sparire l'arco\r\n * **senza errori** — e' il fallimento silenzioso numero uno di @foblex/flow.\r\n */\r\n\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { FlowIssueSeverity } from '../../model/api.model';\r\nimport { FlowOutlet } from '../../core/element-outlets';\r\n\r\n/** Il connettore di ingresso di un node. Lo Start non ne ha. */\r\nexport function targetConnectorId(nodeName: string): string {\r\n return `in:${nodeName}`;\r\n}\r\n\r\n/** Il connettore di uscita di un node, uno per ramo (§3.5). */\r\nexport function sourceConnectorId(nodeName: string, outletKey: string): string {\r\n return `out:${nodeName}:${outletKey}`;\r\n}\r\n\r\n/** Inverso di {@link sourceConnectorId}. */\r\nexport function parseSourceConnectorId(id: string): { nodeName: string; outletKey: string } | null {\r\n if (!id.startsWith('out:')) {\r\n return null;\r\n }\r\n const rest = id.slice(4);\r\n const separator = rest.indexOf(':');\r\n if (separator < 0) {\r\n return null;\r\n }\r\n return { nodeName: rest.slice(0, separator), outletKey: rest.slice(separator + 1) };\r\n}\r\n\r\n/** Inverso di {@link targetConnectorId}. */\r\nexport function parseTargetConnectorId(id: string): string | null {\r\n return id.startsWith('in:') ? id.slice(3) : null;\r\n}\r\n\r\n/** L'id del node sul canvas: prefissato per non collidere con quello dei connettori. */\r\nexport function canvasNodeId(nodeName: string): string {\r\n return `node:${nodeName}`;\r\n}\r\n\r\nexport function parseCanvasNodeId(id: string): string | null {\r\n return id.startsWith('node:') ? id.slice(5) : null;\r\n}\r\n\r\nexport interface FlowCanvasNode {\r\n /** Nome nel documento; `$start` per lo Start, che nel modello non ha nome. */\r\n name: string;\r\n /** Id per il canvas. */\r\n id: string;\r\n /** `'Start'` oppure il discriminatore di `elementTypes`. */\r\n type: FlowElementType | 'Start';\r\n typeLabel: string;\r\n label: string;\r\n description?: string | null;\r\n position: { x: number; y: number };\r\n outlets: FlowOutlet[];\r\n isStart: boolean;\r\n /** Categoria del dizionario: decide il colore dell'icona del node. */\r\n category?: string | null;\r\n /** Glifo mostrato nel badge dell'icona: dipende dal tipo, non dalla categoria. */\r\n icon: string;\r\n /**\r\n * La classe che porta la larghezza del node. Non e' costante: le uscite stanno in fila sul\r\n * bordo inferiore, quindi un elemento con molti rami ha bisogno di piu' spazio perche' le\r\n * etichette restino leggibili. E' una classe e non uno stile inline perche' @foblex/flow\r\n * riscrive l'attributo `style` del node per posizionarlo.\r\n */\r\n widthClass: string;\r\n /**\r\n * Le etichette dei rami si mostrano solo quando i rami sono piu' di uno: su un `next`\r\n * unico l'etichetta direbbe soltanto «Successivo».\r\n */\r\n showsOutletLabels: boolean;\r\n /** `false` → nessun percorso lo raggiunge dallo Start: va reso \"scollegato\" (§6.4). */\r\n isReachable: boolean;\r\n /** La gravita' peggiore dei rilievi sull'elemento (§7). */\r\n severity: FlowIssueSeverity | null;\r\n /** Numero di rilievi, per il badge. */\r\n issueCount: number;\r\n /** L'elemento espone il proprio risultato sotto il proprio nome (§4.5). */\r\n hasAutomaticOutput: boolean;\r\n /** Sintesi di una riga mostrata sul node (l'oggetto letto, il form mostrato, …). */\r\n subtitle?: string | null;\r\n /** Rami dichiarati ma senza destinazione: mostrati come tali, non come archi (§6.4). */\r\n danglingOutlets: FlowOutlet[];\r\n}\r\n\r\nexport interface FlowCanvasEdge {\r\n id: string;\r\n sourceId: string;\r\n targetId: string;\r\n kind: string;\r\n label?: string | null;\r\n isGoTo: boolean;\r\n}\r\n","/**\r\n * Il canvas del grafo.\r\n *\r\n * Il documento e' la fonte di verita': node, archi e raggiungibilita' sono signal derivati\r\n * da {@link FlowDocumentStore}, e ogni gesto dell'utente diventa una mutazione del\r\n * documento. @foblex/flow e' usato in \"classic mode\": la libreria disegna e riconosce i\r\n * gesti, lo stato resta nostro.\r\n *\r\n * Scelta di progetto sulla raggiungibilita': gli archi e la reachability sono calcolati\r\n * **in locale** per il disegno, così trascinare un arco si riflette subito; `isReachable`\r\n * di `POST /flows/outline` (§6.4) resta la fonte autoritativa e, quando arriva, sovrascrive\r\n * il calcolo locale. Chiedere l'outline a ogni movimento del mouse renderebbe il canvas\r\n * dipendente dalla latenza.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\r\nimport { EFConnectableSide, EFMarkerType, FFlowModule } from '@foblex/flow';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { START_NODE_NAME, outletsOf } from '../../core/element-outlets';\r\nimport { elementIcon } from '../../core/element-icons';\r\nimport { FlowAnyNode, FlowElementType } from '../../model/flow.model';\r\nimport { FlowOutline } from '../../model/api.model';\r\nimport {\r\n FlowCanvasEdge,\r\n FlowCanvasNode,\r\n canvasNodeId,\r\n parseCanvasNodeId,\r\n parseSourceConnectorId,\r\n parseTargetConnectorId,\r\n sourceConnectorId,\r\n targetConnectorId,\r\n} from './flow-canvas.model';\r\n\r\n/**\r\n * Dimensioni nominali di un node, usate dal layout automatico.\r\n *\r\n * Le uscite stanno in fila sul bordo **inferiore**: e' la larghezza a dipendere dal numero\r\n * di rami, non l'altezza. L'altezza resta quella della card (intestazione, riga del nome\r\n * tecnico e badge, striscia delle uscite) e non cambia con i rami.\r\n */\r\nexport const FLOW_NODE_WIDTH = 240;\r\nexport const FLOW_NODE_HEIGHT = 116;\r\n\r\n/**\r\n * La larghezza del node per numero di rami: le uscite stanno in fila sul bordo inferiore,\r\n * quindi una Decision con quattro regole ha bisogno di piu' spazio di un Assignment.\r\n *\r\n * E' una tabella a scaglioni, non una formula, perche' la larghezza si applica con una\r\n * **classe** e non con uno stile inline: @foblex/flow riscrive l'attributo `style` del node\r\n * per posizionarlo, e qualunque `[style.width]` di Angular verrebbe cancellato al primo\r\n * spostamento. I valori qui e quelli delle classi `.fb-node--outlets-N` nel CSS devono\r\n * restare uguali: la stessa misura serve a disegnare il node e a stimarlo per dagre.\r\n */\r\nconst OUTLET_WIDTHS = [240, 240, 240, 304, 380, 456, 520];\r\n\r\n/** Oltre questo numero di rami il node non cresce piu': le etichette si troncano. */\r\nconst MAX_OUTLET_BUCKET = OUTLET_WIDTHS.length - 1;\r\n\r\nfunction outletBucket(outletCount: number): number {\r\n return Math.min(Math.max(outletCount, 0), MAX_OUTLET_BUCKET);\r\n}\r\n\r\nexport function flowNodeWidth(outletCount: number): number {\r\n return OUTLET_WIDTHS[outletBucket(outletCount)];\r\n}\r\n\r\n/** La classe che porta quella larghezza: unico modo di sopravvivere ai riposizionamenti. */\r\nexport function flowNodeWidthClass(outletCount: number): string {\r\n return `fb-node--outlets-${outletBucket(outletCount)}`;\r\n}\r\n\r\n\r\n@Component({\r\n selector: 'fb-flow-canvas',\r\n standalone: true,\r\n imports: [FFlowModule],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './flow-canvas.component.html',\r\n styleUrl: './flow-canvas.component.css',\r\n})\r\nexport class FlowCanvasComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /**\r\n * Marker di fine arco: la variante \"all states\" crea sia quello normale sia quello\r\n * selezionato, evitando che l'arco selezionato perda la punta.\r\n */\r\n readonly markerEnd = EFMarkerType.END_ALL_STATES;\r\n\r\n /**\r\n * I lati da cui gli archi partono e arrivano: uscite in basso, ingresso in alto.\r\n * Dichiararli e' quello che rende il grafo leggibile dall'alto verso il basso; lasciando\r\n * fare a foblex, il lato viene calcolato dalla posizione relativa e un ramo che risale\r\n * uscirebbe di fianco.\r\n */\r\n readonly sides = EFConnectableSide;\r\n\r\n /** Il nome dell'elemento selezionato, `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n /**\r\n * L'outline del backend, quando disponibile: da' la raggiungibilita' autoritativa (§6.4).\r\n * Assente → si usa il calcolo locale.\r\n */\r\n readonly outline = input<FlowOutline | null>(null);\r\n\r\n readonly selectionChange = output<string | null>();\r\n readonly nodeOpened = output<string>();\r\n readonly nodeRemoveRequested = output<string>();\r\n readonly nodeDuplicateRequested = output<string>();\r\n /** Rilascio di un elemento dalla palette: tipo + punto nel sistema del canvas. */\r\n readonly elementDropped = output<{ type: FlowElementType; x: number; y: number }>();\r\n\r\n /** Raggiungibilita': backend se c'e', locale altrimenti. */\r\n private readonly reachability = computed<ReadonlySet<string>>(() => {\r\n const outline = this.outline();\r\n if (outline?.nodes?.length) {\r\n const unreachable = new Set(\r\n outline.nodes.filter((node) => node.isReachable === false).map((node) => node.name),\r\n );\r\n const names = new Set(this.store.nodes().map((reference) => reference.name));\r\n for (const name of unreachable) {\r\n names.delete(name);\r\n }\r\n return names;\r\n }\r\n return this.store.reachableNames();\r\n });\r\n\r\n readonly nodes = computed<FlowCanvasNode[]>(() => {\r\n const result: FlowCanvasNode[] = [];\r\n const reachable = this.reachability();\r\n\r\n const start = this.store.start() as FlowAnyNode;\r\n result.push(\r\n this.toCanvasNode({\r\n name: START_NODE_NAME,\r\n type: 'Start',\r\n node: start,\r\n label: 'Start',\r\n typeLabel: 'Avvio',\r\n category: 'Avvio',\r\n isStart: true,\r\n // Lo Start e' raggiungibile per definizione: e' il punto di ingresso.\r\n isReachable: true,\r\n subtitle: this.startSubtitle(),\r\n }),\r\n );\r\n\r\n for (const reference of this.store.nodes()) {\r\n result.push(\r\n this.toCanvasNode({\r\n name: reference.name,\r\n type: reference.type,\r\n node: reference.node,\r\n label: reference.node.label || reference.name,\r\n typeLabel: this.dictionaries.labelOf(reference.type),\r\n category: this.dictionaries.elementType(reference.type)?.category ?? null,\r\n isStart: false,\r\n isReachable: reachable.has(reference.name),\r\n subtitle: this.subtitleOf(reference.type, reference.node),\r\n }),\r\n );\r\n }\r\n return result;\r\n });\r\n\r\n private toCanvasNode(input: {\r\n name: string;\r\n type: FlowElementType | 'Start';\r\n node: FlowAnyNode;\r\n label: string;\r\n typeLabel: string;\r\n category: string | null;\r\n isStart: boolean;\r\n isReachable: boolean;\r\n subtitle: string | null;\r\n }): FlowCanvasNode {\r\n const outlets = outletsOf(input.type, input.node);\r\n const issues = this.validation.issuesByElement().get(input.isStart ? '' : input.name) ?? [];\r\n return {\r\n icon: elementIcon(input.type, input.typeLabel),\r\n widthClass: flowNodeWidthClass(outlets.length),\r\n showsOutletLabels: outlets.length > 1,\r\n name: input.name,\r\n id: canvasNodeId(input.name),\r\n type: input.type,\r\n typeLabel: input.typeLabel,\r\n label: input.label,\r\n description: (input.node.description as string | undefined) ?? null,\r\n position: { x: input.node.locationX ?? 0, y: input.node.locationY ?? 0 },\r\n outlets,\r\n isStart: input.isStart,\r\n category: input.category,\r\n isReachable: input.isReachable,\r\n severity: input.isStart ? null : this.validation.severityOf(input.name),\r\n issueCount: input.isStart ? 0 : issues.length,\r\n hasAutomaticOutput: !input.isStart && this.dictionaries.hasAutomaticOutput(input.type as string),\r\n subtitle: input.subtitle,\r\n // Un ramo dichiarato senza destinazione non e' un arco: si mostra sul node, perche'\r\n // un arco che non arriva da nessuna parte non e' disegnabile (§6.4, `to: null`).\r\n danglingOutlets: outlets.filter((outlet) => {\r\n const connector = outlet.read(input.node);\r\n return !!connector && !connector.targetReference;\r\n }),\r\n };\r\n }\r\n\r\n /** Gli archi con destinazione: solo questi diventano `<f-connection>`. */\r\n readonly edges = computed<FlowCanvasEdge[]>(() => {\r\n const known = new Set(this.nodes().map((node) => node.name));\r\n return this.store\r\n .edges()\r\n .filter((edge) => !!edge.to && known.has(edge.to))\r\n .map((edge) => ({\r\n id: edge.id,\r\n sourceId: sourceConnectorId(edge.from, edge.outletKey),\r\n targetId: targetConnectorId(edge.to as string),\r\n kind: edge.kind,\r\n label: edge.label,\r\n isGoTo: !!edge.isGoTo,\r\n }));\r\n });\r\n\r\n /** Sintesi mostrata sul node: la cosa che serve sapere senza aprire l'inspector. */\r\n private subtitleOf(type: FlowElementType, node: FlowAnyNode): string | null {\r\n switch (type) {\r\n case 'Screen':\r\n return (node['formName'] as string) || null;\r\n case 'RecordLookup':\r\n case 'RecordCreate':\r\n case 'RecordUpdate':\r\n case 'RecordDelete':\r\n return (node['object'] as string) || (node['inputReference'] as string) || null;\r\n case 'Loop':\r\n return (node['collectionReference'] as string) || null;\r\n case 'CollectionProcessor': {\r\n const kind = node['collectionProcessorType'] as string | undefined;\r\n const collection = node['collectionReference'] as string | undefined;\r\n return [kind, collection].filter(Boolean).join(' · ') || null;\r\n }\r\n case 'Decision': {\r\n const rules = (node['rules'] as unknown[] | undefined)?.length ?? 0;\r\n return rules ? `${rules} ${rules === 1 ? 'regola' : 'regole'}` : null;\r\n }\r\n case 'Assignment': {\r\n const items = (node['assignmentItems'] as unknown[] | undefined)?.length ?? 0;\r\n return items ? `${items} ${items === 1 ? 'operazione' : 'operazioni'}` : null;\r\n }\r\n case 'ActionCall': {\r\n const actionType = node['actionType'] as string | undefined;\r\n const actionName = node['actionName'] as string | undefined;\r\n return [actionType, actionName].filter(Boolean).join(' · ') || null;\r\n }\r\n case 'ScriptCall':\r\n return (node['scriptName'] as string) || null;\r\n case 'Subflow':\r\n return (node['flowName'] as string) || null;\r\n case 'Wait': {\r\n const events = (node['waitEvents'] as unknown[] | undefined)?.length ?? 0;\r\n return events ? `${events} ${events === 1 ? 'evento' : 'eventi'}` : null;\r\n }\r\n case 'Transform':\r\n return (node['objectType'] as string) || null;\r\n case 'OrchestratedStage': {\r\n // Gli step non sono una sequenza: si conta quanti sono, non fino a dove si e' arrivati.\r\n const steps = (node['stageSteps'] as unknown[] | undefined)?.length ?? 0;\r\n return steps ? `${steps} step` : null;\r\n }\r\n case 'CustomError': {\r\n const messages = (node['customErrorMessages'] as unknown[] | undefined)?.length ?? 0;\r\n return messages ? `${messages} ${messages === 1 ? 'messaggio' : 'messaggi'}` : null;\r\n }\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n /** Sullo Start conta il trigger: e' cio' che decide quando il flow parte (§3.4). */\r\n private startSubtitle(): string | null {\r\n const start = this.store.start();\r\n const triggerType = start.triggerType ?? 'None';\r\n const label = FlowDictionaryStore.labelIn(this.dictionaries.triggerTypes(), triggerType);\r\n if (triggerType === 'None') {\r\n return label || 'Su richiesta';\r\n }\r\n return [label, start.object].filter(Boolean).join(' · ');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Gesti\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Creazione di un arco. `targetId` assente significa rilascio nel vuoto: si lascia il\r\n * ramo dichiarato ma senza destinazione, che e' esattamente il \"ramo incompleto\" del\r\n * modello, invece di scartare il gesto.\r\n */\r\n onCreateConnection(event: { sourceId: string; targetId?: string }): void {\r\n const source = parseSourceConnectorId(event.sourceId);\r\n if (!source) {\r\n return;\r\n }\r\n const target = event.targetId ? parseTargetConnectorId(event.targetId) : null;\r\n if (target === source.nodeName) {\r\n // `CONNECTOR_SELF_LOOP`: un node che punta a se stesso non e' mai voluto.\r\n return;\r\n }\r\n this.store.setConnector(source.nodeName, source.outletKey, target ?? undefined);\r\n }\r\n\r\n /** Riassegnazione di un arco già disegnato, da un capo o dall'altro. */\r\n onReassignConnection(event: {\r\n endpoint: string;\r\n previousSourceId: string;\r\n nextSourceId?: string;\r\n previousTargetId: string;\r\n nextTargetId?: string;\r\n }): void {\r\n const previousSource = parseSourceConnectorId(event.previousSourceId);\r\n if (!previousSource) {\r\n return;\r\n }\r\n if (event.endpoint === 'target') {\r\n const nextTarget = event.nextTargetId ? parseTargetConnectorId(event.nextTargetId) : null;\r\n this.store.setConnector(previousSource.nodeName, previousSource.outletKey, nextTarget ?? undefined);\r\n return;\r\n }\r\n // Capo sorgente spostato: l'arco cambia uscita, la destinazione resta.\r\n const nextSource = event.nextSourceId ? parseSourceConnectorId(event.nextSourceId) : null;\r\n const target = parseTargetConnectorId(event.previousTargetId);\r\n if (!nextSource || !target) {\r\n return;\r\n }\r\n this.store.removeConnector(previousSource.nodeName, previousSource.outletKey);\r\n this.store.setConnector(nextSource.nodeName, nextSource.outletKey, target);\r\n }\r\n\r\n /**\r\n * Spostamento dei node. Un solo passo di storico per l'intero gesto: le posizioni\r\n * intermedie non sono modifiche che l'utente vuole annullare una per una.\r\n */\r\n onMoveNodes(event: { nodes: Array<{ id: string; position: { x: number; y: number } }> }): void {\r\n const moves = event.nodes\r\n .map((moved) => ({ name: parseCanvasNodeId(moved.id), position: moved.position }))\r\n .filter((moved): moved is { name: string; position: { x: number; y: number } } => !!moved.name);\r\n if (!moves.length) {\r\n return;\r\n }\r\n moves.forEach((moved, index) => {\r\n this.store.moveNode(moved.name, moved.position.x, moved.position.y, { silent: index > 0 });\r\n });\r\n }\r\n\r\n onSelectionChange(event: { nodeIds: string[] }): void {\r\n const first = event.nodeIds[0];\r\n this.selectionChange.emit(first ? parseCanvasNodeId(first) : null);\r\n }\r\n\r\n /** `Delete` sulla selezione: lo Start non e' cancellabile, e' uno per flow (§3.4). */\r\n onDeleteSelected(event: { nodeIds: string[] }): void {\r\n for (const id of event.nodeIds) {\r\n const name = parseCanvasNodeId(id);\r\n if (name && name !== START_NODE_NAME) {\r\n this.nodeRemoveRequested.emit(name);\r\n }\r\n }\r\n }\r\n\r\n /** Rilascio di un elemento trascinato dalla palette. */\r\n onCreateNode(event: { data: unknown; externalItemRect: { x: number; y: number } }): void {\r\n const type = typeof event.data === 'string' ? event.data : (event.data as { type?: string })?.type;\r\n if (!type) {\r\n return;\r\n }\r\n this.elementDropped.emit({\r\n type,\r\n x: Math.round(event.externalItemRect.x),\r\n y: Math.round(event.externalItemRect.y),\r\n });\r\n }\r\n\r\n onNodeDoubleClick(name: string): void {\r\n this.nodeOpened.emit(name);\r\n }\r\n\r\n /**\r\n * Il bottone «✎» sul node: apre il dettaglio senza aspettare il doppio click, che e' un\r\n * gesto che non si vede. `stopPropagation` evita che il click valga anche come selezione\r\n * dell'area sottostante.\r\n */\r\n onEditClick(event: Event, name: string): void {\r\n event.stopPropagation();\r\n this.nodeOpened.emit(name);\r\n }\r\n\r\n connectorIdOf(node: FlowCanvasNode, outletKey: string): string {\r\n return sourceConnectorId(node.name, outletKey);\r\n }\r\n\r\n targetIdOf(node: FlowCanvasNode): string {\r\n return targetConnectorId(node.name);\r\n }\r\n\r\n isSelected(node: FlowCanvasNode): boolean {\r\n return this.selectedName() === node.name;\r\n }\r\n\r\n /** Etichette dei rami dichiarati senza destinazione, per il tooltip del badge. */\r\n danglingLabels(node: FlowCanvasNode): string {\r\n return node.danglingOutlets.map((outlet) => outlet.label).join(', ');\r\n }\r\n\r\n /** Classe della fascia colorata, per categoria del dizionario. */\r\n categoryClass(node: FlowCanvasNode): string {\r\n const category = (node.category ?? '').toLowerCase();\r\n if (node.isStart) {\r\n return 'cat-start';\r\n }\r\n if (category.startsWith('inter')) {\r\n return 'cat-screen';\r\n }\r\n if (category.startsWith('log')) {\r\n return 'cat-logic';\r\n }\r\n if (category.startsWith('dat')) {\r\n return 'cat-data';\r\n }\r\n if (category.startsWith('az')) {\r\n return 'cat-action';\r\n }\r\n if (category.startsWith('flow')) {\r\n return 'cat-flow';\r\n }\r\n return 'cat-other';\r\n }\r\n}\r\n","<!--\r\n Gerarchia obbligatoria: f-flow > f-canvas > fNode / f-connection.\r\n I `@for` sono direttamente dentro <f-canvas>: nessun wrapper, quindi non serve\r\n `ngProjectAs` (che sarebbe indispensabile con blocchi annidati).\r\n-->\r\n<f-flow\r\n fDraggable\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n (fReassignConnection)=\"onReassignConnection($event)\"\r\n (fMoveNodes)=\"onMoveNodes($event)\"\r\n (fSelectionChange)=\"onSelectionChange($event)\"\r\n (fDeleteSelected)=\"onDeleteSelected($event)\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n>\r\n <f-canvas fZoom>\r\n <f-background>\r\n <f-circle-pattern />\r\n </f-background>\r\n\r\n @for (edge of edges(); track edge.id) {\r\n <f-connection\r\n [fConnectionId]=\"edge.id\"\r\n [fSourceId]=\"edge.sourceId\"\r\n [fTargetId]=\"edge.targetId\"\r\n fBehavior=\"floating\"\r\n [fType]=\"edge.isGoTo ? 'segment' : 'bezier'\"\r\n [class]=\"'fb-edge fb-edge--' + edge.kind + (edge.isGoTo ? ' fb-edge--goto' : '')\"\r\n >\r\n <f-connection-marker-arrow [type]=\"markerEnd\" />\r\n @if (edge.label) {\r\n <div fConnectionContent class=\"fb-edge-label\">{{ edge.label }}</div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n @for (node of nodes(); track node.id) {\r\n <div\r\n fNode\r\n fDragHandle\r\n [fNodeId]=\"node.id\"\r\n [fNodePosition]=\"node.position\"\r\n [class]=\"'fb-node ' + categoryClass(node) + ' ' + node.widthClass\"\r\n [class.fb-node--start]=\"node.isStart\"\r\n [class.fb-node--selected]=\"isSelected(node)\"\r\n [class.fb-node--unreachable]=\"!node.isReachable\"\r\n [class.fb-node--error]=\"node.severity === 'Error'\"\r\n [class.fb-node--warning]=\"node.severity === 'Warning'\"\r\n (dblclick)=\"onNodeDoubleClick(node.name)\"\r\n >\r\n <!--\r\n Lo Start non ha ingresso: e' il punto di partenza (§3.4).\r\n `fConnectorConnectableSide` e' cio' che fa entrare l'arco dall'alto: senza, foblex\r\n calcola il lato e un arco che scende dal node sopra potrebbe agganciarsi di fianco.\r\n -->\r\n @if (!node.isStart) {\r\n <div\r\n fConnector\r\n fConnectorType=\"target\"\r\n [fConnectorId]=\"targetIdOf(node)\"\r\n [fConnectorConnectableSide]=\"sides.TOP\"\r\n fConnectorMultiple=\"true\"\r\n class=\"fb-connector fb-connector--in\"\r\n title=\"Ingresso\"\r\n ></div>\r\n }\r\n\r\n <div class=\"fb-node__head\">\r\n <span class=\"fb-node__icon\" aria-hidden=\"true\">{{ node.icon }}</span>\r\n <div class=\"fb-node__text\">\r\n <span class=\"fb-node__title\" [title]=\"node.description || node.label\">{{ node.label }}</span>\r\n <span class=\"fb-node__sub\">\r\n {{ node.typeLabel }}\r\n @if (node.subtitle) {\r\n <span class=\"fb-node__sub-dot\">·</span>{{ node.subtitle }}\r\n }\r\n </span>\r\n </div>\r\n @if (node.hasAutomaticOutput) {\r\n <!-- L'elemento espone il proprio risultato sotto il proprio nome (§4.5). -->\r\n <span class=\"fb-node__auto\" title=\"Espone un output automatico referenziabile come «{{ node.name }}»\">\r\n ƒ\r\n </span>\r\n }\r\n <!--\r\n `fDragBlocker` impedisce che il pointerdown sul bottone diventi un trascinamento\r\n del node: senza, aprire il dettaglio sposterebbe l'elemento di qualche pixel.\r\n -->\r\n <button\r\n type=\"button\"\r\n fDragBlocker\r\n class=\"fb-node__edit\"\r\n [attr.aria-label]=\"'Apri il dettaglio di ' + node.label\"\r\n title=\"Apri il dettaglio\"\r\n (click)=\"onEditClick($event, node.name)\"\r\n >\r\n ✎\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-node__meta\">\r\n @if (!node.isStart) {\r\n <span class=\"fb-node__name\" [title]=\"'Nome tecnico: ' + node.name\">{{ node.name }}</span>\r\n }\r\n @if (!node.isReachable) {\r\n <span class=\"fb-badge fb-badge--unreachable\" title=\"Nessun percorso raggiunge questo elemento dallo Start\">\r\n scollegato\r\n </span>\r\n }\r\n @if (node.issueCount > 0) {\r\n <span\r\n class=\"fb-badge\"\r\n [class.fb-badge--error]=\"node.severity === 'Error'\"\r\n [class.fb-badge--warning]=\"node.severity === 'Warning'\"\r\n [class.fb-badge--info]=\"node.severity === 'Info'\"\r\n [title]=\"node.issueCount + ' rilievi di validazione'\"\r\n >\r\n {{ node.issueCount }}\r\n </span>\r\n }\r\n @if (node.danglingOutlets.length > 0) {\r\n <span\r\n class=\"fb-badge fb-badge--dangling\"\r\n [title]=\"'Rami dichiarati senza destinazione: ' + danglingLabels(node)\"\r\n >\r\n ramo incompleto\r\n </span>\r\n }\r\n </div>\r\n\r\n <!--\r\n Le uscite stanno sul bordo **inferiore**, una per ramo, nell'ordine in cui il modello\r\n le dichiara: per una Decision e' l'ordine di valutazione delle regole, che e'\r\n semantico (§5.3), e da sinistra a destra si legge come la lista nell'inspector.\r\n L'etichetta si mostra solo quando i rami sono piu' di uno: su un `next` unico\r\n direbbe soltanto «Successivo».\r\n -->\r\n <div class=\"fb-node__outlets\" [class.fb-node__outlets--labelled]=\"node.showsOutletLabels\">\r\n @for (outlet of node.outlets; track outlet.key) {\r\n <div class=\"fb-outlet\">\r\n @if (node.showsOutletLabels) {\r\n <span class=\"fb-outlet__label\" [title]=\"outlet.label\">{{ outlet.label }}</span>\r\n }\r\n <div\r\n fConnector\r\n fConnectorType=\"source\"\r\n [fConnectorId]=\"connectorIdOf(node, outlet.key)\"\r\n [fConnectorConnectableSide]=\"sides.BOTTOM\"\r\n [class]=\"'fb-connector fb-connector--out fb-connector--' + outlet.kind\"\r\n [title]=\"outlet.label\"\r\n ></div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Anteprima dell'arco durante il trascinamento. -->\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"bezier\" class=\"fb-edge fb-edge--creating\">\r\n <f-connection-marker-arrow [type]=\"markerEnd\" />\r\n </f-connection-for-create>\r\n\r\n <f-selection-area />\r\n </f-canvas>\r\n\r\n <f-minimap [fMinSize]=\"1200\" class=\"fb-minimap\" />\r\n</f-flow>\r\n","/**\r\n * La palette degli elementi — FRONTEND.md §3.2, §11 (\"Aggiungere un elemento\").\r\n *\r\n * L'elenco arriva dal dizionario `elementTypes`: nessun tipo e' cablato qui. I tipi con\r\n * `isSupported: false` sono nascosti, perche' il motore li rifiuta e la validazione li\r\n * segnala come `ELEMENT_NOT_SUPPORTED`: lasciarli disegnare produce un flow che non parte.\r\n *\r\n * Ogni voce e' un `fExternalItem`: si trascina sul canvas e il punto di rilascio diventa\r\n * `locationX`/`locationY`. Il click aggiunge l'elemento al centro della vista.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output, signal } from '@angular/core';\r\nimport { FFlowModule } from '@foblex/flow';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { elementIcon } from '../../core/element-icons';\r\nimport { outletsOf } from '../../core/element-outlets';\r\nimport { FlowElementTypeEntry } from '../../model/dictionary.model';\r\nimport { FlowElementType } from '../../model/flow.model';\r\n\r\ninterface PaletteGroup {\r\n category: string;\r\n entries: FlowElementTypeEntry[];\r\n}\r\n\r\n@Component({\r\n selector: 'fb-element-palette',\r\n standalone: true,\r\n imports: [FFlowModule],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-palette.component.html',\r\n styleUrl: './element-palette.component.css',\r\n})\r\nexport class ElementPaletteComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n /**\r\n * Il `processType` del flow: un flow `AutoLaunched` che contiene screen e' un errore di\r\n * validazione, perche' non c'e' nessuno a cui mostrarli (§3.1). La palette lo segnala\r\n * prima che l'utente lo scopra dal pannello dei problemi.\r\n */\r\n readonly processType = input<string | undefined>(undefined);\r\n\r\n readonly elementPicked = output<FlowElementType>();\r\n\r\n private readonly filter = signal('');\r\n\r\n readonly groups = computed<PaletteGroup[]>(() => {\r\n const needle = this.filter().trim().toLowerCase();\r\n const groups: PaletteGroup[] = [];\r\n for (const entry of this.dictionaries.paletteTypes()) {\r\n if (needle && !`${entry.label} ${entry.value}`.toLowerCase().includes(needle)) {\r\n continue;\r\n }\r\n const category = entry.category ?? 'Altro';\r\n let group = groups.find((candidate) => candidate.category === category);\r\n if (!group) {\r\n group = { category, entries: [] };\r\n groups.push(group);\r\n }\r\n group.entries.push(entry);\r\n }\r\n return groups;\r\n });\r\n\r\n readonly isEmpty = computed(() => this.dictionaries.paletteTypes().length === 0);\r\n\r\n onFilter(value: string): void {\r\n this.filter.set(value);\r\n }\r\n\r\n pick(entry: FlowElementTypeEntry): void {\r\n this.elementPicked.emit(entry.value);\r\n }\r\n\r\n /** Uno screen in un flow che non mostra nulla: si segnala, non si nasconde (§3.1). */\r\n isIncompatible(entry: FlowElementTypeEntry): boolean {\r\n return entry.value === 'Screen' && this.processType() === 'AutoLaunched';\r\n }\r\n\r\n incompatibleHint(entry: FlowElementTypeEntry): string | null {\r\n if (!this.isIncompatible(entry)) {\r\n return null;\r\n }\r\n return 'In un flow AutoLaunched non c’e’ nessuno a cui mostrare uno screen: sarebbe un errore di validazione.';\r\n }\r\n\r\n /** Lo stesso glifo che l'elemento avra' sul canvas, così il trascinamento e' prevedibile. */\r\n iconOf(entry: FlowElementTypeEntry): string {\r\n return elementIcon(entry.value, entry.label);\r\n }\r\n\r\n /**\r\n * L'etichetta del ramo di fault, presa dalla mappa delle uscite invece di scrivere «ramo di\r\n * errore» per tutti: su uno stage di orchestrazione quel ramo **non** e' un guasto, e' lo step\r\n * rifiutato (§5.13). Un tipo nuovo eredita l'etichetta giusta senza toccare la palette.\r\n */\r\n faultLabel(entry: FlowElementTypeEntry): string | null {\r\n if (!entry.hasFaultConnector) {\r\n return null;\r\n }\r\n const outlet = outletsOf(entry.value, {}).find((candidate) => candidate.kind === 'Fault');\r\n return outlet ? `ramo «${outlet.label.toLowerCase()}»` : 'ramo di errore';\r\n }\r\n\r\n categoryClass(category: string): string {\r\n const normalized = category.toLowerCase();\r\n if (normalized.startsWith('inter')) {\r\n return 'cat-screen';\r\n }\r\n if (normalized.startsWith('log')) {\r\n return 'cat-logic';\r\n }\r\n if (normalized.startsWith('dat')) {\r\n return 'cat-data';\r\n }\r\n if (normalized.startsWith('az')) {\r\n return 'cat-action';\r\n }\r\n if (normalized.startsWith('flow')) {\r\n return 'cat-flow';\r\n }\r\n return 'cat-other';\r\n }\r\n}\r\n","<div class=\"fb-palette__search\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Cerca un elemento\"\r\n aria-label=\"Cerca un elemento\"\r\n (input)=\"onFilter($any($event.target).value)\"\r\n />\r\n</div>\r\n\r\n@if (isEmpty()) {\r\n <p class=\"fb-palette__empty\">\r\n Il dizionario degli elementi non e’ ancora disponibile.\r\n </p>\r\n}\r\n\r\n<div class=\"fb-palette__groups\">\r\n @for (group of groups(); track group.category) {\r\n <section class=\"fb-palette__group\">\r\n <h3 class=\"fb-palette__category\">{{ group.category }}</h3>\r\n @for (entry of group.entries; track entry.value) {\r\n <!--\r\n `fExternalItem` rende la voce trascinabile sul canvas: il rilascio emette\r\n `fCreateNode` con questo `fData` e la posizione, che diventa locationX/locationY.\r\n -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-palette__item\"\r\n fExternalItem\r\n [fExternalItemId]=\"entry.value\"\r\n [fData]=\"entry.value\"\r\n [class.fb-palette__item--warn]=\"isIncompatible(entry)\"\r\n [title]=\"incompatibleHint(entry) || entry.description || entry.label\"\r\n (click)=\"pick(entry)\"\r\n >\r\n <span class=\"fb-palette__icon\" [class]=\"'fb-palette__icon ' + categoryClass(group.category)\">\r\n {{ iconOf(entry) }}\r\n </span>\r\n <span class=\"fb-palette__text\">\r\n <span class=\"fb-palette__label\">{{ entry.label }}</span>\r\n @if (entry.hasAutomaticOutput) {\r\n <span class=\"fb-palette__flag\" title=\"Espone un output automatico sotto il nome dell’elemento\">\r\n output automatico\r\n </span>\r\n }\r\n @if (faultLabel(entry)) {\r\n <span class=\"fb-palette__flag\" title=\"Ha un ramo che l’autore puo’ prevedere e disegnare\">\r\n {{ faultLabel(entry) }}\r\n </span>\r\n }\r\n </span>\r\n @if (isIncompatible(entry)) {\r\n <span class=\"fb-palette__warn\" aria-hidden=\"true\">!</span>\r\n }\r\n </button>\r\n }\r\n </section>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di riferimento — FRONTEND.md §4.1, §4.5, §6.4, §13.3.\r\n *\r\n * Un riferimento e' testo libero, e un nome sbagliato e' indistinguibile da uno giusto se\r\n * non si conosce l'insieme dei nomi definiti. Questo componente chiede l'insieme a\r\n * `POST /flows/references` (o `.../writable` per le destinazioni) invece di far digitare:\r\n * e' l'unico modo di evitare `REFERENCE_UNKNOWN` prima di scoprirlo dalla validazione.\r\n *\r\n * Include gli **output automatici** (`Leggi_Ordine.Numero`), che sono riferimenti validi\r\n * pur non essendo dichiarati in nessuna collection di risorse: la primitiva li restituisce\r\n * già, ed e' il motivo per cui non si ricostruisce l'elenco lato client.\r\n *\r\n * Resta possibile scrivere a mano: i percorsi di relazione e i campi di un record non sono\r\n * enumerabili. Gli scope del sistema ospite (`$User.X`), invece, sono verificabili **quando\r\n * l'host li dichiara**: se `globalVariables` porta almeno un percorso di quello scope, un\r\n * percorso che non c'e' e' `GLOBAL_UNKNOWN`; se non ne porta nessuno, lo scope resta non\r\n * verificabile — che significa \"non lo so\", non \"non esiste\" (§4.1).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowReference } from '../../model/api.model';\r\nimport { FlowDataType } from '../../model/flow.model';\r\nimport { referenceRoot } from '../../core/flow-name.util';\r\n\r\n@Component({\r\n selector: 'fb-reference-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './reference-picker.component.html',\r\n styleUrl: './reference-picker.component.css',\r\n})\r\nexport class ReferencePickerComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n readonly label = input<string>('Riferimento');\r\n readonly placeholder = input<string>('Scegli o scrivi un riferimento');\r\n readonly disabled = input(false);\r\n\r\n /** Filtra i riferimenti compatibili col campo che si sta compilando (§6.4). */\r\n readonly dataType = input<FlowDataType | undefined>(undefined);\r\n readonly isCollection = input<boolean | undefined>(undefined);\r\n readonly objectType = input<string | undefined>(undefined);\r\n\r\n /**\r\n * `true` → propone solo destinazioni scrivibili. Assegnare a una costante o a una\r\n * formula e' `TARGET_NOT_WRITABLE` (§4.6).\r\n */\r\n readonly writableOnly = input(false);\r\n\r\n /**\r\n * `true` → a sinistra ci va il nome di un **node**, non di una risorsa: e' il caso di\r\n * `WasVisited` e `HasError` (§4.3).\r\n */\r\n readonly elementsOnly = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly references = signal<FlowReference[]>([]);\r\n private readonly isLoading = signal(false);\r\n private readonly loadError = signal<string | null>(null);\r\n\r\n readonly isOpen = signal(false);\r\n readonly query = signal('');\r\n\r\n constructor() {\r\n // Le proposte dipendono dal documento in lavorazione: cambia il documento, cambia\r\n // l'elenco (un elemento appena aggiunto espone subito il suo output automatico).\r\n effect(() => {\r\n const definition = this.store.document();\r\n const writable = this.writableOnly();\r\n const dataType = this.dataType();\r\n const isCollection = this.isCollection();\r\n const objectType = this.objectType();\r\n if (this.elementsOnly()) {\r\n // I node li conosce già il documento: nessuna richiesta necessaria.\r\n this.references.set(\r\n this.store.nodes().map((reference) => ({\r\n name: reference.name,\r\n label: (reference.node.label as string) ?? null,\r\n kind: 'ElementOutput',\r\n description: this.dictionaries.labelOf(reference.type),\r\n isWritable: false,\r\n })),\r\n );\r\n return;\r\n }\r\n /**\r\n * `?? undefined` non e' cosmetico: nei template il safe navigation di Angular\r\n * (`describe(x)?.isCollection`) produce **null**, non `undefined`. Un `isCollection: null`\r\n * che arriva alla primitiva viene letto come \"filtra per valore singolo\" e svuota\r\n * l'elenco: un campo senza filtro deve mandare il campo **assente**.\r\n */\r\n const query = {\r\n definition,\r\n dataType: dataType ?? undefined,\r\n isCollection: isCollection ?? undefined,\r\n objectType: objectType ?? undefined,\r\n };\r\n this.isLoading.set(true);\r\n this.loadError.set(null);\r\n const request = writable ? this.api.getWritableReferences(query) : this.api.getReferences(query);\r\n void request\r\n .then((list) => this.references.set(list ?? []))\r\n .catch((error: unknown) => {\r\n // Senza l'elenco il campo resta scrivibile a mano: e' meglio di un campo bloccato.\r\n this.loadError.set(error instanceof Error ? error.message : String(error));\r\n this.references.set([]);\r\n })\r\n .finally(() => this.isLoading.set(false));\r\n });\r\n }\r\n\r\n readonly options = computed<FlowReference[]>(() => {\r\n const needle = this.query().trim().toLowerCase();\r\n // Le globali assegnabili — `$Flow.CurrentStage`, `$Flow.ActiveStages` e quelle che l'host\r\n // dichiara scrivibili — le comprende già `POST /flows/references/writable`: aggiungerle\r\n // qui le duplicherebbe (§5.2, §6.4).\r\n const all = this.references();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((reference) =>\r\n `${reference.name} ${reference.label ?? ''} ${reference.description ?? ''}`\r\n .toLowerCase()\r\n .includes(needle),\r\n );\r\n });\r\n\r\n /** Le opzioni raggruppate per `kind`, così gli output automatici si distinguono. */\r\n readonly groups = computed<Array<{ kind: string; label: string; items: FlowReference[] }>>(() => {\r\n const groups: Array<{ kind: string; label: string; items: FlowReference[] }> = [];\r\n for (const reference of this.options()) {\r\n const kind = reference.kind ?? 'Variable';\r\n let group = groups.find((candidate) => candidate.kind === kind);\r\n if (!group) {\r\n group = { kind, label: ReferencePickerComponent.kindLabel(kind), items: [] };\r\n groups.push(group);\r\n }\r\n group.items.push(reference);\r\n }\r\n return groups;\r\n });\r\n\r\n private static kindLabel(kind: string): string {\r\n switch (kind) {\r\n case 'Variable':\r\n return 'Variabili';\r\n case 'Constant':\r\n return 'Costanti';\r\n case 'Formula':\r\n return 'Formule';\r\n case 'TextTemplate':\r\n return 'Text template';\r\n case 'Choice':\r\n return 'Choice';\r\n case 'DynamicChoiceSet':\r\n return 'Dynamic choice set';\r\n case 'Stage':\r\n return 'Stage';\r\n case 'ElementOutput':\r\n return 'Output di elementi';\r\n case 'Global':\r\n return 'Variabili globali';\r\n default:\r\n return kind;\r\n }\r\n }\r\n\r\n /**\r\n * Stato del valore corrente rispetto all'elenco.\r\n * - `known`: presente nell'elenco;\r\n * - `navigated`: la radice e' nota ma c'e' un percorso dopo il punto (campo di record,\r\n * output automatico navigato): la validazione non verifica i percorsi con il punto,\r\n * quindi si accetta senza segnalare;\r\n * - `host`: scope del sistema ospite che **non dichiara percorsi**: non verificabile (§4.1);\r\n * - `unknown`: nessuna corrispondenza: si avvisa, senza bloccare. Ci finisce anche il\r\n * percorso inesistente di uno scope che i percorsi li dichiara, perche' lì il backend\r\n * risponderebbe `GLOBAL_UNKNOWN`.\r\n */\r\n readonly valueState = computed<'empty' | 'known' | 'navigated' | 'host' | 'unknown'>(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value) {\r\n return 'empty';\r\n }\r\n const all = this.references();\r\n if (all.some((reference) => reference.name === value)) {\r\n return 'known';\r\n }\r\n const root = referenceRoot(value);\r\n if (this.dictionaries.globalScope(root) && !this.dictionaries.isGlobalScopeVerifiable(root)) {\r\n return 'host';\r\n }\r\n if (all.some((reference) => reference.name === root)) {\r\n return 'navigated';\r\n }\r\n // Se l'elenco non e' arrivato, non si accusa nessuno.\r\n return all.length === 0 && this.isLoading() ? 'empty' : 'unknown';\r\n });\r\n\r\n readonly hint = computed<string | null>(() => {\r\n switch (this.valueState()) {\r\n case 'host':\r\n return 'Scope risolto dal sistema ospite, che non dichiara i suoi percorsi: il backend non puo’ verificarlo.';\r\n case 'navigated':\r\n return 'Percorso su un riferimento noto: la validazione non verifica i campi dopo il punto.';\r\n case 'unknown':\r\n return 'Questo nome non e’ fra i riferimenti disponibili: la validazione lo segnalerebbe.';\r\n default:\r\n return null;\r\n }\r\n });\r\n\r\n readonly errorMessage = computed(() => this.loadError());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set('');\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onQuery(value: string): void {\r\n this.query.set(value);\r\n }\r\n\r\n choose(reference: FlowReference): void {\r\n this.valueChange.emit(reference.name);\r\n this.close();\r\n }\r\n\r\n /** Scrittura libera: indispensabile per i campi di un record e per gli scope dell'host. */\r\n onManualInput(value: string): void {\r\n this.valueChange.emit(value.trim() ? value.trim() : undefined);\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n }\r\n\r\n describe(reference: FlowReference): string {\r\n const parts: string[] = [];\r\n if (reference.dataType) {\r\n parts.push(reference.isCollection ? `${reference.dataType}[]` : reference.dataType);\r\n }\r\n if (reference.objectType) {\r\n parts.push(reference.objectType);\r\n }\r\n if (reference.description) {\r\n parts.push(reference.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-ref\" [class.fb-ref--open]=\"isOpen()\">\r\n <div class=\"fb-ref__control\">\r\n <input\r\n class=\"fb-ref__input\"\r\n type=\"text\"\r\n [value]=\"value() || ''\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n (input)=\"onManualInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-ref__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i riferimenti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-ref__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (hint()) {\r\n <p class=\"fb-ref__hint\" [class.fb-ref__hint--warn]=\"valueState() === 'unknown'\">{{ hint() }}</p>\r\n }\r\n @if (errorMessage()) {\r\n <p class=\"fb-ref__hint fb-ref__hint--warn\">\r\n Elenco dei riferimenti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-ref__panel\" role=\"listbox\">\r\n <input\r\n class=\"fb-ref__search\"\r\n type=\"search\"\r\n placeholder=\"Filtra\"\r\n aria-label=\"Filtra i riferimenti\"\r\n (input)=\"onQuery($any($event.target).value)\"\r\n />\r\n @if (groups().length === 0) {\r\n <p class=\"fb-ref__empty\">Nessun riferimento compatibile.</p>\r\n }\r\n @for (group of groups(); track group.kind) {\r\n <div class=\"fb-ref__group\">\r\n <span class=\"fb-ref__group-label\">{{ group.label }}</span>\r\n @for (item of group.items; track item.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-ref__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"item.name === value()\"\r\n (click)=\"choose(item)\"\r\n >\r\n <span class=\"fb-ref__name\">{{ item.name }}</span>\r\n <span class=\"fb-ref__meta\">{{ describe(item) }}</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-ref__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di oggetto (entita') — FRONTEND.md §4.2.\r\n *\r\n * Il catalogo degli oggetti (`listObjects()`) puo' essere lungo: un `<select>` obbliga a\r\n * scorrerlo, e quando il catalogo non arriva resta solo un campo di testo cieco. Qui la\r\n * casella e' **una sola** in entrambi i casi — si scrive per filtrare, si scegle dall'elenco —\r\n * e la scrittura libera resta possibile perche' l'host puo' esporre entita' che il catalogo\r\n * non elenca (o non esporlo affatto).\r\n *\r\n * Il valore emesso e' sempre il **nome** dell'oggetto, mai la sua label: la label e' testo\r\n * per l'occhio, il documento porta il nome.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowObjectSummary } from '../../model/dictionary.model';\r\n\r\n@Component({\r\n selector: 'fb-object-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './object-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class ObjectPickerComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n readonly label = input<string>('Oggetto');\r\n readonly placeholder = input<string>('Scrivi o scegli un oggetto');\r\n readonly disabled = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly objects = signal<FlowObjectSummary[]>([]);\r\n private readonly loadFailed = signal(false);\r\n\r\n readonly isOpen = signal(false);\r\n\r\n /**\r\n * Il testo digitato **mentre** il pannello e' aperto: filtra l'elenco. Chiuso il pannello\r\n * torna a null e la casella mostra di nuovo il valore del documento, che e' l'unica\r\n * fonte di verita'.\r\n */\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n void this.catalog\r\n .listObjects()\r\n .then((list) => this.objects.set(list ?? []))\r\n .catch(() => this.loadFailed.set(true));\r\n\r\n /**\r\n * Il filtro sopravvive alla **propria** scrittura — digitare aggiorna il valore a ogni\r\n * tasto — ma non a un valore che arriva da fuori: l'inspector riusa questo componente\r\n * quando si passa a un altro elemento dello stesso tipo, e il testo del precedente\r\n * resterebbe nella casella pur non essendo piu' il valore del documento.\r\n */\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n /** Quel che si vede nella casella: il filtro se si sta digitando, il valore altrimenti. */\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly options = computed<FlowObjectSummary[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.objects();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((object) =>\r\n `${object.name} ${object.label ?? ''} ${object.description ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasCatalog = computed(() => this.objects().length > 0);\r\n\r\n /**\r\n * Nome fuori catalogo: si avvisa e non si blocca. Senza catalogo non si accusa nessuno —\r\n * \"non lo so\" non e' \"non esiste\".\r\n */\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasCatalog()) {\r\n return false;\r\n }\r\n return !this.objects().some((object) => object.name === value);\r\n });\r\n\r\n readonly labelOfValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.objects().find((object) => object.name === value);\r\n return found?.label && found.label !== found.name ? found.label : null;\r\n });\r\n\r\n readonly loadErrored = computed(() => this.loadFailed());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n /** Digitare filtra **e** scrive: il nome puo' non essere in catalogo. */\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(object: FlowObjectSummary): void {\r\n this.valueChange.emit(object.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(object: FlowObjectSummary): string {\r\n const parts: string[] = [];\r\n if (object.label && object.label !== object.name) {\r\n parts.push(object.label);\r\n }\r\n if (object.description) {\r\n parts.push(object.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra gli oggetti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Questo nome non e’ fra gli oggetti disponibili: la validazione lo segnalerebbe.\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\r\n </p>\r\n }\r\n @for (object of options(); track object.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"object.name === value()\"\r\n (click)=\"choose(object)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ object.name }}</span>\r\n @if (describe(object)) {\r\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di campo di un'entita' — FRONTEND.md §4.4, §5.7, §6.4.\r\n *\r\n * L'uso con cui si chiedono i campi non e' un dettaglio: `filterable`, `sortable` e\r\n * `updateable` sono insiemi diversi, e proporre un campo fuori dall'insieme giusto porta\r\n * dritti a `FIELD_NOT_FILTERABLE` / `FIELD_NOT_UPDATEABLE`. L'input `usage` viaggia quindi\r\n * fino alla primitiva **e** decide il testo dell'avviso, che altrimenti direbbe la cosa\r\n * sbagliata (\"non aggiornabile\" su un filtro).\r\n *\r\n * La scrittura libera resta possibile perche' i percorsi di relazione (`Cliente.Citta`) non\r\n * sono enumerabili: su un valore col punto non si accusa nessuno, si avvisa che la\r\n * validazione non lo verifica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription, FlowFieldUsage } from '../../model/dictionary.model';\r\n\r\n@Component({\r\n selector: 'fb-field-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './field-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class FieldPickerComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n /** L'entita' di cui elencare i campi: senza oggetto non c'e' catalogo. */\r\n readonly object = input<string | undefined>(undefined);\r\n readonly usage = input<FlowFieldUsage>('any');\r\n readonly label = input<string>('Campo');\r\n readonly placeholder = input<string>('Scrivi o scegli un campo');\r\n readonly disabled = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n private readonly loadFailed = signal(false);\r\n\r\n readonly isOpen = signal(false);\r\n\r\n /** Il testo digitato mentre il pannello e' aperto: filtra l'elenco. */\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n const usage = this.usage();\r\n this.loadFailed.set(false);\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, usage)\r\n .then((list) => this.fields.set(list ?? []))\r\n // Catalogo non disponibile: il campo resta scrivibile a mano, non bloccato.\r\n .catch(() => {\r\n this.fields.set([]);\r\n this.loadFailed.set(true);\r\n });\r\n });\r\n\r\n // Vedi ObjectPickerComponent: il filtro sopravvive alla propria scrittura, non a un\r\n // valore che arriva da fuori (un'altra riga della lista, un altro elemento).\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly options = computed<FlowFieldDescription[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.fields();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((field) =>\r\n `${field.name} ${field.label ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasCatalog = computed(() => this.fields().length > 0);\r\n\r\n /** `true` se il valore e' un percorso di relazione: non enumerabile, non verificato (§4.4). */\r\n readonly isRelationPath = computed(() => (this.value() ?? '').includes('.'));\r\n\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasCatalog() || this.isRelationPath()) {\r\n return false;\r\n }\r\n return !this.fields().some((field) => field.name === value);\r\n });\r\n\r\n /** L'avviso dipende dall'uso: un campo puo' esistere e non essere filtrabile. */\r\n readonly unknownMessage = computed(() => {\r\n switch (this.usage()) {\r\n case 'filterable':\r\n return 'Questo campo non e’ fra quelli filtrabili dell’oggetto.';\r\n case 'sortable':\r\n return 'Questo campo non e’ fra quelli su cui si puo’ ordinare.';\r\n case 'updateable':\r\n return 'Questo campo non e’ fra quelli aggiornabili dell’oggetto.';\r\n default:\r\n return 'Questo campo non e’ fra quelli dell’oggetto.';\r\n }\r\n });\r\n\r\n readonly describeValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.fields().find((field) => field.name === value);\r\n return found ? this.describe(found) || null : null;\r\n });\r\n\r\n readonly loadErrored = computed(() => this.loadFailed());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(field: FlowFieldDescription): void {\r\n this.valueChange.emit(field.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(field: FlowFieldDescription): string {\r\n const parts: string[] = [];\r\n if (field.label && field.label !== field.name) {\r\n parts.push(field.label);\r\n }\r\n if (field.dataType) {\r\n parts.push(field.objectType ? `${field.dataType} · ${field.objectType}` : field.dataType);\r\n }\r\n if (field.isRequired) {\r\n parts.push('obbligatorio');\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i campi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isRelationPath()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Percorso di relazione: la validazione non lo verifica, un errore si scopre solo eseguendo.\r\n </p>\r\n } @else if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!object()) {\r\n Scegli prima un oggetto.\r\n } @else {\r\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\r\n }\r\n </p>\r\n }\r\n @for (field of options(); track field.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"field.name === value()\"\r\n (click)=\"choose(field)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ field.name }}</span>\r\n @if (describe(field)) {\r\n <span class=\"fb-pick__meta\">{{ describe(field) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Combo con autocomplete su un elenco di nomi già in mano al chiamante.\r\n *\r\n * A differenza di {@link ObjectPickerComponent} e {@link FieldPickerComponent} questo non\r\n * sa da dove arrivi l'elenco: lo riceve. Serve dove i candidati non sono un catalogo di\r\n * schema ma dipendono dal contesto — i flow invocabili escludono il flow corrente\r\n * (`listSubflowCandidates`), le variabili di input di un subflow dipendono da quale subflow\r\n * si e' scelto — e dove quindi il componente non puo' chiederli da se'.\r\n *\r\n * Elenco vuoto significa **\"non lo so\"**, non \"nessuno\": il campo resta scrivibile a mano e\r\n * non si accusa il nome scritto (§7). Con l'elenco popolato, invece, un nome che non c'e' e'\r\n * segnalato subito: e' l'unica differenza rispetto a un `datalist`, che accetta qualunque\r\n * cosa in silenzio.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nexport interface NamePickerOption {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-name-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './name-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class NamePickerComponent {\r\n readonly value = input<string | undefined>(undefined);\r\n readonly options = input<NamePickerOption[]>([]);\r\n readonly label = input<string>('Nome');\r\n readonly placeholder = input<string>('Scrivi o scegli un nome');\r\n readonly disabled = input(false);\r\n\r\n /** Il testo dell'avviso sul nome fuori elenco: dipende da cosa si sta scegliendo. */\r\n readonly unknownMessage = input<string>('Questo nome non e’ fra quelli disponibili.');\r\n /** Cosa dire quando l'elenco e' vuoto: e' il caso \"non lo so\", non un errore. */\r\n readonly emptyMessage = input<string>('Elenco non disponibile: puoi scrivere il nome a mano.');\r\n /** Testo monospazio: i nomi tecnici si leggono meglio, ed e' come li mostra il resto del form. */\r\n readonly isMono = input(true);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n readonly isOpen = signal(false);\r\n\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n // Vedi ObjectPickerComponent: il filtro non sopravvive a un valore che arriva da fuori.\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly visibleOptions = computed<NamePickerOption[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.options();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((option) =>\r\n `${option.name} ${option.label ?? ''} ${option.description ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasOptions = computed(() => this.options().length > 0);\r\n\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasOptions()) {\r\n return false;\r\n }\r\n return !this.options().some((option) => option.name === value);\r\n });\r\n\r\n readonly labelOfValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.options().find((option) => option.name === value);\r\n return found ? this.describe(found) || null : null;\r\n });\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(option: NamePickerOption): void {\r\n this.valueChange.emit(option.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(option: NamePickerOption): string {\r\n const parts: string[] = [];\r\n if (option.label && option.label !== option.name) {\r\n parts.push(option.label);\r\n }\r\n if (option.description) {\r\n parts.push(option.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n [class.fb-pick__input--mono]=\"isMono()\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i nomi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (!hasOptions()) {\r\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (visibleOptions().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\r\n </p>\r\n }\r\n @for (option of visibleOptions(); track option.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"option.name === value()\"\r\n (click)=\"choose(option)\"\r\n >\r\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\r\n @if (describe(option)) {\r\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * `[fbValue]` su un `<select>`.\r\n *\r\n * Perche' esiste: quasi tutte le tendine dell'editor hanno opzioni che arrivano dopo il\r\n * primo render — dizionari, cataloghi, destinazioni dei connector, campi di un oggetto.\r\n * Un `[value]` normale viene applicato quando le `<option>` non esistono ancora, il browser\r\n * lo scarta, e Angular non lo riapplica perche' il valore del binding non e' cambiato: il\r\n * risultato e' una tendina che mostra «— scegli —» su un campo che nel documento ha un\r\n * valore. Succedeva, per esempio, sulla destinazione dello Start.\r\n *\r\n * La direttiva riallinea l'elemento al valore dichiarato a ogni giro di change detection,\r\n * così quando le opzioni compaiono la selezione si sistema da se'.\r\n */\r\n\r\nimport { AfterViewChecked, Directive, ElementRef, inject, input } from '@angular/core';\r\n\r\n@Directive({\r\n selector: 'select[fbValue]',\r\n standalone: true,\r\n})\r\nexport class SelectValueDirective implements AfterViewChecked {\r\n private readonly element = inject<ElementRef<HTMLSelectElement>>(ElementRef);\r\n\r\n readonly fbValue = input<string | number | null | undefined>('');\r\n\r\n ngAfterViewChecked(): void {\r\n const select = this.element.nativeElement;\r\n const value = this.fbValue();\r\n const normalized = value === null || value === undefined ? '' : String(value);\r\n if (select.value !== normalized) {\r\n select.value = normalized;\r\n }\r\n }\r\n}\r\n","/**\r\n * `FlowElementReferenceOrValue` — FRONTEND.md §4.2.\r\n *\r\n * La struttura accetta \"un riferimento **oppure** un valore letterale\", e va valorizzato\r\n * **uno e un solo** campo. Valorizzarne piu' di uno e' `VALUE_AMBIGUOUS`: non e' un errore\r\n * bloccante, ma rende il comportamento a runtime dipendente dall'ordine di lettura.\r\n *\r\n * Questo editor rende quella regola strutturale invece che sperata: ogni scrittura\r\n * costruisce un oggetto nuovo con **una** chiave. `formulaExpression` e' l'unico caso a\r\n * due campi (espressione + tipo atteso del risultato) e viene trattato come tale.\r\n *\r\n * Il tipo del letterale deve corrispondere al tipo della destinazione: quando il tipo e'\r\n * noto, l'editor mostra il controllo giusto e propone quella modalita' per default.\r\n *\r\n * Due dettagli di formato che il contratto tratta come sostanza, non come presentazione:\r\n *\r\n * - i numeri viaggiano in **cultura invariante** (§4.3): il separatore decimale e' il punto, e\r\n * `1234,50` viene tradotto in `1234.50` invece di essere troncato in silenzio;\r\n * - un valore data **senza fuso** significa \"ora locale dell'applicazione\", non \"UTC\"\r\n * (§4.2, §13.15): sono due istanti diversi, quindi il fuso e' una scelta esplicita\r\n * dell'utente e non un effetto collaterale del datepicker.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { parseInvariantNumber } from '../../core/condition-types.util';\r\nimport { FlowDataType, FlowValue } from '../../model/flow.model';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n/** Le modalita' offerte: una per campo del modello. */\r\nexport type ValueMode = 'reference' | 'literal' | 'formula' | 'globalConstant' | 'empty';\r\n\r\n@Component({\r\n selector: 'fb-value-editor',\r\n standalone: true,\r\n imports: [ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './value-editor.component.html',\r\n styleUrl: './value-editor.component.css',\r\n})\r\nexport class ValueEditorComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly value = input<FlowValue | undefined>(undefined);\r\n readonly label = input<string>('Valore');\r\n /** Il tipo atteso dalla destinazione: guida il controllo del letterale. */\r\n readonly dataType = input<FlowDataType | undefined>(undefined);\r\n readonly objectType = input<string | undefined>(undefined);\r\n readonly isCollection = input<boolean | undefined>(undefined);\r\n readonly disabled = input(false);\r\n /** Nasconde la modalita' formula dove il modello non la prevede. */\r\n readonly allowFormula = input(true);\r\n\r\n readonly valueChange = output<FlowValue | undefined>();\r\n\r\n /** La modalita' dedotta dal campo effettivamente valorizzato. */\r\n readonly mode = computed<ValueMode>(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return this.dataType() ? 'literal' : 'reference';\r\n }\r\n if (value.formulaExpression !== undefined) {\r\n return 'formula';\r\n }\r\n if (value.elementReference !== undefined) {\r\n return value.elementReference.startsWith('$GlobalConstant.') ? 'globalConstant' : 'reference';\r\n }\r\n if (\r\n value.stringValue !== undefined ||\r\n value.integerValue !== undefined ||\r\n value.numberValue !== undefined ||\r\n value.dateValue !== undefined ||\r\n value.booleanValue !== undefined ||\r\n value.enumValue !== undefined\r\n ) {\r\n return 'literal';\r\n }\r\n return 'empty';\r\n });\r\n\r\n /**\r\n * Quanti campi di valore sono valorizzati: piu' di uno e' `VALUE_AMBIGUOUS` (§4.2).\r\n * Puo' capitare su un documento arrivato da un altro editor: si segnala e si offre\r\n * di normalizzarlo, invece di nasconderlo.\r\n */\r\n readonly filledFieldCount = computed(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return 0;\r\n }\r\n const keys: Array<keyof FlowValue> = [\r\n 'elementReference',\r\n 'stringValue',\r\n 'integerValue',\r\n 'numberValue',\r\n 'dateValue',\r\n 'booleanValue',\r\n 'enumValue',\r\n 'formulaExpression',\r\n ];\r\n return keys.filter((key) => value[key] !== undefined).length;\r\n });\r\n\r\n readonly isAmbiguous = computed(() => this.filledFieldCount() > 1);\r\n\r\n /** Il campo del valore che corrisponde al `dataType` (§4.2, tabella dei sette tipi). */\r\n readonly literalField = computed<keyof FlowValue>(() => {\r\n switch (this.dataType()) {\r\n case 'Integer':\r\n return 'integerValue';\r\n case 'Number':\r\n return 'numberValue';\r\n case 'Date':\r\n return 'dateValue';\r\n case 'Boolean':\r\n return 'booleanValue';\r\n case 'Enum':\r\n return 'enumValue';\r\n case 'String':\r\n return 'stringValue';\r\n default:\r\n return 'stringValue';\r\n }\r\n });\r\n\r\n /**\r\n * `Object` non ha un campo letterale: un record si passa per riferimento (§4.2).\r\n * Lo stesso vale per una collection.\r\n */\r\n readonly literalAllowed = computed(() => {\r\n if (this.isCollection()) {\r\n return false;\r\n }\r\n return this.dataType() !== 'Object';\r\n });\r\n\r\n readonly literalInputType = computed<string>(() => {\r\n switch (this.dataType()) {\r\n case 'Integer':\r\n case 'Number':\r\n return 'number';\r\n case 'Date':\r\n // `Date` porta data **e** ora insieme: non esiste un tipo \"ora\" separato (§4.2).\r\n return 'datetime-local';\r\n default:\r\n return 'text';\r\n }\r\n });\r\n\r\n readonly literalText = computed<string>(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return '';\r\n }\r\n const field = this.literalField();\r\n if (field === 'dateValue' && value.dateValue !== undefined) {\r\n // `datetime-local` rifiuta un valore col fuso e resterebbe **vuoto** pur avendo un\r\n // valore: il suffisso si toglie qui e si riscrive in uscita. Se il documento porta un\r\n // campo diverso da quello atteso si passa al fallback qui sotto, che lo mostra comunque.\r\n return ValueEditorComponent.stripZone(value.dateValue);\r\n }\r\n const raw = value[field];\r\n if (raw === undefined || raw === null) {\r\n // Se il documento porta un tipo diverso da quello atteso, mostralo comunque:\r\n // nasconderlo farebbe sparire un valore che esiste.\r\n const fallback =\r\n value.stringValue ??\r\n value.integerValue ??\r\n value.numberValue ??\r\n value.dateValue ??\r\n value.enumValue;\r\n return fallback === undefined || fallback === null ? '' : String(fallback);\r\n }\r\n return String(raw);\r\n });\r\n\r\n readonly booleanValue = computed(() => this.value()?.booleanValue === true);\r\n\r\n /** Il fuso dichiarato nel valore data: `Z`, un offset, oppure niente = ora locale (§4.2). */\r\n readonly dateIsUtc = computed(() => ValueEditorComponent.hasZone(this.value()?.dateValue));\r\n\r\n private static readonly ZONE_PATTERN = /(Z|[+-]\\d{2}:?\\d{2})$/;\r\n\r\n private static hasZone(value: string | undefined): boolean {\r\n return !!value && ValueEditorComponent.ZONE_PATTERN.test(value);\r\n }\r\n\r\n private static stripZone(value: string | undefined): string {\r\n return (value ?? '').replace(ValueEditorComponent.ZONE_PATTERN, '');\r\n }\r\n\r\n readonly globalConstants = computed(() => {\r\n const entry = this.dictionaries\r\n .globalVariables()\r\n .find((candidate) => candidate.scope === '$GlobalConstant' || candidate.value === '$GlobalConstant');\r\n // Fuori dai quattro percorsi noti e' un errore di validazione: si propongono, non si\r\n // fanno digitare (§4.1).\r\n return (entry?.paths ?? []).map((path) => `$GlobalConstant.${path}`);\r\n });\r\n\r\n readonly numericHint = computed<string | null>(() => {\r\n switch (this.dataType()) {\r\n case 'Number':\r\n // Il punto decimale non e' una preferenza di formato: la virgola non e' accettata (§4.3).\r\n return 'Separatore decimale: il punto. Usa Number per importi e quantita’: Integer troncherebbe i decimali.';\r\n case 'Integer':\r\n return 'Numero intero, senza separatore delle migliaia.';\r\n default:\r\n return null;\r\n }\r\n });\r\n\r\n setMode(mode: ValueMode): void {\r\n switch (mode) {\r\n case 'reference':\r\n this.emit({ elementReference: '' });\r\n break;\r\n case 'literal':\r\n this.emit(this.dataType() === 'Boolean' ? { booleanValue: false } : { [this.literalField()]: '' });\r\n break;\r\n case 'formula':\r\n // L'unico caso con due campi: espressione + tipo atteso del risultato.\r\n this.emit({ formulaExpression: '', formulaDataType: this.dataType() ?? 'String' });\r\n break;\r\n case 'globalConstant':\r\n this.emit({ elementReference: this.globalConstants()[0] ?? '$GlobalConstant.Null' });\r\n break;\r\n case 'empty':\r\n this.emit(undefined);\r\n break;\r\n }\r\n }\r\n\r\n onReferenceChange(reference: string | undefined): void {\r\n this.emit(reference === undefined ? undefined : { elementReference: reference });\r\n }\r\n\r\n onLiteralChange(raw: string): void {\r\n const field = this.literalField();\r\n if (raw === '') {\r\n this.emit(undefined);\r\n return;\r\n }\r\n switch (field) {\r\n case 'integerValue': {\r\n // Cultura invariante anche sugli interi: `1.234` non e' milleduecentotrentaquattro.\r\n const parsed = parseInvariantNumber(raw);\r\n this.emit(parsed === undefined ? undefined : { integerValue: Math.trunc(parsed) });\r\n return;\r\n }\r\n case 'numberValue': {\r\n const parsed = parseInvariantNumber(raw);\r\n this.emit(parsed === undefined ? undefined : { numberValue: parsed });\r\n return;\r\n }\r\n case 'dateValue':\r\n // L'input `datetime-local` produce `2026-08-15T00:00` senza fuso: si completano i\r\n // secondi e si riscrive il fuso scelto, perche' senza `Z` il valore significa\r\n // \"ora locale\" e il motore lo converte prima di confrontarlo (§4.2).\r\n this.emit({ dateValue: this.withDateZone(raw.length === 16 ? `${raw}:00` : raw) });\r\n return;\r\n case 'enumValue':\r\n this.emit({ enumValue: raw });\r\n return;\r\n default:\r\n this.emit({ stringValue: raw });\r\n }\r\n }\r\n\r\n onBooleanChange(checked: boolean): void {\r\n this.emit({ booleanValue: checked });\r\n }\r\n\r\n private withDateZone(local: string, utc = this.dateIsUtc()): string {\r\n return utc ? `${ValueEditorComponent.stripZone(local)}Z` : ValueEditorComponent.stripZone(local);\r\n }\r\n\r\n /**\r\n * Cambia il fuso **dichiarato**, non l'istante: `09:00Z` e `09:00` sono le nove in due fusi\r\n * diversi, e l'editor non converte al posto dell'utente. Riscrivere lo stesso orario con\r\n * l'altro fuso e' esattamente cio' che serve quando il valore e' stato inserito sbagliato.\r\n */\r\n setDateZone(utc: boolean): void {\r\n const current = this.value()?.dateValue;\r\n if (!current) {\r\n return;\r\n }\r\n this.emit({ dateValue: this.withDateZone(current, utc) });\r\n }\r\n\r\n onFormulaChange(expression: string): void {\r\n this.emit({\r\n formulaExpression: expression,\r\n formulaDataType: this.value()?.formulaDataType ?? this.dataType() ?? 'String',\r\n });\r\n }\r\n\r\n onFormulaTypeChange(dataType: string): void {\r\n this.emit({\r\n formulaExpression: this.value()?.formulaExpression ?? '',\r\n formulaDataType: dataType,\r\n });\r\n }\r\n\r\n onGlobalConstantChange(value: string): void {\r\n this.emit({ elementReference: value });\r\n }\r\n\r\n /** Normalizza un valore ambiguo tenendo il campo della modalita' corrente. */\r\n normalize(): void {\r\n const value = this.value();\r\n if (!value) {\r\n return;\r\n }\r\n switch (this.mode()) {\r\n case 'formula':\r\n this.emit({\r\n formulaExpression: value.formulaExpression,\r\n formulaDataType: value.formulaDataType ?? this.dataType() ?? 'String',\r\n });\r\n return;\r\n case 'reference':\r\n case 'globalConstant':\r\n this.emit({ elementReference: value.elementReference });\r\n return;\r\n default: {\r\n const field = this.literalField();\r\n this.emit({ [field]: value[field] } as FlowValue);\r\n }\r\n }\r\n }\r\n\r\n private emit(value: FlowValue | undefined): void {\r\n this.valueChange.emit(value);\r\n }\r\n\r\n readonly dataTypeOptions = computed(() => this.dictionaries.dataTypes());\r\n}\r\n","<div class=\"fb-value\">\r\n <div class=\"fb-value__modes\" role=\"group\" [attr.aria-label]=\"label() + ': modalita’'\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'reference'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Riferimento a una risorsa o all’output di un elemento\"\r\n (click)=\"setMode('reference')\"\r\n >\r\n Riferimento\r\n </button>\r\n @if (literalAllowed()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'literal'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Valore letterale del tipo della destinazione\"\r\n (click)=\"setMode('literal')\"\r\n >\r\n Valore\r\n </button>\r\n }\r\n @if (allowFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'formula'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Espressione calcolata dal motore di regole\"\r\n (click)=\"setMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n @if (globalConstants().length) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'globalConstant'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Costante globale\"\r\n (click)=\"setMode('globalConstant')\"\r\n >\r\n Costante globale\r\n </button>\r\n }\r\n @if (mode() !== 'empty') {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode fb-value__mode--clear\"\r\n [disabled]=\"disabled()\"\r\n title=\"Nessun valore\"\r\n (click)=\"setMode('empty')\"\r\n >\r\n ×\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (isAmbiguous()) {\r\n <!-- Piu' campi di valore insieme: il comportamento a runtime dipende dall'ordine di lettura. -->\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo valore ha {{ filledFieldCount() }} campi valorizzati insieme: a runtime conta l’ordine di lettura.\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"normalize()\">\r\n Tieni solo «{{ mode() === 'formula' ? 'formula' : mode() === 'literal' ? 'valore' : 'riferimento' }}»\r\n </button>\r\n </p>\r\n }\r\n\r\n @switch (mode()) {\r\n @case ('reference') {\r\n <fb-reference-picker\r\n [value]=\"value()?.elementReference\"\r\n [label]=\"label()\"\r\n [dataType]=\"dataType()\"\r\n [isCollection]=\"isCollection()\"\r\n [objectType]=\"objectType()\"\r\n [disabled]=\"disabled()\"\r\n (valueChange)=\"onReferenceChange($event)\"\r\n />\r\n }\r\n\r\n @case ('globalConstant') {\r\n <select\r\n class=\"fb-select\"\r\n [disabled]=\"disabled()\"\r\n [fbValue]=\"value()?.elementReference || ''\"\r\n (change)=\"onGlobalConstantChange($any($event.target).value)\"\r\n >\r\n @for (constant of globalConstants(); track constant) {\r\n <option [value]=\"constant\">{{ constant }}</option>\r\n }\r\n </select>\r\n }\r\n\r\n @case ('literal') {\r\n @if (dataType() === 'Boolean') {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"booleanValue()\"\r\n [disabled]=\"disabled()\"\r\n (change)=\"onBooleanChange($any($event.target).checked)\"\r\n />\r\n {{ booleanValue() ? 'vero' : 'falso' }}\r\n </label>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [type]=\"literalInputType()\"\r\n [value]=\"literalText()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [placeholder]=\"dataType() === 'Enum' ? 'Nome del valore di enum' : ''\"\r\n (input)=\"onLiteralChange($any($event.target).value)\"\r\n />\r\n @if (numericHint()) {\r\n <p class=\"fb-field__hint\">{{ numericHint() }}</p>\r\n }\r\n @if (dataType() === 'Date') {\r\n <!--\r\n Il fuso e' una scelta, non un dettaglio: `09:00Z` e `09:00` sono due istanti\r\n diversi, e il motore converte in UTC prima di ogni confronto (§4.2).\r\n -->\r\n <div class=\"fb-value__modes\" role=\"group\" aria-label=\"Fuso del valore data\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"!dateIsUtc()\"\r\n [disabled]=\"disabled()\"\r\n title=\"Interpretato nel fuso dell’applicazione\"\r\n (click)=\"setDateZone(false)\"\r\n >\r\n Ora locale\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"dateIsUtc()\"\r\n [disabled]=\"disabled()\"\r\n title=\"Scrive il suffisso Z: l’orario e’ in UTC\"\r\n (click)=\"setDateZone(true)\"\r\n >\r\n UTC (Z)\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Data e ora insieme.\r\n {{\r\n dateIsUtc()\r\n ? 'Con «UTC» l’orario e’ assoluto.'\r\n : 'Senza fuso l’orario e’ interpretato nel fuso dell’applicazione, non in UTC.'\r\n }}\r\n Cambiare fuso riscrive l’orario, non lo converte.\r\n </p>\r\n }\r\n }\r\n }\r\n\r\n @case ('formula') {\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"value()?.formulaExpression || ''\"\r\n [disabled]=\"disabled()\"\r\n placeholder=\"Importo * 1.22\"\r\n [attr.aria-label]=\"label() + ': espressione'\"\r\n (input)=\"onFormulaChange($any($event.target).value)\"\r\n ></textarea>\r\n <div class=\"fb-field__row\">\r\n <label class=\"fb-field__hint\">Tipo del risultato</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"value()?.formulaDataType || ''\"\r\n [disabled]=\"disabled()\"\r\n (change)=\"onFormulaTypeChange($any($event.target).value)\"\r\n >\r\n @for (type of dataTypeOptions(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n L’espressione va al motore di regole: il backend non ne verifica la sintassi.\r\n </p>\r\n }\r\n\r\n @case ('empty') {\r\n <p class=\"fb-field__hint\">Nessun valore.</p>\r\n }\r\n }\r\n</div>\r\n","/**\r\n * Editor delle condizioni — FRONTEND.md §4.3 e trappole §13.1, §13.4, §13.13, §13.14.\r\n *\r\n * Quattro cose che questo componente fa deliberatamente, perche' un editor che non le fa\r\n * produce condizioni che fanno il contrario di quello che l'utente crede:\r\n *\r\n * 1. **Operatori unari.** Sette operatori non confrontano due valori: per loro\r\n * `rightValue` e' l'**esito atteso**, non il termine di confronto. Qui il lato destro\r\n * diventa un selettore \"è / non è\", e il testo mostrato dice esplicitamente cosa\r\n * verra' scritto. Il flag arriva da `isUnary` del dizionario, non da una lista cablata.\r\n *\r\n * 2. **`conditionLogic`.** Cancellare o spostare una condizione riscrive l'espressione,\r\n * perche' gli indici sono 1-based e scalano. La riscrittura sta in\r\n * {@link removeCondition} / {@link moveCondition}.\r\n *\r\n * 3. **Testo e numero non si confrontano** (`CONDITION_TYPE_MISMATCH`, errore che blocca\r\n * l'attivazione). Il tipo del lato sinistro arriva da `POST /flows/references` e guida il\r\n * secondo operando: il letterale finisce nel campo giusto e una risorsa incompatibile e'\r\n * segnalata. Il backend segnala solo quando conosce **entrambi** i tipi, e su un campo di\r\n * un record non li conosce: fermare qui e' il solo modo di fermare in tempo.\r\n *\r\n * 4. **`None` non e' un operatore, e' un \"da completare\"**: la bozza si salva, l'attivazione\r\n * no. La condizione e' evidenziata come incompleta, non presentata come valida.\r\n *\r\n * Inoltre: `WasVisited` e `HasError` vogliono a sinistra il nome di un **node**, non di una\r\n * risorsa (`appliesToElements`), e il selettore cambia di conseguenza.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowReference } from '../../model/api.model';\r\nimport { FlowCondition, FlowConditionHolder, FlowDataType, FlowValue } from '../../model/flow.model';\r\nimport {\r\n checkConditionLogic,\r\n isCustomConditionLogic,\r\n moveCondition as moveConditionInPlace,\r\n removeCondition as removeConditionInPlace,\r\n} from '../../core/condition-logic.util';\r\nimport { areTypesComparable, isTypeCheckedOperator } from '../../core/condition-types.util';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-condition-editor',\r\n standalone: true,\r\n imports: [ReferencePickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './condition-editor.component.html',\r\n styleUrl: './condition-editor.component.css',\r\n})\r\nexport class ConditionEditorComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n\r\n /** Il contenitore: porta `conditions`, `conditionLogic` e, se serve, `formula`. */\r\n readonly holder = input.required<FlowConditionHolder>();\r\n readonly title = input<string>('Condizioni');\r\n /** `false` dove il modello non prevede la modalita' formula sull'elemento. */\r\n readonly allowFormula = input(true);\r\n /**\r\n * `false` dove il modello porta **solo** la lista di condizioni, senza un campo per la\r\n * logica: gli `entryConditions` / `exitConditions` di uno step di orchestrazione (§5.13).\r\n * Mostrare i pulsanti della logica lì scriverebbe un campo che il contratto non prevede.\r\n */\r\n readonly allowLogic = input(true);\r\n /** Path per ancorare i rilievi di validazione, es. `rules[Approvato]`. */\r\n readonly issuePath = input<string>('');\r\n\r\n /** Emesso a ogni modifica: il chiamante applica la mutazione allo store. */\r\n readonly changed = output<(holder: FlowConditionHolder) => void>();\r\n\r\n readonly conditions = computed<FlowCondition[]>(() => this.holder().conditions ?? []);\r\n\r\n /**\r\n * I riferimenti del documento, per conoscere il tipo del lato sinistro. Non e' un doppione\r\n * del picker: serve **il tipo**, che e' l'unica cosa che permette di impedire il confronto\r\n * fra testo e numero prima che lo dica la validazione (§4.3).\r\n */\r\n private readonly references = signal<FlowReference[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n const definition = this.store.document();\r\n // Senza condizioni non serve conoscere nessun tipo: in un form con molti blocchi di\r\n // condizioni vuoti (uno stage con dieci step) risparmia altrettante richieste.\r\n if (!this.conditions().length) {\r\n return;\r\n }\r\n void this.api\r\n .getReferences({ definition })\r\n .then((list) => this.references.set(list ?? []))\r\n // Senza l'elenco non si segnala nulla: non sapere non e' sapere che e' sbagliato.\r\n .catch(() => this.references.set([]));\r\n });\r\n }\r\n\r\n /** Il tipo di un riferimento, `undefined` se navigato o ignoto: lì non si segnala (§4.3). */\r\n private typeOfReference(reference: string | undefined): FlowDataType | undefined {\r\n if (!reference) {\r\n return undefined;\r\n }\r\n return this.references().find((entry) => entry.name === reference)?.dataType ?? undefined;\r\n }\r\n\r\n /** Il tipo del lato sinistro: guida il secondo operando. */\r\n leftDataType(condition: FlowCondition): FlowDataType | undefined {\r\n return this.typeOfReference(condition.leftValueReference);\r\n }\r\n\r\n /** Il tipo del lato destro, dedotto dal campo valorizzato o dal riferimento scelto. */\r\n private rightDataType(condition: FlowCondition): FlowDataType | undefined {\r\n const value = condition.rightValue;\r\n if (!value) {\r\n return undefined;\r\n }\r\n if (value.formulaExpression !== undefined) {\r\n return value.formulaDataType;\r\n }\r\n if (value.elementReference !== undefined) {\r\n return this.typeOfReference(value.elementReference);\r\n }\r\n if (value.stringValue !== undefined) {\r\n return 'String';\r\n }\r\n if (value.integerValue !== undefined) {\r\n return 'Integer';\r\n }\r\n if (value.numberValue !== undefined) {\r\n return 'Number';\r\n }\r\n if (value.dateValue !== undefined) {\r\n return 'Date';\r\n }\r\n if (value.booleanValue !== undefined) {\r\n return 'Boolean';\r\n }\r\n if (value.enumValue !== undefined) {\r\n return 'Enum';\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * `true` quando i due lati sono incompatibili: e' `CONDITION_TYPE_MISMATCH`, un errore che\r\n * blocca l'attivazione. L'unica coppia vietata e' testo con numero (§4.3).\r\n */\r\n hasTypeMismatch(condition: FlowCondition): boolean {\r\n if (!isTypeCheckedOperator(condition.operator, this.isUnary(condition))) {\r\n return false;\r\n }\r\n return !areTypesComparable(this.leftDataType(condition), this.rightDataType(condition));\r\n }\r\n\r\n typeMismatchMessage(condition: FlowCondition): string {\r\n const left = this.leftDataType(condition) ?? '?';\r\n const right = this.rightDataType(condition) ?? '?';\r\n return `Un valore ${left} non si confronta con un valore ${right}: e’ CONDITION_TYPE_MISMATCH e blocca l’attivazione.`;\r\n }\r\n\r\n readonly logicMode = computed<'and' | 'or' | 'custom' | 'formula'>(() => {\r\n const logic = this.holder().conditionLogic;\r\n if (!logic) {\r\n // Assente = tutte le condizioni devono essere vere (§4.3).\r\n return 'and';\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n if (normalized === 'and') {\r\n return 'and';\r\n }\r\n if (normalized === 'or') {\r\n return 'or';\r\n }\r\n if (normalized === 'formula') {\r\n return 'formula';\r\n }\r\n return 'custom';\r\n });\r\n\r\n readonly customLogic = computed(() =>\r\n isCustomConditionLogic(this.holder().conditionLogic) ? (this.holder().conditionLogic as string) : '',\r\n );\r\n\r\n /** Feedback immediato sull'espressione: la verita' resta della validazione backend. */\r\n readonly customLogicError = computed(() => {\r\n const logic = this.customLogic();\r\n return logic ? checkConditionLogic(logic, this.conditions().length) : null;\r\n });\r\n\r\n /** Con `Formula` il campo `conditions` viene **ignorato** dal motore (§4.3). */\r\n readonly conditionsIgnored = computed(() => this.logicMode() === 'formula');\r\n\r\n /**\r\n * Gli operatori applicabili al tipo del lato sinistro: `appliesTo` del dizionario, vuoto =\r\n * qualunque tipo (§4.3). L'operatore già scritto si tiene comunque nell'elenco, altrimenti\r\n * il `select` resterebbe vuoto pur avendo un valore.\r\n */\r\n operatorsFor(condition: FlowCondition): ReturnType<FlowDictionaryStore['operatorsFor']> {\r\n const applicable = this.dictionaries.operatorsFor(this.leftDataType(condition));\r\n if (!condition.operator || applicable.some((entry) => entry.value === condition.operator)) {\r\n return applicable;\r\n }\r\n const current = this.dictionaries.operator(condition.operator);\r\n return current ? [...applicable, current] : applicable;\r\n }\r\n\r\n isUnary(condition: FlowCondition): boolean {\r\n return this.dictionaries.isUnaryOperator(condition.operator);\r\n }\r\n\r\n appliesToElements(condition: FlowCondition): boolean {\r\n return this.dictionaries.operatorAppliesToElements(condition.operator);\r\n }\r\n\r\n /** L'esito atteso di un operatore unario: assente equivale a `true` (§4.3). */\r\n unaryExpectation(condition: FlowCondition): boolean {\r\n return condition.rightValue?.booleanValue !== false;\r\n }\r\n\r\n /**\r\n * Testo che dice cosa e' stato scritto, in italiano. Serve perche' la differenza fra\r\n * `IsNull` + `true` e `IsNull` + `false` e' invisibile nel JSON e capitale a runtime.\r\n */\r\n unarySummary(condition: FlowCondition): string {\r\n const label = this.operatorLabel(condition.operator).toLowerCase();\r\n const left = condition.leftValueReference || '…';\r\n return this.unaryExpectation(condition) ? `${left} ${label}` : `${left} NON ${label}`;\r\n }\r\n\r\n operatorLabel(operator: string | undefined): string {\r\n if (!operator) {\r\n return '';\r\n }\r\n return this.dictionaries.operator(operator)?.label ?? operator;\r\n }\r\n\r\n operatorDescription(operator: string | undefined): string | null {\r\n return this.dictionaries.operator(operator)?.description ?? null;\r\n }\r\n\r\n /**\r\n * `None` e' uno stato dell'editor, non un operatore: la **bozza si salva, l'attivazione no**\r\n * (`CONDITION_INCOMPLETE`, errore). A runtime vale sempre falso (§4.3, §13.14).\r\n */\r\n isPlaceholderOperator(condition: FlowCondition): boolean {\r\n return condition.operator === 'None';\r\n }\r\n\r\n /** Quante condizioni sono da completare: si dice in testa, non solo riga per riga. */\r\n readonly incompleteCount = computed(\r\n () => this.conditions().filter((condition) => condition.operator === 'None').length,\r\n );\r\n\r\n // -------------------------------------------------------------------------\r\n // Mutazioni\r\n // -------------------------------------------------------------------------\r\n\r\n addCondition(): void {\r\n this.changed.emit((holder) => {\r\n holder.conditions ??= [];\r\n holder.conditions.push({ operator: 'EqualTo' });\r\n });\r\n }\r\n\r\n removeCondition(index: number): void {\r\n this.changed.emit((holder) => {\r\n // Riscrive `conditionLogic`: gli indici sono 1-based e scalano (§13.4).\r\n removeConditionInPlace(holder, index);\r\n });\r\n }\r\n\r\n moveCondition(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.conditions().length) {\r\n return;\r\n }\r\n this.changed.emit((holder) => moveConditionInPlace(holder, index, target));\r\n }\r\n\r\n setLogicMode(mode: 'and' | 'or' | 'custom' | 'formula'): void {\r\n this.changed.emit((holder) => {\r\n switch (mode) {\r\n case 'and':\r\n holder.conditionLogic = 'and';\r\n break;\r\n case 'or':\r\n holder.conditionLogic = 'or';\r\n break;\r\n case 'custom': {\r\n // Espressione iniziale che riproduce l'AND corrente: cambiarla e' un passo\r\n // esplicito dell'utente, non un effetto collaterale del cambio di modalita'.\r\n const count = holder.conditions?.length ?? 0;\r\n holder.conditionLogic = count\r\n ? Array.from({ length: count }, (_, index) => index + 1).join(' AND ')\r\n : '1';\r\n break;\r\n }\r\n case 'formula':\r\n holder.conditionLogic = 'Formula';\r\n holder.formula ??= '';\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setCustomLogic(logic: string): void {\r\n this.changed.emit((holder) => {\r\n holder.conditionLogic = logic;\r\n });\r\n }\r\n\r\n setFormula(formula: string): void {\r\n this.changed.emit((holder) => {\r\n holder.formula = formula;\r\n });\r\n }\r\n\r\n setLeft(index: number, reference: string | undefined): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n condition.leftValueReference = reference;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n const becomesUnary = this.dictionaries.isUnaryOperator(operator);\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (!condition) {\r\n return;\r\n }\r\n condition.operator = operator;\r\n if (becomesUnary) {\r\n // Passando a un unario, il vecchio termine di confronto non significa piu'\r\n // \"confronta con questo\" ma \"l'esito atteso e' questo\": va riscritto, non tenuto.\r\n condition.rightValue = { booleanValue: true };\r\n } else if (condition.rightValue?.booleanValue !== undefined && operator !== 'EqualTo') {\r\n condition.rightValue = undefined;\r\n }\r\n });\r\n }\r\n\r\n setRightValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n condition.rightValue = value;\r\n }\r\n });\r\n }\r\n\r\n setUnaryExpectation(index: number, expectation: boolean): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n // Esplicito in entrambi i casi: `false` significa \"non è\", e omettere il campo\r\n // significherebbe \"è\".\r\n condition.rightValue = { booleanValue: expectation };\r\n }\r\n });\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (allowLogic()) {\r\n <div class=\"fb-cond__logic\">\r\n <label class=\"fb-field__label\">Come si combinano</label>\r\n <div class=\"fb-cond__modes\" role=\"group\" aria-label=\"Logica delle condizioni\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'and'\"\r\n title=\"Tutte le condizioni devono essere vere\"\r\n (click)=\"setLogicMode('and')\"\r\n >\r\n Tutte (AND)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'or'\"\r\n title=\"Almeno una condizione deve essere vera\"\r\n (click)=\"setLogicMode('or')\"\r\n >\r\n Almeno una (OR)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'custom'\"\r\n title=\"Espressione sugli indici delle condizioni, es. 1 AND (2 OR 3)\"\r\n (click)=\"setLogicMode('custom')\"\r\n >\r\n Espressione\r\n </button>\r\n @if (allowFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'formula'\"\r\n title=\"L’esito lo determina una formula: le condizioni vengono ignorate\"\r\n (click)=\"setLogicMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Devono essere vere <strong>tutte</strong>: qui il modello non prevede una logica separata.\r\n </p>\r\n }\r\n\r\n @if (logicMode() === 'custom') {\r\n <div class=\"fb-field\">\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!customLogicError()\"\r\n [value]=\"customLogic()\"\r\n placeholder=\"1 AND (2 OR 3)\"\r\n aria-label=\"Espressione sugli indici delle condizioni\"\r\n (input)=\"setCustomLogic($any($event.target).value)\"\r\n />\r\n @if (customLogicError()) {\r\n <p class=\"fb-field__error\">{{ customLogicError() }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Gli indici sono 1-based e si riferiscono all’ordine sotto. Cancellare una condizione riscrive\r\n l’espressione automaticamente.\r\n </p>\r\n }\r\n </div>\r\n }\r\n\r\n @if (logicMode() === 'formula') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Formula</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"holder().formula || ''\"\r\n placeholder=\"AND(Esito = 'KO', Importo > 1000)\"\r\n (input)=\"setFormula($any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">\r\n Con la modalita’ Formula le condizioni sotto vengono ignorate dal motore.\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (conditionsIgnored() && conditions().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Ci sono {{ conditions().length }} condizioni ma la logica e’ «Formula»: il motore le ignora.\r\n </p>\r\n }\r\n\r\n @if (incompleteCount()) {\r\n <!-- `None` blocca l'attivazione: la bozza si salva, la versione attiva no (§13.14). -->\r\n <p class=\"fb-callout fb-callout--error\">\r\n {{ incompleteCount() === 1 ? 'Una condizione e’' : incompleteCount() + ' condizioni sono' }} da\r\n completare: la bozza si salva, l’attivazione no (CONDITION_INCOMPLETE).\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (condition of conditions(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <!-- L'indice e' 1-based perche' e' quello che l'espressione referenzia. -->\r\n <span class=\"fb-list__index\" [title]=\"'Indice ' + ($index + 1) + ' nell’espressione'\">\r\n {{ $index + 1 }}\r\n </span>\r\n @if (isPlaceholderOperator(condition)) {\r\n <span\r\n class=\"fb-cond__placeholder\"\r\n title=\"A runtime vale sempre falso, e l’attivazione la rifiuta: va completata\"\r\n >\r\n da completare\r\n </span>\r\n }\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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveCondition($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveCondition($index, 1)\"\r\n >\r\n ↓\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 la condizione\"\r\n (click)=\"removeCondition($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ appliesToElements(condition) ? 'Elemento' : 'Risorsa' }}\r\n </label>\r\n <fb-reference-picker\r\n [value]=\"condition.leftValueReference\"\r\n [elementsOnly]=\"appliesToElements(condition)\"\r\n [placeholder]=\"appliesToElements(condition) ? 'Scegli un elemento del flow' : 'Scegli una risorsa'\"\r\n (valueChange)=\"setLeft($index, $event)\"\r\n />\r\n @if (appliesToElements(condition)) {\r\n <p class=\"fb-field__hint\">\r\n Questo operatore si applica a un elemento del flow, non a una risorsa.\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operatore</label>\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-input--invalid]=\"isPlaceholderOperator(condition)\"\r\n [fbValue]=\"condition.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n <!-- Filtrati per il tipo del lato sinistro: `appliesTo` del dizionario (§4.3). -->\r\n @for (operator of operatorsFor(condition); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n @if (isPlaceholderOperator(condition)) {\r\n <p class=\"fb-field__error\">\r\n Segnaposto: a runtime vale sempre falso e l’attivazione lo rifiuta\r\n (CONDITION_INCOMPLETE). Scegli un operatore.\r\n </p>\r\n } @else if (operatorDescription(condition.operator)) {\r\n <p class=\"fb-field__hint\">{{ operatorDescription(condition.operator) }}</p>\r\n }\r\n </div>\r\n\r\n @if (isUnary(condition)) {\r\n <!--\r\n Trappola numero uno: per gli operatori unari `rightValue` non e' il termine di\r\n confronto ma l'esito atteso. Qui non c'e' un campo \"valore da confrontare\":\r\n c'e' un selettore che dice quale delle due cose si sta chiedendo.\r\n -->\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Esito atteso</label>\r\n <div class=\"fb-cond__unary\" role=\"group\" aria-label=\"Esito atteso\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"unaryExpectation(condition)\"\r\n (click)=\"setUnaryExpectation($index, true)\"\r\n >\r\n {{ operatorLabel(condition.operator) }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"!unaryExpectation(condition)\"\r\n (click)=\"setUnaryExpectation($index, false)\"\r\n >\r\n NON {{ operatorLabel(condition.operator) }}\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Questa condizione e’ vera quando: <strong>{{ unarySummary(condition) }}</strong>.\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Confronta con</label>\r\n <!--\r\n Il tipo del lato sinistro guida il secondo operando: il letterale finisce nel\r\n campo giusto e le risorse proposte sono quelle compatibili. Testo con numero e'\r\n CONDITION_TYPE_MISMATCH e blocca l'attivazione (§4.3).\r\n -->\r\n <fb-value-editor\r\n [value]=\"condition.rightValue\"\r\n label=\"Valore di confronto\"\r\n [dataType]=\"leftDataType(condition)\"\r\n (valueChange)=\"setRightValue($index, $event)\"\r\n />\r\n @if (hasTypeMismatch(condition)) {\r\n <p class=\"fb-field__error\">{{ typeMismatchMessage(condition) }}</p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna condizione.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addCondition()\">Aggiungi condizione</button>\r\n</fieldset>\r\n","/**\r\n * Editor dei filtri sui record — FRONTEND.md §4.4.\r\n *\r\n * I filtri sono una struttura **diversa** dalle condizioni: agiscono su campi di un'entita',\r\n * non su risorse, e il loro operatore e' un altro enum (`recordFilterOperators`).\r\n *\r\n * Due dettagli che il modello impone e che qui sono espliciti:\r\n *\r\n * - **`filterLogic` non esiste su tutti gli elementi che hanno `filters`.** C'e' su Get\r\n * Records, Create Records, Start e sugli eventi di un Wait; **non** c'e' su Update\r\n * Records, Delete Records e sui dynamic choice set, dove i filtri sono sempre in AND.\r\n * Inviarlo dove non esiste significa perderlo silenziosamente al primo salvataggio:\r\n * l'input `supportsLogic` decide se il controllo viene mostrato.\r\n *\r\n * - I campi proposti passano da `GET /schema/{object}/fields?usage=filterable`, così un\r\n * campo non filtrabile non arriva nemmeno alla validazione (`FIELD_NOT_FILTERABLE`).\r\n * La scrittura libera resta possibile, perche' i percorsi di relazione\r\n * (`Cliente.Citta`) non sono enumerabili — e la validazione non li verifica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription, FlowFieldUsage } from '../../model/dictionary.model';\r\nimport { FlowRecordFilter, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from './field-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n/** Il contenitore dei filtri, qualunque elemento sia. */\r\nexport interface FilterHolder {\r\n filters?: FlowRecordFilter[];\r\n filterLogic?: string;\r\n filterFormula?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-record-filter-editor',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-filter-editor.component.html',\r\n styleUrl: './record-filter-editor.component.css',\r\n})\r\nexport class RecordFilterEditorComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly holder = input.required<FilterHolder>();\r\n readonly object = input<string | undefined>(undefined);\r\n readonly title = input<string>('Filtri');\r\n /** L'uso con cui chiedere i campi: `filterable` per i filtri, `updateable` altrove. */\r\n readonly usage = input<FlowFieldUsage>('filterable');\r\n\r\n /** `false` dove il modello non ha `filterLogic`: i filtri sono sempre in AND (§4.4). */\r\n readonly supportsLogic = input(true);\r\n /** `true` dove esiste `filterFormula` come alternativa ai filtri. */\r\n readonly supportsFormula = input(false);\r\n\r\n /**\r\n * Avviso da mostrare quando la lista e' vuota. Un Delete senza filtri e' un **errore**,\r\n * un Update senza filtri e' solo un avviso — ma aggiorna tutti i record dell'entita'\r\n * (§5.7, §13.10).\r\n */\r\n readonly emptyWarning = input<string | null>(null);\r\n readonly emptyWarningSeverity = input<'warn' | 'error'>('warn');\r\n\r\n readonly changed = output<(holder: FilterHolder) => void>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n\r\n readonly filters = computed<FlowRecordFilter[]>(() => this.holder().filters ?? []);\r\n readonly operators = computed(() => this.dictionaries.recordFilterOperators());\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n const usage = this.usage();\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, usage)\r\n .then((list) => this.fields.set(list ?? []))\r\n // Catalogo non disponibile: il campo resta scrivibile a mano.\r\n .catch(() => this.fields.set([]));\r\n });\r\n }\r\n\r\n readonly logicMode = computed<'and' | 'or' | 'custom' | 'formula'>(() => {\r\n const logic = this.holder().filterLogic;\r\n if (!logic) {\r\n return 'and';\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n if (normalized === 'and') {\r\n return 'and';\r\n }\r\n if (normalized === 'or') {\r\n return 'or';\r\n }\r\n if (normalized === 'formula') {\r\n return 'formula';\r\n }\r\n return 'custom';\r\n });\r\n\r\n readonly customLogic = computed(() => {\r\n const mode = this.logicMode();\r\n return mode === 'custom' ? (this.holder().filterLogic as string) : '';\r\n });\r\n\r\n readonly showEmptyWarning = computed(() => !!this.emptyWarning() && this.filters().length === 0);\r\n\r\n addFilter(): void {\r\n this.changed.emit((holder) => {\r\n holder.filters ??= [];\r\n holder.filters.push({ operator: 'EqualTo' });\r\n });\r\n }\r\n\r\n removeFilter(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.filters?.splice(index, 1);\r\n if (holder.filters && holder.filters.length === 0) {\r\n // Lista vuota dichiarata vs assente: il backend le distingue, ma per un diff\r\n // pulito conviene omettere le liste vuote (§2).\r\n delete holder.filters;\r\n }\r\n });\r\n }\r\n\r\n setField(index: number, field: string): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (!filter) {\r\n return;\r\n }\r\n filter.operator = operator;\r\n if (operator === 'IsNull') {\r\n // `IsNull` fra i filtri sui record e' l'unico unario: `value` e' l'esito atteso.\r\n filter.value = { booleanValue: true };\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.value = value;\r\n }\r\n });\r\n }\r\n\r\n isNullOperator(filter: FlowRecordFilter): boolean {\r\n return filter.operator === 'IsNull';\r\n }\r\n\r\n nullExpectation(filter: FlowRecordFilter): boolean {\r\n return filter.value?.booleanValue !== false;\r\n }\r\n\r\n setNullExpectation(index: number, expectation: boolean): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.value = { booleanValue: expectation };\r\n }\r\n });\r\n }\r\n\r\n setLogicMode(mode: 'and' | 'or' | 'custom' | 'formula'): void {\r\n this.changed.emit((holder) => {\r\n switch (mode) {\r\n case 'and':\r\n holder.filterLogic = 'and';\r\n break;\r\n case 'or':\r\n holder.filterLogic = 'or';\r\n break;\r\n case 'custom': {\r\n const count = holder.filters?.length ?? 0;\r\n holder.filterLogic = count\r\n ? Array.from({ length: count }, (_, index) => index + 1).join(' AND ')\r\n : '1';\r\n break;\r\n }\r\n case 'formula':\r\n holder.filterLogic = 'Formula';\r\n holder.filterFormula ??= '';\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setCustomLogic(logic: string): void {\r\n this.changed.emit((holder) => {\r\n holder.filterLogic = logic;\r\n });\r\n }\r\n\r\n setFormula(formula: string): void {\r\n this.changed.emit((holder) => {\r\n holder.filterFormula = formula;\r\n });\r\n }\r\n\r\n /**\r\n * Il tipo del campo, per proporre il controllo giusto sul valore: e' il motivo per cui il\r\n * catalogo resta caricato qui, e non solo dentro il picker.\r\n */\r\n fieldDataType(filter: FlowRecordFilter): string | undefined {\r\n return this.fields().find((field) => field.name === filter.field)?.dataType;\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (!object()) {\r\n <p class=\"fb-field__hint\">Scegli prima un oggetto per poter filtrare sui suoi campi.</p>\r\n }\r\n\r\n @if (supportsLogic()) {\r\n <div class=\"fb-filter__modes\" role=\"group\" aria-label=\"Logica dei filtri\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'and'\"\r\n (click)=\"setLogicMode('and')\"\r\n >\r\n Tutti (AND)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'or'\"\r\n (click)=\"setLogicMode('or')\"\r\n >\r\n Almeno uno (OR)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'custom'\"\r\n (click)=\"setLogicMode('custom')\"\r\n >\r\n Espressione\r\n </button>\r\n @if (supportsFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'formula'\"\r\n (click)=\"setLogicMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Qui il modello non ha `filterLogic`: mostrarlo lo farebbe perdere al salvataggio. -->\r\n <p class=\"fb-field__hint\">Su questo elemento i filtri sono sempre combinati in AND.</p>\r\n }\r\n\r\n @if (supportsLogic() && logicMode() === 'custom') {\r\n <div class=\"fb-field\">\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [value]=\"customLogic()\"\r\n placeholder=\"1 AND (2 OR 3)\"\r\n aria-label=\"Espressione sugli indici dei filtri\"\r\n (input)=\"setCustomLogic($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (supportsFormula() && logicMode() === 'formula') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Formula di filtro</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"holder().filterFormula || ''\"\r\n (input)=\"setFormula($any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">Valutata dal motore di regole, in alternativa ai filtri.</p>\r\n </div>\r\n }\r\n\r\n @if (showEmptyWarning()) {\r\n <p\r\n class=\"fb-callout\"\r\n [class.fb-callout--warn]=\"emptyWarningSeverity() === 'warn'\"\r\n [class.fb-callout--error]=\"emptyWarningSeverity() === 'error'\"\r\n >\r\n {{ emptyWarning() }}\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (filter of filters(); 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 il filtro\"\r\n (click)=\"removeFilter($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo</label>\r\n <fb-field-picker\r\n [value]=\"filter.field\"\r\n [object]=\"object()\"\r\n [usage]=\"usage()\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setField($index, $event ?? '')\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operatore</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"filter.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n @for (operator of operators(); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (isNullOperator(filter)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Esito atteso</label>\r\n <div class=\"fb-filter__modes\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"nullExpectation(filter)\"\r\n (click)=\"setNullExpectation($index, true)\"\r\n >\r\n è vuoto\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"!nullExpectation(filter)\"\r\n (click)=\"setNullExpectation($index, false)\"\r\n >\r\n non è vuoto\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor\r\n [value]=\"filter.value\"\r\n [dataType]=\"fieldDataType(filter)\"\r\n label=\"Valore del filtro\"\r\n [allowFormula]=\"false\"\r\n (valueChange)=\"setValue($index, $event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun filtro.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addFilter()\">Aggiungi filtro</button>\r\n</fieldset>\r\n","/**\r\n * Editor dei parametri di input e output — FRONTEND.md §5.1, §5.8, §5.9.\r\n *\r\n * I nomi dei parametri sono quelli che il form, l'action o lo script si aspettano. Quando\r\n * il catalogo li espone (`.../parameters`) vengono proposti, e con il catalogo popolato un\r\n * nome inesistente e' un **errore** di validazione (`PARAMETER_UNKNOWN`). Con il catalogo\r\n * vuoto — che significa \"non lo so\", non \"nessuno\" — la scrittura resta libera.\r\n *\r\n * Gli output vanno in `assignToReference`, che deve essere una destinazione **scrivibile**:\r\n * il selettore chiede `POST /flows/references/writable`, così una costante o una formula\r\n * non sono nemmeno proponibili (`TARGET_NOT_WRITABLE`).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n input,\r\n output,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowInputParameter, FlowOutputParameter, FlowValue } from '../../model/flow.model';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n/** Contenitore generico: gli input hanno `value`, gli output `assignToReference`. */\r\nexport interface ParameterHolder {\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n}\r\n\r\n@Component({\r\n selector: 'fb-parameter-editor',\r\n standalone: true,\r\n imports: [ReferencePickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './parameter-editor.component.html',\r\n styleUrl: './parameter-editor.component.css',\r\n})\r\nexport class ParameterEditorComponent {\r\n readonly holder = input.required<ParameterHolder>();\r\n /** Parametri dichiarati dal catalogo; vuoto = catalogo non popolato. */\r\n readonly catalogParameters = input<FlowCatalogParameter[]>([]);\r\n readonly inputTitle = input<string>('Parametri di ingresso');\r\n readonly outputTitle = input<string>('Parametri di uscita');\r\n readonly showInputs = input(true);\r\n readonly showOutputs = input(true);\r\n /** `true` → gli output vanno all'output automatico, e i parametri sono ignorati. */\r\n readonly outputsDisabledReason = input<string | null>(null);\r\n\r\n readonly changed = output<(holder: ParameterHolder) => void>();\r\n\r\n readonly inputs = computed<FlowInputParameter[]>(() => this.holder().inputParameters ?? []);\r\n readonly outputs = computed<FlowOutputParameter[]>(() => this.holder().outputParameters ?? []);\r\n\r\n readonly hasCatalog = computed(() => this.catalogParameters().length > 0);\r\n\r\n readonly inputCatalog = computed(() =>\r\n this.catalogParameters().filter((parameter) => parameter.isOutput !== true),\r\n );\r\n readonly outputCatalog = computed(() =>\r\n this.catalogParameters().filter((parameter) => parameter.isOutput === true),\r\n );\r\n\r\n /** Parametri obbligatori dichiarati dal catalogo e non ancora presenti. */\r\n readonly missingRequired = computed<FlowCatalogParameter[]>(() => {\r\n if (!this.hasCatalog()) {\r\n return [];\r\n }\r\n const present = new Set(this.inputs().map((parameter) => parameter.name));\r\n return this.inputCatalog().filter((parameter) => parameter.isRequired && !present.has(parameter.name));\r\n });\r\n\r\n /** Parametri presenti che il catalogo non conosce: sarebbero `PARAMETER_UNKNOWN`. */\r\n unknownInput(parameter: FlowInputParameter): boolean {\r\n if (!this.hasCatalog() || !parameter.name) {\r\n return false;\r\n }\r\n return !this.inputCatalog().some((candidate) => candidate.name === parameter.name);\r\n }\r\n\r\n unknownOutput(parameter: FlowOutputParameter): boolean {\r\n if (!this.hasCatalog() || !parameter.name) {\r\n return false;\r\n }\r\n return !this.outputCatalog().some((candidate) => candidate.name === parameter.name);\r\n }\r\n\r\n describe(name: string | undefined): FlowCatalogParameter | undefined {\r\n return this.catalogParameters().find((parameter) => parameter.name === name);\r\n }\r\n\r\n addInput(name?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.inputParameters ??= [];\r\n holder.inputParameters.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n addOutput(name?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.outputParameters ??= [];\r\n holder.outputParameters.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeInput(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.inputParameters?.splice(index, 1);\r\n if (holder.inputParameters?.length === 0) {\r\n delete holder.inputParameters;\r\n }\r\n });\r\n }\r\n\r\n removeOutput(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.outputParameters?.splice(index, 1);\r\n if (holder.outputParameters?.length === 0) {\r\n delete holder.outputParameters;\r\n }\r\n });\r\n }\r\n\r\n setInputName(index: number, name: string): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.inputParameters?.[index];\r\n if (parameter) {\r\n parameter.name = name;\r\n }\r\n });\r\n }\r\n\r\n setInputValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.inputParameters?.[index];\r\n if (parameter) {\r\n parameter.value = value;\r\n }\r\n });\r\n }\r\n\r\n setOutputName(index: number, name: string): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.outputParameters?.[index];\r\n if (parameter) {\r\n parameter.name = name;\r\n }\r\n });\r\n }\r\n\r\n setOutputTarget(index: number, reference: string | undefined): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.outputParameters?.[index];\r\n if (parameter) {\r\n parameter.assignToReference = reference;\r\n }\r\n });\r\n }\r\n}\r\n","@if (showInputs()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ inputTitle() }}</legend>\r\n\r\n @if (missingRequired().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Parametri obbligatori non ancora impostati:\r\n @for (parameter of missingRequired(); track parameter.name) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"addInput(parameter.name)\">\r\n + {{ parameter.name }}\r\n </button>\r\n }\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (parameter of inputs(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n @if (hasCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"parameter.name || ''\"\r\n aria-label=\"Nome del parametro\"\r\n (change)=\"setInputName($index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (candidate of inputCatalog(); track candidate.name) {\r\n <option [value]=\"candidate.name\">\r\n {{ candidate.label || candidate.name }}{{ candidate.isRequired ? ' *' : '' }}\r\n </option>\r\n }\r\n @if (unknownInput(parameter)) {\r\n <option [value]=\"parameter.name\">{{ parameter.name }} (non nel catalogo)</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"parameter.name || ''\"\r\n placeholder=\"Nome del parametro\"\r\n aria-label=\"Nome del parametro\"\r\n (input)=\"setInputName($index, $any($event.target).value)\"\r\n />\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il parametro\"\r\n (click)=\"removeInput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n @if (unknownInput(parameter)) {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Il catalogo non dichiara questo parametro: la validazione lo segnalerebbe come errore.\r\n </p>\r\n }\r\n @if (describe(parameter.name)?.description) {\r\n <p class=\"fb-field__hint\">{{ describe(parameter.name)?.description }}</p>\r\n }\r\n\r\n <fb-value-editor\r\n [value]=\"parameter.value\"\r\n [dataType]=\"describe(parameter.name)?.dataType\"\r\n [objectType]=\"describe(parameter.name)?.objectType || undefined\"\r\n [isCollection]=\"describe(parameter.name)?.isCollection\"\r\n label=\"Valore del parametro\"\r\n (valueChange)=\"setInputValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun parametro di ingresso.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addInput()\">Aggiungi parametro</button>\r\n </fieldset>\r\n}\r\n\r\n@if (showOutputs()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ outputTitle() }}</legend>\r\n\r\n @if (outputsDisabledReason()) {\r\n <p class=\"fb-callout\">{{ outputsDisabledReason() }}</p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (parameter of outputs(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n @if (hasCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"parameter.name || ''\"\r\n aria-label=\"Nome del parametro di uscita\"\r\n (change)=\"setOutputName($index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (candidate of outputCatalog(); track candidate.name) {\r\n <option [value]=\"candidate.name\">{{ candidate.label || candidate.name }}</option>\r\n }\r\n @if (unknownOutput(parameter)) {\r\n <option [value]=\"parameter.name\">{{ parameter.name }} (non nel catalogo)</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"parameter.name || ''\"\r\n placeholder=\"Nome del parametro\"\r\n aria-label=\"Nome del parametro di uscita\"\r\n (input)=\"setOutputName($index, $any($event.target).value)\"\r\n />\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il parametro\"\r\n (click)=\"removeOutput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n @if (unknownOutput(parameter)) {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Il catalogo non dichiara questo parametro di uscita.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <!-- Solo variabili: assegnare a una costante o a una formula e' un errore. -->\r\n <fb-reference-picker\r\n [value]=\"parameter.assignToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"describe(parameter.name)?.dataType\"\r\n [isCollection]=\"describe(parameter.name)?.isCollection\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun parametro di uscita.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutput()\">Aggiungi parametro</button>\r\n </fieldset>\r\n}\r\n","/**\r\n * Editor di `inputAssignments` — FRONTEND.md §5.7.\r\n *\r\n * Campo dell'entita' → valore. I campi proposti passano da\r\n * `GET /schema/{object}/fields?usage=updateable`, perche' scrivere su un campo non\r\n * aggiornabile e' `FIELD_NOT_UPDATEABLE`.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription } from '../../model/dictionary.model';\r\nimport { FlowInputFieldAssignment, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from './field-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\n\r\nexport interface FieldAssignmentHolder {\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n}\r\n\r\n@Component({\r\n selector: 'fb-field-assignment-editor',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ValueEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './field-assignment-editor.component.html',\r\n styleUrl: './field-assignment-editor.component.css',\r\n})\r\nexport class FieldAssignmentEditorComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly holder = input.required<FieldAssignmentHolder>();\r\n readonly object = input<string | undefined>(undefined);\r\n readonly title = input<string>('Valori dei campi');\r\n readonly disabledReason = input<string | null>(null);\r\n\r\n readonly changed = output<(holder: FieldAssignmentHolder) => void>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n\r\n readonly assignments = computed<FlowInputFieldAssignment[]>(() => this.holder().inputAssignments ?? []);\r\n readonly hasCatalog = computed(() => this.fields().length > 0);\r\n\r\n /** Campi obbligatori dell'entita' non ancora valorizzati. */\r\n readonly missingRequired = computed<FlowFieldDescription[]>(() => {\r\n if (!this.hasCatalog()) {\r\n return [];\r\n }\r\n const present = new Set(this.assignments().map((assignment) => assignment.field));\r\n return this.fields().filter((field) => field.isRequired && !present.has(field.name));\r\n });\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, 'updateable')\r\n .then((list) => this.fields.set(list ?? []))\r\n .catch(() => this.fields.set([]));\r\n });\r\n }\r\n\r\n add(field?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.inputAssignments ??= [];\r\n holder.inputAssignments.push({ field: field ?? '' });\r\n });\r\n }\r\n\r\n remove(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.inputAssignments?.splice(index, 1);\r\n if (holder.inputAssignments?.length === 0) {\r\n delete holder.inputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setField(index: number, field: string): void {\r\n this.changed.emit((holder) => {\r\n const assignment = holder.inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const assignment = holder.inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.value = value;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Il tipo del campo serve all'editor di valore: e' il motivo per cui il catalogo resta\r\n * caricato anche qui, oltre che dentro il picker.\r\n */\r\n describe(name: string | undefined): FlowFieldDescription | undefined {\r\n return this.fields().find((field) => field.name === name);\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (disabledReason()) {\r\n <p class=\"fb-callout\">{{ disabledReason() }}</p>\r\n }\r\n @if (!object()) {\r\n <p class=\"fb-field__hint\">Scegli prima un oggetto per poterne valorizzare i campi.</p>\r\n }\r\n @if (missingRequired().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Campi obbligatori non valorizzati:\r\n @for (field of missingRequired(); track field.name) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"add(field.name)\">\r\n + {{ field.label || field.name }}\r\n </button>\r\n }\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (assignment of assignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-field-picker\r\n [value]=\"assignment.field\"\r\n [object]=\"object()\"\r\n usage=\"updateable\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setField($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"remove($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <fb-value-editor\r\n [value]=\"assignment.value\"\r\n [dataType]=\"describe(assignment.field)?.dataType\"\r\n [objectType]=\"describe(assignment.field)?.objectType || undefined\"\r\n label=\"Valore del campo\"\r\n (valueChange)=\"setValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun campo valorizzato.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"add()\">Aggiungi campo</button>\r\n</fieldset>\r\n","/**\r\n * Editor delle uscite di un elemento — FRONTEND.md §3.5.\r\n *\r\n * Le destinazioni arrivano da `POST /flows/connector-targets?excluding={nome del node}`:\r\n * escludendo l'elemento stesso si evita `CONNECTOR_SELF_LOOP` senza dover ricordare la\r\n * regola in dieci form diversi.\r\n *\r\n * Tre cose che questo editor dice a voce alta, perche' nel JSON non si vedono:\r\n * - un connector assente e' **legittimo**: il percorso finisce lì (Info, non errore);\r\n * - tranne dove il ramo e' strutturale, come il corpo di un Loop;\r\n * - `isGoTo` e' solo un suggerimento di disegno: la semantica di esecuzione e' identica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowOutlet } from '../../core/element-outlets';\r\nimport { FlowConnectorTarget } from '../../model/api.model';\r\nimport { FlowAnyNode } from '../../model/flow.model';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-connector-editor',\r\n standalone: true,\r\n imports: [SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './connector-editor.component.html',\r\n styleUrl: './connector-editor.component.css',\r\n})\r\nexport class ConnectorEditorComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n\r\n /** Il node di cui si editano le uscite; per lo Start passa il nome fittizio. */\r\n readonly nodeName = input.required<string>();\r\n readonly node = input.required<FlowAnyNode>();\r\n readonly outlets = input.required<FlowOutlet[]>();\r\n readonly title = input<string>('Uscite');\r\n\r\n readonly connectorChanged = output<{ outletKey: string; target?: string; isGoTo?: boolean }>();\r\n\r\n private readonly targets = signal<FlowConnectorTarget[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n const definition = this.store.document();\r\n const excluding = this.nodeName();\r\n void this.api\r\n .getConnectorTargets(definition, excluding)\r\n .then((list) => this.targets.set(list ?? []))\r\n .catch(() => {\r\n // Senza la primitiva si ripiega sui node del documento, che il client conosce.\r\n this.targets.set(\r\n this.store\r\n .nodes()\r\n .filter((reference) => reference.name !== excluding)\r\n .map((reference) => ({ name: reference.name, label: (reference.node.label as string) ?? null })),\r\n );\r\n });\r\n });\r\n }\r\n\r\n readonly targetOptions = computed(() => this.targets());\r\n\r\n currentTarget(outlet: FlowOutlet): string {\r\n return outlet.read(this.node())?.targetReference ?? '';\r\n }\r\n\r\n isGoTo(outlet: FlowOutlet): boolean {\r\n return outlet.read(this.node())?.isGoTo === true;\r\n }\r\n\r\n /** Il connector esiste ma non ha destinazione: ramo incompleto, da mostrare come tale. */\r\n isDangling(outlet: FlowOutlet): boolean {\r\n const connector = outlet.read(this.node());\r\n return !!connector && !connector.targetReference;\r\n }\r\n\r\n /** Nessun connector: il percorso finisce lì. Legittimo, tranne sui rami strutturali. */\r\n isTerminal(outlet: FlowOutlet): boolean {\r\n return !outlet.read(this.node());\r\n }\r\n\r\n hintFor(outlet: FlowOutlet): string | null {\r\n if (this.isDangling(outlet)) {\r\n return 'Ramo dichiarato senza destinazione: scegline una o rimuovi il ramo.';\r\n }\r\n if (this.isTerminal(outlet)) {\r\n return outlet.isStructural\r\n ? 'Questo ramo e’ strutturale: senza destinazione l’elemento non funziona.'\r\n : 'Nessuna destinazione: il percorso finisce qui, e l’esecuzione termina.';\r\n }\r\n return null;\r\n }\r\n\r\n setTarget(outlet: FlowOutlet, target: string): void {\r\n this.connectorChanged.emit({ outletKey: outlet.key, target: target || undefined });\r\n }\r\n\r\n setGoTo(outlet: FlowOutlet, isGoTo: boolean): void {\r\n this.connectorChanged.emit({\r\n outletKey: outlet.key,\r\n target: this.currentTarget(outlet) || undefined,\r\n isGoTo,\r\n });\r\n }\r\n\r\n clear(outlet: FlowOutlet): void {\r\n this.connectorChanged.emit({ outletKey: outlet.key, target: undefined, isGoTo: false });\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @for (outlet of outlets(); track outlet.key) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\" [class.fb-field__label--required]=\"outlet.isStructural\">\r\n {{ outlet.label }}\r\n <span class=\"fb-conn__kind\" [attr.data-kind]=\"outlet.kind\">{{ outlet.kind }}</span>\r\n </label>\r\n\r\n <div class=\"fb-field__row\">\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"currentTarget(outlet)\"\r\n [attr.aria-label]=\"'Destinazione di ' + outlet.label\"\r\n (change)=\"setTarget(outlet, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— nessuna destinazione —</option>\r\n @for (target of targetOptions(); track target.name) {\r\n <option [value]=\"target.name\">{{ target.label || target.name }}</option>\r\n }\r\n </select>\r\n @if (!isTerminal(outlet)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il ramo\"\r\n title=\"Rimuove il ramo: il percorso finira’ qui\"\r\n (click)=\"clear(outlet)\"\r\n >\r\n ×\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (currentTarget(outlet)) {\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"isGoTo(outlet)\" (change)=\"setGoTo(outlet, $any($event.target).checked)\" />\r\n Disegna come salto indietro (isGoTo)\r\n </label>\r\n }\r\n\r\n @if (hintFor(outlet)) {\r\n <p\r\n class=\"fb-field__hint\"\r\n [class.fb-field__hint--warn]=\"isDangling(outlet) || (isTerminal(outlet) && outlet.isStructural)\"\r\n >\r\n {{ hintFor(outlet) }}\r\n </p>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-field__hint\">Questo elemento non ha uscite: interrompe l’esecuzione.</p>\r\n }\r\n</fieldset>\r\n","/**\r\n * Base comune degli inspector.\r\n *\r\n * Ogni inspector riceve il nome dell'elemento e il node, e scrive nel documento attraverso\r\n * {@link FlowDocumentStore}: il node passato in input e' una vista di sola lettura sulla\r\n * copia corrente, e le mutazioni passano sempre per `patch()`, che lavora sulla copia di\r\n * lavoro dello store. Nessun inspector modifica l'oggetto che riceve.\r\n */\r\n\r\nimport { Directive, computed, inject, input } from '@angular/core';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowOutlet, outletsOf } from '../../core/element-outlets';\r\nimport { FlowAnyNode, FlowElementType } from '../../model/flow.model';\r\nimport { FlowValidationIssue } from '../../model/api.model';\r\n\r\n/**\r\n * `@Directive()` senza selettore: e' il modo in cui Angular riconosce come input quelli\r\n * dichiarati su una classe base ereditata da piu' componenti.\r\n */\r\n@Directive()\r\nexport abstract class NodeInspectorBase {\r\n protected readonly store = inject(FlowDocumentStore);\r\n protected readonly dictionaries = inject(FlowDictionaryStore);\r\n protected readonly validation = inject(FlowValidationStore);\r\n\r\n readonly name = input.required<string>();\r\n readonly node = input.required<FlowAnyNode>();\r\n\r\n /** Il tipo dell'elemento: ogni inspector sa il proprio, ma serve alle uscite. */\r\n abstract readonly elementType: FlowElementType;\r\n\r\n readonly outlets = computed<FlowOutlet[]>(() => outletsOf(this.elementType, this.node()));\r\n\r\n /** I rilievi ancorati a questo elemento (§7). */\r\n readonly issues = computed<FlowValidationIssue[]>(\r\n () => this.validation.issuesByElement().get(this.name()) ?? [],\r\n );\r\n\r\n /** I rilievi su un campo preciso, per evidenziarlo nel form. */\r\n issuesAt(pathPrefix: string): FlowValidationIssue[] {\r\n return this.validation.issuesAt(this.name(), pathPrefix);\r\n }\r\n\r\n hasIssueCode(code: string): boolean {\r\n return this.issues().some((issue) => issue.code === code);\r\n }\r\n\r\n /** Applica una modifica al node. */\r\n protected patch(mutate: (node: FlowAnyNode) => void): void {\r\n this.store.updateNode(this.name(), mutate);\r\n }\r\n\r\n /** Scorciatoia per i campi semplici: valore vuoto → chiave omessa (§2). */\r\n protected setField(field: string, value: unknown): void {\r\n this.patch((node) => {\r\n if (value === undefined || value === null || value === '') {\r\n delete node[field];\r\n } else {\r\n node[field] = value;\r\n }\r\n });\r\n }\r\n\r\n /** Scrive la destinazione di un'uscita. */\r\n onConnectorChanged(event: { outletKey: string; target?: string; isGoTo?: boolean }): void {\r\n this.store.setConnector(this.name(), event.outletKey, event.target, event.isGoTo);\r\n }\r\n}\r\n","/**\r\n * Action — FRONTEND.md §5.8.\r\n *\r\n * `actionType` + `actionName` identificano l'action, e i parametri arrivano dal catalogo:\r\n * con il catalogo popolato, un nome inesistente o un parametro inesistente sono **errori**.\r\n *\r\n * L'Action ha **tre uscite**: `connector`, `faultConnector`, `timeoutConnector`. Il ramo di\r\n * timeout esiste solo se `timeoutPathUsage: 'EnableTimeoutPath'`, e dichiararne uno senza\r\n * l'altro e' un avviso: qui i due controlli sono legati, come chiede la specifica.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowActionCall, FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-action-call-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './action-call-inspector.component.html',\r\n})\r\nexport class ActionCallInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'ActionCall';\r\n\r\n readonly action = computed<FlowActionCall>(() => this.node() as FlowActionCall);\r\n readonly transactionModels = computed(() => this.dictionaries.transactionModels());\r\n readonly offsetUnits = computed(() => this.dictionaries.offsetUnits());\r\n\r\n private readonly actionTypes = signal<FlowCatalogEntry[]>([]);\r\n private readonly actions = signal<FlowCatalogEntry[]>([]);\r\n private readonly parameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listActionTypes()\r\n .then((list) => this.actionTypes.set(list ?? []))\r\n .catch(() => this.actionTypes.set([]));\r\n\r\n effect(() => {\r\n const actionType = this.action().actionType;\r\n if (!actionType) {\r\n this.actions.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listActions(actionType)\r\n .then((list) => this.actions.set(list ?? []))\r\n .catch(() => this.actions.set([]));\r\n });\r\n\r\n effect(() => {\r\n const action = this.action();\r\n if (!action.actionType || !action.actionName) {\r\n this.parameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listActionParameters(action.actionType, action.actionName)\r\n .then((list) => this.parameters.set(list ?? []))\r\n .catch(() => this.parameters.set([]));\r\n });\r\n }\r\n\r\n readonly actionTypeOptions = computed(() => this.actionTypes());\r\n readonly actionOptions = computed(() => this.actions());\r\n readonly parameterCatalog = computed(() => this.parameters());\r\n readonly hasTypeCatalog = computed(() => this.actionTypes().length > 0);\r\n readonly hasActionCatalog = computed(() => this.actions().length > 0);\r\n\r\n /** Con il catalogo popolato, un'action inesistente e' un errore (`ACTION_UNKNOWN`). */\r\n readonly isUnknownAction = computed(() => {\r\n const name = this.action().actionName;\r\n if (!name || !this.hasActionCatalog()) {\r\n return false;\r\n }\r\n return !this.actions().some((entry) => entry.name === name);\r\n });\r\n\r\n readonly timeoutEnabled = computed(() => this.action().timeoutPathUsage === 'EnableTimeoutPath');\r\n\r\n /** Un ramo di timeout senza il flag, o il flag senza il ramo: avviso da segnalare (§5.8). */\r\n readonly timeoutMismatch = computed(() => {\r\n const action = this.action();\r\n const hasBranch = !!action.timeoutConnector?.targetReference;\r\n return hasBranch !== this.timeoutEnabled();\r\n });\r\n\r\n readonly storeOutputAutomatically = computed(() => this.action().storeOutputAutomatically === true);\r\n\r\n setActionType(value: string): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (action.actionType === value) {\r\n return;\r\n }\r\n action.actionType = value || undefined;\r\n // Cambiare tipo cambia l'insieme delle action e dei loro parametri.\r\n delete action.actionName;\r\n delete action.inputParameters;\r\n delete action.outputParameters;\r\n });\r\n }\r\n\r\n setActionName(value: string): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (action.actionName === value) {\r\n return;\r\n }\r\n action.actionName = value || undefined;\r\n delete action.inputParameters;\r\n delete action.outputParameters;\r\n });\r\n }\r\n\r\n setTransactionModel(value: string): void {\r\n this.setField('flowTransactionModel', value);\r\n }\r\n\r\n setWaitUntilCompleted(value: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (value) {\r\n action.isWaitUntilCompleted = true;\r\n } else {\r\n delete action.isWaitUntilCompleted;\r\n }\r\n });\r\n }\r\n\r\n setOffset(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('offset', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n setOffsetUnit(value: string): void {\r\n this.setField('offsetUnit', value);\r\n }\r\n\r\n /** Il flag e il ramo si accendono insieme: sono la stessa decisione. */\r\n setTimeoutEnabled(enabled: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (enabled) {\r\n action.timeoutPathUsage = 'EnableTimeoutPath';\r\n } else {\r\n delete action.timeoutPathUsage;\r\n // Spegnere il ramo di timeout rimuove anche la destinazione: lasciarla darebbe un\r\n // connector che il motore non percorrera' mai.\r\n delete action.timeoutConnector;\r\n }\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (value) {\r\n action.storeOutputAutomatically = true;\r\n delete action.outputParameters;\r\n } else {\r\n delete action.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo di action</label>\r\n @if (hasTypeCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action().actionType || ''\"\r\n (change)=\"setActionType($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (type of actionTypeOptions(); track type.name) {\r\n <option [value]=\"type.name\">{{ type.label || type.name }}</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"action().actionType || ''\"\r\n (input)=\"setActionType($any($event.target).value)\"\r\n />\r\n }\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Action</label>\r\n @if (hasActionCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-select--invalid]=\"isUnknownAction()\"\r\n [fbValue]=\"action().actionName || ''\"\r\n (change)=\"setActionName($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of actionOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n @if (isUnknownAction()) {\r\n <option [value]=\"action().actionName\">{{ action().actionName }} (non nel catalogo)</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"action().actionName || ''\"\r\n (input)=\"setActionName($any($event.target).value)\"\r\n />\r\n }\r\n @if (isUnknownAction()) {\r\n <p class=\"fb-field__error\">\r\n Questa action non esiste nel catalogo del tipo scelto: la validazione la segnala come errore.\r\n </p>\r\n }\r\n</div>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Esecuzione</legend>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Modello transazionale</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action().flowTransactionModel || ''\"\r\n (change)=\"setTransactionModel($any($event.target).value)\"\r\n >\r\n <option value=\"\">— predefinito —</option>\r\n @for (model of transactionModels(); track model.value) {\r\n <option [value]=\"model.value\">{{ model.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"action().isWaitUntilCompleted === true\"\r\n (change)=\"setWaitUntilCompleted($any($event.target).checked)\"\r\n />\r\n Attendi il completamento\r\n </label>\r\n\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Attesa</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"0\"\r\n [value]=\"action().offset ?? ''\"\r\n (input)=\"setOffset($any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Unita’</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action().offsetUnit || ''\"\r\n (change)=\"setOffsetUnit($any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (unit of offsetUnits(); track unit.value) {\r\n <option [value]=\"unit.value\">{{ unit.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <p class=\"fb-field__hint\">Definiscono l’attesa di un’action asincrona.</p>\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Ramo di timeout</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"timeoutEnabled()\"\r\n (change)=\"setTimeoutEnabled($any($event.target).checked)\"\r\n />\r\n Abilita il ramo di timeout\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n Il ramo esiste solo con questo flag: qui il flag e la destinazione sono legati, così non possono\r\n contraddirsi.\r\n </p>\r\n @if (timeoutMismatch()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Il flag e il ramo di timeout non sono coerenti fra loro.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Output</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (storeOutputAutomatically()) {\r\n <p class=\"fb-field__hint\">\r\n Gli output dell’action si referenziano col nome dell’elemento: <code>{{ name() }}.NomeOutput</code>.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"action()\"\r\n [catalogParameters]=\"parameterCatalog()\"\r\n [showOutputs]=\"!storeOutputAutomatically()\"\r\n [outputsDisabledReason]=\"\r\n storeOutputAutomatically() ? 'Con l’output automatico i parametri di uscita non servono.' : null\r\n \"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Le tre uscite\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Assignment — FRONTEND.md §5.2.\r\n *\r\n * Tre cose che il modello impone e che questo form rende visibili:\r\n *\r\n * 1. **Le operazioni sono eseguite nell'ordine dichiarato**, quindi devono essere\r\n * riordinabili: un'interfaccia che le presenta come un insieme nasconde la semantica.\r\n * 2. **Cosa puo' stare in `assignToReference`**: una variabile, un campo di una variabile\r\n * record, un campo di `$Record` e, fra le globali, `$Flow.CurrentStage`,\r\n * `$Flow.ActiveStages` e quelle che il sistema ospite dichiara scrivibili — le propone\r\n * già `POST /flows/references/writable`. Tutto il resto e' di sola lettura.\r\n * 3. Gli operatori marcati `expectsCollection` hanno senso **solo** su destinazioni\r\n * collection: su una variabile singola non falliscono, non fanno nulla.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowAssignment, FlowAssignmentItem, FlowElementType, FlowValue } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-assignment-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ReferencePickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './assignment-inspector.component.html',\r\n})\r\nexport class AssignmentInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Assignment';\r\n\r\n readonly assignment = computed<FlowAssignment>(() => this.node() as FlowAssignment);\r\n readonly items = computed<FlowAssignmentItem[]>(() => this.assignment().assignmentItems ?? []);\r\n readonly operators = computed(() => this.dictionaries.assignmentOperators());\r\n\r\n operatorLabel(value: string | undefined): string {\r\n if (!value) {\r\n return '';\r\n }\r\n return this.operators().find((entry) => entry.value === value)?.label ?? value;\r\n }\r\n\r\n operatorDescription(value: string | undefined): string | null {\r\n return this.operators().find((entry) => entry.value === value)?.description ?? null;\r\n }\r\n\r\n expectsCollection(item: FlowAssignmentItem): boolean {\r\n return this.dictionaries.assignmentExpectsCollection(item.operator);\r\n }\r\n\r\n /**\r\n * `Add` cambia significato col tipo della destinazione: numero → somma, data → giorni,\r\n * testo → concatena, collection → accoda. Vale la pena dirlo accanto al campo.\r\n */\r\n addSemanticsHint(item: FlowAssignmentItem): string | null {\r\n if (item.operator !== 'Add') {\r\n return null;\r\n }\r\n return 'Su un numero somma, su una data aggiunge giorni, su un testo concatena, su una collection accoda.';\r\n }\r\n\r\n addItem(): void {\r\n this.patch((node) => {\r\n const assignment = node as FlowAssignment;\r\n assignment.assignmentItems ??= [];\r\n assignment.assignmentItems.push({ operator: 'Assign' });\r\n });\r\n }\r\n\r\n removeItem(index: number): void {\r\n this.patch((node) => {\r\n const assignment = node as FlowAssignment;\r\n assignment.assignmentItems?.splice(index, 1);\r\n if (assignment.assignmentItems?.length === 0) {\r\n delete assignment.assignmentItems;\r\n }\r\n });\r\n }\r\n\r\n /** L'ordine e' semantico: spostare un'operazione cambia il risultato. */\r\n moveItem(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.items().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const items = (node as FlowAssignment).assignmentItems;\r\n if (!items) {\r\n return;\r\n }\r\n const [moved] = items.splice(index, 1);\r\n items.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.assignToReference = reference;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.operator = operator;\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.value = value;\r\n }\r\n });\r\n }\r\n\r\n /** Gli operatori di rimozione non prendono un valore da assegnare. */\r\n needsValue(item: FlowAssignmentItem): boolean {\r\n const operator = item.operator ?? '';\r\n return !operator.startsWith('Remove') || operator === 'RemovePosition' || operator === 'RemoveUncommon';\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Operazioni</legend>\r\n <p class=\"fb-section__note\">\r\n Le operazioni sono eseguite <strong>nell’ordine in cui compaiono</strong>: spostarne una cambia il\r\n risultato.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n @for (item of items(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveItem($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveItem($index, 1)\"\r\n >\r\n ↓\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 l’operazione\"\r\n (click)=\"removeItem($index)\"\r\n >\r\n ×\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\">Destinazione</label>\r\n <!--\r\n Solo destinazioni scrivibili: una costante o una formula produrrebbero\r\n TARGET_NOT_WRITABLE. Le globali assegnabili — `$Flow.CurrentStage`,\r\n `$Flow.ActiveStages` e quelle dichiarate scrivibili dall'host — arrivano già\r\n dalla primitiva, non si aggiungono qui.\r\n -->\r\n <fb-reference-picker\r\n [value]=\"item.assignToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setTarget($index, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Puoi scrivere anche un campo di un record: <code>Cliente.Email</code>, <code>$Record.Stato</code>.\r\n </p>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"item.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n @for (operator of operators(); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n @if (operatorDescription(item.operator)) {\r\n <p class=\"fb-field__hint\">{{ operatorDescription(item.operator) }}</p>\r\n }\r\n @if (addSemanticsHint(item)) {\r\n <p class=\"fb-field__hint\">{{ addSemanticsHint(item) }}</p>\r\n }\r\n @if (expectsCollection(item)) {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Questa operazione ha senso solo su una destinazione collection: su una variabile singola non\r\n fallisce, semplicemente non fa nulla.\r\n </p>\r\n }\r\n </div>\r\n\r\n @if (needsValue(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor [value]=\"item.value\" label=\"Valore\" (valueChange)=\"setValue($index, $event)\" />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Nessuna operazione: un Assignment senza operazioni non fa nulla (ASSIGNMENT_WITHOUT_ITEMS).\r\n </p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addItem()\">Aggiungi operazione</button>\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Collection Processor — FRONTEND.md §5.5 e trappola §13.2.\r\n *\r\n * Un solo tipo di node con un discriminatore: `collectionProcessorType` vale `Sort` o\r\n * `Filter`, e i campi rilevanti cambiano.\r\n *\r\n * La trappola: **`assignNextValueToReference` non e' la destinazione del risultato.** È la\r\n * variabile che espone alle condizioni l'elemento in esame, come nel Loop. Il risultato e'\r\n * l'output automatico dell'elemento, cioe' il suo nome. Confonderle e' un errore classico,\r\n * e l'unico rimedio e' etichettare quel campo per quello che e': \"elemento in esame\".\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport {\r\n FlowCollectionProcessor,\r\n FlowConditionHolder,\r\n FlowElementType,\r\n FlowSortOption,\r\n} from '../../model/flow.model';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-collection-processor-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent, ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './collection-processor-inspector.component.html',\r\n})\r\nexport class CollectionProcessorInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'CollectionProcessor';\r\n\r\n readonly processor = computed<FlowCollectionProcessor>(() => this.node() as FlowCollectionProcessor);\r\n readonly kinds = computed(() => this.dictionaries.collectionProcessorTypes());\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n readonly isSort = computed(() => this.processor().collectionProcessorType === 'Sort');\r\n readonly isFilter = computed(() => this.processor().collectionProcessorType === 'Filter');\r\n readonly hasKind = computed(() => !!this.processor().collectionProcessorType);\r\n\r\n readonly sortOptions = computed<FlowSortOption[]>(() => this.processor().sortOptions ?? []);\r\n\r\n /** Il tipo degli elementi: serve alla variabile dell'elemento in esame. */\r\n readonly elementDataType = computed(() => {\r\n const reference = this.processor().collectionReference;\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.dataType;\r\n });\r\n\r\n readonly elementObjectType = computed(() => {\r\n const reference = this.processor().collectionReference;\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.objectType;\r\n });\r\n\r\n setKind(kind: string): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.collectionProcessorType = kind;\r\n // Cambiare tipo lascia campi che il nuovo tipo non usa: si rimuovono, perche'\r\n // un `Sort` con `conditions` non e' un documento che qualcuno voglia salvare.\r\n if (kind === 'Sort') {\r\n delete processor.conditions;\r\n delete processor.conditionLogic;\r\n delete processor.formula;\r\n delete processor.assignNextValueToReference;\r\n } else if (kind === 'Filter') {\r\n delete processor.sortOptions;\r\n }\r\n });\r\n }\r\n\r\n setCollection(reference: string | undefined): void {\r\n this.setField('collectionReference', reference);\r\n }\r\n\r\n setCurrentElementVariable(reference: string | undefined): void {\r\n this.setField('assignNextValueToReference', reference);\r\n }\r\n\r\n setLimit(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('limit', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n addSortOption(): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.sortOptions ??= [];\r\n processor.sortOptions.push({ sortOrder: 'Asc' });\r\n });\r\n }\r\n\r\n removeSortOption(index: number): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.sortOptions?.splice(index, 1);\r\n if (processor.sortOptions?.length === 0) {\r\n delete processor.sortOptions;\r\n }\r\n });\r\n }\r\n\r\n moveSortOption(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.sortOptions().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const options = (node as FlowCollectionProcessor).sortOptions;\r\n if (!options) {\r\n return;\r\n }\r\n const [moved] = options.splice(index, 1);\r\n options.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setSortField(index: number, field: string): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.sortField = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setSortOrder(index: number, order: string): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.sortOrder = order;\r\n }\r\n });\r\n }\r\n\r\n setEmptyFirst(index: number, value: boolean): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.doesPutEmptyStringAndNullFirst = value;\r\n }\r\n });\r\n }\r\n\r\n onConditionsChanged(mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => mutate(node as FlowConditionHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Cosa fa</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"processor().collectionProcessorType || ''\"\r\n (change)=\"setKind($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (kind of kinds(); track kind.value) {\r\n <option [value]=\"kind.value\">{{ kind.label }}</option>\r\n }\r\n </select>\r\n @if (!hasKind()) {\r\n <p class=\"fb-field__error\">Senza questo valore l’elemento non e’ eseguibile (PROCESSOR_TYPE_MISSING).</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\">Collection di partenza</label>\r\n <fb-reference-picker\r\n [value]=\"processor().collectionReference\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setCollection($event)\"\r\n />\r\n</div>\r\n\r\n<p class=\"fb-callout\">\r\n Il risultato non si assegna a una variabile: e’ l’<strong>output automatico</strong> dell’elemento, e si\r\n referenzia col suo nome — <code>{{ name() }}</code>.\r\n</p>\r\n\r\n@if (isSort()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Ordinamento</legend>\r\n <div class=\"fb-list\">\r\n @for (option of sortOptions(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveSortOption($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveSortOption($index, 1)\"\r\n >\r\n ↓\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\"\r\n (click)=\"removeSortOption($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"option.sortField || ''\"\r\n placeholder=\"Nome del campo degli elementi\"\r\n (input)=\"setSortField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"option.sortOrder || ''\"\r\n (change)=\"setSortOrder($index, $any($event.target).value)\"\r\n >\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"option.doesPutEmptyStringAndNullFirst === true\"\r\n (change)=\"setEmptyFirst($index, $any($event.target).checked)\"\r\n />\r\n Metti prima i valori vuoti e nulli\r\n </label>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Un Sort senza criteri di ordinamento e’ un errore (SORT_OPTIONS_MISSING).</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addSortOption()\">Aggiungi criterio</button>\r\n </fieldset>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo di elementi</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"processor().limit ?? ''\"\r\n (input)=\"setLimit($any($event.target).value)\"\r\n />\r\n </div>\r\n}\r\n\r\n@if (isFilter()) {\r\n <div class=\"fb-field\">\r\n <!--\r\n Trappola: questo NON e' dove finisce il risultato. È la variabile che espone alle\r\n condizioni l'elemento che si sta esaminando, esattamente come nel Loop.\r\n -->\r\n <label class=\"fb-field__label fb-field__label--required\">Elemento in esame</label>\r\n <fb-reference-picker\r\n [value]=\"processor().assignNextValueToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"elementDataType()\"\r\n [objectType]=\"elementObjectType()\"\r\n [isCollection]=\"false\"\r\n placeholder=\"Variabile che espone l’elemento alle condizioni\"\r\n (valueChange)=\"setCurrentElementVariable($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Questa variabile serve <strong>a scrivere le condizioni</strong> qui sotto: non e’ la destinazione del\r\n risultato.\r\n </p>\r\n </div>\r\n\r\n <fb-condition-editor\r\n [holder]=\"processor()\"\r\n title=\"Tieni gli elementi per cui\"\r\n (changed)=\"onConditionsChanged($event)\"\r\n />\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Custom Error — FRONTEND.md §5.11.\r\n *\r\n * Il Custom Error **interrompe** l'esecuzione e restituisce i messaggi al chiamante: sono il\r\n * suo prodotto principale, e almeno uno e' obbligatorio (`CUSTOM_ERROR_WITHOUT_MESSAGES`).\r\n * Non ha uscite: per questo il form non mostra nessun connector.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCustomError, FlowCustomErrorMessage, FlowElementType } from '../../model/flow.model';\r\n\r\n@Component({\r\n selector: 'fb-custom-error-inspector',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './custom-error-inspector.component.html',\r\n})\r\nexport class CustomErrorInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'CustomError';\r\n\r\n readonly customError = computed<FlowCustomError>(() => this.node() as FlowCustomError);\r\n readonly messages = computed<FlowCustomErrorMessage[]>(() => this.customError().customErrorMessages ?? []);\r\n\r\n addMessage(): void {\r\n this.patch((node) => {\r\n const customError = node as FlowCustomError;\r\n customError.customErrorMessages ??= [];\r\n customError.customErrorMessages.push({ errorMessage: '' });\r\n });\r\n }\r\n\r\n removeMessage(index: number): void {\r\n this.patch((node) => {\r\n const customError = node as FlowCustomError;\r\n customError.customErrorMessages?.splice(index, 1);\r\n if (customError.customErrorMessages?.length === 0) {\r\n delete customError.customErrorMessages;\r\n }\r\n });\r\n }\r\n\r\n setMessage(index: number, message: string): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (entry) {\r\n entry.errorMessage = message;\r\n }\r\n });\r\n }\r\n\r\n setIsFieldError(index: number, value: boolean): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (!entry) {\r\n return;\r\n }\r\n if (value) {\r\n entry.isFieldError = true;\r\n } else {\r\n delete entry.isFieldError;\r\n // Senza `isFieldError` il campo indicato non ha significato.\r\n delete entry.fieldSelection;\r\n }\r\n });\r\n }\r\n\r\n setFieldSelection(index: number, field: string): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (entry) {\r\n entry.fieldSelection = field || undefined;\r\n }\r\n });\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Questo elemento <strong>interrompe</strong> l’esecuzione e restituisce i messaggi al chiamante. Non ha\r\n uscite: quello che c’e’ dopo non verra’ eseguito.\r\n</p>\r\n\r\n<div class=\"fb-list\">\r\n @for (message of messages(); 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 il messaggio\"\r\n (click)=\"removeMessage($index)\"\r\n >\r\n ×\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\">Messaggio</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"message.errorMessage || ''\"\r\n placeholder=\"L’importo supera il limite consentito.\"\r\n (input)=\"setMessage($index, $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"message.isFieldError === true\"\r\n (change)=\"setIsFieldError($index, $any($event.target).checked)\"\r\n />\r\n Mostra accanto a un campo\r\n </label>\r\n\r\n @if (message.isFieldError) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"message.fieldSelection || ''\"\r\n placeholder=\"Importo\"\r\n (input)=\"setFieldSelection($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Almeno un messaggio e’ obbligatorio: sono il prodotto di questo elemento\r\n (CUSTOM_ERROR_WITHOUT_MESSAGES).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addMessage()\">Aggiungi messaggio</button>\r\n","/**\r\n * Decision — FRONTEND.md §5.3 e trappola §13.7.\r\n *\r\n * **Le regole sono valutate in ordine e ci si ferma alla prima vera.** L'ordine e' quindi\r\n * semantico, e questo form lo rende evidente: le regole sono numerate, riordinabili, e il\r\n * testo dice cosa accade quando nessuna e' vera. Un'interfaccia che le presenta come un\r\n * insieme non ordinato nasconde una parte del significato del flow.\r\n *\r\n * `label` di una regola e' l'etichetta del ramo sul canvas: senza, l'arco resta senza nome.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowConditionHolder, FlowDecision, FlowDecisionRule, FlowElementType } from '../../model/flow.model';\r\nimport { checkFlowName, slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-decision-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './decision-inspector.component.html',\r\n})\r\nexport class DecisionInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Decision';\r\n\r\n readonly decision = computed<FlowDecision>(() => this.node() as FlowDecision);\r\n readonly rules = computed<FlowDecisionRule[]>(() => this.decision().rules ?? []);\r\n\r\n /** Se nessuna regola e' vera si prende il ramo di default; se manca, l'esecuzione finisce. */\r\n readonly defaultLabel = computed(() => this.decision().defaultConnectorLabel ?? '');\r\n readonly hasDefaultTarget = computed(() => !!this.decision().defaultConnector?.targetReference);\r\n\r\n /** I nomi delle regole vivono nello spazio dei nomi delle regole, non del flow. */\r\n ruleNameError(index: number): string | null {\r\n const rules = this.rules();\r\n const rule = rules[index];\r\n if (!rule?.name) {\r\n return 'Il nome della regola e’ obbligatorio.';\r\n }\r\n const others = rules.filter((_, position) => position !== index).map((candidate) => candidate.name ?? '');\r\n const check = checkFlowName(rule.name, others);\r\n return check.isValid ? null : (check.message ?? 'Nome non valido.');\r\n }\r\n\r\n addRule(): void {\r\n this.patch((node) => {\r\n const decision = node as FlowDecision;\r\n decision.rules ??= [];\r\n const existing = decision.rules.map((rule) => rule.name ?? '');\r\n const name = uniqueFlowName('Regola', existing);\r\n decision.rules.push({\r\n name,\r\n label: `Regola ${decision.rules.length + 1}`,\r\n conditionLogic: 'and',\r\n conditions: [{ operator: 'EqualTo' }],\r\n });\r\n });\r\n }\r\n\r\n removeRule(index: number): void {\r\n this.patch((node) => {\r\n const decision = node as FlowDecision;\r\n decision.rules?.splice(index, 1);\r\n if (decision.rules?.length === 0) {\r\n delete decision.rules;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Sposta una regola. L'ordine e' l'ordine di valutazione: la prima vera vince, quindi\r\n * spostare una regola piu' in alto puo' cambiare quale ramo viene preso.\r\n */\r\n moveRule(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.rules().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const rules = (node as FlowDecision).rules;\r\n if (!rules) {\r\n return;\r\n }\r\n const [moved] = rules.splice(index, 1);\r\n rules.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setRuleLabel(index: number, label: string): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (!rule) {\r\n return;\r\n }\r\n rule.label = label || undefined;\r\n // Il nome tecnico si genera dalla label solo se non e' ancora stato personalizzato.\r\n if (!rule.name && label) {\r\n rule.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setRuleName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (rule) {\r\n rule.name = name;\r\n }\r\n });\r\n }\r\n\r\n onRuleConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (rule) {\r\n mutate(rule);\r\n }\r\n });\r\n }\r\n\r\n setDefaultLabel(label: string): void {\r\n this.setField('defaultConnectorLabel', label);\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Le regole sono valutate <strong>dall’alto verso il basso</strong> e si ferma alla prima vera. L’ordine e’\r\n parte del significato del flow: usa le frecce per cambiarlo.\r\n</p>\r\n\r\n<div class=\"fb-list\">\r\n @for (rule of rules(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__index\" [title]=\"'Valutata per ' + ($index + 1) + 'ª'\">{{ $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=\"Valuta prima\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveRule($index, -1)\"\r\n >\r\n ↑\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=\"Valuta dopo\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveRule($index, 1)\"\r\n >\r\n ↓\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 la regola\"\r\n (click)=\"removeRule($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"rule.label || ''\"\r\n placeholder=\"Approvato\"\r\n (input)=\"setRuleLabel($index, $any($event.target).value)\"\r\n />\r\n @if (!rule.label) {\r\n <p class=\"fb-field__hint\">Senza etichetta l’arco resta senza nome sul canvas.</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\">Nome tecnico</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!ruleNameError($index)\"\r\n [value]=\"rule.name || ''\"\r\n (input)=\"setRuleName($index, $any($event.target).value)\"\r\n />\r\n @if (ruleNameError($index)) {\r\n <p class=\"fb-field__error\">{{ ruleNameError($index) }}</p>\r\n }\r\n </div>\r\n\r\n <fb-condition-editor\r\n [holder]=\"rule\"\r\n title=\"Quando prendere questo ramo\"\r\n [issuePath]=\"'rules[' + (rule.name || $index) + ']'\"\r\n (changed)=\"onRuleConditionsChanged($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Nessuna regola: una Decision senza regole prende sempre il ramo di default\r\n (DECISION_WITHOUT_RULES).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addRule()\">Aggiungi regola</button>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Se nessuna regola e’ vera</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo di default</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"defaultLabel()\"\r\n placeholder=\"Rifiutato\"\r\n (input)=\"setDefaultLabel($any($event.target).value)\"\r\n />\r\n </div>\r\n @if (!hasDefaultTarget()) {\r\n <p class=\"fb-field__hint\">\r\n Nessuna destinazione di default: se nessuna regola e’ vera l’esecuzione finisce qui.\r\n </p>\r\n }\r\n</fieldset>\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","/**\r\n * Loop — FRONTEND.md §5.4.\r\n *\r\n * - `collectionReference` deve puntare a una **collection**: il selettore filtra su\r\n * `isCollection`, così una variabile singola non e' nemmeno proponibile.\r\n * - `assignNextValueToReference` e' la variabile che riceve l'elemento corrente: senza,\r\n * il corpo del ciclo non ha modo di leggerlo.\r\n * - il corpo deve **richiudersi sul Loop** perche' il ciclo prosegua. Nel disegno e' l'arco\r\n * di ritorno, tipicamente marcato `isGoTo`: il form lo verifica e lo dice.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType, FlowLoop } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-loop-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './loop-inspector.component.html',\r\n})\r\nexport class LoopInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Loop';\r\n\r\n readonly loop = computed<FlowLoop>(() => this.node() as FlowLoop);\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n /** Il tipo degli elementi della collection: guida il tipo della variabile del ciclo. */\r\n readonly collectionType = computed(() => {\r\n const reference = this.loop().collectionReference;\r\n if (!reference) {\r\n return undefined;\r\n }\r\n const variable = this.store.document().variables?.find((candidate) => candidate.name === reference);\r\n return variable?.dataType;\r\n });\r\n\r\n readonly collectionObjectType = computed(() => {\r\n const reference = this.loop().collectionReference;\r\n if (!reference) {\r\n return undefined;\r\n }\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.objectType;\r\n });\r\n\r\n /**\r\n * Verifica che il corpo si richiuda sul Loop. Il cursore si azzera all'uscita, quindi un\r\n * corpo che non torna indietro esegue una sola iterazione: e' un errore logico che la\r\n * validazione non puo' distinguere da una scelta.\r\n */\r\n readonly bodyReturnsToLoop = computed(() => {\r\n const bodyStart = this.loop().nextValueConnector?.targetReference;\r\n if (!bodyStart) {\r\n return false;\r\n }\r\n const edges = this.store.edges();\r\n const visited = new Set<string>();\r\n const queue = [bodyStart];\r\n while (queue.length) {\r\n const current = queue.shift() as string;\r\n if (current === this.name()) {\r\n return true;\r\n }\r\n if (visited.has(current)) {\r\n continue;\r\n }\r\n visited.add(current);\r\n for (const edge of edges) {\r\n if (edge.from === current && edge.to) {\r\n queue.push(edge.to);\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n\r\n readonly hasBody = computed(() => !!this.loop().nextValueConnector?.targetReference);\r\n\r\n setCollection(reference: string | undefined): void {\r\n this.setField('collectionReference', reference);\r\n }\r\n\r\n setCurrentValueVariable(reference: string | undefined): void {\r\n this.setField('assignNextValueToReference', reference);\r\n }\r\n\r\n setIterationOrder(order: string): void {\r\n this.setField('iterationOrder', order);\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Collection da iterare</label>\r\n <!-- Solo collection: iterare una variabile singola e' un errore (LOOP_COLLECTION_MISSING). -->\r\n <fb-reference-picker\r\n [value]=\"loop().collectionReference\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setCollection($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Anche l’output automatico di un Get Records senza «solo il primo record» e’ iterabile.\r\n </p>\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Elemento corrente</label>\r\n <fb-reference-picker\r\n [value]=\"loop().assignNextValueToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"collectionType()\"\r\n [objectType]=\"collectionObjectType()\"\r\n [isCollection]=\"false\"\r\n placeholder=\"Variabile che riceve l’elemento\"\r\n (valueChange)=\"setCurrentValueVariable($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Deve essere una variabile <strong>singola</strong> dello stesso tipo degli elementi: senza, il corpo del\r\n ciclo non ha modo di leggere l’elemento corrente.\r\n </p>\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordine di iterazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"loop().iterationOrder || ''\"\r\n (change)=\"setIterationOrder($any($event.target).value)\"\r\n >\r\n <option value=\"\">— predefinito —</option>\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n</div>\r\n\r\n@if (hasBody() && !bodyReturnsToLoop()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Il corpo del ciclo non torna sul Loop: nessun percorso dal ramo «per ogni valore» rientra qui, quindi\r\n verrebbe eseguita una sola iterazione. Collega l’ultimo elemento del corpo di nuovo al Loop, marcando\r\n l’arco come salto indietro.\r\n </p>\r\n}\r\n@if (!hasBody()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Il ramo «per ogni valore» non ha destinazione: il ciclo non ha corpo.\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 del ciclo\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n\r\n<p class=\"fb-field__hint\">\r\n Il cursore si azzera all’uscita: rientrare nello stesso Loop ricomincia da capo.\r\n</p>\r\n","/**\r\n * Orchestrated Stage — FRONTEND.md §5.13.\r\n *\r\n * Un gruppo di step, alcuni affidati a una persona. Quello che questo form fa di diverso da un\r\n * elenco di sotto-elementi, e che il modello impone:\r\n *\r\n * 1. **Gli step non sono una sequenza.** L'ordine nell'array e' solo l'ordine d'esame: uno\r\n * step parte appena le sue `entryConditions` sono vere. Non sono numerati come passi, e le\r\n * frecce dicono di riordinare l'*esame*, non l'esecuzione.\r\n * 2. **Il `name` di uno step sta nello stesso spazio dei nomi** di node e risorse (§3.3): un\r\n * omonimo di una variabile e' `NAME_DUPLICATED`, e il controllo e' lo stesso dell'inspector.\r\n * 3. **Una condizione non puo' referenziare l'output di un altro step**: finche' quello step\r\n * non ha girato il riferimento e' irrisolvibile, e a runtime un riferimento irrisolvibile\r\n * e' un errore. Qui e' segnalato con la via d'uscita: scrivere il risultato in una\r\n * variabile e condizionare su quella.\r\n * 4. **`entryConditions` e `exitConditions` non sono simmetriche**: se le prime non si\r\n * avverano lo step viene saltato, se le seconde restano false lo stage va in **stallo** e\r\n * l'esecuzione fallisce. Sono due cose diverse che si assomigliano, quindi e' scritto.\r\n * 5. **`faultConnector` e' il ramo dello step rifiutato**, non un ramo di guasto: senza, un\r\n * rifiuto fa fallire l'interview. Per un flow di approvazione va quasi sempre disegnato.\r\n *\r\n * `runAsUser` viene ignorato dal runtime e `canAssigneeEdit` / `shouldLock` /\r\n * `requiresAsyncProcessing` sono riservati: non sono esposti.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { checkFlowName, slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport {\r\n ORCHESTRATION_CONDITION_OUTPUT,\r\n stageStepOutputReferenced,\r\n stepsOf,\r\n} from '../../core/stage-step.util';\r\nimport { FlowSummary } from '../../model/api.model';\r\nimport {\r\n FlowConditionHolder,\r\n FlowElementType,\r\n FlowOrchestratedStage,\r\n FlowStageStep,\r\n FlowStageStepAssignee,\r\n FlowValue,\r\n} from '../../model/flow.model';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent, NamePickerOption } from '../shared/name-picker.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I due contenitori di condizioni di uno step, come li vuole l'editor condiviso. */\r\ninterface StepConditionHolders {\r\n entry: FlowConditionHolder;\r\n exit: FlowConditionHolder;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-orchestrated-stage-inspector',\r\n standalone: true,\r\n imports: [\r\n ConditionEditorComponent,\r\n ConnectorEditorComponent,\r\n NamePickerComponent,\r\n ParameterEditorComponent,\r\n ValueEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './orchestrated-stage-inspector.component.html',\r\n})\r\nexport class OrchestratedStageInspectorComponent extends NodeInspectorBase {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n readonly elementType: FlowElementType = 'OrchestratedStage';\r\n\r\n readonly stage = computed<FlowOrchestratedStage>(() => this.node() as FlowOrchestratedStage);\r\n readonly steps = computed<FlowStageStep[]>(() => stepsOf(this.stage()));\r\n\r\n /** I tre tipi di step: `stageStepTypes` e' l'elenco autoritativo (§6.4). */\r\n readonly stepTypes = computed(() => this.dictionaries.stageStepTypes());\r\n readonly assigneeTypes = computed(() => this.dictionaries.assigneeTypes());\r\n\r\n /** L'output che il runtime legge da un evaluation flow di condizione. */\r\n readonly conditionOutputName = ORCHESTRATION_CONDITION_OUTPUT;\r\n\r\n /**\r\n * I flow proponibili come step in background o come evaluation flow. Una lista vuota\r\n * significa \"non lo so\": in quel caso il campo resta scrivibile a mano (§5.9, §7).\r\n */\r\n private readonly flowCandidates = signal<FlowSummary[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.api\r\n .listSubflowCandidates(this.store.document().fullName ?? undefined)\r\n .then((list) => this.flowCandidates.set(list ?? []))\r\n .catch(() => this.flowCandidates.set([]));\r\n }\r\n\r\n /** I candidati come li vuole il picker: il nome del flow e' il suo `flowName`. */\r\n readonly candidateOptions = computed<NamePickerOption[]>(() =>\r\n this.flowCandidates().map((candidate) => ({\r\n name: candidate.flowName,\r\n label: candidate.label,\r\n description: candidate.description,\r\n })),\r\n );\r\n\r\n /**\r\n * I contenitori di condizioni, uno per step, calcolati **una volta** per documento: costruirli\r\n * nel template creerebbe un oggetto nuovo a ogni ciclo di change detection.\r\n */\r\n readonly conditionHolders = computed<StepConditionHolders[]>(() =>\r\n this.steps().map((step) => ({\r\n entry: { conditions: step.entryConditions ?? [] },\r\n exit: { conditions: step.exitConditions ?? [] },\r\n })),\r\n );\r\n\r\n // -------------------------------------------------------------------------\r\n // Diagnostica locale\r\n // -------------------------------------------------------------------------\r\n\r\n requiresActionName(step: FlowStageStep): boolean {\r\n return this.dictionaries.stageStepRequiresActionName(step.actionType);\r\n }\r\n\r\n requiresAssignees(step: FlowStageStep): boolean {\r\n return this.dictionaries.stageStepRequiresAssignees(step.actionType);\r\n }\r\n\r\n /** Il rifiuto e' un esito previsto solo per l'approvazione: e' lì che serve il ramo. */\r\n supportsRejection(step: FlowStageStep): boolean {\r\n const entry = this.dictionaries.stageStepType(step.actionType);\r\n return entry?.supportsRejection ?? step.actionType === 'stepApproval';\r\n }\r\n\r\n stepTypeDescription(step: FlowStageStep): string | null {\r\n return this.dictionaries.stageStepType(step.actionType)?.description ?? null;\r\n }\r\n\r\n /** Un `actionType` che il dizionario non conosce: sarebbe `STAGE_STEP_TYPE_UNKNOWN`. */\r\n isUnknownStepType(step: FlowStageStep): boolean {\r\n if (!step.actionType || !this.stepTypes().length) {\r\n return false;\r\n }\r\n return !this.dictionaries.stageStepType(step.actionType);\r\n }\r\n\r\n /**\r\n * Il nome dello step: stessa regola dei node, sullo spazio dei nomi comune (§3.3).\r\n * L'unicita' si conta sulle occorrenze in `usedNames`, che gli step li comprende già: una\r\n * sola occorrenza e' questo step, due sono un omonimo.\r\n */\r\n stepNameError(step: FlowStageStep): string | null {\r\n const check = checkFlowName(step.name, [], step.name);\r\n if (!check.isValid) {\r\n return check.message ?? 'Nome non valido.';\r\n }\r\n const key = (step.name ?? '').toLowerCase();\r\n const occurrences = this.store.usedNames().filter((name) => name.toLowerCase() === key).length;\r\n return occurrences > 1\r\n ? 'Questo nome e’ già usato da un elemento, una risorsa o un altro step (NAME_DUPLICATED).'\r\n : null;\r\n }\r\n\r\n /**\r\n * Il nome dello step il cui output una condizione sta leggendo: e' irrisolvibile finche'\r\n * quello step non ha girato (§5.13, punto 4). `undefined` quando va tutto bene.\r\n */\r\n stepOutputInConditions(step: FlowStageStep): string | undefined {\r\n const conditions = [...(step.entryConditions ?? []), ...(step.exitConditions ?? [])];\r\n for (const condition of conditions) {\r\n const referenced =\r\n stageStepOutputReferenced(condition.leftValueReference, this.steps()) ??\r\n stageStepOutputReferenced(condition.rightValue?.elementReference, this.steps());\r\n if (referenced) {\r\n return referenced;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /** Lo step tiene un output senza destinazione: e' lecito, ma vale la pena dirlo. */\r\n hasSimulatedOutputs(step: FlowStageStep): boolean {\r\n return step.debugSimulateStep === true;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Step\r\n // -------------------------------------------------------------------------\r\n\r\n addStep(): void {\r\n const name = uniqueFlowName('Step', this.store.usedNames());\r\n this.patch((node) => {\r\n const stage = node as FlowOrchestratedStage;\r\n stage.stageSteps ??= [];\r\n stage.stageSteps.push({\r\n name,\r\n label: `Step ${stage.stageSteps.length + 1}`,\r\n // Il tipo lo scelga l'utente: senza, e' `STAGE_STEP_TYPE_MISSING` e si vede subito.\r\n });\r\n });\r\n }\r\n\r\n removeStep(index: number): void {\r\n this.patch((node) => {\r\n const stage = node as FlowOrchestratedStage;\r\n stage.stageSteps?.splice(index, 1);\r\n if (stage.stageSteps?.length === 0) {\r\n delete stage.stageSteps;\r\n }\r\n });\r\n }\r\n\r\n /** Sposta lo step nell'ordine d'**esame**: non e' un ordine di esecuzione (§5.13). */\r\n moveStep(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.steps().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const steps = (node as FlowOrchestratedStage).stageSteps;\r\n if (!steps) {\r\n return;\r\n }\r\n const [moved] = steps.splice(index, 1);\r\n steps.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n private patchStep(index: number, mutate: (step: FlowStageStep) => void): void {\r\n this.patch((node) => {\r\n const step = (node as FlowOrchestratedStage).stageSteps?.[index];\r\n if (step) {\r\n mutate(step);\r\n }\r\n });\r\n }\r\n\r\n setStepLabel(index: number, label: string): void {\r\n this.patchStep(index, (step) => {\r\n step.label = label || undefined;\r\n if (!step.name && label) {\r\n step.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setStepName(index: number, name: string): void {\r\n this.patchStep(index, (step) => {\r\n step.name = name || undefined;\r\n });\r\n }\r\n\r\n setStepDescription(index: number, description: string): void {\r\n this.patchStep(index, (step) => {\r\n step.description = description || undefined;\r\n });\r\n }\r\n\r\n /**\r\n * Cambiare tipo cambia cosa lo step pretende: gli assegnatari non hanno senso su uno step in\r\n * background, e `actionName` non ne ha su uno assegnato. I campi che il nuovo tipo non\r\n * prevede si rimuovono, invece di restare nel documento a dire una cosa che non vale piu'.\r\n */\r\n setStepType(index: number, actionType: string): void {\r\n const requiresActionName = this.dictionaries.stageStepRequiresActionName(actionType);\r\n const requiresAssignees = this.dictionaries.stageStepRequiresAssignees(actionType);\r\n this.patchStep(index, (step) => {\r\n step.actionType = actionType || undefined;\r\n if (!requiresActionName) {\r\n delete step.actionName;\r\n }\r\n if (!requiresAssignees) {\r\n delete step.assignees;\r\n delete step.requiresMultiMemberApproval;\r\n } else {\r\n step.assignees ??= [{}];\r\n }\r\n });\r\n }\r\n\r\n setStepActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n step.actionName = actionName || undefined;\r\n });\r\n }\r\n\r\n setMultiMemberApproval(index: number, required: boolean): void {\r\n this.patchStep(index, (step) => {\r\n // Il modello lo porta come stringa: `\"1\"` oppure `\"0\"` (§5.13).\r\n step.requiresMultiMemberApproval = required ? '1' : '0';\r\n });\r\n }\r\n\r\n isMultiMemberApproval(step: FlowStageStep): boolean {\r\n return step.requiresMultiMemberApproval === '1';\r\n }\r\n\r\n setSimulateStep(index: number, simulate: boolean): void {\r\n this.patchStep(index, (step) => {\r\n if (simulate) {\r\n step.debugSimulateStep = true;\r\n } else {\r\n delete step.debugSimulateStep;\r\n delete step.outputConfigParams;\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Assegnatari\r\n // -------------------------------------------------------------------------\r\n\r\n assigneesOf(step: FlowStageStep): FlowStageStepAssignee[] {\r\n return step.assignees ?? [];\r\n }\r\n\r\n addAssignee(index: number): void {\r\n this.patchStep(index, (step) => {\r\n step.assignees ??= [];\r\n step.assignees.push({});\r\n });\r\n }\r\n\r\n removeAssignee(stepIndex: number, assigneeIndex: number): void {\r\n this.patchStep(stepIndex, (step) => {\r\n step.assignees?.splice(assigneeIndex, 1);\r\n if (step.assignees?.length === 0) {\r\n delete step.assignees;\r\n }\r\n });\r\n }\r\n\r\n setAssigneeType(stepIndex: number, assigneeIndex: number, assigneeType: string): void {\r\n this.patchStep(stepIndex, (step) => {\r\n const assignee = step.assignees?.[assigneeIndex];\r\n if (assignee) {\r\n assignee.assigneeType = assigneeType || undefined;\r\n }\r\n });\r\n }\r\n\r\n setAssigneeValue(stepIndex: number, assigneeIndex: number, value: FlowValue | undefined): void {\r\n this.patchStep(stepIndex, (step) => {\r\n const assignee = step.assignees?.[assigneeIndex];\r\n if (assignee) {\r\n assignee.assignee = value;\r\n }\r\n });\r\n }\r\n\r\n /** Assegnatario senza tipo o senza valore: e' `STAGE_STEP_ASSIGNEE_INVALID`. */\r\n isAssigneeIncomplete(assignee: FlowStageStepAssignee): boolean {\r\n return !assignee.assigneeType || !assignee.assignee;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Condizioni ed evaluation flow\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Le condizioni di uno step sono condizioni come le altre (§4.3), ma il modello porta solo\r\n * la lista: `conditionLogic` e `formula` non esistono e non vanno scritti.\r\n */\r\n onEntryConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.applyConditions(index, 'entryConditions', mutate);\r\n }\r\n\r\n onExitConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.applyConditions(index, 'exitConditions', mutate);\r\n }\r\n\r\n private applyConditions(\r\n index: number,\r\n field: 'entryConditions' | 'exitConditions',\r\n mutate: (holder: FlowConditionHolder) => void,\r\n ): void {\r\n this.patchStep(index, (step) => {\r\n const holder: FlowConditionHolder = { conditions: step[field] ?? [] };\r\n mutate(holder);\r\n const conditions = holder.conditions ?? [];\r\n if (conditions.length) {\r\n step[field] = conditions;\r\n } else {\r\n // Lista vuota omessa, non scritta come `[]` (§2).\r\n delete step[field];\r\n }\r\n });\r\n }\r\n\r\n setEntryActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n if (actionName) {\r\n step.entryActionName = actionName;\r\n // Il tipo e' implicito: la condizione la decide un evaluation flow (§5.13).\r\n step.entryActionType = 'EvaluationFlow';\r\n } else {\r\n delete step.entryActionName;\r\n delete step.entryActionType;\r\n }\r\n });\r\n }\r\n\r\n setExitActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n if (actionName) {\r\n step.exitActionName = actionName;\r\n step.exitActionType = 'EvaluationFlow';\r\n } else {\r\n delete step.exitActionName;\r\n delete step.exitActionType;\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Parametri\r\n // -------------------------------------------------------------------------\r\n\r\n onParametersChanged(index: number, mutate: (holder: ParameterHolder) => void): void {\r\n this.patchStep(index, (step) => mutate(step));\r\n }\r\n\r\n /** Il ramo del rifiuto e' disegnato: senza, un rifiuto fa fallire l'interview (§5.13). */\r\n readonly hasRejectionBranch = computed(() => !!this.stage().faultConnector);\r\n\r\n /** C'e' almeno uno step il cui rifiuto e' un esito previsto. */\r\n readonly hasApprovalStep = computed(() => this.steps().some((step) => this.supportsRejection(step)));\r\n}\r\n","<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’ingresso sono vere, e\r\n l’ordine qui sotto e’ solo l’ordine 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 || '—' }}</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’ordine d’esame, non l’ordine di esecuzione\"\r\n [disabled]=\"isFirst\"\r\n (click)=\"moveStep(stepIndex, -1)\"\r\n >\r\n ↑\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’ordine d’esame, non l’ordine di esecuzione\"\r\n [disabled]=\"isLast\"\r\n (click)=\"moveStep(stepIndex, 1)\"\r\n >\r\n ↓\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 ×\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=\"\">— scegli —</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’ valido (STAGE_STEP_TYPE_MISSING).</p>\r\n } @else if (isUnknownStepType(step)) {\r\n <p class=\"fb-field__error\">\r\n «{{ step.actionType }}» non e’ 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 (§7).\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’ 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’ 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’interview si <strong>sospende</strong>: resta aperto un work item finche’\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’assegnatario\"\r\n (click)=\"removeAssignee(stepIndex, $index)\"\r\n >\r\n ×\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=\"\">— scegli —</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’ 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’approvazione 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 (§5.13).\r\n -->\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].entry\"\r\n title=\"Condizioni d’ingresso (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’uscita (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’e’ piu’ niente in esecuzione, lo stage e’ in stallo e\r\n l’esecuzione <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’output dello step «{{ stepOutputInConditions(step) }}»: finche’\r\n quello step non ha girato il riferimento e’ irrisolvibile, e a runtime e’ un errore. Fai\r\n scrivere quel risultato in una variabile (parametro di uscita → 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’ingresso</label>\r\n <fb-name-picker\r\n [value]=\"step.entryActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l’ingresso\"\r\n placeholder=\"Valuta_Ingresso\"\r\n unknownMessage=\"Questo flow non e’ 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’output booleano <code>{{ conditionOutputName }}</code>: e’ l’unico che il\r\n runtime legge, dichiararne altri e’ 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’uscita</label>\r\n <fb-name-picker\r\n [value]=\"step.exitActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l’uscita\"\r\n placeholder=\"Valuta_Uscita\"\r\n unknownMessage=\"Questo flow non e’ 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’ <strong>facoltativa</strong>: l’output e’ già 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’ 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’ 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’e’ uno step di approvazione ma il ramo «Step rifiutato» non e’ disegnato: senza, un rifiuto fa\r\n <strong>fallire</strong> l’interview. Non e’ un ramo di guasto, e’ l’esito 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","/**\r\n * Get Records — FRONTEND.md §5.6.\r\n *\r\n * Due modi di raccogliere il risultato, **alternativi**:\r\n * 1. `storeOutputAutomatically: true` → il risultato e' l'output automatico\r\n * (`Leggi_Ordine.Numero`). È il modo consigliato, e quello proposto per default.\r\n * 2. `outputReference` (una variabile) oppure `outputAssignments` (campo → variabile).\r\n *\r\n * Dichiarare entrambi e' `OUTPUT_CONFIGURATION_CONFLICT`; non dichiarare nessuno dei due e'\r\n * `LOOKUP_RESULT_DISCARDED`, cioe' interrogare il database e buttare via il risultato.\r\n * Il form modella le tre modalita' come mutuamente esclusive, così il conflitto non e'\r\n * rappresentabile.\r\n *\r\n * `getFirstRecordOnly` decide se il risultato e' un record singolo o una collection:\r\n * e' l'informazione che dice se questo elemento e' iterabile da un Loop.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowRecordLookup } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\ntype OutputMode = 'automatic' | 'variable' | 'assignments' | 'discard';\r\n\r\n@Component({\r\n selector: 'fb-record-lookup-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n FieldPickerComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n ReferencePickerComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-lookup-inspector.component.html',\r\n})\r\nexport class RecordLookupInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'RecordLookup';\r\n\r\n readonly lookup = computed<FlowRecordLookup>(() => this.node() as FlowRecordLookup);\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n /**\r\n * Serve solo alla griglia dei «campi da leggere»: gli altri elenchi (oggetti, campi di\r\n * ordinamento, campi di output) li carica il picker che li mostra.\r\n */\r\n private readonly allFields = signal<FlowFieldDescription[]>([]);\r\n\r\n constructor() {\r\n super();\r\n effect(() => {\r\n const object = this.lookup().object;\r\n if (!object) {\r\n this.allFields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, 'any')\r\n .then((list) => this.allFields.set(list ?? []))\r\n .catch(() => this.allFields.set([]));\r\n });\r\n }\r\n\r\n readonly fieldOptions = computed(() => this.allFields());\r\n\r\n readonly queriedFields = computed<string[]>(() => this.lookup().queriedFields ?? []);\r\n\r\n /** La modalita' di output dedotta dai campi valorizzati. */\r\n readonly outputMode = computed<OutputMode>(() => {\r\n const lookup = this.lookup();\r\n if (lookup.storeOutputAutomatically) {\r\n return 'automatic';\r\n }\r\n if (lookup.outputAssignments?.length) {\r\n return 'assignments';\r\n }\r\n if (lookup.outputReference) {\r\n return 'variable';\r\n }\r\n return 'discard';\r\n });\r\n\r\n /** Entrambi dichiarati: capita su documenti arrivati da altri editor. */\r\n readonly hasOutputConflict = computed(() => {\r\n const lookup = this.lookup();\r\n return (\r\n lookup.storeOutputAutomatically === true &&\r\n (!!lookup.outputReference || (lookup.outputAssignments?.length ?? 0) > 0)\r\n );\r\n });\r\n\r\n readonly returnsCollection = computed(() => this.lookup().getFirstRecordOnly !== true);\r\n\r\n readonly outputAssignments = computed(() => this.lookup().outputAssignments ?? []);\r\n\r\n setObject(object: string): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n if (lookup.object === object) {\r\n return;\r\n }\r\n lookup.object = object || undefined;\r\n // Cambiare oggetto invalida campi, filtri e ordinamento: tenerli produrrebbe\r\n // FIELD_UNKNOWN su ogni riga.\r\n delete lookup.queriedFields;\r\n delete lookup.filters;\r\n delete lookup.sortField;\r\n delete lookup.outputAssignments;\r\n });\r\n }\r\n\r\n setFirstOnly(value: boolean): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n if (value) {\r\n lookup.getFirstRecordOnly = true;\r\n } else {\r\n delete lookup.getFirstRecordOnly;\r\n }\r\n });\r\n }\r\n\r\n setSortField(field: string): void {\r\n this.setField('sortField', field);\r\n }\r\n\r\n setSortOrder(order: string): void {\r\n this.setField('sortOrder', order);\r\n }\r\n\r\n setLimit(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('limit', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n toggleQueriedField(field: string, checked: boolean): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n const fields = new Set(lookup.queriedFields ?? []);\r\n if (checked) {\r\n fields.add(field);\r\n } else {\r\n fields.delete(field);\r\n }\r\n if (fields.size) {\r\n lookup.queriedFields = Array.from(fields);\r\n } else {\r\n delete lookup.queriedFields;\r\n }\r\n });\r\n }\r\n\r\n isQueried(field: string): boolean {\r\n return this.queriedFields().includes(field);\r\n }\r\n\r\n /** Il passaggio fra modalita' azzera i campi delle altre: il conflitto non e' scrivibile. */\r\n setOutputMode(mode: OutputMode): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n delete lookup.storeOutputAutomatically;\r\n delete lookup.outputReference;\r\n delete lookup.outputAssignments;\r\n switch (mode) {\r\n case 'automatic':\r\n lookup.storeOutputAutomatically = true;\r\n break;\r\n case 'variable':\r\n lookup.outputReference = '';\r\n break;\r\n case 'assignments':\r\n lookup.outputAssignments = [{}];\r\n break;\r\n case 'discard':\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setOutputReference(reference: string | undefined): void {\r\n this.setField('outputReference', reference);\r\n }\r\n\r\n addOutputAssignment(): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n lookup.outputAssignments ??= [];\r\n lookup.outputAssignments.push({});\r\n });\r\n }\r\n\r\n removeOutputAssignment(index: number): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n lookup.outputAssignments?.splice(index, 1);\r\n if (lookup.outputAssignments?.length === 0) {\r\n delete lookup.outputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setOutputAssignmentField(index: number, field: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowRecordLookup).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setOutputAssignmentTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowRecordLookup).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.assignToReference = reference;\r\n }\r\n });\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.patch((node) => mutate(node as FilterHolder));\r\n }\r\n\r\n /** `relatedRecords` e' modellato ma non tradotto in query: se c'e', si avvisa (§5.6). */\r\n readonly hasRelatedRecords = computed(() => (this.lookup().relatedRecords?.length ?? 0) > 0);\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"lookup().object\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<fb-record-filter-editor\r\n [holder]=\"lookup()\"\r\n [object]=\"lookup().object\"\r\n title=\"Quali record leggere\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"true\"\r\n [supportsFormula]=\"true\"\r\n emptyWarning=\"Senza filtri legge tutti i record dell’oggetto.\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n/>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Quanti e in che ordine</legend>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"lookup().getFirstRecordOnly === true\"\r\n (change)=\"setFirstOnly($any($event.target).checked)\"\r\n />\r\n Solo il primo record\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n @if (returnsCollection()) {\r\n Il risultato e’ una <strong>collection</strong>: puo’ essere iterata da un Loop.\r\n } @else {\r\n Il risultato e’ un <strong>record singolo</strong>: non e’ iterabile da un Loop.\r\n }\r\n </p>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordina per</label>\r\n <fb-field-picker\r\n [value]=\"lookup().sortField\"\r\n [object]=\"lookup().object\"\r\n usage=\"sortable\"\r\n label=\"Campo di ordinamento\"\r\n placeholder=\"Nessun ordinamento\"\r\n (valueChange)=\"setSortField($event ?? '')\"\r\n />\r\n </div>\r\n\r\n @if (lookup().sortField) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select class=\"fb-select\" [fbValue]=\"lookup().sortOrder || ''\" (change)=\"setSortOrder($any($event.target).value)\">\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n\r\n @if (returnsCollection()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo di record</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"lookup().limit ?? ''\"\r\n (input)=\"setLimit($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n</fieldset>\r\n\r\n@if (fieldOptions().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Campi da leggere</legend>\r\n <p class=\"fb-section__note\">Nessuna selezione = tutti i campi disponibili.</p>\r\n <div class=\"fb-fields-grid\">\r\n @for (field of fieldOptions(); track field.name) {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isQueried(field.name)\"\r\n (change)=\"toggleQueriedField(field.name, $any($event.target).checked)\"\r\n />\r\n {{ field.label || field.name }}\r\n </label>\r\n }\r\n </div>\r\n </fieldset>\r\n}\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Dove finisce il risultato</legend>\r\n\r\n @if (hasOutputConflict()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Sono dichiarati insieme l’output automatico e una destinazione esplicita: e’ un conflitto\r\n (OUTPUT_CONFIGURATION_CONFLICT). Scegli una sola modalita’ qui sotto.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'automatic'\"\r\n (change)=\"setOutputMode('automatic')\"\r\n />\r\n Output automatico <em>(consigliato)</em>\r\n </label>\r\n @if (outputMode() === 'automatic') {\r\n <p class=\"fb-field__hint\">\r\n Il risultato si referenzia con il nome dell’elemento: <code>{{ name() }}</code>,\r\n <code>{{ name() }}.Campo</code>. Non serve dichiarare nessuna variabile.\r\n </p>\r\n }\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'variable'\"\r\n (change)=\"setOutputMode('variable')\"\r\n />\r\n In una variabile\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'assignments'\"\r\n (change)=\"setOutputMode('assignments')\"\r\n />\r\n Campo per campo\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'discard'\"\r\n (change)=\"setOutputMode('discard')\"\r\n />\r\n Scarta il risultato\r\n </label>\r\n </div>\r\n\r\n @if (outputMode() === 'variable') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Variabile di destinazione</label>\r\n <fb-reference-picker\r\n [value]=\"lookup().outputReference\"\r\n [writableOnly]=\"true\"\r\n [isCollection]=\"returnsCollection()\"\r\n [objectType]=\"lookup().object\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputReference($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (outputMode() === 'assignments') {\r\n <div class=\"fb-list\">\r\n @for (assignment of outputAssignments(); 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\"\r\n (click)=\"removeOutputAssignment($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo del record</label>\r\n <fb-field-picker\r\n [value]=\"assignment.field\"\r\n [object]=\"lookup().object\"\r\n usage=\"any\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setOutputAssignmentField($index, $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <fb-reference-picker\r\n [value]=\"assignment.assignToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputAssignmentTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutputAssignment()\">Aggiungi campo</button>\r\n }\r\n\r\n @if (outputMode() === 'discard') {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n L’elemento interroga il database e butta via il risultato (LOOKUP_RESULT_DISCARDED).\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n@if (hasRelatedRecords()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo elemento dichiara <code>relatedRecords</code>: il campo e’ modellato ma non viene tradotto in\r\n query, quindi non ha effetto.\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 (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Roll Back Records — FRONTEND.md §5.11, ultimo capoverso.\r\n *\r\n * Non ha campi oltre a `connector`: annulla le modifiche pendenti. Ha senso solo in uno\r\n * screen flow, dove esiste una transazione aperta fra due schermate — e il form lo dice,\r\n * perche' altrove non annulla nulla senza segnalare niente.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-record-rollback-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-rollback-inspector.component.html',\r\n})\r\nexport class RecordRollbackInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'RecordRollback';\r\n\r\n /** Fuori da uno screen flow non c'e' una transazione aperta da annullare. */\r\n readonly isScreenFlow = computed(() => this.store.document().processType === 'Screen');\r\n}\r\n","<p class=\"fb-callout\">\r\n Annulla le modifiche ai record ancora pendenti. Non ha altri campi da configurare.\r\n</p>\r\n\r\n@if (!isScreenFlow()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo elemento ha senso in uno screen flow, dove esiste una transazione aperta fra due schermate. In un\r\n flow «{{ store.document().processType }}» non c’e’ nulla da annullare.\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 (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Create / Update / Delete Records — FRONTEND.md §5.7 e trappola §13.10.\r\n *\r\n * Un solo componente per i tre, perche' condividono la stessa scelta di fondo — un record\r\n * già in memoria (`inputReference`) **oppure** oggetto piu' campi — e differiscono su tre\r\n * punti precisi, che qui sono espliciti invece di essere dedotti:\r\n *\r\n * - **Create**: serve `inputReference` oppure `object` + `inputAssignments`. Con\r\n * `doesUpsert` serve `upsertExternalIdField` **o** `upsertStandardIdField`, mai entrambi.\r\n * - **Update**: serve `inputReference` oppure `object` + `filters` + `inputAssignments`.\r\n * Un update per filtro **senza filtri** aggiornerebbe tutti i record dell'entita': e' un\r\n * avviso, e l'editor chiede una conferma esplicita.\r\n * - **Delete**: serve `inputReference` oppure `object` + `filters`. Senza filtri e' un\r\n * **errore**: cancellare un'intera tabella non e' un'operazione che si fa per distrazione.\r\n *\r\n * Inoltre Update e Delete **non hanno `filterLogic`**: i filtri sono sempre in AND, e\r\n * mostrare il controllo lo farebbe perdere silenziosamente al primo salvataggio (§4.4).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport {\r\n FieldAssignmentEditorComponent,\r\n FieldAssignmentHolder,\r\n} from '../shared/field-assignment-editor.component';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\n\r\ntype RecordWriteType = 'RecordCreate' | 'RecordUpdate' | 'RecordDelete';\r\n\r\n/** Vista unificata sui tre node: i campi assenti su un tipo restano semplicemente vuoti. */\r\ninterface RecordWriteNode {\r\n object?: string;\r\n inputReference?: string;\r\n inputAssignments?: unknown[];\r\n filters?: unknown[];\r\n doesUpsert?: boolean;\r\n upsertExternalIdField?: string;\r\n upsertStandardIdField?: string;\r\n storeOutputAutomatically?: boolean;\r\n assignRecordIdToReference?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-record-write-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n FieldAssignmentEditorComponent,\r\n FieldPickerComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n ReferencePickerComponent,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-write-inspector.component.html',\r\n})\r\nexport class RecordWriteInspectorComponent extends NodeInspectorBase {\r\n /** Passato dall'host: distingue Create, Update e Delete. */\r\n readonly type = input.required<RecordWriteType>();\r\n\r\n get elementType(): FlowElementType {\r\n return this.type();\r\n }\r\n\r\n readonly record = computed<RecordWriteNode>(() => this.node() as RecordWriteNode);\r\n\r\n /**\r\n * La modalita' scelta col radio, finche' il documento non la rende evidente da se'.\r\n *\r\n * Non si puo' dedurre solo da `inputReference`: appena scelta la modalita' «record in\r\n * memoria» il riferimento non c'e' ancora, e scriverlo vuoto per ricordarsene sarebbe una\r\n * chiave vuota nel documento (§2). Senza questo, il radio tornava indietro da solo e i\r\n * campi per oggetto restavano visibili.\r\n */\r\n private readonly chosenMode = signal<'reference' | 'object' | null>(null);\r\n\r\n constructor() {\r\n super();\r\n // Cambiare elemento azzera le scelte locali al form: sono di questo node, non del prossimo.\r\n effect(() => {\r\n this.name();\r\n this.chosenMode.set(null);\r\n this.bulkUpdateConfirmed.set(false);\r\n });\r\n }\r\n\r\n readonly isCreate = computed(() => this.type() === 'RecordCreate');\r\n readonly isUpdate = computed(() => this.type() === 'RecordUpdate');\r\n readonly isDelete = computed(() => this.type() === 'RecordDelete');\r\n\r\n /** Le due modalita' alternative del modello. */\r\n readonly mode = computed<'reference' | 'object'>(() =>\r\n this.record().inputReference ? 'reference' : (this.chosenMode() ?? 'object'),\r\n );\r\n\r\n /** Update e Delete non hanno `filterLogic`: i filtri sono sempre in AND (§4.4). */\r\n readonly supportsFilterLogic = computed(() => this.isCreate());\r\n\r\n readonly needsFilters = computed(() => this.isUpdate() || this.isDelete());\r\n\r\n readonly filterCount = computed(() => this.record().filters?.length ?? 0);\r\n\r\n /** Un Delete senza filtri e' un errore; un Update senza filtri e' un avviso (§13.10). */\r\n readonly emptyFilterWarning = computed<string | null>(() => {\r\n if (this.mode() === 'reference' || !this.needsFilters()) {\r\n return null;\r\n }\r\n if (this.isDelete()) {\r\n return 'Un Delete senza filtri cancellerebbe tutti i record dell’oggetto: e’ un errore e blocca l’attivazione.';\r\n }\r\n return 'Un Update senza filtri aggiornerebbe tutti i record dell’oggetto. Se e’ quello che vuoi, confermalo qui sotto.';\r\n });\r\n\r\n readonly emptyFilterSeverity = computed<'warn' | 'error'>(() => (this.isDelete() ? 'error' : 'warn'));\r\n\r\n /** Conferma esplicita per l'update di massa: locale al form, non finisce nel documento. */\r\n readonly bulkUpdateConfirmed = signal(false);\r\n\r\n readonly showsBulkConfirm = computed(\r\n () => this.isUpdate() && this.mode() === 'object' && this.filterCount() === 0,\r\n );\r\n\r\n readonly upsertMode = computed<'none' | 'external' | 'standard'>(() => {\r\n const record = this.record();\r\n if (!record.doesUpsert) {\r\n return 'none';\r\n }\r\n return record.upsertStandardIdField ? 'standard' : 'external';\r\n });\r\n\r\n /** Entrambi i campi di upsert insieme e' `UPSERT_CONFIGURATION_INVALID`. */\r\n readonly hasUpsertConflict = computed(() => {\r\n const record = this.record();\r\n return !!record.upsertExternalIdField && !!record.upsertStandardIdField;\r\n });\r\n\r\n readonly title = computed(() => {\r\n switch (this.type()) {\r\n case 'RecordCreate':\r\n return 'record da creare';\r\n case 'RecordUpdate':\r\n return 'record da aggiornare';\r\n default:\r\n return 'record da cancellare';\r\n }\r\n });\r\n\r\n setMode(mode: 'reference' | 'object'): void {\r\n this.chosenMode.set(mode);\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (mode === 'reference') {\r\n // Le due modalita' sono alternative: tenere entrambe rende ambiguo cosa fara'.\r\n delete record.object;\r\n delete record.inputAssignments;\r\n delete record.filters;\r\n } else {\r\n delete record.inputReference;\r\n }\r\n });\r\n }\r\n\r\n setInputReference(reference: string | undefined): void {\r\n this.setField('inputReference', reference);\r\n }\r\n\r\n setObject(object: string): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (record.object === object) {\r\n return;\r\n }\r\n record.object = object || undefined;\r\n delete record.inputAssignments;\r\n delete record.filters;\r\n delete record.upsertExternalIdField;\r\n delete record.upsertStandardIdField;\r\n });\r\n }\r\n\r\n setDoesUpsert(value: boolean): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (value) {\r\n record.doesUpsert = true;\r\n } else {\r\n delete record.doesUpsert;\r\n delete record.upsertExternalIdField;\r\n delete record.upsertStandardIdField;\r\n }\r\n });\r\n }\r\n\r\n setUpsertMode(mode: 'external' | 'standard'): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n record.doesUpsert = true;\r\n // Mai entrambi: scegliere l'uno cancella l'altro.\r\n if (mode === 'external') {\r\n delete record.upsertStandardIdField;\r\n record.upsertExternalIdField ??= '';\r\n } else {\r\n delete record.upsertExternalIdField;\r\n record.upsertStandardIdField ??= '';\r\n }\r\n });\r\n }\r\n\r\n setUpsertExternalField(value: string): void {\r\n this.setField('upsertExternalIdField', value);\r\n }\r\n\r\n setUpsertStandardField(value: string): void {\r\n this.setField('upsertStandardIdField', value);\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (value) {\r\n record.storeOutputAutomatically = true;\r\n delete record.assignRecordIdToReference;\r\n } else {\r\n delete record.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n setAssignRecordId(reference: string | undefined): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n record.assignRecordIdToReference = reference;\r\n if (reference) {\r\n delete record.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n confirmBulkUpdate(value: boolean): void {\r\n this.bulkUpdateConfirmed.set(value);\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.patch((node) => mutate(node as FilterHolder));\r\n }\r\n\r\n onAssignmentsChanged(mutate: (holder: FieldAssignmentHolder) => void): void {\r\n this.patch((node) => mutate(node as FieldAssignmentHolder));\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Come indicare i {{ title() }}</legend>\r\n <label class=\"fb-check\">\r\n <input type=\"radio\" name=\"write-mode\" [checked]=\"mode() === 'object'\" (change)=\"setMode('object')\" />\r\n Per oggetto{{ needsFilters() ? ' e filtri' : ' e valori' }}\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"radio\" name=\"write-mode\" [checked]=\"mode() === 'reference'\" (change)=\"setMode('reference')\" />\r\n Un record già in memoria\r\n </label>\r\n</fieldset>\r\n\r\n@if (mode() === 'reference') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Record</label>\r\n <fb-reference-picker\r\n [value]=\"record().inputReference\"\r\n dataType=\"Object\"\r\n placeholder=\"Variabile di tipo record\"\r\n (valueChange)=\"setInputReference($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Il record porta con se’ i propri valori: non serve indicare oggetto ne’ campi.\r\n </p>\r\n </div>\r\n} @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"record().object\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n </div>\r\n\r\n @if (needsFilters()) {\r\n <fb-record-filter-editor\r\n [holder]=\"$any(record())\"\r\n [object]=\"record().object\"\r\n [title]=\"isDelete() ? 'Quali record cancellare' : 'Quali record aggiornare'\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"supportsFilterLogic()\"\r\n [emptyWarning]=\"emptyFilterWarning()\"\r\n [emptyWarningSeverity]=\"emptyFilterSeverity()\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n />\r\n\r\n @if (showsBulkConfirm()) {\r\n <label class=\"fb-check fb-confirm\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"bulkUpdateConfirmed()\"\r\n (change)=\"confirmBulkUpdate($any($event.target).checked)\"\r\n />\r\n Confermo di voler aggiornare <strong>tutti</strong> i record di «{{ record().object || 'questo oggetto' }}»\r\n </label>\r\n }\r\n }\r\n\r\n @if (!isDelete()) {\r\n <fb-field-assignment-editor\r\n [holder]=\"$any(record())\"\r\n [object]=\"record().object\"\r\n [title]=\"isCreate() ? 'Valori del nuovo record' : 'Valori da scrivere'\"\r\n (changed)=\"onAssignmentsChanged($event)\"\r\n />\r\n }\r\n}\r\n\r\n@if (isCreate()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Upsert</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"record().doesUpsert === true\"\r\n (change)=\"setDoesUpsert($any($event.target).checked)\"\r\n />\r\n Aggiorna il record se esiste già\r\n </label>\r\n\r\n @if (record().doesUpsert) {\r\n @if (hasUpsertConflict()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Sono indicati insieme il campo di id esterno e quello standard: va scelto uno solo\r\n (UPSERT_CONFIGURATION_INVALID).\r\n </p>\r\n }\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"upsert-mode\"\r\n [checked]=\"upsertMode() === 'external'\"\r\n (change)=\"setUpsertMode('external')\"\r\n />\r\n Riconosci il record da un id esterno\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"upsert-mode\"\r\n [checked]=\"upsertMode() === 'standard'\"\r\n (change)=\"setUpsertMode('standard')\"\r\n />\r\n Riconosci il record dall’id standard\r\n </label>\r\n\r\n @if (upsertMode() === 'external') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo id esterno</label>\r\n <fb-field-picker\r\n [value]=\"record().upsertExternalIdField\"\r\n [object]=\"record().object\"\r\n usage=\"any\"\r\n label=\"Campo id esterno\"\r\n (valueChange)=\"setUpsertExternalField($event ?? '')\"\r\n />\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo id standard</label>\r\n <fb-field-picker\r\n [value]=\"record().upsertStandardIdField\"\r\n [object]=\"record().object\"\r\n usage=\"any\"\r\n label=\"Campo id standard\"\r\n (valueChange)=\"setUpsertStandardField($event ?? '')\"\r\n />\r\n </div>\r\n }\r\n }\r\n </fieldset>\r\n\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Identificativo creato</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"record().storeOutputAutomatically === true\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (record().storeOutputAutomatically) {\r\n <p class=\"fb-field__hint\">\r\n L’identificativo creato si referenzia col nome dell’elemento: <code>{{ name() }}</code>.\r\n </p>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna l’identificativo a</label>\r\n <fb-reference-picker\r\n [value]=\"record().assignRecordIdToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setAssignRecordId($event)\"\r\n />\r\n </div>\r\n }\r\n </fieldset>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Screen — FRONTEND.md §5.1.\r\n *\r\n * Lo screen **non descrive i propri campi**: dichiara *quale* form mostrare e il contratto\r\n * di dati con cui parlarci. Il form e' un componente scritto a mano nel frontend\r\n * applicativo, e il flow lo referenzia per nome esattamente come referenzia un'action.\r\n * Non c'e' un albero di componenti da disegnare, e non serve.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowScreen } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-screen-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './screen-inspector.component.html',\r\n})\r\nexport class ScreenInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Screen';\r\n\r\n readonly screen = computed<FlowScreen>(() => this.node() as FlowScreen);\r\n\r\n private readonly forms = signal<FlowCatalogEntry[]>([]);\r\n private readonly formParameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listForms()\r\n .then((list) => this.forms.set(list ?? []))\r\n .catch(() => this.forms.set([]));\r\n\r\n effect(() => {\r\n const formName = this.screen().formName;\r\n if (!formName) {\r\n this.formParameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFormParameters(formName)\r\n .then((list) => this.formParameters.set(list ?? []))\r\n .catch(() => this.formParameters.set([]));\r\n });\r\n }\r\n\r\n readonly formOptions = computed(() => this.forms());\r\n /** Catalogo vuoto = \"non lo so\": nessun controllo, nessun falso allarme (§7). */\r\n readonly hasFormCatalog = computed(() => this.forms().length > 0);\r\n readonly parameters = computed(() => this.formParameters());\r\n\r\n /** Con il catalogo popolato, un form non presente e' un errore (`FORM_UNKNOWN`). */\r\n readonly isUnknownForm = computed(() => {\r\n const formName = this.screen().formName;\r\n if (!formName || !this.hasFormCatalog()) {\r\n return false;\r\n }\r\n return !this.forms().some((form) => form.name === formName);\r\n });\r\n\r\n /**\r\n * `allowBack`, `allowFinish`, `allowPause` hanno default `true`: un valore assente\r\n * significa concesso, non negato.\r\n */\r\n allowBack = computed(() => this.screen().allowBack !== false);\r\n allowFinish = computed(() => this.screen().allowFinish !== false);\r\n allowPause = computed(() => this.screen().allowPause !== false);\r\n\r\n /**\r\n * Uno screen senza `connector` e con `allowFinish: false` e' un vicolo cieco:\r\n * `SCREEN_DEAD_END`. Vale la pena dirlo prima che lo dica la validazione.\r\n */\r\n readonly isDeadEnd = computed(() => {\r\n const screen = this.screen();\r\n return !screen.connector?.targetReference && screen.allowFinish === false;\r\n });\r\n\r\n setFormName(value: string): void {\r\n this.setField('formName', value);\r\n }\r\n\r\n setHelpText(value: string): void {\r\n this.setField('helpText', value);\r\n }\r\n\r\n setPausedText(value: string): void {\r\n this.setField('pausedText', value);\r\n }\r\n\r\n setFlag(flag: 'allowBack' | 'allowFinish' | 'allowPause', value: boolean): void {\r\n this.patch((node) => {\r\n // Il default e' `true`: si scrive solo quando si nega, per non sporcare il diff.\r\n if (value) {\r\n delete node[flag];\r\n } else {\r\n node[flag] = false;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Lo screen dichiara <strong>quale form</strong> mostrare, non i suoi campi: il form e’ un componente del\r\n frontend applicativo, e qui si definisce solo il contratto di dati.\r\n</p>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Form</label>\r\n @if (hasFormCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-select--invalid]=\"isUnknownForm()\"\r\n [fbValue]=\"screen().formName || ''\"\r\n (change)=\"setFormName($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli un form —</option>\r\n @for (form of formOptions(); track form.name) {\r\n <option [value]=\"form.name\">{{ form.label || form.name }}</option>\r\n }\r\n @if (isUnknownForm()) {\r\n <option [value]=\"screen().formName\">{{ screen().formName }} (non nel catalogo)</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"screen().formName || ''\"\r\n placeholder=\"Nome del form\"\r\n (input)=\"setFormName($any($event.target).value)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Il catalogo dei form non e’ popolato: il nome non viene verificato.\r\n </p>\r\n }\r\n @if (isUnknownForm()) {\r\n <p class=\"fb-field__error\">Questo form non esiste nel catalogo: la validazione lo segnala come errore.</p>\r\n }\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Testo di aiuto</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"screen().helpText || ''\"\r\n (input)=\"setHelpText($any($event.target).value)\"\r\n ></textarea>\r\n</div>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Navigazione</legend>\r\n <p class=\"fb-section__note\">\r\n Questi flag sono un’intenzione, non la verita’ finale: a runtime il motore comunica\r\n <code>canGoBack</code>, <code>canFinish</code> e <code>canPause</code> nella richiesta del form —\r\n per esempio «indietro» conta solo se esiste uno screen precedente nel percorso.\r\n </p>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowBack()\" (change)=\"setFlag('allowBack', $any($event.target).checked)\" />\r\n Consenti «indietro»\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowFinish()\" (change)=\"setFlag('allowFinish', $any($event.target).checked)\" />\r\n Consenti «fine»\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowPause()\" (change)=\"setFlag('allowPause', $any($event.target).checked)\" />\r\n Consenti «pausa»\r\n </label>\r\n\r\n @if (allowPause()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Testo mostrato alla pausa</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"screen().pausedText || ''\"\r\n (input)=\"setPausedText($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (isDeadEnd()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Questo screen non ha una destinazione e non consente «fine»: e’ un vicolo cieco, e l’utente resterebbe\r\n bloccato.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"screen()\"\r\n [catalogParameters]=\"parameters()\"\r\n inputTitle=\"Valori passati al form\"\r\n outputTitle=\"Valori raccolti dal form\"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Script — FRONTEND.md §5.8, ultimo capoverso.\r\n *\r\n * Piu' semplice dell'Action: `scriptName`, parametri, `connector`, `faultConnector`.\r\n * Nessun timeout, nessun modello transazionale.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowScriptPluginCall } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-script-call-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './script-call-inspector.component.html',\r\n})\r\nexport class ScriptCallInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'ScriptCall';\r\n\r\n readonly script = computed<FlowScriptPluginCall>(() => this.node() as FlowScriptPluginCall);\r\n\r\n private readonly scripts = signal<FlowCatalogEntry[]>([]);\r\n private readonly parameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listScripts()\r\n .then((list) => this.scripts.set(list ?? []))\r\n .catch(() => this.scripts.set([]));\r\n\r\n effect(() => {\r\n const scriptName = this.script().scriptName;\r\n if (!scriptName) {\r\n this.parameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listScriptParameters(scriptName)\r\n .then((list) => this.parameters.set(list ?? []))\r\n .catch(() => this.parameters.set([]));\r\n });\r\n }\r\n\r\n readonly scriptOptions = computed(() => this.scripts());\r\n readonly hasCatalog = computed(() => this.scripts().length > 0);\r\n readonly parameterCatalog = computed(() => this.parameters());\r\n\r\n readonly isUnknownScript = computed(() => {\r\n const name = this.script().scriptName;\r\n if (!name || !this.hasCatalog()) {\r\n return false;\r\n }\r\n return !this.scripts().some((entry) => entry.name === name);\r\n });\r\n\r\n readonly storeOutputAutomatically = computed(() => this.script().storeOutputAutomatically === true);\r\n\r\n setScriptName(value: string): void {\r\n this.patch((node) => {\r\n const script = node as FlowScriptPluginCall;\r\n if (script.scriptName === value) {\r\n return;\r\n }\r\n script.scriptName = value || undefined;\r\n delete script.inputParameters;\r\n delete script.outputParameters;\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const script = node as FlowScriptPluginCall;\r\n if (value) {\r\n script.storeOutputAutomatically = true;\r\n delete script.outputParameters;\r\n } else {\r\n delete script.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Script</label>\r\n @if (hasCatalog()) {\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-select--invalid]=\"isUnknownScript()\"\r\n [fbValue]=\"script().scriptName || ''\"\r\n (change)=\"setScriptName($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of scriptOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n @if (isUnknownScript()) {\r\n <option [value]=\"script().scriptName\">{{ script().scriptName }} (non nel catalogo)</option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"script().scriptName || ''\"\r\n (input)=\"setScriptName($any($event.target).value)\"\r\n />\r\n }\r\n @if (isUnknownScript()) {\r\n <p class=\"fb-field__error\">Questo script non esiste nel catalogo.</p>\r\n }\r\n</div>\r\n\r\n<label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n</label>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"script()\"\r\n [catalogParameters]=\"parameterCatalog()\"\r\n [showOutputs]=\"!storeOutputAutomatically()\"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * L'elemento Start — FRONTEND.md §3.4.\r\n *\r\n * Dice **quando** il flow parte e **da dove** comincia. I campi obbligatori dipendono dal\r\n * trigger, e il form li mostra di conseguenza:\r\n * - `object` e' obbligatorio con i trigger su record (`START_OBJECT_MISSING`);\r\n * - `schedule` e' obbligatorio con `Scheduled` (`START_SCHEDULE_MISSING`);\r\n * - `connector.targetReference` serve **sempre**: senza, `START_NO_ENTRY_POINT`.\r\n *\r\n * Con un trigger su record il flow espone `$Record` e `$Record__Prior`; senza, quei\r\n * riferimenti non sono disponibili e la validazione lo segnala. Il form lo dice, perche' e'\r\n * la differenza fra un riferimento che funziona e uno che no.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowAnyNode, FlowScheduledPath, FlowStart } from '../../model/flow.model';\r\nimport { outletsOf } from '../../core/element-outlets';\r\nimport { uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I trigger che lavorano su un record e abilitano `$Record`. */\r\nconst RECORD_TRIGGERS = new Set(['RecordBeforeSave', 'RecordAfterSave', 'RecordBeforeDelete']);\r\n\r\n@Component({\r\n selector: 'fb-start-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './start-inspector.component.html',\r\n})\r\nexport class StartInspectorComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n readonly start = computed<FlowStart>(() => this.store.start());\r\n readonly startNode = computed<FlowAnyNode>(() => this.start() as FlowAnyNode);\r\n readonly outlets = computed(() => outletsOf('Start', this.startNode()));\r\n\r\n readonly triggerTypes = computed(() => this.dictionaries.triggerTypes());\r\n readonly recordTriggerTypes = computed(() => this.dictionaries.recordTriggerTypes());\r\n readonly frequencies = computed(() => this.dictionaries.startFrequencies());\r\n readonly offsetUnits = computed(() => this.dictionaries.offsetUnits());\r\n\r\n readonly triggerType = computed(() => this.start().triggerType ?? 'None');\r\n readonly isRecordTrigger = computed(() => RECORD_TRIGGERS.has(this.triggerType()));\r\n readonly isScheduled = computed(() => this.triggerType() === 'Scheduled');\r\n readonly isEvent = computed(() => this.triggerType() === 'Event');\r\n\r\n readonly hasEntryPoint = computed(() => !!this.start().connector?.targetReference);\r\n\r\n readonly scheduledPaths = computed<FlowScheduledPath[]>(() => this.start().scheduledPaths ?? []);\r\n\r\n /** I rilievi sul documento, che e' dove finiscono quelli dello Start (§7). */\r\n readonly issues = computed(() => this.validation.documentIssues());\r\n\r\n setTriggerType(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.triggerType = value === 'None' ? undefined : value;\r\n if (!RECORD_TRIGGERS.has(value)) {\r\n // Campi che appartengono ai soli trigger su record: tenerli sarebbe rumore che il\r\n // motore ignora e che sporca il diff.\r\n delete start.object;\r\n delete start.recordTriggerType;\r\n delete start.filters;\r\n delete start.filterLogic;\r\n delete start.filterFormula;\r\n delete start.doesRequireRecordChangedToMeetCriteria;\r\n }\r\n if (value !== 'Scheduled') {\r\n delete start.schedule;\r\n delete start.scheduledPaths;\r\n } else {\r\n start.schedule ??= { frequency: this.frequencies()[0]?.value ?? 'Once' };\r\n }\r\n });\r\n }\r\n\r\n setObject(value: string): void {\r\n this.store.updateStart((start) => {\r\n if (start.object === value) {\r\n return;\r\n }\r\n start.object = value || undefined;\r\n delete start.filters;\r\n });\r\n }\r\n\r\n setRecordTriggerType(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.recordTriggerType = value || undefined;\r\n });\r\n }\r\n\r\n setRequireChanged(value: boolean): void {\r\n this.store.updateStart((start) => {\r\n if (value) {\r\n start.doesRequireRecordChangedToMeetCriteria = true;\r\n } else {\r\n delete start.doesRequireRecordChangedToMeetCriteria;\r\n }\r\n });\r\n }\r\n\r\n setFrequency(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n start.schedule.frequency = value || undefined;\r\n });\r\n }\r\n\r\n setStartDate(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n // Data senza fuso, come chiede il contratto: `2026-08-01T00:00:00`.\r\n start.schedule.startDate = value ? `${value}T00:00:00` : undefined;\r\n });\r\n }\r\n\r\n setStartTime(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n start.schedule.startTime = value ? (value.length === 5 ? `${value}:00` : value) : undefined;\r\n });\r\n }\r\n\r\n /** La data arriva come `2026-08-01T00:00:00`; l'input `date` vuole solo la parte data. */\r\n readonly startDateValue = computed(() => (this.start().schedule?.startDate ?? '').slice(0, 10));\r\n readonly startTimeValue = computed(() => (this.start().schedule?.startTime ?? '').slice(0, 5));\r\n\r\n addScheduledPath(): void {\r\n this.store.updateStart((start) => {\r\n start.scheduledPaths ??= [];\r\n const existing = start.scheduledPaths.map((path) => path.name ?? '');\r\n start.scheduledPaths.push({\r\n name: uniqueFlowName('Percorso', existing),\r\n label: `Percorso differito ${start.scheduledPaths.length + 1}`,\r\n offsetNumber: 1,\r\n offsetUnit: 'Days',\r\n });\r\n });\r\n }\r\n\r\n removeScheduledPath(index: number): void {\r\n this.store.updateStart((start) => {\r\n start.scheduledPaths?.splice(index, 1);\r\n if (start.scheduledPaths?.length === 0) {\r\n delete start.scheduledPaths;\r\n }\r\n });\r\n }\r\n\r\n setPathField(index: number, field: keyof FlowScheduledPath, value: unknown): void {\r\n this.store.updateStart((start) => {\r\n const path = start.scheduledPaths?.[index] as Record<string, unknown> | undefined;\r\n if (!path) {\r\n return;\r\n }\r\n if (value === undefined || value === null || value === '') {\r\n delete path[field as string];\r\n } else {\r\n path[field as string] = value;\r\n }\r\n });\r\n }\r\n\r\n setPathOffsetNumber(index: number, value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setPathField(index, 'offsetNumber', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.store.updateStart((start) => mutate(start as FilterHolder));\r\n }\r\n\r\n onConnectorChanged(event: { outletKey: string; target?: string; isGoTo?: boolean }): void {\r\n this.store.setConnector('$start', event.outletKey, event.target, event.isGoTo);\r\n }\r\n}\r\n","@if (!hasEntryPoint()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Lo Start non punta a nessun elemento: il flow non ha un punto di ingresso e non e’ eseguibile\r\n (START_NO_ENTRY_POINT).\r\n </p>\r\n}\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Quando parte</label>\r\n <select class=\"fb-select\" [fbValue]=\"triggerType()\" (change)=\"setTriggerType($any($event.target).value)\">\r\n @for (trigger of triggerTypes(); track trigger.value) {\r\n <option [value]=\"trigger.value\">{{ trigger.label }}</option>\r\n }\r\n </select>\r\n</div>\r\n\r\n@if (isRecordTrigger()) {\r\n <p class=\"fb-callout\">\r\n Con un trigger su record il flow espone <code>$Record</code> e <code>$Record__Prior</code>.\r\n </p>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto che innesca</label>\r\n <fb-object-picker\r\n [value]=\"start().object\"\r\n label=\"Oggetto che innesca\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n @if (!start().object) {\r\n <p class=\"fb-field__error\">Obbligatorio con i trigger su record (START_OBJECT_MISSING).</p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Su quale operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"start().recordTriggerType || ''\"\r\n (change)=\"setRecordTriggerType($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (type of recordTriggerTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <fb-record-filter-editor\r\n [holder]=\"$any(start())\"\r\n [object]=\"start().object\"\r\n title=\"Criteri di ingresso\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"true\"\r\n [supportsFormula]=\"true\"\r\n emptyWarning=\"Senza criteri il flow parte su ogni record.\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n />\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"start().doesRequireRecordChangedToMeetCriteria === true\"\r\n (change)=\"setRequireChanged($any($event.target).checked)\"\r\n />\r\n Solo se il record <em>non</em> soddisfaceva i criteri prima del salvataggio\r\n </label>\r\n}\r\n\r\n@if (isScheduled()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Pianificazione</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Frequenza</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"start().schedule?.frequency || ''\"\r\n (change)=\"setFrequency($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (frequency of frequencies(); track frequency.value) {\r\n <option [value]=\"frequency.value\">{{ frequency.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Data di inizio</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"date\"\r\n [value]=\"startDateValue()\"\r\n (input)=\"setStartDate($any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ora</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"time\"\r\n [value]=\"startTimeValue()\"\r\n (input)=\"setStartTime($any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n @if (!start().schedule?.frequency) {\r\n <p class=\"fb-field__error\">La pianificazione e’ obbligatoria con questo trigger (START_SCHEDULE_MISSING).</p>\r\n }\r\n </fieldset>\r\n\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Percorsi differiti</legend>\r\n <p class=\"fb-section__note\">\r\n Ogni percorso e’ un ramo che parte dopo un intervallo, calcolato da un istante di riferimento.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n @for (path of scheduledPaths(); 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 il percorso\"\r\n (click)=\"removeScheduledPath($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.label || ''\"\r\n (input)=\"setPathField($index, 'label', $any($event.target).value)\"\r\n />\r\n </div>\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 [value]=\"path.name || ''\"\r\n (input)=\"setPathField($index, 'name', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Dopo</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n [value]=\"path.offsetNumber ?? ''\"\r\n (input)=\"setPathOffsetNumber($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Unita’</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"path.offsetUnit || ''\"\r\n (change)=\"setPathField($index, 'offsetUnit', $any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (unit of offsetUnits(); track unit.value) {\r\n <option [value]=\"unit.value\">{{ unit.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Istante di riferimento</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.timeSource || ''\"\r\n placeholder=\"Es. RecordTriggerEvent\"\r\n (input)=\"setPathField($index, 'timeSource', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo data del record</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.recordField || ''\"\r\n (input)=\"setPathField($index, 'recordField', $any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun percorso differito.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addScheduledPath()\">Aggiungi percorso</button>\r\n </fieldset>\r\n}\r\n\r\n@if (triggerType() === 'None') {\r\n <p class=\"fb-field__hint\">\r\n Il flow parte solo su richiesta. I valori iniziali si passano nelle variabili di input.\r\n </p>\r\n}\r\n\r\n@if (isEvent()) {\r\n <p class=\"fb-field__hint\">Il flow parte alla ricezione di un evento.</p>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"'$start'\"\r\n [node]=\"startNode()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Da dove comincia\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Subflow — FRONTEND.md §5.9.\r\n *\r\n * `flowName` e' l'API name di un altro flow, proposto da `GET /flows/subflow-candidates`,\r\n * che restituisce **solo i flow con una versione attiva** ed esclude quello corrente: un\r\n * subflow che invoca il flow che lo contiene e' `SUBFLOW_RECURSIVE`.\r\n *\r\n * I nomi degli input e degli output sono quelli delle variabili `isInput`/`isOutput` **del\r\n * flow invocato**: per proporli si carica la definizione attiva di quel flow e se ne leggono\r\n * le variabili, che e' esattamente quello che fa questo componente.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowSummary } from '../../model/api.model';\r\nimport { FlowElementType, FlowSubflow, FlowValue, FlowVariable } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent, NamePickerOption } from '../shared/name-picker.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\n\r\n/** Una variabile del flow invocato come opzione: nome piu' tipo, collection compresa. */\r\nfunction describeVariable(variable: FlowVariable): NamePickerOption {\r\n const dataType = variable.dataType ?? 'Sconosciuto';\r\n const type = variable.isCollection ? `${dataType}[]` : dataType;\r\n return {\r\n // Il nome di una variabile e' facoltativo nel tipo, ma una senza nome non e' proponibile.\r\n name: variable.name ?? '',\r\n description: variable.objectType ? `${type} · ${variable.objectType}` : type,\r\n };\r\n}\r\n\r\n@Component({\r\n selector: 'fb-subflow-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, NamePickerComponent, ReferencePickerComponent, ValueEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './subflow-inspector.component.html',\r\n})\r\nexport class SubflowInspectorComponent extends NodeInspectorBase {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n readonly elementType: FlowElementType = 'Subflow';\r\n\r\n readonly subflow = computed<FlowSubflow>(() => this.node() as FlowSubflow);\r\n\r\n private readonly flowCandidates = signal<FlowSummary[]>([]);\r\n /** Le variabili del flow invocato: il contratto verso cui si passano i valori. */\r\n private readonly targetVariables = signal<FlowVariable[]>([]);\r\n private readonly targetLoadFailed = signal(false);\r\n\r\n constructor() {\r\n super();\r\n effect(() => {\r\n const current = this.store.document().fullName;\r\n void this.api\r\n .listSubflowCandidates(current)\r\n .then((list) => this.flowCandidates.set(list ?? []))\r\n .catch(() => this.flowCandidates.set([]));\r\n });\r\n\r\n effect(() => {\r\n const flowName = this.subflow().flowName;\r\n if (!flowName) {\r\n this.targetVariables.set([]);\r\n this.targetLoadFailed.set(false);\r\n return;\r\n }\r\n this.targetLoadFailed.set(false);\r\n void this.api\r\n // Senza `version` si ottiene la versione attiva, che e' quella che verra' eseguita.\r\n .loadFlow(flowName)\r\n .then((definition) => this.targetVariables.set(definition.variables ?? []))\r\n .catch(() => {\r\n this.targetVariables.set([]);\r\n this.targetLoadFailed.set(true);\r\n });\r\n });\r\n }\r\n\r\n /** I candidati come li vuole il picker: il nome di un flow e' il suo `flowName`. */\r\n readonly candidates = computed<NamePickerOption[]>(() =>\r\n this.flowCandidates().map((candidate) => ({\r\n name: candidate.flowName,\r\n label: candidate.label,\r\n description: candidate.description,\r\n })),\r\n );\r\n readonly hasCandidates = computed(() => this.flowCandidates().length > 0);\r\n readonly couldNotLoadTarget = computed(() => this.targetLoadFailed());\r\n\r\n readonly inputVariables = computed(() => this.targetVariables().filter((variable) => variable.isInput));\r\n readonly outputVariables = computed(() => this.targetVariables().filter((variable) => variable.isOutput));\r\n\r\n /** Il tipo della variabile fa da descrizione: dice subito se il valore ci sta dentro. */\r\n readonly inputOptions = computed<NamePickerOption[]>(() =>\r\n this.inputVariables().map(describeVariable).filter((option) => !!option.name),\r\n );\r\n readonly outputOptions = computed<NamePickerOption[]>(() =>\r\n this.outputVariables().map(describeVariable).filter((option) => !!option.name),\r\n );\r\n\r\n readonly inputAssignments = computed(() => this.subflow().inputAssignments ?? []);\r\n readonly outputAssignments = computed(() => this.subflow().outputAssignments ?? []);\r\n\r\n /** Il flow invocato coincide con questo: `SUBFLOW_RECURSIVE`. */\r\n readonly isRecursive = computed(() => {\r\n const flowName = this.subflow().flowName;\r\n return !!flowName && flowName === this.store.document().fullName;\r\n });\r\n\r\n readonly storeOutputAutomatically = computed(() => this.subflow().storeOutputAutomatically === true);\r\n\r\n variableOf(name: string | undefined): FlowVariable | undefined {\r\n return this.targetVariables().find((variable) => variable.name === name);\r\n }\r\n\r\n setFlowName(value: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n if (subflow.flowName === value) {\r\n return;\r\n }\r\n subflow.flowName = value || undefined;\r\n // Il contratto cambia con il flow invocato: gli assegnamenti vecchi non valgono piu'.\r\n delete subflow.inputAssignments;\r\n delete subflow.outputAssignments;\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n if (value) {\r\n subflow.storeOutputAutomatically = true;\r\n delete subflow.outputAssignments;\r\n } else {\r\n delete subflow.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n addInput(name?: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.inputAssignments ??= [];\r\n subflow.inputAssignments.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeInput(index: number): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.inputAssignments?.splice(index, 1);\r\n if (subflow.inputAssignments?.length === 0) {\r\n delete subflow.inputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setInputName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.name = name;\r\n }\r\n });\r\n }\r\n\r\n setInputValue(index: number, value: FlowValue | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.value = value;\r\n }\r\n });\r\n }\r\n\r\n addOutput(name?: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.outputAssignments ??= [];\r\n subflow.outputAssignments.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeOutput(index: number): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.outputAssignments?.splice(index, 1);\r\n if (subflow.outputAssignments?.length === 0) {\r\n delete subflow.outputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setOutputName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.name = name;\r\n }\r\n });\r\n }\r\n\r\n setOutputTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.assignToReference = reference;\r\n }\r\n });\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Flow da invocare</label>\r\n <fb-name-picker\r\n [value]=\"subflow().flowName\"\r\n [options]=\"candidates()\"\r\n label=\"Flow da invocare\"\r\n placeholder=\"API name del flow\"\r\n unknownMessage=\"Questo flow non e’ fra quelli invocabili: solo i flow con una versione attiva lo sono.\"\r\n emptyMessage=\"Nessun flow attivo disponibile come subflow: attivane uno, oppure scrivi il nome a mano.\"\r\n (valueChange)=\"setFlowName($event ?? '')\"\r\n />\r\n @if (hasCandidates()) {\r\n <p class=\"fb-field__hint\">Solo i flow con una versione attiva possono essere invocati.</p>\r\n }\r\n @if (isRecursive()) {\r\n <p class=\"fb-field__error\">Un flow non puo’ invocare se stesso (SUBFLOW_RECURSIVE).</p>\r\n }\r\n</div>\r\n\r\n@if (couldNotLoadTarget()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Non e’ stato possibile leggere la definizione del flow invocato: i nomi di input e output non vengono\r\n proposti, ma puoi scriverli a mano.\r\n </p>\r\n}\r\n\r\n<p class=\"fb-callout\">\r\n Un subflow che si sospende — cioe’ che contiene screen o Wait — non e’ supportato dal motore.\r\n</p>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori passati al subflow</legend>\r\n @if (inputVariables().length) {\r\n <p class=\"fb-section__note\">\r\n Sono le variabili di input del flow invocato: {{ inputVariables().length }} disponibili.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (assignment of inputAssignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"assignment.name\"\r\n [options]=\"inputOptions()\"\r\n label=\"Variabile del subflow\"\r\n placeholder=\"Nome della variabile di input\"\r\n unknownMessage=\"Questa variabile non e’ fra gli input del flow invocato.\"\r\n emptyMessage=\"Input del flow invocato non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setInputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"removeInput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <fb-value-editor\r\n [value]=\"assignment.value\"\r\n [dataType]=\"variableOf(assignment.name)?.dataType\"\r\n [objectType]=\"variableOf(assignment.name)?.objectType\"\r\n [isCollection]=\"variableOf(assignment.name)?.isCollection\"\r\n label=\"Valore\"\r\n (valueChange)=\"setInputValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun valore passato.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addInput()\">Aggiungi valore</button>\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori restituiti</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (storeOutputAutomatically()) {\r\n <p class=\"fb-field__hint\">\r\n Le variabili di output del subflow si referenziano col nome dell’elemento:\r\n <code>{{ name() }}.NomeVariabile</code>.\r\n </p>\r\n } @else {\r\n <div class=\"fb-list\">\r\n @for (assignment of outputAssignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"assignment.name\"\r\n [options]=\"outputOptions()\"\r\n label=\"Variabile di output del subflow\"\r\n placeholder=\"Nome della variabile di output\"\r\n unknownMessage=\"Questa variabile non e’ fra gli output del flow invocato.\"\r\n emptyMessage=\"Output del flow invocato non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setOutputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"removeOutput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <fb-reference-picker\r\n [value]=\"assignment.assignToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"variableOf(assignment.name)?.dataType\"\r\n [isCollection]=\"variableOf(assignment.name)?.isCollection\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun valore raccolto.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutput()\">Aggiungi valore</button>\r\n }\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Transform — FRONTEND.md §5.12.\r\n *\r\n * Tre tipi di trasformazione: `Map` (assegna un valore), `Sum` (somma un campo degli\r\n * elementi di una collection), `Count` (conta gli elementi). `Sum` e `Count` richiedono\r\n * l'input `aggregationValues`; `Sum` anche `aggregationField`. Il form li gestisce come\r\n * campi propri, invece di lasciare all'utente il compito di indovinare i nomi dei parametri.\r\n *\r\n * Nota: `connector` qui e' un **array** — la mappa delle uscite lo nasconde al resto.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport {\r\n FlowElementType,\r\n FlowTransform,\r\n FlowTransformValueAction,\r\n FlowValue,\r\n} from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I nomi dei parametri che le aggregazioni richiedono, fissati dal modello. */\r\nconst AGGREGATION_VALUES = 'aggregationValues';\r\nconst AGGREGATION_FIELD = 'aggregationField';\r\n\r\n@Component({\r\n selector: 'fb-transform-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n ObjectPickerComponent,\r\n ReferencePickerComponent,\r\n ValueEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './transform-inspector.component.html',\r\n})\r\nexport class TransformInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Transform';\r\n\r\n readonly transform = computed<FlowTransform>(() => this.node() as FlowTransform);\r\n readonly transformTypes = computed(() => this.dictionaries.transformTypes());\r\n readonly dataTypes = computed(() => this.dictionaries.dataTypes());\r\n\r\n private readonly enumTypes = signal<FlowCatalogEntry[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog.listEnumTypes().then((list) => this.enumTypes.set(list ?? []));\r\n }\r\n\r\n readonly enumOptions = computed(() => this.enumTypes());\r\n\r\n readonly requiresObjectType = computed(() => this.dictionaries.requiresObjectType(this.transform().dataType));\r\n\r\n /** Il modello prevede una lista di liste; l'editor lavora sulla prima, che e' il caso d'uso. */\r\n readonly actions = computed<FlowTransformValueAction[]>(\r\n () => this.transform().transformValues?.[0]?.transformValueActions ?? [],\r\n );\r\n\r\n setDataType(dataType: string): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n transform.dataType = dataType || undefined;\r\n if (!this.dictionaries.requiresObjectType(dataType)) {\r\n delete transform.objectType;\r\n }\r\n });\r\n }\r\n\r\n setObjectType(objectType: string): void {\r\n this.setField('objectType', objectType);\r\n }\r\n\r\n setIsCollection(value: boolean): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n if (value) {\r\n transform.isCollection = true;\r\n } else {\r\n delete transform.isCollection;\r\n }\r\n });\r\n }\r\n\r\n addAction(): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n transform.transformValues ??= [{}];\r\n const first = transform.transformValues[0];\r\n first.transformValueActions ??= [];\r\n first.transformValueActions.push({ transformType: 'Map' });\r\n });\r\n }\r\n\r\n removeAction(index: number): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n const actions = transform.transformValues?.[0]?.transformValueActions;\r\n actions?.splice(index, 1);\r\n if (actions?.length === 0) {\r\n delete transform.transformValues;\r\n }\r\n });\r\n }\r\n\r\n private mutateAction(index: number, mutate: (action: FlowTransformValueAction) => void): void {\r\n this.patch((node) => {\r\n const action = (node as FlowTransform).transformValues?.[0]?.transformValueActions?.[index];\r\n if (action) {\r\n mutate(action);\r\n }\r\n });\r\n }\r\n\r\n setActionType(index: number, transformType: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.transformType = transformType;\r\n // Map usa `value`, Sum e Count usano `inputParameters`: tenere entrambi renderebbe\r\n // ambiguo cosa viene applicato.\r\n if (transformType === 'Map') {\r\n delete action.inputParameters;\r\n } else {\r\n delete action.value;\r\n action.inputParameters ??= [{ name: AGGREGATION_VALUES }];\r\n if (transformType === 'Sum' && !action.inputParameters.some((p) => p.name === AGGREGATION_FIELD)) {\r\n action.inputParameters.push({ name: AGGREGATION_FIELD });\r\n }\r\n if (transformType === 'Count') {\r\n action.inputParameters = action.inputParameters.filter((p) => p.name === AGGREGATION_VALUES);\r\n }\r\n }\r\n });\r\n }\r\n\r\n setOutputField(index: number, field: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.outputFieldApiName = field || undefined;\r\n });\r\n }\r\n\r\n setMapValue(index: number, value: FlowValue | undefined): void {\r\n this.mutateAction(index, (action) => {\r\n action.value = value;\r\n });\r\n }\r\n\r\n aggregationCollection(action: FlowTransformValueAction): string | undefined {\r\n return action.inputParameters?.find((parameter) => parameter.name === AGGREGATION_VALUES)?.value\r\n ?.elementReference;\r\n }\r\n\r\n aggregationField(action: FlowTransformValueAction): string {\r\n return (\r\n action.inputParameters?.find((parameter) => parameter.name === AGGREGATION_FIELD)?.value?.stringValue ?? ''\r\n );\r\n }\r\n\r\n setAggregationCollection(index: number, reference: string | undefined): void {\r\n this.mutateAction(index, (action) => {\r\n action.inputParameters ??= [];\r\n const existing = action.inputParameters.find((parameter) => parameter.name === AGGREGATION_VALUES);\r\n if (existing) {\r\n existing.value = reference ? { elementReference: reference } : undefined;\r\n } else {\r\n action.inputParameters.push({\r\n name: AGGREGATION_VALUES,\r\n value: reference ? { elementReference: reference } : undefined,\r\n });\r\n }\r\n });\r\n }\r\n\r\n setAggregationField(index: number, field: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.inputParameters ??= [];\r\n const existing = action.inputParameters.find((parameter) => parameter.name === AGGREGATION_FIELD);\r\n if (existing) {\r\n existing.value = field ? { stringValue: field } : undefined;\r\n } else {\r\n action.inputParameters.push({\r\n name: AGGREGATION_FIELD,\r\n value: field ? { stringValue: field } : undefined,\r\n });\r\n }\r\n });\r\n }\r\n\r\n isMap(action: FlowTransformValueAction): boolean {\r\n return (action.transformType ?? 'Map') === 'Map';\r\n }\r\n\r\n needsAggregationField(action: FlowTransformValueAction): boolean {\r\n return action.transformType === 'Sum';\r\n }\r\n\r\n needsAggregationValues(action: FlowTransformValueAction): boolean {\r\n return action.transformType === 'Sum' || action.transformType === 'Count';\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo del risultato</label>\r\n <select class=\"fb-select\" [fbValue]=\"transform().dataType || ''\" (change)=\"setDataType($any($event.target).value)\">\r\n <option value=\"\">— scegli —</option>\r\n @for (type of dataTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n @if (!transform().dataType) {\r\n <p class=\"fb-field__error\">Obbligatorio (TRANSFORM_DATA_TYPE_MISSING).</p>\r\n }\r\n</div>\r\n\r\n@if (requiresObjectType()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo dell’oggetto</label>\r\n @if (transform().dataType === 'Enum') {\r\n <!-- Le enumerazioni sono un dizionario chiuso: non c'e' scrittura libera da concedere. -->\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"transform().objectType || ''\"\r\n (change)=\"setObjectType($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of enumOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n } @else {\r\n <fb-object-picker\r\n [value]=\"transform().objectType\"\r\n label=\"Tipo dell’oggetto\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObjectType($event ?? '')\"\r\n />\r\n }\r\n </div>\r\n}\r\n\r\n<label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"transform().isCollection === true\"\r\n (change)=\"setIsCollection($any($event.target).checked)\"\r\n />\r\n Il risultato e’ una collection\r\n</label>\r\n\r\n<p class=\"fb-callout\">\r\n Il risultato e’ l’<strong>output automatico</strong> dell’elemento: si referenzia con\r\n <code>{{ name() }}</code>.\r\n</p>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Trasformazioni</legend>\r\n\r\n <div class=\"fb-list\">\r\n @for (action of actions(); 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\"\r\n (click)=\"removeAction($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action.transformType || 'Map'\"\r\n (change)=\"setActionType($index, $any($event.target).value)\"\r\n >\r\n @for (type of transformTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo di destinazione</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"action.outputFieldApiName || ''\"\r\n placeholder=\"Totale\"\r\n (input)=\"setOutputField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n @if (isMap(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor\r\n [value]=\"action.value\"\r\n label=\"Valore\"\r\n (valueChange)=\"setMapValue($index, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (needsAggregationValues(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Collection su cui aggregare</label>\r\n <fb-reference-picker\r\n [value]=\"aggregationCollection(action)\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setAggregationCollection($index, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (needsAggregationField(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo da sommare</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"aggregationField(action)\"\r\n placeholder=\"Importo\"\r\n (input)=\"setAggregationField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna trasformazione: l’elemento non produce nulla (TRANSFORM_WITHOUT_VALUES).</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAction()\">Aggiungi trasformazione</button>\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Wait — FRONTEND.md §5.10.\r\n *\r\n * - almeno un evento e' obbligatorio (`WAIT_WITHOUT_EVENTS`); ogni evento vuole `eventType`\r\n * e una `label`, che e' l'etichetta del ramo sul canvas;\r\n * - `defaultConnector` e' il ramo percorso se le condizioni di **tutti** gli eventi sono\r\n * false;\r\n * - ogni evento puo' avere condizioni, filtri e parametri.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport { FlowConditionHolder, FlowElementType, FlowWait, FlowWaitEvent } from '../../model/flow.model';\r\nimport { slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-wait-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './wait-inspector.component.html',\r\n})\r\nexport class WaitInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Wait';\r\n\r\n readonly wait = computed<FlowWait>(() => this.node() as FlowWait);\r\n readonly events = computed<FlowWaitEvent[]>(() => this.wait().waitEvents ?? []);\r\n /** I tipi noti al motore: `AlarmEvent` per un istante, `DateRefAlarmEvent` per un campo. */\r\n readonly eventTypes = computed(() => this.dictionaries.waitEventTypes());\r\n\r\n private readonly catalogEvents = signal<FlowCatalogEntry[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listEvents()\r\n .then((list) => this.catalogEvents.set(list ?? []))\r\n .catch(() => this.catalogEvents.set([]));\r\n }\r\n\r\n readonly catalogEventOptions = computed(() => this.catalogEvents());\r\n\r\n addEvent(): void {\r\n this.patch((node) => {\r\n const wait = node as FlowWait;\r\n wait.waitEvents ??= [];\r\n const existing = wait.waitEvents.map((event) => event.name ?? '');\r\n wait.waitEvents.push({\r\n name: uniqueFlowName('Evento', existing),\r\n label: `Evento ${wait.waitEvents.length + 1}`,\r\n eventType: this.eventTypes()[0]?.value,\r\n });\r\n });\r\n }\r\n\r\n removeEvent(index: number): void {\r\n this.patch((node) => {\r\n const wait = node as FlowWait;\r\n wait.waitEvents?.splice(index, 1);\r\n if (wait.waitEvents?.length === 0) {\r\n delete wait.waitEvents;\r\n }\r\n });\r\n }\r\n\r\n moveEvent(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.events().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const events = (node as FlowWait).waitEvents;\r\n if (!events) {\r\n return;\r\n }\r\n const [moved] = events.splice(index, 1);\r\n events.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setEventLabel(index: number, label: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (!event) {\r\n return;\r\n }\r\n event.label = label || undefined;\r\n if (!event.name && label) {\r\n event.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setEventName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n event.name = name;\r\n }\r\n });\r\n }\r\n\r\n setEventType(index: number, eventType: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n event.eventType = eventType || undefined;\r\n }\r\n });\r\n }\r\n\r\n onEventConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n mutate(event);\r\n }\r\n });\r\n }\r\n\r\n onEventParametersChanged(index: number, mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n mutate(event);\r\n }\r\n });\r\n }\r\n\r\n setDefaultLabel(label: string): void {\r\n this.setField('defaultConnectorLabel', label);\r\n }\r\n}\r\n","<div class=\"fb-list\">\r\n @for (event of events(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveEvent($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveEvent($index, 1)\"\r\n >\r\n ↓\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 l’evento\"\r\n (click)=\"removeEvent($index)\"\r\n >\r\n ×\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 del ramo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"event.label || ''\"\r\n placeholder=\"Alla scadenza\"\r\n (input)=\"setEventLabel($index, $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 [value]=\"event.name || ''\"\r\n (input)=\"setEventName($index, $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\">Tipo di evento</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"event.eventType || ''\"\r\n (change)=\"setEventType($index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (type of eventTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n @for (entry of catalogEventOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n @if (!event.eventType) {\r\n <p class=\"fb-field__error\">Senza tipo l’evento non e’ valido (WAIT_EVENT_TYPE_MISSING).</p>\r\n }\r\n </div>\r\n\r\n <fb-parameter-editor\r\n [holder]=\"event\"\r\n inputTitle=\"Parametri dell’evento\"\r\n [showOutputs]=\"true\"\r\n outputTitle=\"Valori prodotti dall’evento\"\r\n (changed)=\"onEventParametersChanged($index, $event)\"\r\n />\r\n\r\n <fb-condition-editor\r\n [holder]=\"event\"\r\n title=\"Condizioni dell’evento\"\r\n (changed)=\"onEventConditionsChanged($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Almeno un evento e’ obbligatorio: un Wait senza eventi non e’ eseguibile (WAIT_WITHOUT_EVENTS).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addEvent()\">Aggiungi evento</button>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Se nessun evento si verifica</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo di default</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"wait().defaultConnectorLabel || ''\"\r\n (input)=\"setDefaultLabel($any($event.target).value)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n È il ramo percorso quando le condizioni di <strong>tutti</strong> gli eventi sono false.\r\n </p>\r\n </div>\r\n</fieldset>\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","/**\r\n * L'inspector: intestazione comune piu' il form del tipo selezionato.\r\n *\r\n * L'intestazione tiene i campi comuni a ogni node (`label`, `name`, `description`) e la\r\n * rinomina, che e' il punto delicato: **rinominare un elemento non aggiorna i riferimenti**,\r\n * e nessuna primitiva del backend lo fa (§13.8). Qui la riscrittura la fa il client, tramite\r\n * `FlowDocumentStore.renameNode`, e il form dice quanti riferimenti verranno riscritti prima\r\n * di farlo.\r\n *\r\n * Il corpo e' scelto per tipo. I tipi non supportati (`Step`, `Experiment`) non sono creabili\r\n * dalla palette, ma possono arrivare da un documento importato: in quel caso l'inspector li\r\n * mostra in sola lettura, dicendo perche'.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output, signal } from '@angular/core';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { START_NODE_NAME, UNSUPPORTED_TYPES } from '../../core/element-outlets';\r\nimport { checkFlowName, slugifyFlowName } from '../../core/flow-name.util';\r\nimport { FlowAnyNode } from '../../model/flow.model';\r\nimport { ActionCallInspectorComponent } from './action-call-inspector.component';\r\nimport { AssignmentInspectorComponent } from './assignment-inspector.component';\r\nimport { CollectionProcessorInspectorComponent } from './collection-processor-inspector.component';\r\nimport { CustomErrorInspectorComponent } from './custom-error-inspector.component';\r\nimport { DecisionInspectorComponent } from './decision-inspector.component';\r\nimport { LoopInspectorComponent } from './loop-inspector.component';\r\nimport { OrchestratedStageInspectorComponent } from './orchestrated-stage-inspector.component';\r\nimport { RecordLookupInspectorComponent } from './record-lookup-inspector.component';\r\nimport { RecordRollbackInspectorComponent } from './record-rollback-inspector.component';\r\nimport { RecordWriteInspectorComponent } from './record-write-inspector.component';\r\nimport { ScreenInspectorComponent } from './screen-inspector.component';\r\nimport { ScriptCallInspectorComponent } from './script-call-inspector.component';\r\nimport { StartInspectorComponent } from './start-inspector.component';\r\nimport { SubflowInspectorComponent } from './subflow-inspector.component';\r\nimport { TransformInspectorComponent } from './transform-inspector.component';\r\nimport { WaitInspectorComponent } from './wait-inspector.component';\r\n\r\n@Component({\r\n selector: 'fb-element-inspector',\r\n standalone: true,\r\n imports: [\r\n ActionCallInspectorComponent,\r\n AssignmentInspectorComponent,\r\n CollectionProcessorInspectorComponent,\r\n CustomErrorInspectorComponent,\r\n DecisionInspectorComponent,\r\n LoopInspectorComponent,\r\n OrchestratedStageInspectorComponent,\r\n RecordLookupInspectorComponent,\r\n RecordRollbackInspectorComponent,\r\n RecordWriteInspectorComponent,\r\n ScreenInspectorComponent,\r\n ScriptCallInspectorComponent,\r\n StartInspectorComponent,\r\n SubflowInspectorComponent,\r\n TransformInspectorComponent,\r\n WaitInspectorComponent,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-inspector.component.html',\r\n styleUrl: './element-inspector.component.css',\r\n})\r\nexport class ElementInspectorComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /** Il nome dell'elemento selezionato; `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n /**\r\n * `false` quando l'inspector e' dentro la dialog: lì il tipo e il titolo sono già\r\n * nell'intestazione della dialog, e ripeterli sprecherebbe la riga piu' preziosa.\r\n */\r\n readonly showHeader = input(true);\r\n\r\n readonly closed = output<void>();\r\n readonly removeRequested = output<string>();\r\n readonly duplicateRequested = output<string>();\r\n\r\n readonly isStart = computed(() => this.selectedName() === START_NODE_NAME);\r\n\r\n readonly reference = computed(() => {\r\n const name = this.selectedName();\r\n return name && name !== START_NODE_NAME ? this.store.nodeByName().get(name) : undefined;\r\n });\r\n\r\n readonly node = computed<FlowAnyNode | undefined>(() => this.reference()?.node);\r\n readonly type = computed(() => this.reference()?.type ?? '');\r\n readonly typeLabel = computed(() => (this.isStart() ? 'Avvio' : this.dictionaries.labelOf(this.type())));\r\n\r\n readonly isUnsupported = computed(() => {\r\n const type = this.type();\r\n if (!type) {\r\n return false;\r\n }\r\n const entry = this.dictionaries.elementType(type);\r\n if (entry?.isSupported === false) {\r\n return true;\r\n }\r\n return entry?.isSupported === undefined && UNSUPPORTED_TYPES.has(type);\r\n });\r\n\r\n /** I rilievi ancorati all'elemento (§7). */\r\n readonly issues = computed(() => {\r\n const name = this.selectedName();\r\n if (!name) {\r\n return [];\r\n }\r\n return this.validation.issuesByElement().get(this.isStart() ? '' : name) ?? [];\r\n });\r\n\r\n /** Il nome tecnico in modifica: si applica con un comando esplicito, non a ogni tasto. */\r\n readonly pendingName = signal<string | null>(null);\r\n\r\n readonly nameError = computed(() => {\r\n const pending = this.pendingName();\r\n if (pending === null) {\r\n return null;\r\n }\r\n const check = checkFlowName(pending, this.store.usedNames(), this.selectedName());\r\n return check.isValid ? null : (check.message ?? 'Nome non valido.');\r\n });\r\n\r\n /**\r\n * Quanti riferimenti verrebbero riscritti dalla rinomina. Serve a rendere visibile che\r\n * l'operazione tocca il resto del documento, non solo questo elemento.\r\n */\r\n readonly referenceCount = computed(() => {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return 0;\r\n }\r\n const serialized = JSON.stringify(this.store.document());\r\n // Conta le occorrenze del nome come valore di un campo di riferimento, incluso il caso\r\n // navigato (`Nome.Campo`).\r\n const pattern = new RegExp(`\"(${name})(\\\\.[A-Za-z0-9_.]+)?\"`, 'g');\r\n return (serialized.match(pattern) ?? []).length;\r\n });\r\n\r\n readonly canRename = computed(() => {\r\n const pending = this.pendingName();\r\n return pending !== null && pending !== this.selectedName() && !this.nameError();\r\n });\r\n\r\n startRename(): void {\r\n this.pendingName.set(this.selectedName());\r\n }\r\n\r\n onPendingNameInput(value: string): void {\r\n this.pendingName.set(value);\r\n }\r\n\r\n cancelRename(): void {\r\n this.pendingName.set(null);\r\n }\r\n\r\n /** Applica la rinomina riscrivendo tutti i riferimenti che raggiungono l'elemento. */\r\n applyRename(): void {\r\n const pending = this.pendingName();\r\n const current = this.selectedName();\r\n if (!pending || !current || !this.canRename()) {\r\n return;\r\n }\r\n this.store.renameNode(current, pending);\r\n this.pendingName.set(null);\r\n }\r\n\r\n setLabel(value: string): void {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return;\r\n }\r\n this.store.updateNode(name, (node) => {\r\n node.label = value || undefined;\r\n });\r\n }\r\n\r\n setDescription(value: string): void {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return;\r\n }\r\n this.store.updateNode(name, (node) => {\r\n node.description = value || undefined;\r\n });\r\n }\r\n\r\n /** Suggerisce il nome tecnico dalla label, come fa la creazione. */\r\n suggestNameFromLabel(): void {\r\n const node = this.node();\r\n if (!node?.label) {\r\n return;\r\n }\r\n this.pendingName.set(slugifyFlowName(node.label as string));\r\n }\r\n\r\n requestRemove(): void {\r\n const name = this.selectedName();\r\n if (name && !this.isStart()) {\r\n this.removeRequested.emit(name);\r\n }\r\n }\r\n\r\n requestDuplicate(): void {\r\n const name = this.selectedName();\r\n if (name && !this.isStart()) {\r\n this.duplicateRequested.emit(name);\r\n }\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n /** Le coordinate sono l'unica informazione di layout che il modello conserva (§3.5). */\r\n readonly position = computed(() => {\r\n const node = this.isStart() ? (this.store.start() as FlowAnyNode) : this.node();\r\n return { x: node?.locationX ?? 0, y: node?.locationY ?? 0 };\r\n });\r\n}\r\n","@if (!selectedName()) {\r\n <p class=\"fb-inspector__empty\">\r\n Seleziona un elemento sul canvas per modificarlo, oppure trascina un elemento dalla palette.\r\n </p>\r\n} @else {\r\n @if (showHeader()) {\r\n <header class=\"fb-inspector__header\">\r\n <div>\r\n <span class=\"fb-inspector__type\">{{ typeLabel() }}</span>\r\n <h2 class=\"fb-inspector__title\">\r\n {{ isStart() ? 'Avvio del flow' : node()?.label || selectedName() }}\r\n </h2>\r\n </div>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">\r\n ×\r\n </button>\r\n </header>\r\n }\r\n\r\n <div class=\"fb-inspector__body\">\r\n @if (issues().length) {\r\n <ul class=\"fb-inspector__issues\">\r\n <!-- `$index`: due rilievi con lo stesso codice e lo stesso path sono possibili. -->\r\n @for (issue of issues(); track $index) {\r\n <li\r\n class=\"fb-inspector__issue\"\r\n [class.fb-inspector__issue--error]=\"issue.severity === 'Error'\"\r\n [class.fb-inspector__issue--warning]=\"issue.severity === 'Warning'\"\r\n >\r\n <span class=\"fb-inspector__issue-code\">{{ issue.code }}</span>\r\n {{ issue.message }}\r\n @if (issue.path) {\r\n <span class=\"fb-inspector__issue-path\">{{ issue.path }}</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n\r\n @if (isUnsupported()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Questo tipo di elemento non e’ supportato dal motore: il flow che lo contiene non parte\r\n (ELEMENT_NOT_SUPPORTED). Non e’ creabile dalla palette; se e’ arrivato da un documento importato,\r\n va rimosso.\r\n </p>\r\n }\r\n\r\n @if (!isStart()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"$any(node()?.label) || ''\"\r\n placeholder=\"Nome mostrato sul canvas\"\r\n (input)=\"setLabel($any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Nome tecnico</label>\r\n @if (pendingName() === null) {\r\n <div class=\"fb-field__row\">\r\n <input class=\"fb-input fb-input--mono\" [value]=\"selectedName() || ''\" readonly />\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"startRename()\">Rinomina</button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n È l’identificatore con cui i riferimenti raggiungono questo elemento.\r\n @if (referenceCount() > 1) {\r\n Compare {{ referenceCount() }} volte nel documento.\r\n }\r\n </p>\r\n } @else {\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!nameError()\"\r\n [value]=\"pendingName() || ''\"\r\n (input)=\"onPendingNameInput($any($event.target).value)\"\r\n />\r\n @if (nameError()) {\r\n <p class=\"fb-field__error\">{{ nameError() }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n La rinomina riscrive tutti i riferimenti che puntano a questo elemento\r\n ({{ referenceCount() }} occorrenze): nessuna primitiva del backend lo fa, lo fa l’editor.\r\n </p>\r\n }\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"!canRename()\" (click)=\"applyRename()\">\r\n Applica\r\n </button>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"suggestNameFromLabel()\">Genera dalla label</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost\" (click)=\"cancelRename()\">Annulla</button>\r\n </div>\r\n }\r\n </div>\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]=\"$any(node()?.description) || ''\"\r\n (input)=\"setDescription($any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n }\r\n\r\n <p class=\"fb-inspector__position\">\r\n Posizione sul canvas: {{ position().x }}, {{ position().y }}\r\n </p>\r\n\r\n <hr class=\"fb-inspector__divider\" />\r\n\r\n @if (isStart()) {\r\n <fb-start-inspector />\r\n } @else if (node()) {\r\n @switch (type()) {\r\n @case ('Screen') {\r\n <fb-screen-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Assignment') {\r\n <fb-assignment-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Decision') {\r\n <fb-decision-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Loop') {\r\n <fb-loop-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('CollectionProcessor') {\r\n <fb-collection-processor-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('CustomError') {\r\n <fb-custom-error-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Wait') {\r\n <fb-wait-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('RecordLookup') {\r\n <fb-record-lookup-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('RecordCreate') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordCreate\" />\r\n }\r\n @case ('RecordUpdate') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordUpdate\" />\r\n }\r\n @case ('RecordDelete') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordDelete\" />\r\n }\r\n @case ('RecordRollback') {\r\n <fb-record-rollback-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('ActionCall') {\r\n <fb-action-call-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('ScriptCall') {\r\n <fb-script-call-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Subflow') {\r\n <fb-subflow-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Transform') {\r\n <fb-transform-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('OrchestratedStage') {\r\n <fb-orchestrated-stage-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @default {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Nessun form specifico per il tipo «{{ type() }}»: i campi comuni sono modificabili qui sopra.\r\n </p>\r\n }\r\n }\r\n }\r\n\r\n @if (!isStart()) {\r\n <hr class=\"fb-inspector__divider\" />\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"requestDuplicate()\">Duplica</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger\" (click)=\"requestRemove()\">Elimina</button>\r\n </div>\r\n }\r\n </div>\r\n}\r\n","/**\r\n * Il dettaglio dell'elemento in una dialog, come nel flow builder di Salesforce.\r\n *\r\n * Perche' una dialog e non solo il pannello laterale: i form degli elementi non hanno tutti\r\n * la stessa taglia. Uno Screen, una Decision con quattro regole o un Get Records con filtri\r\n * e ordinamento occupano piu' spazio di quanto ne abbia una colonna da 340px, e nel pannello\r\n * si scorreva molto. La dialog da' la larghezza necessaria e, mentre e' aperta, dichiara che\r\n * si sta configurando **quell'** elemento.\r\n *\r\n * Non c'e' un «Annulla»: le modifiche entrano nel documento mentre si digita, esattamente\r\n * come nel pannello, e tornare indietro e' compito dell'annulla generale dell'editor. Un\r\n * bottone che promettesse di scartare le modifiche solo di questa dialog mentirebbe, perche'\r\n * il documento e' uno e le modifiche sono già dentro.\r\n *\r\n * La dialog vive **dentro** il componente builder, non in fondo al `body`: la libreria e'\r\n * innestabile in una pagina qualsiasi e appropriarsi del `body` sarebbe una sorpresa per\r\n * l'applicazione ospite (dialog dell'ospite, `overflow`, stacking context).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { START_NODE_NAME } from '../../core/element-outlets';\r\nimport { ElementInspectorComponent } from './element-inspector.component';\r\n\r\n@Component({\r\n selector: 'fb-element-dialog',\r\n standalone: true,\r\n imports: [ElementInspectorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-dialog.component.html',\r\n styleUrl: './element-dialog.component.css',\r\n})\r\nexport class ElementDialogComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n /** L'elemento da configurare; `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n readonly closed = output<void>();\r\n readonly removeRequested = output<string>();\r\n readonly duplicateRequested = output<string>();\r\n\r\n private readonly panel = viewChild<ElementRef<HTMLElement>>('panel');\r\n\r\n readonly isStart = computed(() => this.selectedName() === START_NODE_NAME);\r\n\r\n private readonly reference = computed(() => {\r\n const name = this.selectedName();\r\n return name && !this.isStart() ? this.store.nodeByName().get(name) : undefined;\r\n });\r\n\r\n readonly typeLabel = computed(() =>\r\n this.isStart() ? 'Avvio del flow' : this.dictionaries.labelOf(this.reference()?.type ?? ''),\r\n );\r\n\r\n readonly title = computed(() => {\r\n if (this.isStart()) {\r\n return 'Avvio del flow';\r\n }\r\n const node = this.reference()?.node;\r\n return (node?.label as string) || this.selectedName() || '';\r\n });\r\n\r\n constructor() {\r\n // Il focus entra nella dialog quando cambia elemento: da tastiera si arriva subito ai\r\n // campi, e `Esc` chiude senza dover prima cliccare dentro.\r\n effect(() => {\r\n const name = this.selectedName();\r\n const panel = this.panel()?.nativeElement;\r\n if (name && panel) {\r\n panel.focus({ preventScroll: true });\r\n }\r\n });\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n onRemoveRequested(name: string): void {\r\n this.removeRequested.emit(name);\r\n }\r\n\r\n onDuplicateRequested(name: string): void {\r\n this.duplicateRequested.emit(name);\r\n }\r\n}\r\n","<!--\r\n Il backdrop chiude: e' il gesto che tutti si aspettano. Il pannello ferma la propagazione\r\n del click, altrimenti configurare un campo chiuderebbe la dialog.\r\n-->\r\n<div class=\"fb-dialog__backdrop\" (click)=\"close()\"></div>\r\n\r\n<div\r\n #panel\r\n class=\"fb-dialog__panel\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n [attr.aria-label]=\"typeLabel() + ': ' + title()\"\r\n tabindex=\"-1\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown.escape)=\"close()\"\r\n>\r\n <header class=\"fb-dialog__head\">\r\n <div class=\"fb-dialog__identity\">\r\n <span class=\"fb-dialog__type\">{{ typeLabel() }}</span>\r\n <h2 class=\"fb-dialog__title\">{{ title() }}</h2>\r\n </div>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n </header>\r\n\r\n <div class=\"fb-dialog__body\">\r\n <!-- L'intestazione dell'inspector qui e' quella della dialog: non si ripete. -->\r\n <fb-element-inspector\r\n [selectedName]=\"selectedName()\"\r\n [showHeader]=\"false\"\r\n (removeRequested)=\"onRemoveRequested($event)\"\r\n (duplicateRequested)=\"onDuplicateRequested($event)\"\r\n (closed)=\"close()\"\r\n />\r\n </div>\r\n\r\n <footer class=\"fb-dialog__foot\">\r\n <span class=\"fb-dialog__note\">\r\n Le modifiche sono già nel documento: per tornare indietro c’è l’annulla dell’editor.\r\n </span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" (click)=\"close()\">Fatto</button>\r\n </footer>\r\n</div>\r\n","/**\r\n * Le risorse — FRONTEND.md §4.6.\r\n *\r\n * Sette tipi, ognuno nella propria collection. **Solo le variabili sono scrivibili**:\r\n * assegnare a una costante o a una formula e' `TARGET_NOT_WRITABLE`, e per questo il\r\n * pannello mostra quali risorse possono comparire come destinazione e quali no.\r\n *\r\n * Il nome vive nello stesso spazio dei nomi dei node (§3.3): una variabile chiamata come un\r\n * elemento e' un errore, non una stranezza tollerata, e il controllo qui guarda **entrambi**\r\n * gli insiemi — e' la trappola §13.5.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore, FlowResourceRef } from '../../core/flow-document.store';\r\nimport { checkFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport { FlowResourceCollection, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\ninterface ResourceKindDescriptor {\r\n collection: FlowResourceCollection;\r\n label: string;\r\n singular: string;\r\n isWritable: boolean;\r\n /** Cosa serve dichiarare, in una riga. */\r\n note: string;\r\n}\r\n\r\n/**\r\n * Le sette collection. `resourceKinds` del dizionario le descrive, ma la mappa\r\n * collection → comportamento del form resta qui perche' i campi cambiano per tipo.\r\n */\r\nconst RESOURCE_KINDS: ResourceKindDescriptor[] = [\r\n {\r\n collection: 'variables',\r\n label: 'Variabili',\r\n singular: 'variabile',\r\n isWritable: true,\r\n note: 'Le sole risorse scrivibili: solo queste possono essere una destinazione.',\r\n },\r\n {\r\n collection: 'constants',\r\n label: 'Costanti',\r\n singular: 'costante',\r\n isWritable: false,\r\n note: 'Valore fisso: una costante non puo’ referenziare altre risorse.',\r\n },\r\n {\r\n collection: 'formulas',\r\n label: 'Formule',\r\n singular: 'formula',\r\n isWritable: false,\r\n note: 'L’espressione va al motore di regole: il backend non ne verifica la sintassi.',\r\n },\r\n {\r\n collection: 'textTemplates',\r\n label: 'Text template',\r\n singular: 'text template',\r\n isWritable: false,\r\n note: 'Testo con segnaposto, es. «Gentile {!Cliente.Nome},».',\r\n },\r\n {\r\n collection: 'choices',\r\n label: 'Choice',\r\n singular: 'choice',\r\n isWritable: false,\r\n note: 'Una singola scelta: testo mostrato piu’ valore.',\r\n },\r\n {\r\n collection: 'dynamicChoiceSets',\r\n label: 'Dynamic choice set',\r\n singular: 'dynamic choice set',\r\n isWritable: false,\r\n note: 'Scelte lette dal database. I filtri sono sempre in AND.',\r\n },\r\n {\r\n collection: 'stages',\r\n label: 'Stage',\r\n singular: 'stage',\r\n isWritable: false,\r\n note: 'Gli stage si fanno avanzare con un Assignment su $Flow.CurrentStage.',\r\n },\r\n];\r\n\r\n@Component({\r\n selector: 'fb-resource-panel',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ObjectPickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './resource-panel.component.html',\r\n styleUrl: './resource-panel.component.css',\r\n})\r\nexport class ResourcePanelComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly closed = output<void>();\r\n\r\n readonly kinds = RESOURCE_KINDS;\r\n readonly dataTypes = computed(() => this.dictionaries.dataTypes());\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n private readonly enumTypes = signal<FlowCatalogEntry[]>([]);\r\n\r\n /** La collection aperta nel pannello. */\r\n readonly activeCollection = signal<FlowResourceCollection>('variables');\r\n /** L'indice della risorsa in modifica, o `null`. */\r\n readonly editingIndex = signal<number | null>(null);\r\n\r\n constructor() {\r\n void this.catalog.listEnumTypes().then((list) => this.enumTypes.set(list ?? []));\r\n }\r\n\r\n readonly enumOptions = computed(() => this.enumTypes());\r\n\r\n readonly activeKind = computed<ResourceKindDescriptor>(\r\n () => RESOURCE_KINDS.find((kind) => kind.collection === this.activeCollection()) ?? RESOURCE_KINDS[0],\r\n );\r\n\r\n readonly items = computed<FlowResourceRef[]>(() =>\r\n this.store.resources().filter((reference) => reference.collection === this.activeCollection()),\r\n );\r\n\r\n countOf(collection: FlowResourceCollection): number {\r\n return this.store.resources().filter((reference) => reference.collection === collection).length;\r\n }\r\n\r\n select(collection: FlowResourceCollection): void {\r\n this.activeCollection.set(collection);\r\n this.editingIndex.set(null);\r\n }\r\n\r\n toggleEdit(index: number): void {\r\n this.editingIndex.set(this.editingIndex() === index ? null : index);\r\n }\r\n\r\n /** Nome valido e libero nello spazio dei nomi condiviso con i node (§3.3, §13.5). */\r\n nameError(reference: FlowResourceRef): string | null {\r\n const check = checkFlowName(reference.name, this.store.usedNames(), reference.name);\r\n if (!check.isValid) {\r\n return check.message ?? 'Nome non valido.';\r\n }\r\n // Un omonimo di un node: il controllo di unicita' che guarda solo le risorse lo manca.\r\n const clashes = this.store\r\n .usedNames()\r\n .filter((name) => name.toLowerCase() === reference.name.toLowerCase());\r\n return clashes.length > 1 ? 'Questo nome e’ usato anche da un altro elemento o risorsa.' : null;\r\n }\r\n\r\n add(): void {\r\n const kind = this.activeKind();\r\n const name = uniqueFlowName(kind.singular.replace(/\\s+/g, '_'), this.store.usedNames());\r\n const resource: Record<string, unknown> = { name };\r\n // `dataType` e' obbligatorio su variabili, costanti, formule, choice e choice set (§4.6).\r\n if (kind.collection !== 'textTemplates' && kind.collection !== 'stages') {\r\n resource['dataType'] = 'String';\r\n }\r\n if (kind.collection === 'stages') {\r\n // Gli `stageOrder` devono essere distinti: si parte dal primo libero.\r\n const used = new Set(\r\n this.store\r\n .resources()\r\n .filter((entry) => entry.collection === 'stages')\r\n .map((entry) => entry.resource['stageOrder'] as number),\r\n );\r\n let order = 1;\r\n while (used.has(order)) {\r\n order += 1;\r\n }\r\n resource['stageOrder'] = order;\r\n resource['isActive'] = true;\r\n resource['label'] = name;\r\n }\r\n this.store.addResource(kind.collection, resource);\r\n this.editingIndex.set(this.items().length);\r\n }\r\n\r\n remove(reference: FlowResourceRef): void {\r\n this.store.removeResource(reference.collection, reference.index);\r\n this.editingIndex.set(null);\r\n }\r\n\r\n rename(reference: FlowResourceRef, name: string): void {\r\n // Rinominare riscrive i riferimenti: nessuna primitiva lo fa per noi (§13.8).\r\n this.store.renameResource(reference.collection, reference.index, name);\r\n }\r\n\r\n setField(reference: FlowResourceRef, field: string, value: unknown): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value === undefined || value === null || value === '') {\r\n delete resource[field];\r\n } else {\r\n resource[field] = value;\r\n }\r\n });\r\n }\r\n\r\n setNumberField(reference: FlowResourceRef, field: string, raw: string): void {\r\n const parsed = Number.parseInt(raw, 10);\r\n this.setField(reference, field, Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n setBooleanField(reference: FlowResourceRef, field: string, value: boolean): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value) {\r\n resource[field] = true;\r\n } else {\r\n delete resource[field];\r\n }\r\n });\r\n }\r\n\r\n setValue(reference: FlowResourceRef, value: FlowValue | undefined): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value) {\r\n resource['value'] = value;\r\n } else {\r\n delete resource['value'];\r\n }\r\n });\r\n }\r\n\r\n setDataType(reference: FlowResourceRef, dataType: string): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n resource['dataType'] = dataType;\r\n if (!this.dictionaries.requiresObjectType(dataType)) {\r\n delete resource['objectType'];\r\n }\r\n // `scale` si applica solo ai numerici: altrove e' `SCALE_NOT_APPLICABLE`.\r\n if (!this.dictionaries.supportsScale(dataType)) {\r\n delete resource['scale'];\r\n }\r\n });\r\n }\r\n\r\n requiresObjectType(reference: FlowResourceRef): boolean {\r\n return this.dictionaries.requiresObjectType(reference.resource['dataType'] as string);\r\n }\r\n\r\n supportsScale(reference: FlowResourceRef): boolean {\r\n return this.dictionaries.supportsScale(reference.resource['dataType'] as string);\r\n }\r\n\r\n isEnum(reference: FlowResourceRef): boolean {\r\n return reference.resource['dataType'] === 'Enum';\r\n }\r\n\r\n /** Una costante che referenzia una risorsa e' `CONSTANT_REFERENCES_RESOURCE`. */\r\n constantReferencesResource(reference: FlowResourceRef): boolean {\r\n if (reference.collection !== 'constants') {\r\n return false;\r\n }\r\n const value = reference.resource['value'] as FlowValue | undefined;\r\n return !!value?.elementReference || !!value?.formulaExpression;\r\n }\r\n\r\n /** `stageOrder` duplicati: quale stage sia il corrente all'avvio diventa arbitrario. */\r\n duplicateStageOrder(reference: FlowResourceRef): boolean {\r\n if (reference.collection !== 'stages') {\r\n return false;\r\n }\r\n const order = reference.resource['stageOrder'];\r\n if (order === undefined) {\r\n return false;\r\n }\r\n return (\r\n this.store\r\n .resources()\r\n .filter((entry) => entry.collection === 'stages' && entry.resource['stageOrder'] === order).length > 1\r\n );\r\n }\r\n\r\n string(reference: FlowResourceRef, field: string): string {\r\n const value = reference.resource[field];\r\n return value === undefined || value === null ? '' : String(value);\r\n }\r\n\r\n boolean(reference: FlowResourceRef, field: string): boolean {\r\n return reference.resource[field] === true;\r\n }\r\n\r\n value(reference: FlowResourceRef): FlowValue | undefined {\r\n return reference.resource['value'] as FlowValue | undefined;\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-res__header\">\r\n <h2 class=\"fb-res__title\">Risorse</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<nav class=\"fb-res__tabs\" aria-label=\"Tipi di risorsa\">\r\n @for (kind of kinds; track kind.collection) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-res__tab\"\r\n [class.fb-res__tab--active]=\"activeCollection() === kind.collection\"\r\n (click)=\"select(kind.collection)\"\r\n >\r\n {{ kind.label }}\r\n <span class=\"fb-res__count\">{{ countOf(kind.collection) }}</span>\r\n </button>\r\n }\r\n</nav>\r\n\r\n<div class=\"fb-res__body\">\r\n <p class=\"fb-section__note\">{{ activeKind().note }}</p>\r\n\r\n <div class=\"fb-list\">\r\n @for (item of items(); track item.collection + ':' + item.index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <button type=\"button\" class=\"fb-res__name\" (click)=\"toggleEdit($index)\">\r\n <span class=\"fb-res__name-text\">{{ item.name || '(senza nome)' }}</span>\r\n <span class=\"fb-res__meta\">\r\n {{ string(item, 'dataType') }}{{ boolean(item, 'isCollection') ? '[]' : '' }}\r\n @if (boolean(item, 'isInput')) {\r\n · input\r\n }\r\n @if (boolean(item, 'isOutput')) {\r\n · output\r\n }\r\n </span>\r\n </button>\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 la risorsa\"\r\n (click)=\"remove(item)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n @if (nameError(item)) {\r\n <p class=\"fb-field__error\">{{ nameError(item) }}</p>\r\n }\r\n @if (constantReferencesResource(item)) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Una costante deve essere un valore fisso: non puo’ referenziare altre risorse\r\n (CONSTANT_REFERENCES_RESOURCE).\r\n </p>\r\n }\r\n @if (duplicateStageOrder(item)) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Due stage con lo stesso ordine: quale sia il corrente all’avvio diventa arbitrario\r\n (STAGE_ORDER_DUPLICATED).\r\n </p>\r\n }\r\n\r\n @if (editingIndex() === $index) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Nome</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [value]=\"item.name\"\r\n (change)=\"rename(item, $any($event.target).value)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Il nome vive nello stesso spazio dei nomi degli elementi. Rinominare riscrive i riferimenti.\r\n </p>\r\n </div>\r\n\r\n @if (item.collection === 'stages') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'label')\"\r\n (input)=\"setField(item, 'label', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Ordine</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"string(item, 'stageOrder')\"\r\n (input)=\"setNumberField(item, 'stageOrder', $any($event.target).value)\"\r\n />\r\n </div>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isActive')\"\r\n (change)=\"setBooleanField(item, 'isActive', $any($event.target).checked)\"\r\n />\r\n Attivo all’avvio\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n All’avvio lo stage corrente e’ il primo attivo per ordine. Si avanza con un Assignment su\r\n <code>$Flow.CurrentStage</code>.\r\n </p>\r\n }\r\n\r\n @if (item.collection === 'textTemplates') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Testo</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"string(item, 'text')\"\r\n placeholder=\"Gentile {!Cliente.Nome},\"\r\n (input)=\"setField(item, 'text', $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isViewedAsPlainText')\"\r\n (change)=\"setBooleanField(item, 'isViewedAsPlainText', $any($event.target).checked)\"\r\n />\r\n Testo semplice\r\n </label>\r\n }\r\n\r\n @if (item.collection !== 'textTemplates' && item.collection !== 'stages') {\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]=\"string(item, 'dataType')\"\r\n (change)=\"setDataType(item, $any($event.target).value)\"\r\n >\r\n @for (type of dataTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (requiresObjectType(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">\r\n {{ isEnum(item) ? 'Tipo di enumerazione' : 'Oggetto' }}\r\n </label>\r\n @if (isEnum(item)) {\r\n <!-- Dizionario chiuso: qui la scrittura libera non serve. -->\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"string(item, 'objectType')\"\r\n (change)=\"setField(item, 'objectType', $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of enumOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n } @else {\r\n <fb-object-picker\r\n [value]=\"string(item, 'objectType') || undefined\"\r\n label=\"Oggetto\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setField(item, 'objectType', $event ?? '')\"\r\n />\r\n }\r\n <p class=\"fb-field__hint\">Obbligatorio per Object ed Enum (OBJECT_TYPE_MISSING).</p>\r\n </div>\r\n }\r\n\r\n @if (supportsScale(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Decimali</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"0\"\r\n [value]=\"string(item, 'scale')\"\r\n (input)=\"setNumberField(item, 'scale', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n @if (item.collection === 'variables') {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isCollection')\"\r\n (change)=\"setBooleanField(item, 'isCollection', $any($event.target).checked)\"\r\n />\r\n È una collection\r\n </label>\r\n <p class=\"fb-field__hint\">Solo una collection puo’ essere iterata da un Loop.</p>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isInput')\"\r\n (change)=\"setBooleanField(item, 'isInput', $any($event.target).checked)\"\r\n />\r\n Valorizzabile all’avvio (input)\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isOutput')\"\r\n (change)=\"setBooleanField(item, 'isOutput', $any($event.target).checked)\"\r\n />\r\n Leggibile alla fine (output)\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n Input e output sono il contratto del flow verso chi lo invoca, subflow compresi.\r\n </p>\r\n }\r\n\r\n @if (item.collection === 'formulas') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Espressione</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"string(item, 'expression')\"\r\n placeholder=\"Importo * 1.22\"\r\n (input)=\"setField(item, 'expression', $any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">\r\n Passata verbatim al motore di regole: il backend non la valida.\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (item.collection === 'choices') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Testo mostrato</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'choiceText')\"\r\n (input)=\"setField(item, 'choiceText', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (item.collection === 'dynamicChoiceSets') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"string(item, 'object') || undefined\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setField(item, 'object', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo mostrato</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'displayField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"any\"\r\n label=\"Campo mostrato\"\r\n (valueChange)=\"setField(item, 'displayField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo del valore</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'valueField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"any\"\r\n label=\"Campo del valore\"\r\n (valueChange)=\"setField(item, 'valueField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordina per</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'sortField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"sortable\"\r\n label=\"Campo di ordinamento\"\r\n placeholder=\"Nessun ordinamento\"\r\n (valueChange)=\"setField(item, 'sortField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"string(item, 'sortOrder')\"\r\n (change)=\"setField(item, 'sortOrder', $any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"string(item, 'limit')\"\r\n (input)=\"setNumberField(item, 'limit', $any($event.target).value)\"\r\n />\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n I filtri di un dynamic choice set sono sempre in AND: non c’e’ logica personalizzata.\r\n </p>\r\n }\r\n\r\n @if (\r\n item.collection === 'variables' || item.collection === 'constants' || item.collection === 'choices'\r\n ) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ item.collection === 'variables' ? 'Valore iniziale' : 'Valore' }}\r\n </label>\r\n <fb-value-editor\r\n [value]=\"value(item)\"\r\n [dataType]=\"$any(item.resource['dataType'])\"\r\n [objectType]=\"$any(item.resource['objectType'])\"\r\n [isCollection]=\"boolean(item, 'isCollection')\"\r\n [allowFormula]=\"item.collection !== 'constants'\"\r\n label=\"Valore\"\r\n (valueChange)=\"setValue(item, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Descrizione</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'description')\"\r\n (input)=\"setField(item, 'description', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna risorsa di questo tipo.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" (click)=\"add()\">\r\n Aggiungi {{ activeKind().singular }}\r\n </button>\r\n</div>\r\n","/**\r\n * Il pannello dei problemi — FRONTEND.md §7.\r\n *\r\n * I rilievi arrivano ordinati per gravita' decrescente. `code` e' stabile e si usa per\r\n * raggruppare e per decidere il comportamento; `message` e' testo per l'utente e non va\r\n * interpretato. `elementName` e' l'ancora per portare l'utente sull'elemento con un clic.\r\n *\r\n * Tre effetti che l'interfaccia deve rispettare:\r\n * - `Error` blocca l'**attivazione**, non il salvataggio;\r\n * - `Warning` non blocca nulla, ma dice che qualcosa non fara' cio' che sembra;\r\n * - l'assenza di rilievi **non** e' una garanzia di correttezza: la validazione non verifica\r\n * i percorsi di relazione, la sintassi delle formule, ne' i cataloghi non popolati.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowValidationIssue } from '../../model/api.model';\r\nimport { START_NODE_NAME } from '../../core/element-outlets';\r\n\r\ntype SeverityFilter = 'all' | 'Error' | 'Warning' | 'Info';\r\n\r\n@Component({\r\n selector: 'fb-problems-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './problems-panel.component.html',\r\n styleUrl: './problems-panel.component.css',\r\n})\r\nexport class ProblemsPanelComponent {\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /** Chiede di selezionare l'elemento: `$start` per i rilievi sul documento. */\r\n readonly elementFocused = output<string>();\r\n readonly closed = output<void>();\r\n\r\n readonly filter = signal<SeverityFilter>('all');\r\n\r\n readonly isRunning = computed(() => this.validation.isRunning());\r\n readonly hasResult = computed(() => this.validation.hasResult());\r\n readonly lastError = computed(() => this.validation.lastError());\r\n readonly errorCount = computed(() => this.validation.errorCount());\r\n readonly warningCount = computed(() => this.validation.warningCount());\r\n readonly infoCount = computed(() => this.validation.infoCount());\r\n\r\n readonly issues = computed<FlowValidationIssue[]>(() => {\r\n const filter = this.filter();\r\n const issues = this.validation.issues();\r\n return filter === 'all' ? issues : issues.filter((issue) => issue.severity === filter);\r\n });\r\n\r\n readonly isClean = computed(() => this.hasResult() && this.validation.issues().length === 0);\r\n\r\n setFilter(filter: SeverityFilter): void {\r\n this.filter.set(filter);\r\n }\r\n\r\n focus(issue: FlowValidationIssue): void {\r\n // Un rilievo senza `elementName` riguarda il documento: l'ancora piu' vicina e' lo Start.\r\n this.elementFocused.emit(issue.elementName || START_NODE_NAME);\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-prob__header\">\r\n <h2 class=\"fb-prob__title\">\r\n Problemi\r\n @if (isRunning()) {\r\n <span class=\"fb-prob__running\">validazione in corso…</span>\r\n }\r\n </h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<nav class=\"fb-prob__filters\" aria-label=\"Filtra per gravita’\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter\"\r\n [class.fb-prob__filter--active]=\"filter() === 'all'\"\r\n (click)=\"setFilter('all')\"\r\n >\r\n Tutti\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter fb-prob__filter--error\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Error'\"\r\n (click)=\"setFilter('Error')\"\r\n >\r\n Errori <span class=\"fb-prob__count\">{{ errorCount() }}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter fb-prob__filter--warning\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Warning'\"\r\n (click)=\"setFilter('Warning')\"\r\n >\r\n Avvisi <span class=\"fb-prob__count\">{{ warningCount() }}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Info'\"\r\n (click)=\"setFilter('Info')\"\r\n >\r\n Note <span class=\"fb-prob__count\">{{ infoCount() }}</span>\r\n </button>\r\n</nav>\r\n\r\n<div class=\"fb-prob__body\">\r\n @if (lastError()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Non e’ stato possibile validare: {{ lastError() }}\r\n </p>\r\n }\r\n\r\n @if (!hasResult() && !isRunning()) {\r\n <p class=\"fb-empty\">La validazione non e’ ancora stata eseguita.</p>\r\n }\r\n\r\n @if (isClean()) {\r\n <p class=\"fb-empty\">\r\n Nessun rilievo. Attenzione: non e’ una garanzia di correttezza — la validazione non verifica i percorsi\r\n di relazione nei campi, la sintassi delle formule, ne’ action, form e parametri quando il catalogo\r\n corrispondente non e’ popolato.\r\n </p>\r\n }\r\n\r\n <ul class=\"fb-prob__list\">\r\n <!-- `$index`: due rilievi possono avere codice, elemento e path identici (due condizioni\r\n incomplete nella stessa regola), e una chiave duplicata e' un errore di Angular. -->\r\n @for (issue of issues(); track $index) {\r\n <li\r\n class=\"fb-prob__item\"\r\n [class.fb-prob__item--error]=\"issue.severity === 'Error'\"\r\n [class.fb-prob__item--warning]=\"issue.severity === 'Warning'\"\r\n >\r\n <button type=\"button\" class=\"fb-prob__link\" (click)=\"focus(issue)\">\r\n <span class=\"fb-prob__message\">{{ issue.message }}</span>\r\n <span class=\"fb-prob__meta\">\r\n <code>{{ issue.code }}</code>\r\n @if (issue.elementName) {\r\n · {{ issue.elementName }}\r\n }\r\n @if (issue.path) {\r\n · {{ issue.path }}\r\n }\r\n </span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n\r\n @if (errorCount() > 0) {\r\n <p class=\"fb-prob__note\">\r\n Gli errori bloccano l’<strong>attivazione</strong>, non il salvataggio: puoi interrompere il lavoro a\r\n metà e riprenderlo.\r\n </p>\r\n }\r\n</div>\r\n","/**\r\n * Versioni e ciclo di vita — FRONTEND.md §8, §9.\r\n *\r\n * Le quattro regole che l'interfaccia deve rispettare, tutte visibili qui:\r\n * 1. **si modifica una bozza**: su una versione non modificabile il comando e' \"Nuova\r\n * versione\", non \"Salva\" — `isEditable` arriva dal backend e non si ricalcola;\r\n * 2. una bozza si salva anche con errori, e finisce in `InvalidDraft`;\r\n * 3. **attivare esige zero errori**;\r\n * 4. una sola versione attiva: attivarne una rende `Obsolete` la precedente.\r\n *\r\n * L'eliminazione di una versione e' offerta dietro conferma esplicita, perche' il numero\r\n * piu' alto viene riassegnato e un'esecuzione sospesa nata su quel numero riprenderebbe su\r\n * una definizione diversa (§8, ultimo capoverso).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowEditorSession } from '../../core/flow-editor-session';\r\nimport { FlowVersionSummary } from '../../model/api.model';\r\n\r\n@Component({\r\n selector: 'fb-version-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './version-panel.component.html',\r\n styleUrl: './version-panel.component.css',\r\n})\r\nexport class VersionPanelComponent {\r\n private readonly session = inject(FlowEditorSession);\r\n\r\n readonly closed = output<void>();\r\n readonly versionOpened = output<number>();\r\n /** Comunica un esito all'host, che lo mostra come notifica. */\r\n readonly notice = output<{ kind: 'info' | 'error'; message: string }>();\r\n\r\n readonly versions = computed(() => this.session.versions());\r\n readonly currentVersion = computed(() => this.session.version());\r\n readonly isBusy = computed(() => this.session.isBusy());\r\n readonly canActivate = computed(() => this.session.canActivate());\r\n\r\n /** La versione per cui e' stata chiesta l'eliminazione: conferma in due passi. */\r\n readonly pendingDelete = signal<number | null>(null);\r\n\r\n isCurrent(version: FlowVersionSummary): boolean {\r\n return version.version === this.currentVersion();\r\n }\r\n\r\n statusLabel(version: FlowVersionSummary): string {\r\n switch (version.status) {\r\n case 'Draft':\r\n return 'Bozza';\r\n case 'InvalidDraft':\r\n return 'Bozza con errori';\r\n case 'UnderReview':\r\n return 'In approvazione';\r\n case 'Active':\r\n return 'Attiva';\r\n case 'Obsolete':\r\n return 'Superata';\r\n default:\r\n return version.status ?? '';\r\n }\r\n }\r\n\r\n open(version: FlowVersionSummary): void {\r\n this.versionOpened.emit(version.version);\r\n }\r\n\r\n async activate(version: FlowVersionSummary): Promise<void> {\r\n if (version.version !== this.currentVersion()) {\r\n // L'attivazione agisce sulla versione caricata: prima la si apre.\r\n this.versionOpened.emit(version.version);\r\n return;\r\n }\r\n try {\r\n const result = await this.session.activate();\r\n this.notice.emit({ kind: 'info', message: `Versione ${result.version} attivata.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Attivazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n async deactivate(): Promise<void> {\r\n try {\r\n await this.session.deactivate();\r\n this.notice.emit({ kind: 'info', message: 'Flow disattivato: non e’ piu’ eseguibile.' });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Disattivazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n async createNewVersion(): Promise<void> {\r\n try {\r\n const result = await this.session.createNewVersion();\r\n this.notice.emit({ kind: 'info', message: `Creata la versione ${result.version}.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Creazione della versione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n requestDelete(version: FlowVersionSummary): void {\r\n this.pendingDelete.set(version.version);\r\n }\r\n\r\n cancelDelete(): void {\r\n this.pendingDelete.set(null);\r\n }\r\n\r\n async confirmDelete(version: number): Promise<void> {\r\n this.pendingDelete.set(null);\r\n try {\r\n await this.session.deleteVersion(version);\r\n this.notice.emit({ kind: 'info', message: `Versione ${version} eliminata.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Eliminazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n readonly hasActiveVersion = computed(() => this.versions().some((version) => version.isActive));\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-ver__header\">\r\n <h2 class=\"fb-ver__title\">Versioni</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<div class=\"fb-ver__body\">\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isBusy()\" (click)=\"createNewVersion()\">\r\n Nuova versione dalla corrente\r\n </button>\r\n @if (hasActiveVersion()) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger\" [disabled]=\"isBusy()\" (click)=\"deactivate()\">\r\n Disattiva\r\n </button>\r\n }\r\n </div>\r\n\r\n <ul class=\"fb-ver__list\">\r\n @for (version of versions(); track version.version) {\r\n <li class=\"fb-ver__item\" [class.fb-ver__item--current]=\"isCurrent(version)\">\r\n <div class=\"fb-ver__row\">\r\n <button type=\"button\" class=\"fb-ver__open\" (click)=\"open(version)\">\r\n <span class=\"fb-ver__number\">v{{ version.version }}</span>\r\n <span\r\n class=\"fb-ver__status\"\r\n [class.fb-ver__status--active]=\"version.isActive\"\r\n [class.fb-ver__status--invalid]=\"version.status === 'InvalidDraft'\"\r\n >\r\n {{ statusLabel(version) }}\r\n </span>\r\n @if (isCurrent(version)) {\r\n <span class=\"fb-ver__badge\">aperta</span>\r\n }\r\n </button>\r\n </div>\r\n\r\n <p class=\"fb-ver__meta\">\r\n @if (version.updatedAt) {\r\n aggiornata {{ version.updatedAt }}\r\n }\r\n @if (version.updatedBy) {\r\n da {{ version.updatedBy }}\r\n }\r\n </p>\r\n\r\n <div class=\"fb-ver__actions\">\r\n @if (version.isEditable) {\r\n <span class=\"fb-ver__hint\">Modificabile</span>\r\n } @else {\r\n <!-- Salvare su una versione Active o Obsolete verrebbe rifiutato con NotEditable. -->\r\n <span class=\"fb-ver__hint\">Sola lettura: per modificarla, creane una nuova</span>\r\n }\r\n\r\n @if (!version.isActive && isCurrent(version)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary fb-btn--icon\"\r\n [disabled]=\"isBusy() || !canActivate()\"\r\n [title]=\"canActivate() ? 'Attiva questa versione' : 'Ci sono errori da correggere prima di attivare'\"\r\n (click)=\"activate(version)\"\r\n >\r\n Attiva\r\n </button>\r\n }\r\n\r\n @if (!version.isActive) {\r\n @if (pendingDelete() === version.version) {\r\n <span class=\"fb-ver__confirm\">\r\n Le esecuzioni sospese nate su questo numero riprenderebbero su una definizione diversa.\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger fb-btn--icon\" (click)=\"confirmDelete(version.version)\">\r\n Elimina comunque\r\n </button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"cancelDelete()\">\r\n Annulla\r\n </button>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n [disabled]=\"isBusy()\"\r\n (click)=\"requestDelete(version)\"\r\n >\r\n Elimina\r\n </button>\r\n }\r\n }\r\n </div>\r\n </li>\r\n } @empty {\r\n <li class=\"fb-empty\">Nessuna versione: il flow non e’ ancora stato salvato.</li>\r\n }\r\n </ul>\r\n\r\n <p class=\"fb-ver__note\">\r\n Una sola versione e’ attiva: attivarne una rende superata la precedente, senza doverla disattivare prima.\r\n Le versioni superate costano poco — lo stato «Superata» esiste per questo.\r\n </p>\r\n</div>\r\n","/**\r\n * Provare un flow dall'editor — FRONTEND.md §6.5, §11 (\"Provare\").\r\n *\r\n * Sei cose che questo pannello tratta come dette:\r\n * 1. `status: 'Failed'` **non** e' un errore di trasporto: la richiesta e' riuscita, il flow\r\n * e' fallito. E `NotStarted` significa che i criteri dello Start non erano soddisfatti,\r\n * che non e' un errore.\r\n * 2. il `continuationToken` va rimandato **tale e quale**: e' opaco, non viene letto ne'\r\n * modificato, e non finisce in nessun URL.\r\n * 3. `canGoBack`/`canFinish`/`canPause` di `pendingScreen` sono la verita' su cosa\r\n * abilitare, piu' precisa dei flag del metadata.\r\n * 4. con `Previous` e `Pause` gli output **non** vengono memorizzati: i valori inseriti non\r\n * sono definitivi, e il pannello lo dice.\r\n * 5. `debug: true` popola `trace` e `resources` — **e riporta anche i dati personali**:\r\n * l'avviso e' in chiaro, non nascosto in una tooltip.\r\n * 6. `Suspended` copre due attese diverse — un evento e uno step di orchestrazione — e le\r\n * distinguono `isWaitingForEvent` / `isWaitingForStageStep`. Nel secondo caso si puo'\r\n * concludere lo step da qui, e la risposta puo' portare una `interviewKey` **nuova**: la\r\n * vecchia non e' piu' valida, quindi si sostituisce invece di conservarla (§5.13).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowEditorSession } from '../../core/flow-editor-session';\r\nimport {\r\n FlowInterviewResult,\r\n FlowScreenNavigation,\r\n FlowStageStepState,\r\n FlowStageStepStatus,\r\n FlowTypedValue,\r\n} from '../../model/api.model';\r\nimport { FlowApiError } from '../../model/error.model';\r\nimport { FlowVariable } from '../../model/flow.model';\r\n\r\n@Component({\r\n selector: 'fb-debug-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './debug-panel.component.html',\r\n styleUrl: './debug-panel.component.css',\r\n})\r\nexport class DebugPanelComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly session = inject(FlowEditorSession);\r\n\r\n readonly closed = output<void>();\r\n /** Chiede all'host di evidenziare l'elemento corrente dell'esecuzione. */\r\n readonly elementFocused = output<string>();\r\n\r\n readonly result = signal<FlowInterviewResult | null>(null);\r\n readonly isRunning = signal(false);\r\n readonly errorMessage = signal<string | null>(null);\r\n readonly debugEnabled = signal(true);\r\n\r\n /** I valori che l'utente compila nel piccolo form generato dalle variabili di input. */\r\n readonly inputValues = signal<Record<string, string>>({});\r\n /** I valori raccolti per lo screen corrente, per nome di `outputParameters`. */\r\n readonly screenOutputs = signal<Record<string, string>>({});\r\n\r\n /** Le variabili `isInput` del flow: il contratto verso chi lo invoca (§4.6). */\r\n readonly inputVariables = computed<FlowVariable[]>(\r\n () => this.store.document().variables?.filter((variable) => variable.isInput) ?? [],\r\n );\r\n\r\n readonly canRun = computed(() => !this.session.isNew() && !this.isRunning());\r\n\r\n readonly status = computed(() => this.result()?.status ?? null);\r\n readonly pendingScreen = computed(() => this.result()?.pendingScreen ?? null);\r\n readonly isWaitingForScreen = computed(() => this.status() === 'WaitingForScreen');\r\n\r\n /** §5.13 — l'attesa e' su uno step assegnato a una persona, non su un evento. */\r\n readonly isWaitingForStageStep = computed(() => this.result()?.isWaitingForStageStep === true);\r\n readonly stageSteps = computed<FlowStageStepState[]>(() => this.result()?.stageSteps ?? []);\r\n /** Lo step su cui c'e' un work item aperto: e' quello che si puo' concludere. */\r\n readonly waitingStageSteps = computed(() => this.stageSteps().filter((step) => step.isWaiting));\r\n\r\n /** I valori con cui si conclude uno step, per nome di output. */\r\n readonly stepOutputs = signal<Record<string, string>>({});\r\n\r\n readonly trace = computed(() => this.result()?.trace ?? []);\r\n\r\n /** Le risorse come righe ordinate: il tipo dichiarato vince in lettura (§6.5). */\r\n readonly resourceRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const resources = this.result()?.resources ?? {};\r\n return Object.entries(resources)\r\n .map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }))\r\n .sort((left, right) => left.name.localeCompare(right.name));\r\n });\r\n\r\n readonly outputRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const outputs = this.result()?.outputs ?? {};\r\n return Object.entries(outputs).map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }));\r\n });\r\n\r\n /** Gli input che lo screen corrente riceve, per mostrarli accanto al form generico. */\r\n readonly screenInputRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const inputs = this.pendingScreen()?.inputs ?? {};\r\n return Object.entries(inputs).map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }));\r\n });\r\n\r\n /** I nomi degli output dichiarati dallo screen, per generare i campi da compilare. */\r\n readonly screenOutputNames = computed<string[]>(() => {\r\n const elementName = this.pendingScreen()?.elementName;\r\n if (!elementName) {\r\n return [];\r\n }\r\n const screen = this.store.document().screens?.find((candidate) => candidate.name === elementName);\r\n return (screen?.outputParameters ?? []).map((parameter) => parameter.name ?? '').filter(Boolean);\r\n });\r\n\r\n private static render(typed: FlowTypedValue | undefined): string {\r\n if (!typed || typed.value === undefined || typed.value === null) {\r\n return '—';\r\n }\r\n if (typeof typed.value === 'object') {\r\n return JSON.stringify(typed.value);\r\n }\r\n return String(typed.value);\r\n }\r\n\r\n setDebugEnabled(value: boolean): void {\r\n this.debugEnabled.set(value);\r\n }\r\n\r\n setInputValue(name: string, value: string): void {\r\n this.inputValues.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n setScreenOutput(name: string, value: string): void {\r\n this.screenOutputs.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n /** Converte i valori del form nel tipo dichiarato dalla variabile. */\r\n private coerceInputs(): Record<string, unknown> {\r\n const values = this.inputValues();\r\n const result: Record<string, unknown> = {};\r\n for (const variable of this.inputVariables()) {\r\n const name = variable.name;\r\n if (!name) {\r\n continue;\r\n }\r\n const raw = values[name];\r\n if (raw === undefined || raw === '') {\r\n continue;\r\n }\r\n switch (variable.dataType) {\r\n case 'Integer': {\r\n const parsed = Number.parseInt(raw, 10);\r\n if (!Number.isNaN(parsed)) {\r\n result[name] = parsed;\r\n }\r\n break;\r\n }\r\n case 'Number': {\r\n const parsed = Number.parseFloat(raw);\r\n if (!Number.isNaN(parsed)) {\r\n result[name] = parsed;\r\n }\r\n break;\r\n }\r\n case 'Boolean':\r\n result[name] = raw === 'true';\r\n break;\r\n default:\r\n result[name] = raw;\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async start(): Promise<void> {\r\n const flowName = this.session.flowName();\r\n if (!flowName) {\r\n this.errorMessage.set('Salva il flow prima di provarlo.');\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n this.screenOutputs.set({});\r\n try {\r\n const result = await this.api.startInterview({\r\n flowName,\r\n version: this.session.version() ?? undefined,\r\n inputs: this.coerceInputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n async respond(navigation: FlowScreenNavigation): Promise<void> {\r\n const current = this.result();\r\n // Opaco: si rimanda tale e quale, senza leggerlo.\r\n const token = current?.continuationToken;\r\n if (!token) {\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n try {\r\n const result = await this.api.respondToScreen({\r\n continuationToken: token,\r\n screenElementName: current?.pendingScreen?.elementName,\r\n navigation,\r\n // Con `Previous` e `Pause` il motore non memorizza gli output: si mandano comunque,\r\n // ma il pannello avverte che non sono definitivi.\r\n outputs: this.screenOutputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.screenOutputs.set({});\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n setStepOutput(name: string, value: string): void {\r\n this.stepOutputs.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n /** Gli output dichiarati dallo step, per generare i campi da compilare. */\r\n stepOutputNames(stepName: string | undefined): string[] {\r\n if (!stepName) {\r\n return [];\r\n }\r\n for (const stage of this.store.document().orchestratedStages ?? []) {\r\n const step = stage.stageSteps?.find((candidate) => candidate.name === stepName);\r\n if (step) {\r\n return (step.outputParameters ?? []).map((parameter) => parameter.name ?? '').filter(Boolean);\r\n }\r\n }\r\n return [];\r\n }\r\n\r\n /**\r\n * Conclude uno step come farebbe l'assegnatario. `Rejected` non e' un errore: e' l'esito che\r\n * prende il ramo «Step rifiutato» dello stage — e se quel ramo non c'e', l'interview fallisce.\r\n */\r\n async completeStep(stepName: string | undefined, status: FlowStageStepStatus): Promise<void> {\r\n const key = this.result()?.interviewKey;\r\n if (!key || !stepName) {\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n try {\r\n const result = await this.api.completeStageStep({\r\n interviewKey: key,\r\n stepName,\r\n status,\r\n stepOutputs: this.stepOutputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.stepOutputs.set({});\r\n // La risposta puo' portare una chiave nuova: `apply` sostituisce il risultato intero,\r\n // quindi la vecchia chiave non resta in giro.\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n private apply(result: FlowInterviewResult): void {\r\n this.result.set(result);\r\n if (result.currentElementName) {\r\n this.elementFocused.emit(result.currentElementName);\r\n }\r\n }\r\n\r\n private handleError(error: unknown): void {\r\n if (FlowApiError.is(error)) {\r\n // `InvalidToken` significa che la sessione di prova non e' piu' valida: si riavvia.\r\n this.errorMessage.set(error.message);\r\n return;\r\n }\r\n this.errorMessage.set(error instanceof Error ? error.message : String(error));\r\n }\r\n\r\n reset(): void {\r\n this.result.set(null);\r\n this.errorMessage.set(null);\r\n this.screenOutputs.set({});\r\n this.stepOutputs.set({});\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n /** L'etichetta dello stato, che non e' un errore anche quando dice \"Failed\" (§6.5). */\r\n statusLabel(): string {\r\n switch (this.status()) {\r\n case 'Completed':\r\n return 'Completata';\r\n case 'WaitingForScreen':\r\n return 'In attesa di un form';\r\n case 'Paused':\r\n return 'In pausa';\r\n case 'Suspended':\r\n return 'Sospesa';\r\n case 'Failed':\r\n return 'Fallita';\r\n case 'NotStarted':\r\n return 'Non avviata';\r\n default:\r\n return '';\r\n }\r\n }\r\n\r\n statusNote(): string | null {\r\n switch (this.status()) {\r\n case 'Failed':\r\n return 'Il flow e’ fallito: la richiesta e’ andata a buon fine, l’esecuzione no.';\r\n case 'NotStarted':\r\n return 'I criteri dello Start non erano soddisfatti: non e’ un errore.';\r\n case 'Paused':\r\n return 'L’esecuzione e’ in pausa: puo’ essere ripresa dalla sua chiave.';\r\n case 'Suspended':\r\n // Due attese diverse sotto lo stesso stato: dirlo evita di cercare l'evento sbagliato.\r\n if (this.isWaitingForStageStep()) {\r\n return 'Sospesa su uno step di orchestrazione: aspetta che un assegnatario lo concluda.';\r\n }\r\n return this.result()?.isWaitingForEvent\r\n ? 'Sospesa in attesa di un evento: puo’ essere ripresa dalla sua chiave.'\r\n : 'L’esecuzione e’ sospesa: puo’ essere ripresa dalla sua chiave.';\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n canGoBack(): boolean {\r\n return this.pendingScreen()?.canGoBack === true;\r\n }\r\n\r\n canFinish(): boolean {\r\n return this.pendingScreen()?.canFinish === true;\r\n }\r\n\r\n canPause(): boolean {\r\n return this.pendingScreen()?.canPause === true;\r\n }\r\n}\r\n","<header class=\"fb-dbg__header\">\r\n <h2 class=\"fb-dbg__title\">Prova</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<div class=\"fb-dbg__body\">\r\n @if (errorMessage()) {\r\n <p class=\"fb-callout fb-callout--error\">{{ errorMessage() }}</p>\r\n }\r\n\r\n @if (!result()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori iniziali</legend>\r\n @if (inputVariables().length) {\r\n @for (variable of inputVariables(); track variable.name) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ variable.name }}\r\n <span class=\"fb-dbg__type\">{{ variable.dataType }}{{ variable.isCollection ? '[]' : '' }}</span>\r\n </label>\r\n @if (variable.dataType === 'Boolean') {\r\n <select class=\"fb-select\" (change)=\"setInputValue(variable.name!, $any($event.target).value)\">\r\n <option value=\"\">—</option>\r\n <option value=\"true\">vero</option>\r\n <option value=\"false\">falso</option>\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [type]=\"variable.dataType === 'Number' || variable.dataType === 'Integer' ? 'number' : 'text'\"\r\n (input)=\"setInputValue(variable.name!, $any($event.target).value)\"\r\n />\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <p class=\"fb-field__hint\">Il flow non dichiara variabili di input.</p>\r\n }\r\n </fieldset>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"debugEnabled()\"\r\n (change)=\"setDebugEnabled($any($event.target).checked)\"\r\n />\r\n Traccia di debug\r\n </label>\r\n @if (debugEnabled()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n La traccia riporta i valori di <strong>tutte</strong> le risorse, dati personali compresi: non usarla\r\n su dati reali.\r\n </p>\r\n }\r\n\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"!canRun()\" (click)=\"start()\">\r\n Avvia\r\n </button>\r\n @if (!canRun() && !isRunning()) {\r\n <p class=\"fb-field__hint\">Salva il flow prima di provarlo.</p>\r\n }\r\n }\r\n\r\n @if (result()) {\r\n <div class=\"fb-dbg__status\">\r\n <span\r\n class=\"fb-dbg__badge\"\r\n [class.fb-dbg__badge--ok]=\"status() === 'Completed'\"\r\n [class.fb-dbg__badge--fail]=\"status() === 'Failed'\"\r\n [class.fb-dbg__badge--wait]=\"isWaitingForScreen()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n @if (result()?.currentElementName) {\r\n <span class=\"fb-dbg__current\">su {{ result()?.currentElementName }}</span>\r\n }\r\n <span class=\"fb-dbg__steps\">{{ result()?.steps || 0 }} passi</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"reset()\">Riavvia</button>\r\n </div>\r\n\r\n @if (statusNote()) {\r\n <p class=\"fb-callout\">{{ statusNote() }}</p>\r\n }\r\n\r\n @if (result()?.fault) {\r\n <p class=\"fb-callout fb-callout--error\">{{ result()?.fault }}</p>\r\n }\r\n @for (message of result()?.errors || []; track message) {\r\n <p class=\"fb-callout fb-callout--error\">{{ message }}</p>\r\n }\r\n\r\n @if (isWaitingForScreen() && pendingScreen()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">\r\n Form «{{ pendingScreen()?.formName }}»\r\n </legend>\r\n <p class=\"fb-section__note\">\r\n Nell’editor basta un form generico: qui vedi i valori che il form riceve e puoi compilare quelli\r\n che dichiara di restituire.\r\n </p>\r\n\r\n @if (pendingScreen()?.label) {\r\n <p class=\"fb-dbg__screen-label\">{{ pendingScreen()?.label }}</p>\r\n }\r\n @if (pendingScreen()?.helpText) {\r\n <p class=\"fb-field__hint\">{{ pendingScreen()?.helpText }}</p>\r\n }\r\n\r\n @if (screenInputRows().length) {\r\n <table class=\"fb-dbg__table\">\r\n <caption>\r\n Valori in ingresso\r\n </caption>\r\n <tbody>\r\n @for (row of screenInputRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n @for (output of screenOutputNames(); track output) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">{{ output }}</label>\r\n <input class=\"fb-input\" (input)=\"setScreenOutput(output, $any($event.target).value)\" />\r\n </div>\r\n }\r\n @if (!screenOutputNames().length) {\r\n <p class=\"fb-field__hint\">Lo screen non dichiara parametri di uscita.</p>\r\n }\r\n\r\n <div class=\"fb-field__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"respond('Next')\"\r\n >\r\n Avanti\r\n </button>\r\n <!-- canGoBack/canFinish/canPause sono la verita', piu' precisa dei flag del metadata. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning() || !canGoBack()\"\r\n title=\"Con «indietro» gli output non vengono memorizzati\"\r\n (click)=\"respond('Previous')\"\r\n >\r\n Indietro\r\n </button>\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isRunning() || !canFinish()\" (click)=\"respond('Finish')\">\r\n Fine\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning() || !canPause()\"\r\n title=\"Con «pausa» gli output non vengono memorizzati\"\r\n (click)=\"respond('Pause')\"\r\n >\r\n Pausa\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Con «indietro» e «pausa» i valori inseriti <strong>non</strong> vengono memorizzati.\r\n </p>\r\n </fieldset>\r\n }\r\n\r\n @if (isWaitingForStageStep()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Step di orchestrazione</legend>\r\n <p class=\"fb-section__note\">\r\n L’interview e’ sospesa su uno step assegnato: qui si conclude al posto dell’assegnatario.\r\n Concludere puo’ far <strong>sospendere di nuovo</strong> lo stage, con una chiave nuova.\r\n </p>\r\n\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (step of stageSteps(); track step.stepName) {\r\n <tr>\r\n <th scope=\"row\">{{ step.label || step.stepName }}</th>\r\n <td class=\"fb-dbg__type\">{{ step.actionType }}</td>\r\n <td>{{ step.isWaiting ? 'in attesa' : step.status }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n\r\n @for (step of waitingStageSteps(); track step.stepName) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__title\">{{ step.label || step.stepName }}</span>\r\n </div>\r\n @for (output of stepOutputNames(step.stepName); track output) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">{{ output }}</label>\r\n <input class=\"fb-input\" (input)=\"setStepOutput(output, $any($event.target).value)\" />\r\n </div>\r\n }\r\n <div class=\"fb-field__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"completeStep(step.stepName, 'Completed')\"\r\n >\r\n Concludi\r\n </button>\r\n <!-- Il rifiuto non e' un errore: prende il ramo «Step rifiutato» dello stage. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning()\"\r\n title=\"Prende il ramo «Step rifiutato»; senza quel ramo l’interview fallisce\"\r\n (click)=\"completeStep(step.stepName, 'Rejected')\"\r\n >\r\n Rifiuta\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"completeStep(step.stepName, 'Cancelled')\"\r\n >\r\n Annulla lo step\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n </fieldset>\r\n }\r\n\r\n @if (outputRows().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Output del flow</legend>\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (row of outputRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </fieldset>\r\n }\r\n\r\n @if (trace().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Traccia</legend>\r\n <ol class=\"fb-dbg__trace\">\r\n @for (entry of trace(); track entry.sequence) {\r\n <li class=\"fb-dbg__trace-item\">\r\n <span class=\"fb-dbg__trace-seq\">{{ entry.sequence }}</span>\r\n @if (entry.elementName) {\r\n <button type=\"button\" class=\"fb-dbg__trace-el\" (click)=\"elementFocused.emit(entry.elementName!)\">\r\n {{ entry.elementName }}\r\n </button>\r\n }\r\n <span class=\"fb-dbg__trace-msg\">{{ entry.message }}</span>\r\n </li>\r\n }\r\n </ol>\r\n </fieldset>\r\n }\r\n\r\n @if (resourceRows().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Risorse</legend>\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (row of resourceRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </fieldset>\r\n }\r\n\r\n @if (result()?.interviewKey) {\r\n <p class=\"fb-field__hint\">\r\n Chiave dell’esecuzione sospesa: <code>{{ result()?.interviewKey }}</code>\r\n </p>\r\n }\r\n }\r\n</div>\r\n","/**\r\n * Il builder: il componente standalone da innestare nell'applicazione ospite.\r\n *\r\n * Uso minimo:\r\n *\r\n * ```html\r\n * <fb-flow-builder [flowName]=\"'ApprovazioneOrdine'\" [author]=\"utente\" />\r\n * ```\r\n *\r\n * L'unica dipendenza da fornire e' {@link FlowBuilderApi}: tutto il traffico da e verso il\r\n * backend passa da lì.\r\n *\r\n * ```ts\r\n * providers: [{ provide: FlowBuilderApi, useClass: HttpFlowBuilderApi }]\r\n * ```\r\n *\r\n * Gli store del documento e della sessione sono provider **del componente**, non della\r\n * radice: due builder sulla stessa pagina editano due flow indipendenti.\r\n *\r\n * Il ciclo di lavoro della §11 e' implementato qui: carica, disegna, valida su pausa di\r\n * digitazione, salva con `expectedUpdatedAt`, aggiorna `updatedAt` dalla risposta.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../core/flow-document.store';\r\nimport { FlowEditorSession } from '../core/flow-editor-session';\r\nimport { FlowLayoutService } from '../core/flow-layout.service';\r\nimport { FlowValidationStore } from '../core/flow-validation.store';\r\nimport { START_NODE_NAME, outletsOf } from '../core/element-outlets';\r\nimport { uniqueFlowName } from '../core/flow-name.util';\r\nimport { FlowOutline, FlowSaveResult } from '../model/api.model';\r\nimport { FlowApiError } from '../model/error.model';\r\nimport { FlowAnyNode, FlowDefinition, FlowElementType } from '../model/flow.model';\r\nimport { DebugPanelComponent } from './debug/debug-panel.component';\r\nimport { ElementDialogComponent } from './inspector/element-dialog.component';\r\nimport { ElementInspectorComponent } from './inspector/element-inspector.component';\r\nimport { ElementPaletteComponent } from './palette/element-palette.component';\r\nimport { ProblemsPanelComponent } from './problems/problems-panel.component';\r\nimport { ResourcePanelComponent } from './resources/resource-panel.component';\r\nimport { VersionPanelComponent } from './versions/version-panel.component';\r\nimport { FLOW_NODE_HEIGHT, FlowCanvasComponent, flowNodeWidth } from './canvas/flow-canvas.component';\r\nimport { SelectValueDirective } from './shared/select-value.directive';\r\n\r\ntype SidePanel = 'inspector' | 'resources' | 'versions' | 'debug';\r\n\r\ninterface Notice {\r\n kind: 'info' | 'error';\r\n message: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-flow-builder',\r\n standalone: true,\r\n imports: [DebugPanelComponent,\r\n ElementDialogComponent,\r\n ElementInspectorComponent,\r\n ElementPaletteComponent,\r\n FlowCanvasComponent,\r\n ProblemsPanelComponent,\r\n ResourcePanelComponent,\r\n VersionPanelComponent, SelectValueDirective],\r\n // Gli store sono per-istanza: due builder editano due documenti indipendenti.\r\n providers: [\r\n FlowDocumentStore,\r\n FlowDictionaryStore,\r\n FlowCatalogStore,\r\n FlowValidationStore,\r\n FlowEditorSession,\r\n FlowLayoutService,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './flow-builder.component.html',\r\n styleUrl: './flow-builder.component.css',\r\n})\r\nexport class FlowBuilderComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n protected readonly store = inject(FlowDocumentStore);\r\n protected readonly dictionaries = inject(FlowDictionaryStore);\r\n protected readonly session = inject(FlowEditorSession);\r\n protected readonly validation = inject(FlowValidationStore);\r\n private readonly layout = inject(FlowLayoutService);\r\n\r\n /** Il flow da aprire. Assente → si parte da un flow nuovo. */\r\n readonly flowName = input<string | null>(null);\r\n /** La versione da aprire; assente → l'attiva se c'e', altrimenti l'ultima (§6.1). */\r\n readonly version = input<number | null>(null);\r\n /** Registrato sulla versione e mostrato nell'elenco (§6.2). */\r\n readonly author = input<string | undefined>(undefined);\r\n /** `processType` iniziale di un flow nuovo. */\r\n readonly defaultProcessType = input<string>('Screen');\r\n\r\n /**\r\n * Dove si configura l'elemento selezionato.\r\n *\r\n * `dialog` (predefinito) apre il form in una finestra sopra il canvas, come il flow builder\r\n * di Salesforce: i form degli elementi sono grandi e in una colonna da 340px si scorreva\r\n * troppo. `panel` tiene il form nel pannello laterale, che e' piu' comodo quando si\r\n * modificano molti elementi di fila perche' non c'e' niente da aprire e chiudere.\r\n */\r\n readonly inspectorMode = input<'dialog' | 'panel'>('dialog');\r\n\r\n readonly saved = output<FlowSaveResult>();\r\n readonly activated = output<FlowSaveResult>();\r\n readonly closeRequested = output<void>();\r\n\r\n readonly selectedName = signal<string | null>(START_NODE_NAME);\r\n readonly activePanel = signal<SidePanel>('inspector');\r\n /** La dialog del dettaglio e' aperta. Vale solo con `inspectorMode = 'dialog'`. */\r\n readonly isDialogOpen = signal(false);\r\n readonly showProblems = signal(true);\r\n readonly notice = signal<Notice | null>(null);\r\n readonly outline = signal<FlowOutline | null>(null);\r\n readonly isLoading = signal(false);\r\n\r\n /** Il documento e' cambiato: usato per riscadenzare validazione e outline. */\r\n private lastDocument?: FlowDefinition;\r\n private outlineTimer?: ReturnType<typeof setTimeout>;\r\n\r\n readonly isDialogMode = computed(() => this.inspectorMode() === 'dialog');\r\n\r\n /**\r\n * Il pannello effettivamente mostrato a lato. Con la dialog il tab «Elemento» non esiste:\r\n * avere lo stesso form in due posti confonde su quale dei due sia quello vero.\r\n */\r\n readonly sidePanel = computed<SidePanel>(() => {\r\n const panel = this.activePanel();\r\n return this.isDialogMode() && panel === 'inspector' ? 'resources' : panel;\r\n });\r\n\r\n readonly document = computed(() => this.store.document());\r\n readonly isDirty = computed(() => this.store.isDirty());\r\n readonly canUndo = computed(() => this.store.canUndo());\r\n readonly canRedo = computed(() => this.store.canRedo());\r\n readonly primaryCommand = computed(() => this.session.primaryCommand());\r\n readonly isEditable = computed(() => this.session.isEditable());\r\n readonly conflict = computed(() => this.session.conflict());\r\n readonly errorCount = computed(() => this.validation.errorCount());\r\n readonly warningCount = computed(() => this.validation.warningCount());\r\n readonly canActivate = computed(() => this.session.canActivate());\r\n readonly isBusy = computed(() => this.session.isBusy() || this.isLoading());\r\n\r\n readonly statusLabel = computed(() => {\r\n const summary = this.session.currentVersionSummary();\r\n if (!summary) {\r\n return 'Nuovo';\r\n }\r\n switch (summary.status) {\r\n case 'Draft':\r\n return 'Bozza';\r\n case 'InvalidDraft':\r\n return 'Bozza con errori';\r\n case 'UnderReview':\r\n return 'In approvazione';\r\n case 'Active':\r\n return 'Attiva';\r\n case 'Obsolete':\r\n return 'Superata';\r\n default:\r\n return summary.status ?? '';\r\n }\r\n });\r\n\r\n constructor() {\r\n /**\r\n * I dizionari si caricano una volta e si tengono in cache, **per `processType`**: le\r\n * globali dipendono dal tipo di flow — `$Record` non esiste in uno screen flow — e\r\n * cambiare tipo cambia quali sono proponibili (§4.1, §6.4). Lo store memoizza per tipo,\r\n * quindi tornare a un tipo già visto non produce una richiesta.\r\n */\r\n effect(() => {\r\n void this.dictionaries.load(this.store.document().processType);\r\n });\r\n\r\n effect(() => {\r\n this.session.setAuthor(this.author());\r\n });\r\n\r\n // Apertura: reagisce ai parametri di ingresso.\r\n effect(() => {\r\n const flowName = this.flowName();\r\n const version = this.version();\r\n void this.openOrCreate(flowName, version);\r\n });\r\n\r\n /**\r\n * §11 — a ogni modifica: validazione su pausa di digitazione, e outline rilanciato per\r\n * riflettere archi e raggiungibilita' autorevoli. L'outline e' debounced insieme alla\r\n * validazione: il canvas nel frattempo usa il calcolo locale, così il disegno non\r\n * dipende dalla latenza.\r\n */\r\n effect(() => {\r\n const document = this.store.document();\r\n if (document === this.lastDocument) {\r\n return;\r\n }\r\n this.lastDocument = document;\r\n this.validation.schedule(document);\r\n this.scheduleOutline(document);\r\n });\r\n\r\n this.destroyRef.onDestroy(() => {\r\n if (this.outlineTimer) {\r\n clearTimeout(this.outlineTimer);\r\n }\r\n });\r\n }\r\n\r\n private async openOrCreate(flowName: string | null, version: number | null): Promise<void> {\r\n this.isLoading.set(true);\r\n this.notice.set(null);\r\n // Si sta cambiando documento: una dialog aperta guarderebbe un elemento di un altro flow.\r\n this.isDialogOpen.set(false);\r\n try {\r\n if (flowName) {\r\n await this.session.open(flowName, version ?? undefined);\r\n } else {\r\n // Un flow appena creato ha errori — manca il primo node — ed e' normale (§11).\r\n this.session.startNew('', '', this.defaultProcessType());\r\n }\r\n this.selectedName.set(START_NODE_NAME);\r\n } catch (error) {\r\n this.showError(error);\r\n } finally {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n private scheduleOutline(definition: FlowDefinition): void {\r\n if (this.outlineTimer) {\r\n clearTimeout(this.outlineTimer);\r\n }\r\n this.outlineTimer = setTimeout(() => {\r\n this.outlineTimer = undefined;\r\n void this.api\r\n .getOutline(definition)\r\n .then((outline) => this.outline.set(outline))\r\n // L'outline e' un arricchimento: senza, il canvas usa il calcolo locale.\r\n .catch(() => this.outline.set(null));\r\n }, 500);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Intestazione del documento\r\n // -------------------------------------------------------------------------\r\n\r\n setLabel(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.label = value || undefined;\r\n });\r\n }\r\n\r\n setFullName(value: string): void {\r\n // `fullName` nel documento non rinomina il flow: la rinomina passa da `flowName` nella\r\n // richiesta di salvataggio (§2, §6.2). Qui si scrive il documento; al salvataggio si\r\n // manda anche `flowName`, ed e' quello a vincere.\r\n this.store.updateHeader((definition) => {\r\n definition.fullName = value || undefined;\r\n });\r\n }\r\n\r\n setDescription(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.description = value || undefined;\r\n });\r\n }\r\n\r\n setInterviewLabel(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.interviewLabel = value || undefined;\r\n });\r\n }\r\n\r\n setProcessType(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.processType = value;\r\n });\r\n }\r\n\r\n readonly processTypes = computed(() => this.dictionaries.processTypes());\r\n\r\n /** `AutoLaunched` + screen e' un errore di validazione: si segnala subito (§13.6). */\r\n readonly hasScreensInAutoLaunched = computed(\r\n () =>\r\n this.store.document().processType === 'AutoLaunched' &&\r\n (this.store.document().screens?.length ?? 0) > 0,\r\n );\r\n\r\n /** Un flow `Screen` senza screen e' `SCREEN_FLOW_WITHOUT_SCREENS`. */\r\n readonly hasNoScreensInScreenFlow = computed(\r\n () =>\r\n this.store.document().processType === 'Screen' && (this.store.document().screens?.length ?? 0) === 0,\r\n );\r\n\r\n /**\r\n * Un flow `Orchestration` senza stage di orchestrazione e' un **avviso**\r\n * (`ORCHESTRATION_WITHOUT_STAGES`): il tipo dichiara un'orchestrazione che non c'e' (§3.1).\r\n */\r\n readonly isOrchestrationWithoutStages = computed(() => {\r\n const document = this.store.document();\r\n return document.processType === 'Orchestration' && (document.orchestratedStages?.length ?? 0) === 0;\r\n });\r\n\r\n // -------------------------------------------------------------------------\r\n // Canvas\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Click singolo sul canvas: seleziona. Con la dialog il form **non** si apre qui: un click\r\n * capita anche solo per spostare un node, e una finestra che si apre a ogni click sarebbe\r\n * insopportabile. Nel pannello laterale, invece, mostrare subito il form non costa nulla.\r\n */\r\n onSelectionChange(name: string | null): void {\r\n this.selectedName.set(name);\r\n if (name && !this.isDialogMode()) {\r\n this.activePanel.set('inspector');\r\n }\r\n }\r\n\r\n /** Doppio click o bottone «✎» sul node: qui il dettaglio si apre. */\r\n onNodeOpened(name: string): void {\r\n this.openElement(name);\r\n }\r\n\r\n /** Porta l'utente sull'elemento **e** ne apre il form: e' l'ancora dei problemi (§7). */\r\n focusElement(name: string): void {\r\n this.openElement(name);\r\n }\r\n\r\n /** Apre il dettaglio dell'elemento, nella dialog o nel pannello secondo la modalita'. */\r\n openElement(name: string): void {\r\n this.selectedName.set(name);\r\n if (this.isDialogMode()) {\r\n this.isDialogOpen.set(true);\r\n return;\r\n }\r\n this.activePanel.set('inspector');\r\n }\r\n\r\n /** Il comando della top bar: apre il dettaglio di cio' che e' selezionato. */\r\n openSelectedElement(): void {\r\n const name = this.selectedName();\r\n if (name) {\r\n this.openElement(name);\r\n }\r\n }\r\n\r\n closeDialog(): void {\r\n this.isDialogOpen.set(false);\r\n }\r\n\r\n /**\r\n * Evidenzia l'elemento sul canvas senza cambiare pannello.\r\n * Serve durante la prova: l'esecuzione segnala su quale elemento e' ferma, ma sostituire\r\n * il pannello con l'inspector farebbe sparire il form da compilare a metà interview.\r\n */\r\n highlightElement(name: string): void {\r\n this.selectedName.set(name);\r\n }\r\n\r\n /** Rilascio dalla palette: il punto di rilascio diventa `locationX`/`locationY` (§11). */\r\n onElementDropped(event: { type: FlowElementType; x: number; y: number }): void {\r\n this.createElement(event.type, event.x, event.y);\r\n }\r\n\r\n /** Click sulla palette: l'elemento si posiziona in una zona libera. */\r\n onElementPicked(type: FlowElementType): void {\r\n const nodes = this.store.nodes();\r\n const lowest = nodes.reduce((max, reference) => Math.max(max, reference.node.locationY ?? 0), 60);\r\n this.createElement(type, 60, lowest + 120);\r\n }\r\n\r\n private createElement(type: FlowElementType, x: number, y: number): void {\r\n const collection = this.dictionaries.collectionOf(type);\r\n if (!collection) {\r\n this.notice.set({ kind: 'error', message: `Tipo di elemento non riconosciuto: ${type}.` });\r\n return;\r\n }\r\n const label = this.dictionaries.labelOf(type);\r\n // Il nome si genera dalla label e si verifica contro node **e** risorse (§3.3, §11).\r\n const name = uniqueFlowName(label, this.store.usedNames());\r\n const node: FlowAnyNode = {\r\n name,\r\n label,\r\n locationX: Math.round(x),\r\n locationY: Math.round(y),\r\n };\r\n // Default che rendono l'elemento sensato appena creato, senza inventare configurazione.\r\n if (type === 'RecordLookup' || type === 'RecordCreate') {\r\n node['storeOutputAutomatically'] = true;\r\n }\r\n if (type === 'CollectionProcessor') {\r\n node['collectionProcessorType'] = 'Sort';\r\n }\r\n if (type === 'Decision') {\r\n node['rules'] = [\r\n { name: 'Regola', label: 'Regola 1', conditionLogic: 'and', conditions: [{ operator: 'EqualTo' }] },\r\n ];\r\n }\r\n if (type === 'CustomError') {\r\n node['customErrorMessages'] = [{ errorMessage: '' }];\r\n }\r\n if (type === 'Wait') {\r\n node['waitEvents'] = [{ name: 'Evento', label: 'Evento 1' }];\r\n }\r\n if (type === 'OrchestratedStage') {\r\n // Lo step nasce senza `actionType`: e' l'utente a scegliere se e' in background,\r\n // interattivo o di approvazione, e il form lo segnala finche' manca (§5.13).\r\n node['stageSteps'] = [\r\n { name: uniqueFlowName('Step', [...this.store.usedNames(), name]), label: 'Step 1' },\r\n ];\r\n }\r\n this.store.addNode(collection, node);\r\n // Un elemento appena creato e' vuoto: il posto giusto in cui finire e' il suo form.\r\n this.openElement(name);\r\n }\r\n\r\n onRemoveNode(name: string): void {\r\n // Rimuove anche i connector che lo referenziavano: un target orfano bloccherebbe\r\n // l'attivazione con CONNECTOR_TARGET_UNKNOWN.\r\n this.store.removeNode(name);\r\n if (this.selectedName() === name) {\r\n this.selectedName.set(START_NODE_NAME);\r\n // L'elemento non c'e' piu': una dialog aperta sul vuoto non ha senso.\r\n this.isDialogOpen.set(false);\r\n }\r\n }\r\n\r\n onDuplicateNode(name: string): void {\r\n const newName = uniqueFlowName(`${name}_copia`, this.store.usedNames());\r\n this.store.duplicateNode(name, newName);\r\n this.selectedName.set(newName);\r\n }\r\n\r\n /** Riordina il grafo e **scrive** le coordinate nel documento (§3.5). */\r\n autoLayout(): void {\r\n // La larghezza dipende dal numero di rami, perche' le uscite stanno in fila sul bordo\r\n // inferiore: passare a dagre una larghezza fissa lascerebbe i node larghi sovrapposti.\r\n const nodes = [\r\n {\r\n name: START_NODE_NAME,\r\n width: flowNodeWidth(outletsOf('Start', this.store.start() as FlowAnyNode).length),\r\n height: FLOW_NODE_HEIGHT,\r\n },\r\n ...this.store.nodes().map((reference) => ({\r\n name: reference.name,\r\n width: flowNodeWidth(outletsOf(reference.type, reference.node).length),\r\n height: FLOW_NODE_HEIGHT,\r\n })),\r\n ];\r\n const result = this.layout.layout(nodes, this.store.edges(), { direction: 'TB' });\r\n if (!result.positions.size) {\r\n return;\r\n }\r\n let first = true;\r\n for (const [name, position] of result.positions) {\r\n this.store.moveNode(name, position.x, position.y, { silent: !first });\r\n first = false;\r\n }\r\n }\r\n\r\n undo(): void {\r\n this.store.undo();\r\n }\r\n\r\n redo(): void {\r\n this.store.redo();\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Salvataggio e ciclo di vita\r\n // -------------------------------------------------------------------------\r\n\r\n async save(): Promise<void> {\r\n const definition = this.store.document();\r\n if (!definition.fullName) {\r\n this.notice.set({ kind: 'error', message: 'Dai un nome tecnico al flow prima di salvare.' });\r\n return;\r\n }\r\n try {\r\n const result = await this.session.save({ flowName: definition.fullName });\r\n this.saved.emit(result);\r\n // Il salvataggio riesce anche con errori: l'esito sano si legge in `validation` (§6.2).\r\n const errors = result.validation?.errorCount ?? 0;\r\n this.notice.set({\r\n kind: 'info',\r\n message: errors\r\n ? `Salvato come versione ${result.version}, con ${errors} ${errors === 1 ? 'errore' : 'errori'} da correggere.`\r\n : `Salvato come versione ${result.version}.`,\r\n });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n async createNewVersion(): Promise<void> {\r\n try {\r\n const result = await this.session.createNewVersion();\r\n this.notice.set({ kind: 'info', message: `Creata la versione ${result.version}.` });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n async activate(): Promise<void> {\r\n try {\r\n const result = await this.session.activate();\r\n this.activated.emit(result);\r\n this.notice.set({ kind: 'info', message: `Versione ${result.version} attivata.` });\r\n } catch (error) {\r\n // Con `ValidationFailed` il payload porta l'elenco: si apre il pannello (§11).\r\n if (FlowApiError.is(error) && error.category === 'ValidationFailed') {\r\n this.showProblems.set(true);\r\n }\r\n this.showError(error);\r\n }\r\n }\r\n\r\n /** §9.3 — prima opzione davanti a un conflitto. */\r\n async reloadAfterConflict(): Promise<void> {\r\n try {\r\n await this.session.reloadAfterConflict();\r\n this.notice.set({ kind: 'info', message: 'Ricaricata la versione salvata da altri.' });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n /** §9.3 — seconda opzione: conserva le modifiche locali in una nuova versione. */\r\n async saveAsNewVersionAfterConflict(): Promise<void> {\r\n try {\r\n const result = await this.session.saveAsNewVersionAfterConflict();\r\n this.notice.set({\r\n kind: 'info',\r\n message: `Le tue modifiche sono nella nuova versione ${result.version}.`,\r\n });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n dismissConflict(): void {\r\n this.session.dismissConflict();\r\n }\r\n\r\n /** Esporta il documento come JSON indentato, per un salvataggio fuori dal backend. */\r\n exportJson(): string {\r\n return JSON.stringify(this.store.document(), null, 2);\r\n }\r\n\r\n /**\r\n * Importa un documento. Passa da `POST /flows/parse`, che lo normalizza o lo rifiuta con\r\n * `InvalidDefinition`: e' l'unico modo di sapere se il file e' leggibile prima di caricarlo.\r\n */\r\n async importJson(raw: string): Promise<void> {\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(raw);\r\n } catch {\r\n this.notice.set({ kind: 'error', message: 'Il file non e’ JSON valido.' });\r\n return;\r\n }\r\n try {\r\n const definition = await this.api.parseFlow(parsed);\r\n this.store.load(definition);\r\n this.notice.set({ kind: 'info', message: 'Documento importato.' });\r\n } catch (error) {\r\n if (FlowApiError.is(error) && error.category === 'MissingService') {\r\n // Senza la primitiva si carica il JSON così com'e': la validazione dira' cosa non torna.\r\n this.store.load(parsed as FlowDefinition);\r\n this.notice.set({\r\n kind: 'info',\r\n message: 'Documento importato senza normalizzazione: il backend non espone la primitiva.',\r\n });\r\n return;\r\n }\r\n this.showError(error);\r\n }\r\n }\r\n\r\n onFileSelected(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const file = input.files?.[0];\r\n if (!file) {\r\n return;\r\n }\r\n void file.text().then((raw) => this.importJson(raw));\r\n input.value = '';\r\n }\r\n\r\n async openVersion(version: number): Promise<void> {\r\n const flowName = this.session.flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this.isLoading.set(true);\r\n this.isDialogOpen.set(false);\r\n try {\r\n await this.session.open(flowName, version);\r\n this.selectedName.set(START_NODE_NAME);\r\n } catch (error) {\r\n this.showError(error);\r\n } finally {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /** Valida subito, senza attendere la pausa di digitazione. */\r\n async validateNow(): Promise<void> {\r\n await this.validation.run(this.store.document());\r\n this.showProblems.set(true);\r\n }\r\n\r\n setPanel(panel: SidePanel): void {\r\n this.activePanel.set(panel);\r\n }\r\n\r\n toggleProblems(): void {\r\n this.showProblems.update((value) => !value);\r\n }\r\n\r\n showNotice(notice: Notice): void {\r\n this.notice.set(notice);\r\n }\r\n\r\n dismissNotice(): void {\r\n this.notice.set(null);\r\n }\r\n\r\n private showError(error: unknown): void {\r\n if (FlowApiError.is(error)) {\r\n this.notice.set({ kind: 'error', message: error.message });\r\n return;\r\n }\r\n this.notice.set({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n}\r\n","<div class=\"fb-builder\" [attr.data-fb-theme]=\"null\">\r\n <header class=\"fb-top\">\r\n <div class=\"fb-top__identity\">\r\n <input\r\n class=\"fb-top__label\"\r\n [value]=\"document().label || ''\"\r\n placeholder=\"Nome del flow\"\r\n aria-label=\"Nome del flow\"\r\n [disabled]=\"!isEditable()\"\r\n (input)=\"setLabel($any($event.target).value)\"\r\n />\r\n <div class=\"fb-top__meta\">\r\n <input\r\n class=\"fb-top__name\"\r\n [value]=\"document().fullName || ''\"\r\n placeholder=\"NomeTecnico\"\r\n aria-label=\"Nome tecnico del flow\"\r\n [disabled]=\"!isEditable()\"\r\n (input)=\"setFullName($any($event.target).value)\"\r\n />\r\n <select\r\n class=\"fb-top__process\"\r\n [fbValue]=\"document().processType || ''\"\r\n aria-label=\"Tipo di flow\"\r\n [disabled]=\"!isEditable()\"\r\n (change)=\"setProcessType($any($event.target).value)\"\r\n >\r\n @for (type of processTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n <span class=\"fb-top__status\">{{ statusLabel() }}</span>\r\n @if (session.version() !== null) {\r\n <span class=\"fb-top__version\">v{{ session.version() }}</span>\r\n }\r\n @if (isDirty()) {\r\n <span class=\"fb-top__dirty\" title=\"Ci sono modifiche non salvate\">modificato</span>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"fb-top__actions\">\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"!canUndo()\" aria-label=\"Annulla\" (click)=\"undo()\">↶</button>\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"!canRedo()\" aria-label=\"Ripeti\" (click)=\"redo()\">↷</button>\r\n <button type=\"button\" class=\"fb-btn\" title=\"Ricalcola le posizioni\" (click)=\"autoLayout()\">Riordina</button>\r\n @if (isDialogMode()) {\r\n <!-- Il doppio click sul node fa la stessa cosa, ma non si vede: questo comando sì. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"!selectedName()\"\r\n title=\"Apri il dettaglio dell’elemento selezionato\"\r\n (click)=\"openSelectedElement()\"\r\n >\r\n Dettaglio\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isBusy()\" (click)=\"validateNow()\">Valida</button>\r\n\r\n @switch (primaryCommand()) {\r\n @case ('newVersion') {\r\n <!-- Su una versione non modificabile il comando primario e' \"Nuova versione\" (§8.1). -->\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"createNewVersion()\">\r\n Nuova versione\r\n </button>\r\n }\r\n @case ('create') {\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"save()\">\r\n Crea\r\n </button>\r\n }\r\n @default {\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"save()\">\r\n Salva\r\n </button>\r\n }\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isBusy() || !canActivate()\"\r\n [title]=\"\r\n canActivate()\r\n ? 'Attiva questa versione'\r\n : 'L’attivazione esige zero errori: correggili nel pannello dei problemi'\r\n \"\r\n (click)=\"activate()\"\r\n >\r\n Attiva\r\n </button>\r\n </div>\r\n </header>\r\n\r\n @if (conflict()) {\r\n <!-- §9.3: qualcun altro ha salvato. Due strade, entrambe offerte. -->\r\n <div class=\"fb-banner fb-banner--warn\" role=\"alert\">\r\n <span>\r\n {{ conflict()?.message }}\r\n @if (conflict()?.conflictingAuthor) {\r\n Ha salvato {{ conflict()?.conflictingAuthor }}.\r\n }\r\n </span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--icon\" (click)=\"reloadAfterConflict()\">Ricarica</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--icon\" (click)=\"saveAsNewVersionAfterConflict()\">\r\n Salva come nuova versione\r\n </button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"dismissConflict()\">×</button>\r\n </div>\r\n }\r\n\r\n @if (notice()) {\r\n <div\r\n class=\"fb-banner\"\r\n [class.fb-banner--error]=\"notice()?.kind === 'error'\"\r\n role=\"status\"\r\n >\r\n <span>{{ notice()?.message }}</span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"dismissNotice()\">\r\n ×\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (hasScreensInAutoLaunched()) {\r\n <div class=\"fb-banner fb-banner--error\">\r\n Un flow AutoLaunched che contiene screen e’ un errore di validazione: non c’e’ nessuno a cui mostrarli.\r\n </div>\r\n }\r\n @if (isOrchestrationWithoutStages()) {\r\n <div class=\"fb-banner fb-banner--warn\">\r\n Un flow Orchestration senza stage di orchestrazione viene segnalato dalla validazione\r\n (ORCHESTRATION_WITHOUT_STAGES).\r\n </div>\r\n }\r\n @if (hasNoScreensInScreenFlow()) {\r\n <div class=\"fb-banner fb-banner--warn\">\r\n Un flow di tipo Screen senza nessuno screen viene segnalato dalla validazione.\r\n </div>\r\n }\r\n @if (!isEditable()) {\r\n <div class=\"fb-banner\">\r\n Questa versione e’ in sola lettura: per modificarla creane una nuova.\r\n </div>\r\n }\r\n\r\n <div class=\"fb-main\">\r\n <aside class=\"fb-main__palette\">\r\n <fb-element-palette [processType]=\"document().processType\" (elementPicked)=\"onElementPicked($event)\" />\r\n </aside>\r\n\r\n <div class=\"fb-main__center\">\r\n <fb-flow-canvas\r\n class=\"fb-main__canvas\"\r\n [selectedName]=\"selectedName()\"\r\n [outline]=\"outline()\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n (nodeOpened)=\"onNodeOpened($event)\"\r\n (nodeRemoveRequested)=\"onRemoveNode($event)\"\r\n (nodeDuplicateRequested)=\"onDuplicateNode($event)\"\r\n (elementDropped)=\"onElementDropped($event)\"\r\n />\r\n\r\n @if (showProblems()) {\r\n <fb-problems-panel\r\n class=\"fb-main__problems\"\r\n (elementFocused)=\"focusElement($event)\"\r\n (closed)=\"toggleProblems()\"\r\n />\r\n } @else {\r\n <button type=\"button\" class=\"fb-main__problems-toggle\" (click)=\"toggleProblems()\">\r\n Problemi\r\n @if (errorCount()) {\r\n <span class=\"fb-main__count fb-main__count--error\">{{ errorCount() }}</span>\r\n }\r\n @if (warningCount()) {\r\n <span class=\"fb-main__count fb-main__count--warn\">{{ warningCount() }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <aside class=\"fb-main__side\">\r\n <nav class=\"fb-side__tabs\" aria-label=\"Pannelli\">\r\n @if (!isDialogMode()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'inspector'\"\r\n (click)=\"setPanel('inspector')\"\r\n >\r\n Elemento\r\n </button>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'resources'\"\r\n (click)=\"setPanel('resources')\"\r\n >\r\n Risorse\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'versions'\"\r\n (click)=\"setPanel('versions')\"\r\n >\r\n Versioni\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'debug'\"\r\n (click)=\"setPanel('debug')\"\r\n >\r\n Prova\r\n </button>\r\n </nav>\r\n\r\n <div class=\"fb-side__content\">\r\n @switch (sidePanel()) {\r\n @case ('inspector') {\r\n <fb-element-inspector\r\n [selectedName]=\"selectedName()\"\r\n (removeRequested)=\"onRemoveNode($event)\"\r\n (duplicateRequested)=\"onDuplicateNode($event)\"\r\n (closed)=\"setPanel('resources')\"\r\n />\r\n }\r\n @case ('resources') {\r\n <fb-resource-panel (closed)=\"setPanel('inspector')\" />\r\n }\r\n @case ('versions') {\r\n <fb-version-panel\r\n (versionOpened)=\"openVersion($event)\"\r\n (notice)=\"showNotice($event)\"\r\n (closed)=\"setPanel('inspector')\"\r\n />\r\n }\r\n @case ('debug') {\r\n <!-- Evidenzia sul canvas senza rubare il pannello: l'interview e’ in corso. -->\r\n <fb-debug-panel (elementFocused)=\"highlightElement($event)\" (closed)=\"setPanel('inspector')\" />\r\n }\r\n }\r\n </div>\r\n\r\n <footer class=\"fb-side__footer\">\r\n <label class=\"fb-btn fb-btn--icon\">\r\n Importa JSON\r\n <input type=\"file\" accept=\"application/json,.json\" hidden (change)=\"onFileSelected($event)\" />\r\n </label>\r\n </footer>\r\n </aside>\r\n </div>\r\n\r\n @if (isDialogMode() && isDialogOpen() && selectedName()) {\r\n <!-- La dialog sta dentro il builder, non nel body: la libreria e’ innestabile. -->\r\n <fb-element-dialog\r\n [selectedName]=\"selectedName()\"\r\n (closed)=\"closeDialog()\"\r\n (removeRequested)=\"onRemoveNode($event)\"\r\n (duplicateRequested)=\"onDuplicateNode($event)\"\r\n />\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["removeConditionInPlace","moveConditionInPlace"],"mappings":"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"}
1
+ {"version":3,"file":"esfaenza-flow-builder.mjs","sources":["../../../projects/flow-builder/src/lib/model/flow.model.ts","../../../projects/flow-builder/src/lib/model/dictionary.model.ts","../../../projects/flow-builder/src/lib/model/api.model.ts","../../../projects/flow-builder/src/lib/model/error.model.ts","../../../projects/flow-builder/src/lib/api/flow-builder-api.ts","../../../projects/flow-builder/src/lib/api/http-flow-builder-api.ts","../../../projects/flow-builder/src/lib/core/element-outlets.ts","../../../projects/flow-builder/src/lib/core/element-icons.ts","../../../projects/flow-builder/src/lib/core/element-variants.ts","../../../projects/flow-builder/src/lib/core/flow-name.util.ts","../../../projects/flow-builder/src/lib/core/condition-logic.util.ts","../../../projects/flow-builder/src/lib/core/condition-types.util.ts","../../../projects/flow-builder/src/lib/core/stage-step.util.ts","../../../projects/flow-builder/src/lib/core/flow-document.store.ts","../../../projects/flow-builder/src/lib/core/flow-dictionary.store.ts","../../../projects/flow-builder/src/lib/core/flow-validation.store.ts","../../../projects/flow-builder/src/lib/core/flow-layout.service.ts","../../../projects/flow-builder/src/lib/core/flow-editor-session.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.model.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.component.ts","../../../projects/flow-builder/src/lib/ui/canvas/flow-canvas.component.html","../../../projects/flow-builder/src/lib/ui/palette/element-palette.component.ts","../../../projects/flow-builder/src/lib/ui/palette/element-palette.component.html","../../../projects/flow-builder/src/lib/ui/shared/reference-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/reference-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/object-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/object-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/field-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/field-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/name-picker.component.ts","../../../projects/flow-builder/src/lib/ui/shared/name-picker.component.html","../../../projects/flow-builder/src/lib/ui/shared/select-value.directive.ts","../../../projects/flow-builder/src/lib/ui/shared/value-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/value-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/condition-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/condition-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/record-filter-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/record-filter-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/parameter-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/parameter-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/field-assignment-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/field-assignment-editor.component.html","../../../projects/flow-builder/src/lib/ui/shared/connector-editor.component.ts","../../../projects/flow-builder/src/lib/ui/shared/connector-editor.component.html","../../../projects/flow-builder/src/lib/ui/inspector/node-inspector-base.ts","../../../projects/flow-builder/src/lib/ui/inspector/action-call-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/action-call-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/assignment-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/assignment-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/collection-processor-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/collection-processor-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/custom-error-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/custom-error-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/decision-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/decision-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/loop-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/loop-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/orchestrated-stage-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/orchestrated-stage-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-lookup-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-lookup-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-rollback-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-rollback-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/record-write-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/record-write-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/screen-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/screen-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/script-call-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/script-call-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/start-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/start-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/subflow-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/subflow-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/transform-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/transform-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/wait-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/wait-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/element-inspector.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/element-inspector.component.html","../../../projects/flow-builder/src/lib/ui/inspector/element-dialog.component.ts","../../../projects/flow-builder/src/lib/ui/inspector/element-dialog.component.html","../../../projects/flow-builder/src/lib/ui/resources/resource-panel.component.ts","../../../projects/flow-builder/src/lib/ui/resources/resource-panel.component.html","../../../projects/flow-builder/src/lib/ui/problems/problems-panel.component.ts","../../../projects/flow-builder/src/lib/ui/problems/problems-panel.component.html","../../../projects/flow-builder/src/lib/ui/versions/version-panel.component.ts","../../../projects/flow-builder/src/lib/ui/versions/version-panel.component.html","../../../projects/flow-builder/src/lib/ui/debug/debug-panel.component.ts","../../../projects/flow-builder/src/lib/ui/debug/debug-panel.component.html","../../../projects/flow-builder/src/lib/ui/flow-builder.component.ts","../../../projects/flow-builder/src/lib/ui/flow-builder.component.html","../../../projects/flow-builder/src/esfaenza-flow-builder.ts"],"sourcesContent":["/**\r\n * Modello del documento Flow — FRONTEND.md §3, §4, §5.\r\n *\r\n * Regole del contratto rispettate qui:\r\n * - camelCase su ogni proprieta';\r\n * - ogni campo e' opzionale (una definizione incompleta e' salvabile);\r\n * - nessun `$type`: il tipo di un node e' la collection in cui sta (§3.1);\r\n * - gli enum sono stringhe, ma i tipi sono aperti (`| string`) perche' gli elenchi\r\n * autoritativi arrivano da `GET /flows/dictionaries` e possono crescere (§13.11).\r\n */\r\n\r\n/** §4.2 — i sette tipi del sistema. Aperto: il dizionario `dataTypes` e' autoritativo. */\r\nexport type FlowDataType = 'String' | 'Integer' | 'Number' | 'Date' | 'Boolean' | 'Enum' | 'Object' | string;\r\n\r\nexport type FlowProcessType = 'Screen' | 'AutoLaunched' | 'Evaluation' | 'Orchestration' | string;\r\n\r\nexport type FlowVersionStatus = 'Draft' | 'InvalidDraft' | 'UnderReview' | 'Active' | 'Obsolete' | string;\r\n\r\nexport type FlowTriggerType =\r\n | 'None'\r\n | 'RecordBeforeSave'\r\n | 'RecordAfterSave'\r\n | 'RecordBeforeDelete'\r\n | 'Scheduled'\r\n | 'Event'\r\n | string;\r\n\r\nexport type FlowRecordTriggerType = 'Create' | 'Update' | 'CreateAndUpdate' | 'Delete' | string;\r\n\r\nexport type FlowSortOrder = 'Asc' | 'Desc' | string;\r\n\r\nexport type FlowOffsetUnit = 'Minutes' | 'Hours' | 'Days' | 'Months' | string;\r\n\r\nexport type FlowCollectionProcessorType = 'Sort' | 'Filter' | string;\r\n\r\nexport type FlowTransformType = 'Map' | 'Sum' | 'Count' | string;\r\n\r\nexport type FlowTransactionModel = 'Automatic' | 'CurrentTransaction' | 'NewTransaction' | string;\r\n\r\n/**\r\n * §4.2 — un riferimento **oppure** un valore letterale.\r\n * Va valorizzato **uno e un solo** campo; `formulaExpression` e' l'unica eccezione\r\n * (espressione + tipo atteso). Piu' campi insieme = `VALUE_AMBIGUOUS`.\r\n */\r\nexport interface FlowValue {\r\n elementReference?: string;\r\n stringValue?: string;\r\n integerValue?: number;\r\n numberValue?: number;\r\n /**\r\n * `2026-08-15T09:00:00Z` sono le 9 UTC, `2026-08-15T09:00:00` le 9 nel fuso\r\n * dell'applicazione: sono **due istanti diversi**, e il motore converte prima di\r\n * confrontare. Scrivere il fuso quando lo si conosce e' una scelta, non un dettaglio (§4.2).\r\n */\r\n dateValue?: string;\r\n booleanValue?: boolean;\r\n enumValue?: string;\r\n formulaExpression?: string;\r\n formulaDataType?: FlowDataType;\r\n}\r\n\r\n/** §3.5 — un connector e' sempre la stessa forma; cambia solo il campo in cui vive. */\r\nexport interface FlowConnector {\r\n targetReference?: string;\r\n /** Solo suggerimento di disegno: la semantica di esecuzione e' identica (§3.5). */\r\n isGoTo?: boolean;\r\n}\r\n\r\n/** §4.3 — condizione su risorse. Per gli operatori unari `rightValue` e' l'esito atteso. */\r\nexport interface FlowCondition {\r\n leftValueReference?: string;\r\n operator?: FlowComparisonOperator;\r\n rightValue?: FlowValue;\r\n}\r\n\r\nexport type FlowComparisonOperator =\r\n | 'EqualTo'\r\n | 'NotEqualTo'\r\n | 'GreaterThan'\r\n | 'GreaterThanOrEqualTo'\r\n | 'LessThan'\r\n | 'LessThanOrEqualTo'\r\n | 'Contains'\r\n | 'StartsWith'\r\n | 'EndsWith'\r\n | 'In'\r\n | 'NotIn'\r\n | 'IsNull'\r\n | 'IsBlank'\r\n | 'IsEmpty'\r\n | 'IsChanged'\r\n | 'WasSet'\r\n | 'WasVisited'\r\n | 'HasError'\r\n | 'None'\r\n | string;\r\n\r\n/** §4.4 — filtro su campi di un'entita': struttura **diversa** dalle condizioni. */\r\nexport interface FlowRecordFilter {\r\n field?: string;\r\n operator?: FlowRecordFilterOperator;\r\n value?: FlowValue;\r\n}\r\n\r\nexport type FlowRecordFilterOperator =\r\n | 'EqualTo'\r\n | 'NotEqualTo'\r\n | 'GreaterThan'\r\n | 'GreaterThanOrEqualTo'\r\n | 'LessThan'\r\n | 'LessThanOrEqualTo'\r\n | 'StartsWith'\r\n | 'EndsWith'\r\n | 'Contains'\r\n | 'IsNull'\r\n | string;\r\n\r\n/** §4.3 — `and` | `or` | espressione sugli indici 1-based | `Formula`. */\r\nexport type FlowConditionLogic = 'and' | 'or' | 'Formula' | string;\r\n\r\n/** Blocco condizioni riusato da Decision rule, Wait event, Collection Processor, Start. */\r\nexport interface FlowConditionHolder {\r\n conditionLogic?: FlowConditionLogic;\r\n conditions?: FlowCondition[];\r\n /** Usato quando `conditionLogic === 'Formula'`; in quel caso `conditions` e' ignorato. */\r\n formula?: string;\r\n}\r\n\r\n/** Parametro di input verso form / action / script / wait event. */\r\nexport interface FlowInputParameter {\r\n name?: string;\r\n value?: FlowValue;\r\n}\r\n\r\n/** Parametro di output: `assignToReference` deve essere una destinazione scrivibile (§4.6). */\r\nexport interface FlowOutputParameter {\r\n name?: string;\r\n assignToReference?: string;\r\n}\r\n\r\n/** Campo di un record → valore (Create/Update). */\r\nexport interface FlowInputFieldAssignment {\r\n field?: string;\r\n value?: FlowValue;\r\n}\r\n\r\n/** Campo di un record → variabile (Get Records con output esplicito). */\r\nexport interface FlowOutputFieldAssignment {\r\n field?: string;\r\n assignToReference?: string;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Risorse (§4.6)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowVariable {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n /** Obbligatorio per `Object` ed `Enum`: nome dell'entita' o del tipo di enum. */\r\n objectType?: string;\r\n isCollection?: boolean;\r\n isInput?: boolean;\r\n isOutput?: boolean;\r\n /** Solo per `Number` e `Integer`; altrove e' `SCALE_NOT_APPLICABLE`. */\r\n scale?: number;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowConstant {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n /** Non puo' referenziare altre risorse: `CONSTANT_REFERENCES_RESOURCE`. */\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowFormula {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n scale?: number;\r\n /** Passata verbatim al motore di regole: il backend non la valida (§4.6). */\r\n expression?: string;\r\n}\r\n\r\nexport interface FlowTextTemplate {\r\n name?: string;\r\n description?: string;\r\n text?: string;\r\n isViewedAsPlainText?: boolean;\r\n}\r\n\r\nexport interface FlowChoice {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n choiceText?: string;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowDynamicChoiceSet {\r\n name?: string;\r\n description?: string;\r\n dataType?: FlowDataType;\r\n object?: string;\r\n displayField?: string;\r\n valueField?: string;\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n limit?: number;\r\n /** Sempre in AND: nessun `filterLogic` qui (§4.4). */\r\n filters?: FlowRecordFilter[];\r\n}\r\n\r\nexport interface FlowStage {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n /** Devono essere distinti: `STAGE_ORDER_DUPLICATED`. */\r\n stageOrder?: number;\r\n isActive?: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Node (§5)\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Campi comuni a ogni node. `locationX`/`locationY` sono l'unico layout persistito (§3.5). */\r\nexport interface FlowNodeBase {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n locationX?: number;\r\n locationY?: number;\r\n}\r\n\r\n/** §5.1 — lo screen dichiara *quale* form mostrare, non i suoi campi. */\r\nexport interface FlowScreen extends FlowNodeBase {\r\n formName?: string;\r\n helpText?: string;\r\n allowBack?: boolean;\r\n allowFinish?: boolean;\r\n allowPause?: boolean;\r\n pausedText?: string;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport type FlowAssignmentOperator =\r\n | 'Assign'\r\n | 'Add'\r\n | 'Subtract'\r\n | 'AddAtStart'\r\n | 'AssignCount'\r\n | 'RemoveFirst'\r\n | 'RemoveAll'\r\n | 'RemovePosition'\r\n | 'RemoveAfterFirst'\r\n | 'RemoveBeforeFirst'\r\n | 'RemoveUncommon'\r\n | string;\r\n\r\nexport interface FlowAssignmentItem {\r\n assignToReference?: string;\r\n operator?: FlowAssignmentOperator;\r\n value?: FlowValue;\r\n}\r\n\r\n/** §5.2 — le operazioni sono eseguite nell'ordine dichiarato. */\r\nexport interface FlowAssignment extends FlowNodeBase {\r\n assignmentItems?: FlowAssignmentItem[];\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.3 — una regola per ramo; l'ordine e' semantico. */\r\nexport interface FlowDecisionRule extends FlowConditionHolder {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowDecision extends FlowNodeBase {\r\n rules?: FlowDecisionRule[];\r\n defaultConnector?: FlowConnector;\r\n defaultConnectorLabel?: string;\r\n}\r\n\r\n/** §5.4 */\r\nexport interface FlowLoop extends FlowNodeBase {\r\n collectionReference?: string;\r\n assignNextValueToReference?: string;\r\n iterationOrder?: FlowSortOrder;\r\n nextValueConnector?: FlowConnector;\r\n noMoreValuesConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowSortOption {\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n doesPutEmptyStringAndNullFirst?: boolean;\r\n}\r\n\r\n/** §5.5 — `assignNextValueToReference` e' l'elemento in esame, non la destinazione. */\r\nexport interface FlowCollectionProcessor extends FlowNodeBase, FlowConditionHolder {\r\n collectionProcessorType?: FlowCollectionProcessorType;\r\n collectionReference?: string;\r\n assignNextValueToReference?: string;\r\n limit?: number;\r\n sortOptions?: FlowSortOption[];\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.6 */\r\nexport interface FlowRecordLookup extends FlowNodeBase {\r\n object?: string;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n sortField?: string;\r\n sortOrder?: FlowSortOrder;\r\n getFirstRecordOnly?: boolean;\r\n queriedFields?: string[];\r\n limit?: number;\r\n /** Alternativo a `outputReference`/`outputAssignments`: `OUTPUT_CONFIGURATION_CONFLICT`. */\r\n storeOutputAutomatically?: boolean;\r\n outputReference?: string;\r\n outputAssignments?: FlowOutputFieldAssignment[];\r\n /** Modellato ma non tradotto in query (§5.6). */\r\n relatedRecords?: unknown[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.7 */\r\nexport interface FlowRecordCreate extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n doesUpsert?: boolean;\r\n upsertExternalIdField?: string;\r\n upsertStandardIdField?: string;\r\n storeOutputAutomatically?: boolean;\r\n assignRecordIdToReference?: string;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordUpdate extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n /** Nessun `filterLogic` qui: i filtri sono sempre in AND (§4.4). */\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordDelete extends FlowNodeBase {\r\n object?: string;\r\n inputReference?: string;\r\n /** Senza filtri e' un **errore**, non un avviso (§5.7). */\r\n filters?: FlowRecordFilter[];\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowRecordRollback extends FlowNodeBase {\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.8 */\r\nexport interface FlowActionCall extends FlowNodeBase {\r\n actionType?: string;\r\n actionName?: string;\r\n flowTransactionModel?: FlowTransactionModel;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n storeOutputAutomatically?: boolean;\r\n isWaitUntilCompleted?: boolean;\r\n offset?: number;\r\n offsetUnit?: FlowOffsetUnit;\r\n /** Il ramo di timeout esiste solo con `EnableTimeoutPath`. */\r\n timeoutPathUsage?: 'EnableTimeoutPath' | 'NoTimeoutPath' | string;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n timeoutConnector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowScriptPluginCall extends FlowNodeBase {\r\n scriptName?: string;\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n storeOutputAutomatically?: boolean;\r\n connector?: FlowConnector;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.9 — i `name` sono le variabili isInput/isOutput del flow **invocato**. */\r\nexport interface FlowSubflowInputAssignment {\r\n name?: string;\r\n value?: FlowValue;\r\n}\r\n\r\nexport interface FlowSubflowOutputAssignment {\r\n name?: string;\r\n assignToReference?: string;\r\n}\r\n\r\nexport interface FlowSubflow extends FlowNodeBase {\r\n flowName?: string;\r\n inputAssignments?: FlowSubflowInputAssignment[];\r\n outputAssignments?: FlowSubflowOutputAssignment[];\r\n storeOutputAutomatically?: boolean;\r\n connector?: FlowConnector;\r\n}\r\n\r\n/** §5.10 */\r\nexport interface FlowWaitEvent extends FlowConditionHolder {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n eventType?: string;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowWait extends FlowNodeBase {\r\n waitEvents?: FlowWaitEvent[];\r\n defaultConnector?: FlowConnector;\r\n defaultConnectorLabel?: string;\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n/** §5.11 */\r\nexport interface FlowCustomErrorMessage {\r\n errorMessage?: string;\r\n isFieldError?: boolean;\r\n fieldSelection?: string;\r\n}\r\n\r\nexport interface FlowCustomError extends FlowNodeBase {\r\n customErrorMessages?: FlowCustomErrorMessage[];\r\n}\r\n\r\n/** §5.12 */\r\nexport interface FlowTransformValueAction {\r\n transformType?: FlowTransformType;\r\n outputFieldApiName?: string;\r\n value?: FlowValue;\r\n inputParameters?: FlowInputParameter[];\r\n}\r\n\r\nexport interface FlowTransformValue {\r\n transformValueActions?: FlowTransformValueAction[];\r\n}\r\n\r\nexport interface FlowTransform extends FlowNodeBase {\r\n dataType?: FlowDataType;\r\n objectType?: string;\r\n isCollection?: boolean;\r\n transformValues?: FlowTransformValue[];\r\n /** **Array** per fedelta' storica: usa il primo (§3.5). */\r\n connector?: FlowConnector[];\r\n}\r\n\r\n/** Non supportati dal motore: nascosti dalla palette (§3.2, §13.9). */\r\nexport interface FlowUnsupportedNode extends FlowNodeBase {\r\n connector?: FlowConnector;\r\n [key: string]: unknown;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Orchestrated Stage (§5.13)\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * §5.13 — i tre tipi di step. `stepMuleSoft` non esiste in questo sistema\r\n * (`ELEMENT_NOT_SUPPORTED`); l'elenco autoritativo e' il dizionario `stageStepTypes`.\r\n */\r\nexport type FlowStageStepActionType = 'stepBackground' | 'stepInteractive' | 'stepApproval' | string;\r\n\r\n/** A chi e' assegnato uno step interattivo. `assigneeTypes` e' il dizionario (§6.4). */\r\nexport interface FlowStageStepAssignee {\r\n assigneeType?: string;\r\n assignee?: FlowValue;\r\n}\r\n\r\n/** Il nome di un *evaluation flow* che decide una condizione di ingresso o di uscita. */\r\nexport type FlowStageStepConditionActionType = 'EvaluationFlow' | string;\r\n\r\n/**\r\n * §5.13 — uno step di uno stage.\r\n *\r\n * Due cose che non si vedono dal tipo:\r\n * - gli step **non hanno un ordine di esecuzione**: parte quello le cui `entryConditions`\r\n * sono vere, e l'ordine nell'array e' solo l'ordine d'esame;\r\n * - `name` sta nello **stesso spazio dei nomi** di node e risorse (§3.3), e l'output di uno\r\n * step e' sempre referenziabile come `<NomeStep>.<NomeOutput>`.\r\n *\r\n * I campi riservati (`runAsUser`, ignorato dal runtime, `canAssigneeEdit`, `shouldLock`,\r\n * `requiresAsyncProcessing`) non sono modellati di proposito: non vanno esposti. Sopravvivono\r\n * comunque al round-trip, perche' il documento viaggia come JSON.\r\n */\r\nexport interface FlowStageStep {\r\n name?: string;\r\n label?: string;\r\n description?: string;\r\n actionType?: FlowStageStepActionType;\r\n /** Obbligatorio su `stepBackground`: il flow che il motore esegue subito. */\r\n actionName?: string;\r\n /** Obbligatori su `stepInteractive` e `stepApproval`. */\r\n assignees?: FlowStageStepAssignee[];\r\n /** `\"0\"` o `\"1\"`: il modello lo porta come stringa. */\r\n requiresMultiMemberApproval?: string;\r\n /** *Se* lo step si applica: se non si avverano, viene saltato (§5.13). */\r\n entryConditions?: FlowCondition[];\r\n /** *Quando* lo step libera lo stage: se restano false, lo stage va in stallo (§5.13). */\r\n exitConditions?: FlowCondition[];\r\n /** Evaluation flow che decide l'ingresso: deve restituire `isOrchestrationConditionMet`. */\r\n entryActionName?: string;\r\n entryActionType?: FlowStageStepConditionActionType;\r\n exitActionName?: string;\r\n exitActionType?: FlowStageStepConditionActionType;\r\n inputParameters?: FlowInputParameter[];\r\n /** `assignToReference` e' facoltativo: l'output e' già referenziabile (§5.13). */\r\n outputParameters?: FlowOutputParameter[];\r\n /** `true` → usa `outputConfigParams` come output finti, senza eseguire lo step. */\r\n debugSimulateStep?: boolean;\r\n outputConfigParams?: FlowInputParameter[];\r\n}\r\n\r\nexport interface FlowOrchestratedStage extends FlowNodeBase {\r\n stageSteps?: FlowStageStep[];\r\n connector?: FlowConnector;\r\n /**\r\n * **Non** e' un ramo di guasto: e' il ramo percorso quando uno step viene rifiutato.\r\n * Senza, un rifiuto fa fallire l'interview (§5.13).\r\n */\r\n faultConnector?: FlowConnector;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Start (§3.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowSchedule {\r\n frequency?: 'Once' | 'Daily' | 'Weekly' | 'Monthly' | string;\r\n /** Data senza fuso: `2026-08-01T00:00:00`. */\r\n startDate?: string;\r\n /** `08:00:00`. */\r\n startTime?: string;\r\n}\r\n\r\nexport interface FlowScheduledPath {\r\n name?: string;\r\n label?: string;\r\n offsetNumber?: number;\r\n offsetUnit?: FlowOffsetUnit;\r\n timeSource?: string;\r\n recordField?: string;\r\n connector?: FlowConnector;\r\n}\r\n\r\nexport interface FlowStart {\r\n locationX?: number;\r\n locationY?: number;\r\n /** Sempre necessario: senza, `START_NO_ENTRY_POINT`. */\r\n connector?: FlowConnector;\r\n triggerType?: FlowTriggerType;\r\n object?: string;\r\n recordTriggerType?: FlowRecordTriggerType;\r\n filterLogic?: FlowConditionLogic;\r\n filters?: FlowRecordFilter[];\r\n filterFormula?: string;\r\n doesRequireRecordChangedToMeetCriteria?: boolean;\r\n schedule?: FlowSchedule;\r\n scheduledPaths?: FlowScheduledPath[];\r\n inputs?: FlowInputParameter[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Documento radice (§3.1)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowCustomProperty {\r\n name?: string;\r\n value?: string;\r\n}\r\n\r\n/**\r\n * §3.1 — i node non stanno in un'unica lista: c'e' una collection per tipo.\r\n * Il tipo di un node **e'** la collection in cui sta.\r\n */\r\nexport interface FlowDefinition {\r\n /** Identificatore. Rinominare passa da una primitiva dedicata, non dal JSON (§2). */\r\n fullName?: string;\r\n label?: string;\r\n description?: string;\r\n processType?: FlowProcessType;\r\n /** Sola lettura per l'editor: lo governa il ciclo di vita (§8). */\r\n status?: FlowVersionStatus;\r\n interviewLabel?: string;\r\n\r\n /** Array di uno per fedelta' storica: usa sempre il primo (§3.4). */\r\n start?: FlowStart[];\r\n\r\n variables?: FlowVariable[];\r\n constants?: FlowConstant[];\r\n formulas?: FlowFormula[];\r\n textTemplates?: FlowTextTemplate[];\r\n choices?: FlowChoice[];\r\n dynamicChoiceSets?: FlowDynamicChoiceSet[];\r\n stages?: FlowStage[];\r\n\r\n screens?: FlowScreen[];\r\n assignments?: FlowAssignment[];\r\n decisions?: FlowDecision[];\r\n loops?: FlowLoop[];\r\n collectionProcessors?: FlowCollectionProcessor[];\r\n recordLookups?: FlowRecordLookup[];\r\n recordCreates?: FlowRecordCreate[];\r\n recordUpdates?: FlowRecordUpdate[];\r\n recordDeletes?: FlowRecordDelete[];\r\n recordRollbacks?: FlowRecordRollback[];\r\n actionCalls?: FlowActionCall[];\r\n scriptPluginCalls?: FlowScriptPluginCall[];\r\n subflows?: FlowSubflow[];\r\n transforms?: FlowTransform[];\r\n waits?: FlowWait[];\r\n customErrors?: FlowCustomError[];\r\n orchestratedStages?: FlowOrchestratedStage[];\r\n\r\n /** Non supportati: conservati nel round-trip ma non creabili dalla palette. */\r\n steps?: FlowUnsupportedNode[];\r\n experiments?: FlowUnsupportedNode[];\r\n\r\n apiVersion?: string;\r\n timeZoneSidKey?: string;\r\n triggerOrder?: number;\r\n isTemplate?: boolean;\r\n customProperties?: FlowCustomProperty[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Chiavi delle collection\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Le collection di node: `metadataProperty` del dizionario `elementTypes` (§3.2). */\r\nexport const FLOW_NODE_COLLECTIONS = [\r\n 'screens',\r\n 'assignments',\r\n 'decisions',\r\n 'loops',\r\n 'collectionProcessors',\r\n 'recordLookups',\r\n 'recordCreates',\r\n 'recordUpdates',\r\n 'recordDeletes',\r\n 'recordRollbacks',\r\n 'actionCalls',\r\n 'scriptPluginCalls',\r\n 'subflows',\r\n 'transforms',\r\n 'waits',\r\n 'customErrors',\r\n 'orchestratedStages',\r\n 'steps',\r\n 'experiments',\r\n] as const;\r\n\r\nexport type FlowNodeCollection = (typeof FLOW_NODE_COLLECTIONS)[number];\r\n\r\n/** Le collection di risorse (§4.6). Condividono lo spazio dei nomi con i node (§3.3). */\r\nexport const FLOW_RESOURCE_COLLECTIONS = [\r\n 'variables',\r\n 'constants',\r\n 'formulas',\r\n 'textTemplates',\r\n 'choices',\r\n 'dynamicChoiceSets',\r\n 'stages',\r\n] as const;\r\n\r\nexport type FlowResourceCollection = (typeof FLOW_RESOURCE_COLLECTIONS)[number];\r\n\r\n/** Il discriminatore `value` del dizionario `elementTypes`. */\r\nexport type FlowElementType =\r\n | 'Screen'\r\n | 'Assignment'\r\n | 'Decision'\r\n | 'Loop'\r\n | 'CollectionProcessor'\r\n | 'CustomError'\r\n | 'Wait'\r\n | 'RecordLookup'\r\n | 'RecordCreate'\r\n | 'RecordUpdate'\r\n | 'RecordDelete'\r\n | 'RecordRollback'\r\n | 'ActionCall'\r\n | 'ScriptCall'\r\n | 'Subflow'\r\n | 'Transform'\r\n | 'OrchestratedStage'\r\n | 'Step'\r\n | 'Experiment'\r\n | string;\r\n\r\n/** Un node qualunque, come lo vede il canvas. */\r\nexport type FlowAnyNode = FlowNodeBase & Record<string, unknown>;\r\n","/**\r\n * Dizionari — FRONTEND.md §6.4.\r\n *\r\n * Sono statici: si caricano una volta e si tengono in cache. Nessun elenco di enum\r\n * o di operatori va cablato nel frontend (§13.11): tutte le tendine leggono da qui.\r\n */\r\n\r\nimport { FlowDataType, FlowElementType, FlowNodeCollection } from './flow.model';\r\n\r\n/** Ogni voce di dizionario ha almeno `value` (da scrivere) e `label` (da mostrare). */\r\nexport interface FlowDictionaryEntry {\r\n value: string;\r\n label: string;\r\n description?: string | null;\r\n}\r\n\r\nexport interface FlowDataTypeEntry extends FlowDictionaryEntry {\r\n value: FlowDataType;\r\n /** `Object` ed `Enum` richiedono `objectType` (§4.6). */\r\n requiresObjectType?: boolean;\r\n /** `scale` si applica solo ai numerici (§4.6). */\r\n supportsScale?: boolean;\r\n}\r\n\r\n/** §3.2 — la voce che descrive un tipo di elemento. */\r\nexport interface FlowElementTypeEntry extends FlowDictionaryEntry {\r\n value: FlowElementType;\r\n /** Categoria per raggruppare la palette: Interazione, Logica, Dati, Azione, Flow. */\r\n category?: string | null;\r\n /** La collection in cui scrivere il node (§3.1). */\r\n metadataProperty?: FlowNodeCollection | string;\r\n /** `false` → va nascosto dalla palette (§13.9). */\r\n isSupported?: boolean;\r\n hasFaultConnector?: boolean;\r\n hasAutomaticOutput?: boolean;\r\n}\r\n\r\n/** §4.3 — operatore di confronto per le condizioni su risorse. */\r\nexport interface FlowComparisonOperatorEntry extends FlowDictionaryEntry {\r\n /**\r\n * Trappola numero uno (§13.1): per gli unari `rightValue` e' l'**esito atteso**,\r\n * non il termine di confronto.\r\n */\r\n isUnary?: boolean;\r\n /** A sinistra vuole il nome di un **node**, non di una risorsa (`WasVisited`, `HasError`). */\r\n appliesToElements?: boolean;\r\n /** Tipi a cui l'operatore si applica; vuoto o assente = qualunque tipo. */\r\n appliesTo?: FlowDataType[] | null;\r\n}\r\n\r\n/** §5.2 — operatore di assegnazione. */\r\nexport interface FlowAssignmentOperatorEntry extends FlowDictionaryEntry {\r\n /** Ha senso solo su destinazioni collection; altrove e' un avviso. */\r\n expectsCollection?: boolean;\r\n}\r\n\r\n/**\r\n * §4.1 — variabile globale proponibile invece di farla digitare.\r\n *\r\n * La verificabilita' e' **per scope**: se `paths` porta almeno una voce, un percorso che non\r\n * c'e' e' `GLOBAL_UNKNOWN`; se `paths` e' vuoto, lo scope resta non verificabile — che\r\n * significa \"non lo so\", non \"non esiste\".\r\n */\r\nexport interface FlowGlobalVariableEntry extends FlowDictionaryEntry {\r\n /** `$Flow`, `$GlobalConstant`, `$Record`, `$User`, … */\r\n scope?: string;\r\n /** Percorsi noti dello scope. Vuoto → lo scope non e' verificabile (§4.1). */\r\n paths?: string[] | null;\r\n /** `true` → i percorsi li dichiara il sistema ospite, e solo quelli che dichiara. */\r\n isResolvedByHost?: boolean;\r\n /** Disponibile solo con un trigger su record (`$Record`, `$Record__Prior`). */\r\n requiresRecordTrigger?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — i tipi di step di uno stage di orchestrazione (`stageStepTypes`).\r\n * Le colonne dicono cosa il tipo pretende: senza, l'editor dovrebbe cablare i tre nomi.\r\n */\r\nexport interface FlowStageStepTypeEntry extends FlowDictionaryEntry {\r\n /** `stepBackground`: il flow eseguito subito e' obbligatorio. */\r\n requiresActionName?: boolean;\r\n /** `stepInteractive` / `stepApproval`: gli assegnatari sono obbligatori. */\r\n requiresAssignees?: boolean;\r\n /** `true` → l'interview si **sospende** su questo step, in attesa di una persona. */\r\n suspendsInterview?: boolean;\r\n /** `true` → il rifiuto e' un esito previsto, e prende il `faultConnector` dello stage. */\r\n supportsRejection?: boolean;\r\n}\r\n\r\nexport interface FlowResourceKindEntry extends FlowDictionaryEntry {\r\n /** Solo le variabili sono scrivibili (§4.6). */\r\n isWritable?: boolean;\r\n /** La collection del documento in cui vive la risorsa. */\r\n metadataProperty?: string;\r\n}\r\n\r\n/**\r\n * §6.4 — le tendine in una risposta.\r\n * I campi sono opzionali: un backend che non popola un dizionario non deve far\r\n * crollare l'editor, che degrada mostrando il valore grezzo.\r\n *\r\n * Sono **quasi** statici: `globalVariables` dipende dal `processType` con cui si sono\r\n * chiesti, perche' `$Record` non esiste in uno screen flow (§4.1). Chi lavora su piu' tipi di\r\n * flow ne tiene una copia per tipo — se ne occupa {@link FlowDictionaryStore}.\r\n */\r\nexport interface FlowDictionaries {\r\n dataTypes?: FlowDataTypeEntry[];\r\n comparisonOperators?: FlowComparisonOperatorEntry[];\r\n assignmentOperators?: FlowAssignmentOperatorEntry[];\r\n recordFilterOperators?: FlowDictionaryEntry[];\r\n elementTypes?: FlowElementTypeEntry[];\r\n resourceKinds?: FlowResourceKindEntry[];\r\n globalVariables?: FlowGlobalVariableEntry[];\r\n processTypes?: FlowDictionaryEntry[];\r\n versionStatuses?: FlowDictionaryEntry[];\r\n triggerTypes?: FlowDictionaryEntry[];\r\n recordTriggerTypes?: FlowDictionaryEntry[];\r\n startFrequencies?: FlowDictionaryEntry[];\r\n offsetUnits?: FlowDictionaryEntry[];\r\n sortOrders?: FlowDictionaryEntry[];\r\n collectionProcessorTypes?: FlowDictionaryEntry[];\r\n transformTypes?: FlowDictionaryEntry[];\r\n transactionModels?: FlowDictionaryEntry[];\r\n waitEventTypes?: FlowDictionaryEntry[];\r\n stageStepTypes?: FlowStageStepTypeEntry[];\r\n assigneeTypes?: FlowDictionaryEntry[];\r\n conditionLogicModes?: FlowDictionaryEntry[];\r\n screenNavigations?: FlowDictionaryEntry[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cataloghi (§6.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowObjectSummary {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\nexport interface FlowObjectDescription {\r\n name: string;\r\n label?: string | null;\r\n fields?: FlowFieldDescription[];\r\n}\r\n\r\nexport interface FlowFieldDescription {\r\n name: string;\r\n label?: string | null;\r\n dataType?: FlowDataType;\r\n objectType?: string | null;\r\n isFilterable?: boolean;\r\n isSortable?: boolean;\r\n isUpdateable?: boolean;\r\n isRequired?: boolean;\r\n /** `true` → i valori ammessi si chiedono a `.../fields/{field}/values`. */\r\n hasClosedValueSet?: boolean;\r\n}\r\n\r\n/** `any` | `filterable` | `sortable` | `updateable` (§6.4). */\r\nexport type FlowFieldUsage = 'any' | 'filterable' | 'sortable' | 'updateable';\r\n\r\nexport interface FlowFieldValue {\r\n value: string;\r\n label?: string | null;\r\n}\r\n\r\n/** Voce di catalogo per action, script, form, eventi, tipi di enum. */\r\nexport interface FlowCatalogEntry {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\n/**\r\n * Parametro dichiarato da un'action, uno script o un form.\r\n * Con il catalogo popolato un parametro inesistente e' un **errore** (§5.8).\r\n */\r\nexport interface FlowCatalogParameter {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n dataType?: FlowDataType;\r\n objectType?: string | null;\r\n isCollection?: boolean;\r\n isInput?: boolean;\r\n isOutput?: boolean;\r\n isRequired?: boolean;\r\n}\r\n","/**\r\n * Payload delle primitive — FRONTEND.md §6, §7, §8, §10.\r\n */\r\n\r\nimport { FlowDataType, FlowDefinition, FlowProcessType, FlowVersionStatus } from './flow.model';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Elenchi (§6.1)\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Una riga per **nome**, non per versione (§6.1). */\r\nexport interface FlowSummary {\r\n flowName: string;\r\n label?: string | null;\r\n description?: string | null;\r\n processType?: FlowProcessType;\r\n activeVersion?: number | null;\r\n latestVersion?: number;\r\n versionCount?: number;\r\n hasDraft?: boolean;\r\n updatedAt?: string;\r\n /** Esiste una versione attiva. Non ricalcolarlo lato client (§6.1). */\r\n isRunnable?: boolean;\r\n}\r\n\r\nexport interface FlowVersionSummary {\r\n flowName: string;\r\n version: number;\r\n status?: FlowVersionStatus;\r\n label?: string | null;\r\n description?: string | null;\r\n processType?: FlowProcessType;\r\n createdAt?: string;\r\n /** Da conservare e rimandare come `expectedUpdatedAt` al salvataggio (§9). */\r\n updatedAt?: string;\r\n updatedBy?: string | null;\r\n isActive?: boolean;\r\n /** La versione e' una bozza. Non ricalcolarlo lato client (§6.1). */\r\n isEditable?: boolean;\r\n}\r\n\r\nexport interface FlowListQuery {\r\n search?: string;\r\n processType?: FlowProcessType;\r\n onlyActive?: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Validazione (§7)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowIssueSeverity = 'Error' | 'Warning' | 'Info' | string;\r\n\r\nexport interface FlowValidationIssue {\r\n /** Stabile: usalo per decidere il comportamento. Non interpretare `message` (§7). */\r\n code: string;\r\n severity: FlowIssueSeverity;\r\n message: string;\r\n /** Ancora per portare l'utente sull'elemento con un clic. */\r\n elementName?: string | null;\r\n /** Campo dentro l'elemento, es. `rules[Approvato].connector.targetReference`. */\r\n path?: string | null;\r\n}\r\n\r\nexport interface FlowValidationResult {\r\n /** Ordinati per gravita' decrescente (§7). */\r\n issues: FlowValidationIssue[];\r\n errorCount: number;\r\n warningCount: number;\r\n isValid: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Scrittura (§6.2)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface FlowCreateRequest {\r\n definition: FlowDefinition;\r\n flowName?: string;\r\n author?: string;\r\n}\r\n\r\nexport interface FlowSaveRequest {\r\n definition: FlowDefinition;\r\n /** Se indicato **vince** sul `fullName` del documento: e' cosi' che si rinomina (§6.2). */\r\n flowName?: string;\r\n /** Mandare sempre la versione che si sta editando rende il risultato prevedibile (§8). */\r\n version?: number;\r\n /** Concorrenza ottimistica: facoltativo ma raccomandato (§9). */\r\n expectedUpdatedAt?: string;\r\n author?: string;\r\n /** Salva **e** attiva. Fallisce senza scrivere nulla se ci sono errori. */\r\n activate?: boolean;\r\n}\r\n\r\nexport interface FlowSaveResult {\r\n flowName: string;\r\n version: number;\r\n status: FlowVersionStatus;\r\n isNewVersion: boolean;\r\n /** Da conservare per il salvataggio successivo (§9). */\r\n updatedAt: string;\r\n /** Il salvataggio riesce anche con errori: guarda qui, non l'esito HTTP (§6.2). */\r\n validation?: FlowValidationResult;\r\n}\r\n\r\nexport interface FlowCloneRequest {\r\n targetFlowName: string;\r\n label?: string;\r\n fromVersion?: number;\r\n author?: string;\r\n}\r\n\r\nexport interface FlowNewVersionRequest {\r\n /** Versione da copiare; se omessa, l'ultima. */\r\n from?: number;\r\n author?: string;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Riferimenti e struttura (§6.4)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowReferenceKind =\r\n | 'Variable'\r\n | 'Constant'\r\n | 'Formula'\r\n | 'TextTemplate'\r\n | 'Choice'\r\n | 'DynamicChoiceSet'\r\n | 'Stage'\r\n /** Output automatico di un elemento: valido pur non essendo dichiarato (§4.5, §13.3). */\r\n | 'ElementOutput'\r\n | 'Global'\r\n | string;\r\n\r\nexport interface FlowReference {\r\n name: string;\r\n label?: string | null;\r\n kind: FlowReferenceKind;\r\n dataType?: FlowDataType | null;\r\n isCollection?: boolean;\r\n objectType?: string | null;\r\n /**\r\n * Per i campi di destinazione. Scrivibili sono le variabili, `$Flow.CurrentStage`,\r\n * `$Flow.ActiveStages` e le globali che il sistema ospite dichiara tali: la primitiva\r\n * `POST /flows/references/writable` le comprende già, non vanno aggiunte lato client (§5.2).\r\n */\r\n isWritable?: boolean;\r\n description?: string | null;\r\n}\r\n\r\n/** Filtro opzionale per non trasferire riferimenti che il campo non accetta. */\r\nexport interface FlowReferenceQuery {\r\n definition: FlowDefinition;\r\n dataType?: FlowDataType;\r\n isCollection?: boolean;\r\n objectType?: string;\r\n}\r\n\r\nexport interface FlowConnectorTarget {\r\n name: string;\r\n label?: string | null;\r\n kind?: string;\r\n}\r\n\r\nexport type FlowConnectionKind =\r\n | 'Start'\r\n | 'ScheduledPath'\r\n | 'Next'\r\n | 'Rule'\r\n | 'Default'\r\n | 'LoopNext'\r\n | 'LoopEnd'\r\n | 'WaitEvent'\r\n | 'Fault'\r\n | 'Timeout'\r\n | string;\r\n\r\nexport interface FlowOutlineNode {\r\n name: string;\r\n label?: string | null;\r\n kind: string;\r\n description?: string | null;\r\n locationX?: number;\r\n locationY?: number;\r\n /** `false` → nessun percorso lo raggiunge dallo Start: va reso \"scollegato\" (§6.4). */\r\n isReachable?: boolean;\r\n}\r\n\r\nexport interface FlowOutlineConnection {\r\n /** `null` identifica gli archi uscenti dallo Start, che non ha nome (§6.4). */\r\n from?: string | null;\r\n /** `null` → il connector esiste ma non ha destinazione: ramo incompleto (§6.4). */\r\n to?: string | null;\r\n kind: FlowConnectionKind;\r\n label?: string | null;\r\n isGoTo?: boolean;\r\n}\r\n\r\nexport interface FlowOutline {\r\n flowName?: string | null;\r\n label?: string | null;\r\n processType?: FlowProcessType;\r\n triggerType?: string | null;\r\n entryElementName?: string | null;\r\n nodes: FlowOutlineNode[];\r\n connections: FlowOutlineConnection[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Esecuzione (§6.5)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type FlowInterviewStatus =\r\n | 'Completed'\r\n | 'WaitingForScreen'\r\n | 'Paused'\r\n | 'Suspended'\r\n /** **Non** e' un errore HTTP: la richiesta e' riuscita, il flow e' fallito (§6.5). */\r\n | 'Failed'\r\n /** I criteri dello Start non erano soddisfatti: non e' un errore (§6.5). */\r\n | 'NotStarted'\r\n | string;\r\n\r\nexport type FlowScreenNavigation = 'Next' | 'Previous' | 'Pause' | 'Finish' | string;\r\n\r\n/** Il tipo dichiarato **vince** in lettura: distingue `Integer` da `Number` (§6.5). */\r\nexport interface FlowTypedValue {\r\n type?: FlowDataType;\r\n value?: unknown;\r\n}\r\n\r\nexport interface FlowPendingScreen {\r\n elementName?: string;\r\n formName?: string;\r\n label?: string | null;\r\n helpText?: string | null;\r\n inputs?: Record<string, FlowTypedValue>;\r\n /** Piu' precisi dei flag del metadata: sono la verita' su cosa abilitare (§6.5). */\r\n canGoBack?: boolean;\r\n canFinish?: boolean;\r\n canPause?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — lo stato che un assegnatario comunica concludendo uno step.\r\n * `Pending` non e' accettato in scrittura: e' `INVALID_REQUEST`.\r\n */\r\nexport type FlowStageStepStatus = 'Completed' | 'Rejected' | 'Cancelled' | 'Pending' | string;\r\n\r\n/** Lo stato di uno step, come lo riporta l'ispezione di una sospesa (§5.13, §6.5). */\r\nexport interface FlowStageStepState {\r\n stepName?: string;\r\n label?: string | null;\r\n actionType?: string;\r\n status?: FlowStageStepStatus;\r\n /** `true` → c'e' un work item aperto: e' questo step a tenere sospesa l'interview. */\r\n isWaiting?: boolean;\r\n assignees?: string[];\r\n outputs?: Record<string, FlowTypedValue>;\r\n}\r\n\r\nexport interface FlowTraceEntry {\r\n sequence?: number;\r\n level?: string;\r\n message?: string;\r\n elementName?: string | null;\r\n}\r\n\r\nexport interface FlowInterviewResult {\r\n interviewId?: string;\r\n flowName?: string;\r\n status: FlowInterviewStatus;\r\n /** Opaco: da rimandare tale e quale (§6.5, §13.12). */\r\n continuationToken?: string | null;\r\n interviewKey?: string | null;\r\n pendingScreen?: FlowPendingScreen | null;\r\n outputs?: Record<string, FlowTypedValue>;\r\n errors?: string[];\r\n fault?: string | null;\r\n currentElementName?: string | null;\r\n steps?: number;\r\n /** Popolato solo con `debug: true`. Puo' contenere dati personali (§6.5). */\r\n trace?: FlowTraceEntry[];\r\n /** Con `debug: true`: i valori di **tutte** le risorse, non solo gli output. */\r\n resources?: Record<string, FlowTypedValue>;\r\n /**\r\n * `Suspended` copre due attese diverse, e questi due flag le distinguono: un evento\r\n * oppure uno step di orchestrazione (§6.5).\r\n */\r\n isWaitingForEvent?: boolean;\r\n isWaitingForStageStep?: boolean;\r\n /** Con `isWaitingForStageStep`: lo stato di ogni step dello stage corrente (§5.13). */\r\n stageSteps?: FlowStageStepState[];\r\n isSuccess?: boolean;\r\n}\r\n\r\nexport interface FlowStartInterviewRequest {\r\n flowName: string;\r\n version?: number;\r\n inputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowScreenResponseRequest {\r\n continuationToken: string;\r\n screenElementName?: string;\r\n navigation?: FlowScreenNavigation;\r\n outputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowResumeRequest {\r\n interviewKey: string;\r\n debug?: boolean;\r\n}\r\n\r\n/**\r\n * §5.13 — `POST /interviews/{key}/stage-step`: un assegnatario conclude uno step.\r\n * Se lo stage si sospende di nuovo, la risposta porta una `interviewKey` **nuova** e la\r\n * vecchia non e' piu' valida.\r\n */\r\nexport interface FlowStageStepRequest {\r\n interviewKey: string;\r\n stepName: string;\r\n /** `Pending` viene rifiutato come `INVALID_REQUEST`. */\r\n status: FlowStageStepStatus;\r\n stepOutputs?: Record<string, unknown>;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface FlowExportQuery {\r\n version?: number;\r\n indented?: boolean;\r\n}\r\n","/**\r\n * Errori categorizzati — FRONTEND.md §10.\r\n *\r\n * La UI si comporta in base alla **categoria**, non al messaggio. L'implementazione\r\n * dell'interfaccia backend ha il compito di tradurre l'errore di trasporto\r\n * (status HTTP, payload) in un `FlowApiError`: da lì in poi l'editor non conosce HTTP.\r\n */\r\n\r\nimport { FlowValidationResult } from './api.model';\r\n\r\n/** Categorie di authoring (§10). */\r\nexport type FlowErrorCategory =\r\n /** Bug del client: la richiesta e' incompleta. */\r\n | 'InvalidRequest'\r\n /** Il documento non e' leggibile: tipicamente l'import di un file sbagliato. */\r\n | 'InvalidDefinition'\r\n /** Apri il pannello dei problemi: il payload contiene `validation`. */\r\n | 'ValidationFailed'\r\n | 'FlowNotFound'\r\n | 'VersionNotFound'\r\n /** Nome già usato: chiedi un altro nome. */\r\n | 'AlreadyExists'\r\n /** Versione non modificabile: proponi \"Nuova versione\" (§8.1). */\r\n | 'NotEditable'\r\n /** Qualcun altro ha salvato: proponi ricarica (§9). */\r\n | 'VersionConflict'\r\n /** Funzione non configurata su questo ambiente: disabilita il comando. */\r\n | 'MissingService'\r\n // Categorie dell'esecuzione (§10, secondo capoverso)\r\n | 'InvalidToken'\r\n | 'InterviewNotFound'\r\n /** Fallback per un errore di trasporto non categorizzato. */\r\n | 'Unknown'\r\n | string;\r\n\r\n/** L'errore che ogni primitiva puo' rifiutare (§6, §10). */\r\nexport class FlowApiError extends Error {\r\n constructor(\r\n readonly category: FlowErrorCategory,\r\n message: string,\r\n /** Presente con `ValidationFailed`: l'elenco da aprire nel pannello (§8.3). */\r\n readonly validation?: FlowValidationResult,\r\n /** Con `VersionConflict`: chi ha modificato nel frattempo (§9). */\r\n readonly conflictingAuthor?: string,\r\n readonly details?: unknown,\r\n ) {\r\n super(message);\r\n this.name = 'FlowApiError';\r\n }\r\n\r\n static is(value: unknown): value is FlowApiError {\r\n return value instanceof FlowApiError;\r\n }\r\n}\r\n\r\n/** Mappatura HTTP suggerita (§10). Usata dall'implementazione HTTP dell'interfaccia. */\r\nexport const FLOW_ERROR_HTTP_STATUS: Record<string, number> = {\r\n InvalidRequest: 400,\r\n InvalidDefinition: 400,\r\n ValidationFailed: 422,\r\n FlowNotFound: 404,\r\n VersionNotFound: 404,\r\n InterviewNotFound: 404,\r\n AlreadyExists: 409,\r\n NotEditable: 409,\r\n VersionConflict: 409,\r\n InvalidToken: 400,\r\n MissingService: 501,\r\n};\r\n\r\n/** Messaggi di fallback: `message` del backend, quando c'e', ha la precedenza. */\r\nexport const FLOW_ERROR_FALLBACK_MESSAGE: Record<string, string> = {\r\n InvalidRequest: 'La richiesta non e’ valida.',\r\n InvalidDefinition: 'Il documento non e’ leggibile come definizione di flow.',\r\n ValidationFailed: 'La definizione contiene errori che impediscono l’attivazione.',\r\n FlowNotFound: 'Il flow non esiste piu’.',\r\n VersionNotFound: 'La versione richiesta non esiste.',\r\n AlreadyExists: 'Esiste già un flow con questo nome.',\r\n NotEditable: 'Questa versione non e’ modificabile: creane una nuova.',\r\n VersionConflict: 'Qualcun altro ha salvato questa versione nel frattempo.',\r\n MissingService: 'Funzione non configurata su questo ambiente.',\r\n InvalidToken: 'La sessione di prova non e’ piu’ valida: riavvia l’esecuzione.',\r\n InterviewNotFound: 'L’esecuzione sospesa non esiste piu’.',\r\n Unknown: 'Errore inatteso.',\r\n};\r\n","/**\r\n * L'unica porta verso il backend.\r\n *\r\n * **Tutto** il traffico di dati da e verso il backend passa da qui: nessun componente\r\n * e nessun servizio della libreria conosce HTTP, URL o formati di trasporto. Chi integra\r\n * il builder fornisce una implementazione di questa classe astratta e la registra come\r\n * provider — `FlowBuilderApi` e' anche il token di dependency injection.\r\n *\r\n * Contratto di errore: ogni metodo, in caso di rifiuto, deve fallire con un\r\n * {@link FlowApiError} categorizzato (§10). L'editor si comporta in base alla categoria,\r\n * mai leggendo il messaggio.\r\n *\r\n * Contratto di forma: i metodi restituiscono `Promise`. Le primitive marcate\r\n * \"prende il documento in lavorazione\" ricevono la definizione non ancora salvata,\r\n * perche' la risposta dipende da cio' che l'utente sta scrivendo (§6.4).\r\n *\r\n * I metodi con implementazione di default che lancia `MissingService` sono opzionali:\r\n * un ambiente che non li espone lascia l'editor funzionante, con il comando corrispondente\r\n * disabilitato (§10, categoria `MissingService`).\r\n */\r\n\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowDictionaries,\r\n FlowFieldUsage,\r\n FlowFieldValue,\r\n FlowObjectDescription,\r\n FlowObjectSummary,\r\n} from '../model/dictionary.model';\r\nimport {\r\n FlowCloneRequest,\r\n FlowConnectorTarget,\r\n FlowCreateRequest,\r\n FlowExportQuery,\r\n FlowInterviewResult,\r\n FlowListQuery,\r\n FlowNewVersionRequest,\r\n FlowOutline,\r\n FlowReference,\r\n FlowReferenceQuery,\r\n FlowResumeRequest,\r\n FlowSaveRequest,\r\n FlowSaveResult,\r\n FlowScreenResponseRequest,\r\n FlowStageStepRequest,\r\n FlowStartInterviewRequest,\r\n FlowSummary,\r\n FlowValidationResult,\r\n FlowVersionSummary,\r\n} from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\n\r\n/** Helper per i metodi opzionali non implementati. */\r\nfunction missing(primitive: string): Promise<never> {\r\n return Promise.reject(\r\n new FlowApiError('MissingService', `Primitiva non disponibile su questo ambiente: ${primitive}.`),\r\n );\r\n}\r\n\r\nexport abstract class FlowBuilderApi {\r\n // -------------------------------------------------------------------------\r\n // §6.1 Catalogo e lettura\r\n // -------------------------------------------------------------------------\r\n\r\n /** `GET /flows` — una riga per nome, non per versione. */\r\n abstract listFlows(query?: FlowListQuery): Promise<FlowSummary[]>;\r\n\r\n /** `GET /flows/{name}/versions` — dalla piu' recente. */\r\n abstract listVersions(flowName: string): Promise<FlowVersionSummary[]>;\r\n\r\n /**\r\n * `GET /flows/{name}?version=` — senza `version` restituisce la versione attiva,\r\n * altrimenti l'ultima.\r\n */\r\n abstract loadFlow(flowName: string, version?: number): Promise<FlowDefinition>;\r\n\r\n /** `GET /flows/{name}/export` — il documento come stringa indentata. */\r\n exportFlow(flowName: string, query?: FlowExportQuery): Promise<string> {\r\n void flowName;\r\n void query;\r\n return missing('exportFlow');\r\n }\r\n\r\n /**\r\n * `POST /flows/parse` — normalizza un documento senza salvarlo.\r\n * Serve all'import di un file: rifiuta con `InvalidDefinition` se non e' leggibile.\r\n */\r\n parseFlow(definition: unknown): Promise<FlowDefinition> {\r\n void definition;\r\n return missing('parseFlow');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.2 Scrittura e versionamento\r\n // -------------------------------------------------------------------------\r\n\r\n /** `POST /flows` — crea la versione 1. `AlreadyExists` se il nome e' già usato. */\r\n abstract createFlow(request: FlowCreateRequest): Promise<FlowSaveResult>;\r\n\r\n /**\r\n * `PUT /flows/{name}` — salva sulla bozza esistente o ne crea una nuova versione.\r\n * Riesce **anche con errori** di validazione: l'esito sano si legge in\r\n * `FlowSaveResult.validation`, non nell'assenza di eccezione (§6.2).\r\n */\r\n abstract saveFlow(flowName: string, request: FlowSaveRequest): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/versions?from=` — copia una versione in una nuova bozza. */\r\n abstract createVersion(flowName: string, request?: FlowNewVersionRequest): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/clone` — copia il flow sotto un altro nome, versione 1. */\r\n cloneFlow(flowName: string, request: FlowCloneRequest): Promise<FlowSaveResult> {\r\n void flowName;\r\n void request;\r\n return missing('cloneFlow');\r\n }\r\n\r\n /**\r\n * `POST /flows/{name}/versions/{v}/activate` — valida e attiva; la precedente\r\n * diventa `Obsolete`. Con errori fallisce con `ValidationFailed` e il payload\r\n * contiene l'elenco (§8.3).\r\n */\r\n abstract activateVersion(flowName: string, version: number): Promise<FlowSaveResult>;\r\n\r\n /** `POST /flows/{name}/deactivate` — il flow non e' piu' eseguibile. */\r\n abstract deactivateFlow(flowName: string): Promise<void>;\r\n\r\n /** `DELETE /flows/{name}/versions/{v}` — rifiutata sulla versione attiva. */\r\n deleteVersion(flowName: string, version: number): Promise<void> {\r\n void flowName;\r\n void version;\r\n return missing('deleteVersion');\r\n }\r\n\r\n /** `DELETE /flows/{name}` — rifiutata se esiste una versione attiva. */\r\n deleteFlow(flowName: string): Promise<void> {\r\n void flowName;\r\n return missing('deleteFlow');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.3 Validazione\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `POST /flows/validate` — non scrive nulla. È la primitiva del pannello dei\r\n * problemi, richiamabile a ogni pausa di digitazione (§11, debounce 300–500 ms).\r\n */\r\n abstract validateDefinition(definition: FlowDefinition): Promise<FlowValidationResult>;\r\n\r\n /** `GET /flows/{name}/versions/{v}/validate` — valida una versione già salvata. */\r\n validateVersion(flowName: string, version: number): Promise<FlowValidationResult> {\r\n void flowName;\r\n void version;\r\n return missing('validateVersion');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.4 Dizionari, cataloghi e strumenti per l'interfaccia\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `GET /flows/dictionaries?processType=` — le tendine in una risposta.\r\n *\r\n * Quasi statiche: si caricano una volta e si tengono in cache (§6.4, §13.11). L'eccezione e'\r\n * `globalVariables`, che dipende dal `processType`: `$Record` non esiste in uno screen flow,\r\n * e referenziarlo lì e' un errore, non un avviso (§4.1). Chi lavora su piu' tipi di flow\r\n * tiene una copia di dizionari per tipo.\r\n */\r\n abstract getDictionaries(processType?: string): Promise<FlowDictionaries>;\r\n\r\n /**\r\n * `POST /flows/references` — i valori proponibili in un campo che accetta una risorsa.\r\n * Include gli **output automatici** degli elementi, che non sono dichiarati in nessuna\r\n * collection: e' il motivo per cui non va ricostruita lato client (§4.5, §13.3).\r\n */\r\n abstract getReferences(query: FlowReferenceQuery): Promise<FlowReference[]>;\r\n\r\n /**\r\n * `POST /flows/references/writable` — le variabili **piu' le globali assegnabili**, per i\r\n * campi di destinazione: `$Flow.CurrentStage`, `$Flow.ActiveStages` e quelle che il sistema\r\n * ospite dichiara `isWritable`. La primitiva le comprende già, l'editor non le aggiunge\r\n * (§5.2). Restano fuori i campi di `$Record`, che dipendono dallo schema: quelli arrivano da\r\n * `listFields(object, 'updateable')` (§6.4).\r\n */\r\n abstract getWritableReferences(query: FlowReferenceQuery): Promise<FlowReference[]>;\r\n\r\n /** `POST /flows/connector-targets?excluding=` — i node a cui un arco puo' puntare. */\r\n abstract getConnectorTargets(definition: FlowDefinition, excluding?: string): Promise<FlowConnectorTarget[]>;\r\n\r\n /**\r\n * `POST /flows/outline` — node, archi e raggiungibilita' per il canvas.\r\n * `isReachable` e' la fonte autoritativa dei node scollegati (§6.4).\r\n */\r\n abstract getOutline(definition: FlowDefinition): Promise<FlowOutline>;\r\n\r\n /** `GET /catalog/objects` — le entita' su cui i flow possono operare. */\r\n abstract listObjects(): Promise<FlowObjectSummary[]>;\r\n\r\n /** `GET /schema/{object}` — label e campi. */\r\n describeObject(object: string): Promise<FlowObjectDescription> {\r\n void object;\r\n return missing('describeObject');\r\n }\r\n\r\n /** `GET /schema/{object}/fields?usage=` — proponi solo i campi validi per l'uso (§4.4). */\r\n abstract listFields(object: string, usage?: FlowFieldUsage): Promise<FlowObjectDescription['fields']>;\r\n\r\n /** `GET /schema/{object}/fields/{field}/values` — per non far digitare i valori. */\r\n listFieldValues(object: string, field: string): Promise<FlowFieldValue[]> {\r\n void object;\r\n void field;\r\n return missing('listFieldValues');\r\n }\r\n\r\n /** `GET /catalog/action-types` */\r\n abstract listActionTypes(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/actions?type=` */\r\n abstract listActions(actionType?: string): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/actions/{type}/{name}/parameters` */\r\n abstract listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/scripts` */\r\n abstract listScripts(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/scripts/{name}/parameters` */\r\n abstract listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/forms` — i form realizzati a mano nel frontend applicativo (§5.1). */\r\n abstract listForms(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/forms/{name}/parameters` */\r\n abstract listFormParameters(formName: string): Promise<FlowCatalogParameter[]>;\r\n\r\n /** `GET /catalog/enum-types` — per `objectType` delle risorse `Enum`. */\r\n abstract listEnumTypes(): Promise<FlowCatalogEntry[]>;\r\n\r\n /** `GET /catalog/events` — per gli eventi di un Wait. */\r\n abstract listEvents(): Promise<FlowCatalogEntry[]>;\r\n\r\n /**\r\n * `GET /flows/subflow-candidates?excluding=` — solo i flow con una versione attiva,\r\n * escluso quello corrente (§5.9).\r\n */\r\n abstract listSubflowCandidates(excluding?: string): Promise<FlowSummary[]>;\r\n\r\n // -------------------------------------------------------------------------\r\n // §6.5 Provare un flow dall'editor\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * `POST /interviews` — avvia. Ricorda: `status: 'Failed'` **non** e' un errore\r\n * di trasporto, e `debug: true` popola `trace` e `resources` con dati che\r\n * possono essere personali (§6.5).\r\n */\r\n startInterview(request: FlowStartInterviewRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('startInterview');\r\n }\r\n\r\n /** `POST /interviews/screen` — il `continuationToken` va rimandato tale e quale (§13.12). */\r\n respondToScreen(request: FlowScreenResponseRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('respondToScreen');\r\n }\r\n\r\n /** `POST /interviews/resume` — riprende un'esecuzione in pausa. */\r\n resumeInterview(request: FlowResumeRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('resumeInterview');\r\n }\r\n\r\n /**\r\n * `POST /interviews/{key}/stage-step` — un assegnatario conclude uno step (§5.13).\r\n * Se lo stage si sospende di nuovo, la risposta porta una `interviewKey` **nuova**: la\r\n * vecchia non e' piu' valida e va sostituita, non conservata.\r\n */\r\n completeStageStep(request: FlowStageStepRequest): Promise<FlowInterviewResult> {\r\n void request;\r\n return missing('completeStageStep');\r\n }\r\n\r\n /**\r\n * `GET /interviews/{key}` — ispeziona una sospesa senza consumarla.\r\n * Con `isWaitingForStageStep` porta `stageSteps` con lo stato di ognuno (§5.13).\r\n */\r\n inspectInterview(interviewKey: string): Promise<FlowInterviewResult> {\r\n void interviewKey;\r\n return missing('inspectInterview');\r\n }\r\n\r\n /** `DELETE /interviews/{key}` — abbandona. */\r\n abandonInterview(interviewKey: string): Promise<void> {\r\n void interviewKey;\r\n return missing('abandonInterview');\r\n }\r\n}\r\n","/**\r\n * Implementazione HTTP dell'interfaccia {@link FlowBuilderApi}, sulle rotte proposte\r\n * dalla §6 di FRONTEND.md.\r\n *\r\n * I percorsi HTTP della specifica sono **una proposta**: le rotte definitive le decide\r\n * chi scrive i controller. Se le vostre differiscono, ci sono due strade e nessuna\r\n * tocca l'editor:\r\n * 1. estendere questa classe e sovrascrivere i soli metodi con rotta diversa;\r\n * 2. scrivere un'altra implementazione di `FlowBuilderApi` da zero.\r\n *\r\n * Qui vive l'unica conoscenza di HTTP della libreria, incluso il compito di tradurre\r\n * status e payload in {@link FlowApiError} categorizzati (§10).\r\n */\r\n\r\nimport { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';\r\nimport { InjectionToken, inject } from '@angular/core';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { FlowBuilderApi } from './flow-builder-api';\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowDictionaries,\r\n FlowFieldUsage,\r\n FlowFieldValue,\r\n FlowObjectDescription,\r\n FlowObjectSummary,\r\n} from '../model/dictionary.model';\r\nimport {\r\n FlowCloneRequest,\r\n FlowConnectorTarget,\r\n FlowCreateRequest,\r\n FlowExportQuery,\r\n FlowInterviewResult,\r\n FlowListQuery,\r\n FlowNewVersionRequest,\r\n FlowOutline,\r\n FlowReference,\r\n FlowReferenceQuery,\r\n FlowResumeRequest,\r\n FlowSaveRequest,\r\n FlowSaveResult,\r\n FlowScreenResponseRequest,\r\n FlowStageStepRequest,\r\n FlowStartInterviewRequest,\r\n FlowSummary,\r\n FlowValidationResult,\r\n FlowVersionSummary,\r\n} from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FLOW_ERROR_FALLBACK_MESSAGE, FlowApiError, FlowErrorCategory } from '../model/error.model';\r\n\r\nexport interface FlowBuilderHttpConfig {\r\n /** Prefisso comune, es. `/api` o `https://host/api`. Senza slash finale. */\r\n baseUrl?: string;\r\n}\r\n\r\nexport const FLOW_BUILDER_HTTP_CONFIG = new InjectionToken<FlowBuilderHttpConfig>('FLOW_BUILDER_HTTP_CONFIG', {\r\n factory: () => ({ baseUrl: '/api' }),\r\n});\r\n\r\n/** Forma attesa del corpo di errore del backend. */\r\ninterface FlowErrorBody {\r\n category?: string;\r\n message?: string;\r\n validation?: FlowValidationResult;\r\n conflictingAuthor?: string;\r\n updatedBy?: string;\r\n}\r\n\r\n/** Ricava la categoria dallo status quando il corpo non la dichiara (§10). */\r\nfunction categoryFromStatus(status: number): FlowErrorCategory {\r\n switch (status) {\r\n case 400:\r\n return 'InvalidRequest';\r\n case 404:\r\n return 'FlowNotFound';\r\n case 409:\r\n return 'VersionConflict';\r\n case 422:\r\n return 'ValidationFailed';\r\n case 501:\r\n return 'MissingService';\r\n default:\r\n return 'Unknown';\r\n }\r\n}\r\n\r\nexport class HttpFlowBuilderApi extends FlowBuilderApi {\r\n private readonly http = inject(HttpClient);\r\n private readonly config = inject(FLOW_BUILDER_HTTP_CONFIG);\r\n\r\n protected url(path: string): string {\r\n return `${this.config.baseUrl ?? ''}${path}`;\r\n }\r\n\r\n /** Punto unico in cui un errore di trasporto diventa un errore di dominio. */\r\n protected async request<T>(call: Promise<T>): Promise<T> {\r\n try {\r\n return await call;\r\n } catch (error) {\r\n throw this.toApiError(error);\r\n }\r\n }\r\n\r\n protected toApiError(error: unknown): FlowApiError {\r\n if (FlowApiError.is(error)) {\r\n return error;\r\n }\r\n if (error instanceof HttpErrorResponse) {\r\n const body: FlowErrorBody = (error.error ?? {}) as FlowErrorBody;\r\n const category: FlowErrorCategory = body.category ?? categoryFromStatus(error.status);\r\n const message = body.message ?? FLOW_ERROR_FALLBACK_MESSAGE[category] ?? error.message;\r\n return new FlowApiError(\r\n category,\r\n message,\r\n body.validation,\r\n body.conflictingAuthor ?? body.updatedBy,\r\n error.error,\r\n );\r\n }\r\n const message = error instanceof Error ? error.message : String(error);\r\n return new FlowApiError('Unknown', message, undefined, undefined, error);\r\n }\r\n\r\n private get<T>(path: string, params?: HttpParams): Promise<T> {\r\n return this.request(firstValueFrom(this.http.get<T>(this.url(path), { params })));\r\n }\r\n\r\n private post<T>(path: string, body?: unknown, params?: HttpParams): Promise<T> {\r\n return this.request(firstValueFrom(this.http.post<T>(this.url(path), body ?? {}, { params })));\r\n }\r\n\r\n private put<T>(path: string, body?: unknown): Promise<T> {\r\n return this.request(firstValueFrom(this.http.put<T>(this.url(path), body ?? {})));\r\n }\r\n\r\n private del<T>(path: string): Promise<T> {\r\n return this.request(firstValueFrom(this.http.delete<T>(this.url(path))));\r\n }\r\n\r\n private static params(values: Record<string, string | number | boolean | undefined>): HttpParams {\r\n let params = new HttpParams();\r\n for (const [key, value] of Object.entries(values)) {\r\n if (value !== undefined && value !== null && value !== '') {\r\n params = params.set(key, String(value));\r\n }\r\n }\r\n return params;\r\n }\r\n\r\n private static segment(value: string): string {\r\n return encodeURIComponent(value);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.1\r\n\r\n listFlows(query?: FlowListQuery): Promise<FlowSummary[]> {\r\n return this.get<FlowSummary[]>('/flows/editor/list', HttpFlowBuilderApi.params({ ...query }));\r\n }\r\n\r\n listVersions(flowName: string): Promise<FlowVersionSummary[]> {\r\n return this.get<FlowVersionSummary[]>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/versions`);\r\n }\r\n\r\n loadFlow(flowName: string, version?: number): Promise<FlowDefinition> {\r\n return this.get<FlowDefinition>(\r\n `/flows/editor/${HttpFlowBuilderApi.segment(flowName)}`,\r\n HttpFlowBuilderApi.params({ version }),\r\n );\r\n }\r\n\r\n override exportFlow(flowName: string, query?: FlowExportQuery): Promise<string> {\r\n return this.request(\r\n firstValueFrom(\r\n this.http.get(this.url(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/export`), {\r\n params: HttpFlowBuilderApi.params({ ...query }),\r\n responseType: 'text',\r\n }),\r\n ),\r\n );\r\n }\r\n\r\n override parseFlow(definition: unknown): Promise<FlowDefinition> {\r\n return this.post<FlowDefinition>('/flows/editor/parse', definition);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.2\r\n\r\n createFlow(request: FlowCreateRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>('/flows/editor/create', request);\r\n }\r\n\r\n saveFlow(flowName: string, request: FlowSaveRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>(`/flows/editor/save`, request);\r\n }\r\n\r\n createVersion(flowName: string, request?: FlowNewVersionRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/new-version`, { author: request?.author }, HttpFlowBuilderApi.params({ from: request?.from }));\r\n }\r\n\r\n override cloneFlow(flowName: string, request: FlowCloneRequest): Promise<FlowSaveResult> {\r\n return this.post<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/clone`, request);\r\n }\r\n\r\n activateVersion(flowName: string, version: number): Promise<FlowSaveResult> {\r\n return this.put<FlowSaveResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/activate/${version}`);\r\n }\r\n\r\n deactivateFlow(flowName: string): Promise<void> {\r\n return this.put<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/deactivate`);\r\n }\r\n\r\n override deleteVersion(flowName: string, version: number): Promise<void> {\r\n return this.del<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/versions/${version}`);\r\n }\r\n\r\n override deleteFlow(flowName: string): Promise<void> {\r\n return this.del<void>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}`);\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.3\r\n\r\n validateDefinition(definition: FlowDefinition): Promise<FlowValidationResult> {\r\n return this.post<FlowValidationResult>(`/flows/editor/validate`, definition);\r\n }\r\n\r\n override validateVersion(flowName: string, version: number): Promise<FlowValidationResult> {\r\n return this.get<FlowValidationResult>(`/flows/editor/${HttpFlowBuilderApi.segment(flowName)}/validate`, HttpFlowBuilderApi.params({ version: version }));\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.4\r\n\r\n getDictionaries(processType?: string): Promise<FlowDictionaries> {\r\n // `processType` filtra le globali: `$Record` non esiste in uno screen flow (§4.1).\r\n return this.get<FlowDictionaries>('/flows/editor/dictionaries', HttpFlowBuilderApi.params({ processType }));\r\n }\r\n\r\n getReferences(query: FlowReferenceQuery): Promise<FlowReference[]> {\r\n return this.post<FlowReference[]>('/flows/editor/references', query);\r\n }\r\n\r\n getWritableReferences(query: FlowReferenceQuery): Promise<FlowReference[]> {\r\n return this.post<FlowReference[]>('/flows/editor/writable-references', query);\r\n }\r\n\r\n getConnectorTargets(definition: FlowDefinition, excluding?: string): Promise<FlowConnectorTarget[]> {\r\n return this.post<FlowConnectorTarget[]>('/flows/editor/connector-targets', definition, HttpFlowBuilderApi.params({ excluding }));\r\n }\r\n\r\n getOutline(definition: FlowDefinition): Promise<FlowOutline> {\r\n return this.post<FlowOutline>('/flows/editor/outline', definition);\r\n }\r\n\r\n listObjects(): Promise<FlowObjectSummary[]> {\r\n return this.get<FlowObjectSummary[]>('/flows/objects');\r\n }\r\n\r\n override describeObject(object: string): Promise<FlowObjectDescription> {\r\n return this.get<FlowObjectDescription>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}`);\r\n }\r\n\r\n listFields(object: string, usage?: FlowFieldUsage): Promise<FlowObjectDescription['fields']> {\r\n return this.get<FlowObjectDescription['fields']>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}/fields`, HttpFlowBuilderApi.params({ usage }));\r\n }\r\n\r\n override listFieldValues(object: string, field: string): Promise<FlowFieldValue[]> {\r\n return this.get<FlowFieldValue[]>(`/flows/objects/${HttpFlowBuilderApi.segment(object)}/fields/${HttpFlowBuilderApi.segment(field)}/picklist`);\r\n }\r\n\r\n listActionTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/action-types');\r\n }\r\n\r\n listActions(actionType?: string): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/actions', HttpFlowBuilderApi.params({ type: actionType }));\r\n }\r\n\r\n listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/actions/${HttpFlowBuilderApi.segment(actionType)}/${HttpFlowBuilderApi.segment(actionName)}/parameters`);\r\n }\r\n\r\n listScripts(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/scripts');\r\n }\r\n\r\n listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/editor/scripts/${HttpFlowBuilderApi.segment(scriptName)}/parameters`);\r\n }\r\n\r\n listForms(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/forms');\r\n }\r\n\r\n listFormParameters(formName: string): Promise<FlowCatalogParameter[]> {\r\n return this.get<FlowCatalogParameter[]>(`/flows/editor/forms/${HttpFlowBuilderApi.segment(formName)}/parameters`);\r\n }\r\n\r\n listEnumTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/enum-types');\r\n }\r\n\r\n listEvents(): Promise<FlowCatalogEntry[]> {\r\n return this.get<FlowCatalogEntry[]>('/flows/editor/events');\r\n }\r\n\r\n listSubflowCandidates(excluding?: string): Promise<FlowSummary[]> {\r\n return this.get<FlowSummary[]>('/flows/editor/subflows', HttpFlowBuilderApi.params({ excluding }));\r\n }\r\n\r\n // ---------------------------------------------------------------- §6.5\r\n\r\n override startInterview(request: FlowStartInterviewRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/start', request);\r\n }\r\n\r\n override respondToScreen(request: FlowScreenResponseRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/submit-screen', request);\r\n }\r\n\r\n override resumeInterview(request: FlowResumeRequest): Promise<FlowInterviewResult> {\r\n return this.post<FlowInterviewResult>('/flows/resume-wait', request);\r\n }\r\n\r\n override completeStageStep(request: FlowStageStepRequest): Promise<FlowInterviewResult> {\r\n // La chiave sta nell'URL, il resto nel corpo: la risposta puo' portarne una nuova (§5.13).\r\n let body = { stepName: request.stepName, status: request.status, stepOutputs: request.stepOutputs, debug: request.debug };\r\n return this.post<FlowInterviewResult>(`/flows/${HttpFlowBuilderApi.segment(request.interviewKey)}/resume-stage-step`, body);\r\n }\r\n\r\n override inspectInterview(interviewKey: string): Promise<FlowInterviewResult> {\r\n return this.get<FlowInterviewResult>(`/flows/${HttpFlowBuilderApi.segment(interviewKey)}`);\r\n }\r\n\r\n override abandonInterview(interviewKey: string): Promise<void> {\r\n return this.del<void>(`/flows/${HttpFlowBuilderApi.segment(interviewKey)}`);\r\n }\r\n}\r\n","/**\r\n * Le uscite di ogni tipo di elemento — FRONTEND.md §3.5.\r\n *\r\n * Un connector e' sempre `{ targetReference, isGoTo }`. Quello che cambia e' **in quale\r\n * campo** vive, e il campo dipende dal tipo di elemento. Questo file e' l'unica sede di\r\n * quella mappa: canvas, inspector e outline locale la leggono da qui, invece di ripetere\r\n * `node['faultConnector']` in venti punti.\r\n *\r\n * Ogni uscita e' descritta da una chiave stabile piu' due accessori. La chiave finisce\r\n * nell'id del connettore sul canvas (`out:<node>:<key>`), quindi deve restare uguale fra\r\n * un render e l'altro: per i rami indicizzati (regole, eventi, scheduled path) usa\r\n * l'**indice** dentro la chiave.\r\n *\r\n * Nota: `Transform.connector` e' un array e `start` e' un array di uno, entrambi per\r\n * fedelta' storica; gli accessori qui sotto lo nascondono al resto della libreria.\r\n */\r\n\r\nimport {\r\n FlowAnyNode,\r\n FlowConnector,\r\n FlowDecision,\r\n FlowElementType,\r\n FlowNodeCollection,\r\n FlowStart,\r\n FlowTransform,\r\n FlowWait,\r\n} from '../model/flow.model';\r\nimport { FlowConnectionKind } from '../model/api.model';\r\n\r\n/** Nome fittizio dello Start sul canvas: nel documento non ha `name` (§6.4, `from: null`). */\r\nexport const START_NODE_NAME = '$start';\r\n\r\nexport interface FlowOutlet {\r\n /** Stabile fra i render: entra nell'id del connettore del canvas. */\r\n key: string;\r\n /** Determina lo stile dell'arco: `Fault` rosso, `Rule` etichettato, … (§6.4). */\r\n kind: FlowConnectionKind;\r\n /** Etichetta mostrata sul connettore e nel form. */\r\n label: string;\r\n /** Etichetta di ramo definita dall'autore (label della regola, dell'evento). */\r\n branchLabel?: string | null;\r\n /**\r\n * `true` → l'assenza del connector e' un problema strutturale, non la fine legittima\r\n * di un percorso: il corpo di un Loop (§3.5).\r\n */\r\n isStructural?: boolean;\r\n read(node: FlowAnyNode): FlowConnector | undefined;\r\n write(node: FlowAnyNode, connector: FlowConnector | undefined): void;\r\n}\r\n\r\n/** Accessore per un connector che vive in un campo diretto del node. */\r\nfunction field(\r\n key: string,\r\n kind: FlowConnectionKind,\r\n label: string,\r\n property: string,\r\n extra?: Partial<FlowOutlet>,\r\n): FlowOutlet {\r\n return {\r\n key,\r\n kind,\r\n label,\r\n read: (node) => node[property] as FlowConnector | undefined,\r\n write: (node, connector) => {\r\n if (connector) {\r\n node[property] = connector;\r\n } else {\r\n delete node[property];\r\n }\r\n },\r\n ...extra,\r\n };\r\n}\r\n\r\n/** Accessore per un connector dentro un elemento di array (`rules[i].connector`). */\r\nfunction nested(\r\n key: string,\r\n kind: FlowConnectionKind,\r\n label: string,\r\n arrayProperty: string,\r\n index: number,\r\n branchLabel?: string | null,\r\n): FlowOutlet {\r\n return {\r\n key,\r\n kind,\r\n label,\r\n branchLabel,\r\n read: (node) => {\r\n const list = node[arrayProperty] as Array<{ connector?: FlowConnector }> | undefined;\r\n return list?.[index]?.connector;\r\n },\r\n write: (node, connector) => {\r\n const list = node[arrayProperty] as Array<{ connector?: FlowConnector }> | undefined;\r\n const item = list?.[index];\r\n if (!item) {\r\n return;\r\n }\r\n if (connector) {\r\n item.connector = connector;\r\n } else {\r\n delete item.connector;\r\n }\r\n },\r\n };\r\n}\r\n\r\n/** `Transform.connector` e' un array: usa il primo (§3.5). */\r\nfunction transformOutlet(): FlowOutlet {\r\n return {\r\n key: 'next',\r\n kind: 'Next',\r\n label: 'Successivo',\r\n read: (node) => (node as FlowTransform).connector?.[0],\r\n write: (node, connector) => {\r\n const transform = node as FlowTransform;\r\n if (connector) {\r\n transform.connector = [connector];\r\n } else {\r\n delete transform.connector;\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Le uscite di un node, nell'ordine in cui vanno mostrate.\r\n * `type` e' il discriminatore di `elementTypes`; per lo Start passa `'Start'`.\r\n */\r\nexport function outletsOf(type: FlowElementType, node: FlowAnyNode): FlowOutlet[] {\r\n switch (type) {\r\n case 'Start': {\r\n const start = node as FlowStart;\r\n const outlets: FlowOutlet[] = [\r\n field('next', 'Start', 'Inizio', 'connector', {\r\n // Senza, `START_NO_ENTRY_POINT`: e' strutturale (§3.4).\r\n isStructural: true,\r\n }),\r\n ];\r\n (start.scheduledPaths ?? []).forEach((path, index) => {\r\n outlets.push(\r\n nested(\r\n `scheduledPath:${index}`,\r\n 'ScheduledPath',\r\n path.label || path.name || `Percorso differito ${index + 1}`,\r\n 'scheduledPaths',\r\n index,\r\n path.label ?? path.name ?? null,\r\n ),\r\n );\r\n });\r\n return outlets;\r\n }\r\n\r\n case 'Decision': {\r\n const decision = node as FlowDecision;\r\n const outlets: FlowOutlet[] = (decision.rules ?? []).map((rule, index) =>\r\n nested(\r\n `rule:${index}`,\r\n 'Rule',\r\n rule.label || rule.name || `Regola ${index + 1}`,\r\n 'rules',\r\n index,\r\n rule.label ?? rule.name ?? null,\r\n ),\r\n );\r\n outlets.push(\r\n field('default', 'Default', decision.defaultConnectorLabel || 'Nessuna regola vera', 'defaultConnector', {\r\n branchLabel: decision.defaultConnectorLabel ?? null,\r\n }),\r\n );\r\n return outlets;\r\n }\r\n\r\n case 'Loop':\r\n return [\r\n // Senza corpo il ciclo non ha senso: la validazione lo segnala come errore (§3.5).\r\n field('loopNext', 'LoopNext', 'Per ogni valore', 'nextValueConnector', { isStructural: true }),\r\n field('loopEnd', 'LoopEnd', 'Nessun valore rimasto', 'noMoreValuesConnector'),\r\n ];\r\n\r\n case 'Wait': {\r\n const wait = node as FlowWait;\r\n const outlets: FlowOutlet[] = (wait.waitEvents ?? []).map((event, index) =>\r\n nested(\r\n `waitEvent:${index}`,\r\n 'WaitEvent',\r\n event.label || event.name || `Evento ${index + 1}`,\r\n 'waitEvents',\r\n index,\r\n event.label ?? event.name ?? null,\r\n ),\r\n );\r\n outlets.push(\r\n field('default', 'Default', wait.defaultConnectorLabel || 'Nessun evento verificato', 'defaultConnector', {\r\n branchLabel: wait.defaultConnectorLabel ?? null,\r\n }),\r\n );\r\n outlets.push(field('fault', 'Fault', 'Errore', 'faultConnector'));\r\n return outlets;\r\n }\r\n\r\n case 'ActionCall': {\r\n const outlets: FlowOutlet[] = [\r\n field('next', 'Next', 'Successivo', 'connector'),\r\n field('fault', 'Fault', 'Errore', 'faultConnector'),\r\n ];\r\n // Il ramo di timeout esiste solo con `timeoutPathUsage: 'EnableTimeoutPath'` (§5.8).\r\n if (node['timeoutPathUsage'] === 'EnableTimeoutPath' || node['timeoutConnector']) {\r\n outlets.push(field('timeout', 'Timeout', 'Timeout', 'timeoutConnector'));\r\n }\r\n return outlets;\r\n }\r\n\r\n // Lo `faultConnector` di uno stage **non** e' un ramo di guasto: e' il ramo dello step\r\n // rifiutato, e senza di esso un rifiuto fa fallire l'interview (§5.13). L'etichetta lo\r\n // dice, altrimenti chi disegna un'approvazione lo lascia vuoto credendo di rinunciare\r\n // solo alla gestione degli errori.\r\n case 'OrchestratedStage':\r\n return [\r\n field('next', 'Next', 'Stage concluso', 'connector'),\r\n field('fault', 'Fault', 'Step rifiutato', 'faultConnector'),\r\n ];\r\n\r\n case 'ScriptCall':\r\n case 'RecordLookup':\r\n case 'RecordCreate':\r\n case 'RecordUpdate':\r\n case 'RecordDelete':\r\n return [\r\n field('next', 'Next', 'Successivo', 'connector'),\r\n field('fault', 'Fault', 'Errore', 'faultConnector'),\r\n ];\r\n\r\n case 'Transform':\r\n return [transformOutlet()];\r\n\r\n // Il Custom Error interrompe l'esecuzione: non ha uscite (§5.11).\r\n case 'CustomError':\r\n return [];\r\n\r\n case 'Screen':\r\n case 'Assignment':\r\n case 'CollectionProcessor':\r\n case 'RecordRollback':\r\n case 'Subflow':\r\n return [field('next', 'Next', 'Successivo', 'connector')];\r\n\r\n default:\r\n // Tipo sconosciuto o non supportato: se ha un `connector`, mostralo comunque,\r\n // altrimenti nessuna uscita. Non inventare rami.\r\n return node['connector'] ? [field('next', 'Next', 'Successivo', 'connector')] : [];\r\n }\r\n}\r\n\r\n/** Trova un'uscita per chiave. */\r\nexport function outletByKey(type: FlowElementType, node: FlowAnyNode, key: string): FlowOutlet | undefined {\r\n return outletsOf(type, node).find((outlet) => outlet.key === key);\r\n}\r\n\r\n/**\r\n * Mappa di fallback tipo → collection, usata quando il dizionario `elementTypes` non e'\r\n * disponibile. La fonte autoritativa resta `metadataProperty` del dizionario (§3.2).\r\n */\r\nexport const FALLBACK_COLLECTION_BY_TYPE: Record<string, FlowNodeCollection> = {\r\n Screen: 'screens',\r\n Assignment: 'assignments',\r\n Decision: 'decisions',\r\n Loop: 'loops',\r\n CollectionProcessor: 'collectionProcessors',\r\n CustomError: 'customErrors',\r\n Wait: 'waits',\r\n RecordLookup: 'recordLookups',\r\n RecordCreate: 'recordCreates',\r\n RecordUpdate: 'recordUpdates',\r\n RecordDelete: 'recordDeletes',\r\n RecordRollback: 'recordRollbacks',\r\n ActionCall: 'actionCalls',\r\n ScriptCall: 'scriptPluginCalls',\r\n Subflow: 'subflows',\r\n Transform: 'transforms',\r\n Step: 'steps',\r\n Experiment: 'experiments',\r\n OrchestratedStage: 'orchestratedStages',\r\n};\r\n\r\n/** Inverso della mappa: serve al flatten in lettura (§3.1). */\r\nexport const TYPE_BY_COLLECTION: Record<string, FlowElementType> = Object.fromEntries(\r\n Object.entries(FALLBACK_COLLECTION_BY_TYPE).map(([type, collection]) => [collection, type]),\r\n);\r\n\r\n/** Etichette di fallback, se il dizionario non e' caricato. */\r\nexport const FALLBACK_TYPE_LABEL: Record<string, string> = {\r\n Screen: 'Screen',\r\n Assignment: 'Assegnazione',\r\n Decision: 'Decisione',\r\n Loop: 'Ciclo',\r\n CollectionProcessor: 'Ordina o filtra',\r\n CustomError: 'Errore custom',\r\n Wait: 'Attesa',\r\n RecordLookup: 'Get Records',\r\n RecordCreate: 'Create Records',\r\n RecordUpdate: 'Update Records',\r\n RecordDelete: 'Delete Records',\r\n RecordRollback: 'Roll Back Records',\r\n ActionCall: 'Action',\r\n ScriptCall: 'Script',\r\n Subflow: 'Subflow',\r\n Transform: 'Trasformazione',\r\n Step: 'Segnaposto',\r\n Experiment: 'Esperimento',\r\n OrchestratedStage: 'Stage di orchestrazione',\r\n};\r\n\r\n/** I due tipi che il motore rifiuta: nascosti dalla palette (§3.2, §13.9). */\r\nexport const UNSUPPORTED_TYPES: ReadonlySet<string> = new Set(['Step', 'Experiment']);\r\n\r\n/** Elementi che espongono il proprio risultato sotto il nome dell'elemento (§4.5). */\r\nexport const TYPES_WITH_AUTOMATIC_OUTPUT: ReadonlySet<string> = new Set([\r\n 'RecordLookup',\r\n 'RecordCreate',\r\n 'CollectionProcessor',\r\n 'Transform',\r\n 'ActionCall',\r\n 'Subflow',\r\n]);\r\n","/**\r\n * Il glifo di ogni tipo di elemento.\r\n *\r\n * Sono caratteri Unicode, non icone: la libreria non porta asset e non dipende da un font di\r\n * icone dell'applicazione ospite. Sta in `core` e non nel canvas perche' lo stesso glifo deve\r\n * comparire sulla palette e sul node: se divergessero, l'elemento trascinato non\r\n * assomiglierebbe a quello che compare sul canvas.\r\n */\r\n\r\nexport const FLOW_ELEMENT_ICONS: Record<string, string> = {\r\n Start: '▶',\r\n Screen: '▤',\r\n Decision: '◆',\r\n Assignment: '=',\r\n Loop: '↻',\r\n CollectionProcessor: '⇅',\r\n RecordLookup: '⌕',\r\n RecordCreate: '+',\r\n RecordUpdate: '✎',\r\n RecordDelete: '×',\r\n RecordRollback: '↺',\r\n ActionCall: '⚡',\r\n ScriptCall: '⟨⟩',\r\n Subflow: '⤵',\r\n Transform: '⇄',\r\n Wait: '◷',\r\n CustomError: '!',\r\n OrchestratedStage: '☰',\r\n};\r\n\r\n/**\r\n * Il glifo delle varianti (§5.5): due voci di palette dello stesso tipo con lo stesso simbolo\r\n * si distinguerebbero solo dall'etichetta, e sulla palette il simbolo e' la prima cosa che si\r\n * guarda. La chiave e' `tipo:variante`.\r\n */\r\nexport const FLOW_ELEMENT_VARIANT_ICONS: Record<string, string> = {\r\n 'CollectionProcessor:Sort': '⇅',\r\n 'CollectionProcessor:Filter': '▽',\r\n};\r\n\r\n/**\r\n * Il glifo del tipo, o della sua variante quando c'e'. Per un tipo che il dizionario del\r\n * backend aggiunge e questa mappa non conosce, l'iniziale dell'etichetta e' un segnaposto\r\n * migliore di un simbolo generico.\r\n */\r\nexport function elementIcon(type: string, label?: string, variant?: string): string {\r\n const icon = (variant ? FLOW_ELEMENT_VARIANT_ICONS[`${type}:${variant}`] : undefined) ??\r\n FLOW_ELEMENT_ICONS[type];\r\n if (icon) {\r\n return icon;\r\n }\r\n const fallback = (label || type).trim().charAt(0).toUpperCase();\r\n return fallback || '•';\r\n}\r\n","/**\r\n * I tipi che sulla palette valgono per **piu' di una voce** — FRONTEND.md §5.5.\r\n *\r\n * Il Collection Processor e' un solo tipo di node con un discriminatore\r\n * (`collectionProcessorType`: `Sort` o `Filter`), e i campi rilevanti cambiano con esso: un\r\n * `Sort` vuole `sortOptions`, un `Filter` vuole condizioni. Sono due gesti diversi, e una\r\n * voce sola («ordina o filtra») costringe a scegliere dopo, dentro il form.\r\n *\r\n * Qui sta **solo** la mappa tipo → campo del discriminatore: i valori ammessi restano nel\r\n * dizionario del backend (`collectionProcessorTypes`), come per ogni altro enum (§6.4). Senza\r\n * quel dizionario il tipo torna a essere una voce sola, che e' il comportamento giusto quando\r\n * non si sa quali varianti esistano.\r\n *\r\n * Se un tipo nuovo arrivasse con lo stesso schema — un node con un discriminatore che ne\r\n * cambia i campi — si aggiunge una riga qui e la palette si divide da se'.\r\n */\r\n\r\n/** Tipo di elemento → campo del node che porta la variante. */\r\nexport const FLOW_ELEMENT_VARIANT_FIELDS: Record<string, string> = {\r\n CollectionProcessor: 'collectionProcessorType',\r\n};\r\n\r\n/** Il campo del discriminatore, se il tipo ne ha uno. */\r\nexport function variantFieldOf(type: string): string | undefined {\r\n return FLOW_ELEMENT_VARIANT_FIELDS[type];\r\n}\r\n\r\n/** La variante di un node già scritto, letta dal suo discriminatore. */\r\nexport function variantOf(type: string, node: Record<string, unknown>): string | undefined {\r\n const field = variantFieldOf(type);\r\n const value = field ? node[field] : undefined;\r\n return typeof value === 'string' && value ? value : undefined;\r\n}\r\n\r\n/**\r\n * I campi da scrivere su un node appena creato dalla variante scelta. Vuoto per i tipi senza\r\n * varianti: chi crea l'elemento non deve sapere quali sono.\r\n */\r\nexport function variantPresetOf(type: string, variant: string | undefined): Record<string, unknown> {\r\n const field = variantFieldOf(type);\r\n if (!field || !variant) {\r\n return {};\r\n }\r\n return { [field]: variant };\r\n}\r\n","/**\r\n * Nomi — FRONTEND.md §3.3, §13.5.\r\n *\r\n * Tre regole, tutte e tre implementate qui:\r\n * 1. `^[A-Za-z][A-Za-z0-9_]*$` — niente punti (i riferimenti si spezzano sul punto),\r\n * niente spazi, niente `$`;\r\n * 2. node e risorse condividono **un unico** spazio di nomi;\r\n * 3. il confronto e' **case-insensitive**.\r\n */\r\n\r\nexport const FLOW_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*$/;\r\n\r\nexport type FlowNameProblem = 'empty' | 'pattern' | 'duplicate';\r\n\r\nexport interface FlowNameCheck {\r\n isValid: boolean;\r\n problem?: FlowNameProblem;\r\n message?: string;\r\n}\r\n\r\n/** Verifica solo la forma. */\r\nexport function isValidFlowName(name: string | undefined | null): boolean {\r\n return !!name && FLOW_NAME_PATTERN.test(name);\r\n}\r\n\r\n/**\r\n * Verifica forma **e** unicita' contro l'insieme dei nomi già usati.\r\n * `currentName` esclude se stesso dal controllo, per non segnalare un elemento in modifica.\r\n */\r\nexport function checkFlowName(\r\n name: string | undefined | null,\r\n usedNames: Iterable<string>,\r\n currentName?: string | null,\r\n): FlowNameCheck {\r\n const trimmed = (name ?? '').trim();\r\n if (!trimmed) {\r\n return { isValid: false, problem: 'empty', message: 'Il nome tecnico e’ obbligatorio.' };\r\n }\r\n if (!FLOW_NAME_PATTERN.test(trimmed)) {\r\n return {\r\n isValid: false,\r\n problem: 'pattern',\r\n message: 'Deve iniziare con una lettera e contenere solo lettere, cifre e underscore.',\r\n };\r\n }\r\n const lower = trimmed.toLowerCase();\r\n const currentLower = currentName?.trim().toLowerCase();\r\n for (const used of usedNames) {\r\n const usedLower = used.toLowerCase();\r\n if (usedLower === lower && usedLower !== currentLower) {\r\n // Il confronto e' case-insensitive: `Importo` e `importo` sono lo stesso nome.\r\n return {\r\n isValid: false,\r\n problem: 'duplicate',\r\n message: 'Questo nome e’ già usato da un altro elemento o da una risorsa.',\r\n };\r\n }\r\n }\r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Genera il nome tecnico da una label: `\"Approva ordine\"` → `Approva_Ordine` (§3.3).\r\n * Va lasciato modificabile finche' l'elemento e' nuovo.\r\n */\r\nexport function slugifyFlowName(label: string | undefined | null): string {\r\n const source = (label ?? '').trim();\r\n if (!source) {\r\n return '';\r\n }\r\n const words = source\r\n // Toglie i diacritici: `Città` → `Citta`.\r\n .normalize('NFD')\r\n .replace(/\\p{Diacritic}/gu, '')\r\n .split(/[^A-Za-z0-9]+/)\r\n .filter(Boolean)\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1));\r\n let name = words.join('_');\r\n if (!name) {\r\n return '';\r\n }\r\n // Deve iniziare con una lettera.\r\n if (!/^[A-Za-z]/.test(name)) {\r\n name = `X_${name}`;\r\n }\r\n return name;\r\n}\r\n\r\n/**\r\n * Genera un nome libero a partire da una base, aggiungendo un suffisso numerico.\r\n * `Decisione`, `Decisione_1`, `Decisione_2`, …\r\n */\r\nexport function uniqueFlowName(base: string, usedNames: Iterable<string>): string {\r\n const used = new Set(Array.from(usedNames, (name) => name.toLowerCase()));\r\n const root = slugifyFlowName(base) || 'Elemento';\r\n if (!used.has(root.toLowerCase())) {\r\n return root;\r\n }\r\n let index = 1;\r\n while (used.has(`${root}_${index}`.toLowerCase())) {\r\n index += 1;\r\n }\r\n return `${root}_${index}`;\r\n}\r\n\r\n/**\r\n * La prima parte di un riferimento, cioe' il nome che deve esistere.\r\n * `Cliente.Email` → `Cliente`; `$Record.Stato` → `$Record`; `Importo` → `Importo`.\r\n */\r\nexport function referenceRoot(reference: string | undefined | null): string {\r\n const value = (reference ?? '').trim();\r\n const dot = value.indexOf('.');\r\n return dot < 0 ? value : value.slice(0, dot);\r\n}\r\n\r\n/** `true` se il riferimento e' una variabile globale (`$Record`, `$Flow`, `$User`, …). */\r\nexport function isGlobalReference(reference: string | undefined | null): boolean {\r\n return (reference ?? '').trimStart().startsWith('$');\r\n}\r\n","/**\r\n * `conditionLogic` — FRONTEND.md §4.3 e trappola §13.4.\r\n *\r\n * L'espressione custom referenzia gli **indici 1-based** delle condizioni. Se l'editor\r\n * cancella o riordina una condizione, gli indici scalano e l'espressione va riscritta:\r\n * senza, si ottiene un `CONDITION_LOGIC_INVALID` o — peggio — un'espressione valida che\r\n * punta alla condizione sbagliata.\r\n */\r\n\r\nimport { FlowConditionHolder, FlowConditionLogic } from '../model/flow.model';\r\n\r\n/** Le tre forme non-espressione. `and` e' anche il default quando il campo e' assente. */\r\nexport function isCustomConditionLogic(logic: FlowConditionLogic | undefined): boolean {\r\n if (!logic) {\r\n return false;\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n return normalized !== 'and' && normalized !== 'or' && normalized !== 'formula';\r\n}\r\n\r\n/**\r\n * Riscrive un'espressione custom dopo che le condizioni sono state rimappate.\r\n *\r\n * `mapping[oldIndex0Based]` = nuovo indice 0-based, oppure `-1` se la condizione e' stata\r\n * cancellata. Un indice cancellato non puo' essere rimpiazzato da niente di sensato: il\r\n * termine viene sostituito da un segnaposto e la funzione lo segnala, così la UI puo'\r\n * avvisare che l'espressione va rivista.\r\n */\r\nexport function remapConditionLogic(\r\n logic: string,\r\n mapping: number[],\r\n): { logic: string; hasDroppedTerms: boolean } {\r\n let hasDroppedTerms = false;\r\n const rewritten = logic.replace(/\\d+/g, (match) => {\r\n const oldIndex = Number(match) - 1;\r\n const newIndex = mapping[oldIndex];\r\n if (newIndex === undefined || newIndex < 0) {\r\n hasDroppedTerms = true;\r\n // Segnaposto riconoscibile: la UI lo evidenzia e chiede di correggere.\r\n return '?';\r\n }\r\n return String(newIndex + 1);\r\n });\r\n return { logic: rewritten, hasDroppedTerms };\r\n}\r\n\r\n/**\r\n * Rimuove la condizione all'indice indicato e aggiorna `conditionLogic` di conseguenza.\r\n * Muta l'oggetto passato (che nello store e' già una copia di lavoro).\r\n */\r\nexport function removeCondition(holder: FlowConditionHolder, index: number): { hasDroppedTerms: boolean } {\r\n const conditions = holder.conditions ?? [];\r\n if (index < 0 || index >= conditions.length) {\r\n return { hasDroppedTerms: false };\r\n }\r\n conditions.splice(index, 1);\r\n\r\n if (!isCustomConditionLogic(holder.conditionLogic)) {\r\n return { hasDroppedTerms: false };\r\n }\r\n // Le condizioni dopo quella cancellata scalano di uno; quella cancellata → -1.\r\n const mapping: number[] = [];\r\n for (let position = 0; position <= conditions.length; position += 1) {\r\n if (position < index) {\r\n mapping.push(position);\r\n } else if (position === index) {\r\n mapping.push(-1);\r\n } else {\r\n mapping.push(position - 1);\r\n }\r\n }\r\n const result = remapConditionLogic(holder.conditionLogic as string, mapping);\r\n holder.conditionLogic = result.logic;\r\n return { hasDroppedTerms: result.hasDroppedTerms };\r\n}\r\n\r\n/** Sposta una condizione e riscrive l'espressione perche' punti agli stessi termini. */\r\nexport function moveCondition(holder: FlowConditionHolder, from: number, to: number): void {\r\n const conditions = holder.conditions ?? [];\r\n if (from === to || from < 0 || to < 0 || from >= conditions.length || to >= conditions.length) {\r\n return;\r\n }\r\n const [moved] = conditions.splice(from, 1);\r\n conditions.splice(to, 0, moved);\r\n\r\n if (!isCustomConditionLogic(holder.conditionLogic)) {\r\n return;\r\n }\r\n // Ricostruisce dove e' finito ogni vecchio indice.\r\n const order: number[] = [];\r\n for (let index = 0; index < conditions.length; index += 1) {\r\n order.push(index);\r\n }\r\n const oldOrder = order.slice();\r\n const [movedIndex] = oldOrder.splice(to, 1);\r\n oldOrder.splice(from, 0, movedIndex);\r\n // `oldOrder[oldIndex] = newIndex`\r\n const mapping: number[] = [];\r\n oldOrder.forEach((newIndex, oldIndex) => {\r\n mapping[oldIndex] = newIndex;\r\n });\r\n holder.conditionLogic = remapConditionLogic(holder.conditionLogic as string, mapping).logic;\r\n}\r\n\r\n/**\r\n * Verifica che un'espressione custom sia sintatticamente accettabile e che ogni indice\r\n * esista. Serve al feedback immediato nel form: la verita' resta della validazione\r\n * del backend (`CONDITION_LOGIC_INVALID`).\r\n */\r\nexport function checkConditionLogic(logic: string, conditionCount: number): string | null {\r\n const trimmed = logic.trim();\r\n if (!trimmed) {\r\n return null;\r\n }\r\n if (!isCustomConditionLogic(trimmed)) {\r\n return null;\r\n }\r\n // Caratteri ammessi: indici, AND, OR, NOT, parentesi, spazi.\r\n const stripped = trimmed.replace(/\\b(AND|OR|NOT)\\b/gi, ' ').replace(/[()\\s]/g, '');\r\n if (/[^0-9]/.test(stripped)) {\r\n return 'Ammessi solo indici, AND, OR, NOT e parentesi.';\r\n }\r\n let depth = 0;\r\n for (const character of trimmed) {\r\n if (character === '(') {\r\n depth += 1;\r\n } else if (character === ')') {\r\n depth -= 1;\r\n if (depth < 0) {\r\n return 'Parentesi non bilanciate.';\r\n }\r\n }\r\n }\r\n if (depth !== 0) {\r\n return 'Parentesi non bilanciate.';\r\n }\r\n const indexes = trimmed.match(/\\d+/g) ?? [];\r\n if (indexes.length === 0) {\r\n return 'L’espressione non referenzia nessuna condizione.';\r\n }\r\n for (const raw of indexes) {\r\n const index = Number(raw);\r\n if (index < 1 || index > conditionCount) {\r\n return `La condizione ${index} non esiste: sono definite ${conditionCount} condizioni.`;\r\n }\r\n }\r\n return null;\r\n}\r\n","/**\r\n * Testo e numero non si confrontano — FRONTEND.md §4.3, §13.13.\r\n *\r\n * `Importo > \"1000\"` con `Importo` numerico e' `CONDITION_TYPE_MISMATCH`, un **errore** che\r\n * blocca l'attivazione: la conversione implicita renderebbe l'esito dipendente dal formato\r\n * del testo, e chi disegna il flow non ha modo di accorgersene.\r\n *\r\n * Il backend segnala solo quando conosce **entrambi** i tipi, e su un campo di un record o\r\n * sull'output automatico di un elemento non li conosce: il posto giusto in cui fermare\r\n * l'utente e' il picker, cioe' l'editor delle condizioni. Questo file e' la regola, in un\r\n * posto solo.\r\n *\r\n * Vale per i soli operatori di uguaglianza e ordine. `Contains`, `StartsWith`, `EndsWith`,\r\n * `In` e `NotIn` hanno una semantica propria e non sono soggetti alla regola; gli unari non\r\n * hanno un secondo operando.\r\n */\r\n\r\nimport { FlowDataType } from '../model/flow.model';\r\n\r\n/** Gli operatori con una semantica propria: la regola non li riguarda (§4.3). */\r\nconst OPERATORS_WITHOUT_TYPE_CHECK: ReadonlySet<string> = new Set([\r\n 'Contains',\r\n 'StartsWith',\r\n 'EndsWith',\r\n 'In',\r\n 'NotIn',\r\n 'None',\r\n]);\r\n\r\n/** `Integer` e `Number` sono intercambiabili fra loro. */\r\nconst NUMERIC_TYPES: ReadonlySet<string> = new Set(['Integer', 'Number']);\r\n\r\n/**\r\n * `true` → per questo operatore i due lati devono essere compatibili.\r\n * `isUnary` arriva dal dizionario: un unario non ha un termine di confronto.\r\n */\r\nexport function isTypeCheckedOperator(operator: string | undefined | null, isUnary: boolean): boolean {\r\n if (!operator || isUnary) {\r\n return false;\r\n }\r\n return !OPERATORS_WITHOUT_TYPE_CHECK.has(operator);\r\n}\r\n\r\nexport function isNumericType(dataType: FlowDataType | undefined | null): boolean {\r\n return !!dataType && NUMERIC_TYPES.has(dataType);\r\n}\r\n\r\n/**\r\n * `false` solo per la coppia vietata: testo con numero.\r\n *\r\n * È l'**unica** coppia vietata. Un `Enum` confrontato con un testo resta lecito, perche' un\r\n * enum si confronta anche per nome; e con un tipo ignoto da un lato non si segnala nulla,\r\n * perche' non sapere non e' sapere che e' sbagliato.\r\n */\r\nexport function areTypesComparable(\r\n left: FlowDataType | undefined | null,\r\n right: FlowDataType | undefined | null,\r\n): boolean {\r\n if (!left || !right) {\r\n return true;\r\n }\r\n if (isNumericType(left) && right === 'String') {\r\n return false;\r\n }\r\n if (left === 'String' && isNumericType(right)) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * I numeri viaggiano in **cultura invariante**: il separatore decimale e' il punto, la virgola\r\n * non e' accettata (§4.3). Un campo che mostra `1.234,50` deve scrivere `1234.50`.\r\n *\r\n * Accetta la virgola come separatore decimale digitato — e' quello che un utente italiano\r\n * scrive — e la traduce, invece di lasciare che `parseFloat` tronchi silenziosamente a `1`.\r\n */\r\nexport function parseInvariantNumber(raw: string): number | undefined {\r\n const trimmed = raw.trim();\r\n if (!trimmed) {\r\n return undefined;\r\n }\r\n // Una sola virgola e nessun punto: e' il separatore decimale.\r\n const normalized =\r\n !trimmed.includes('.') && (trimmed.match(/,/g) ?? []).length === 1\r\n ? trimmed.replace(',', '.')\r\n : trimmed;\r\n if (!/^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?$/.test(normalized)) {\r\n return undefined;\r\n }\r\n const parsed = Number(normalized);\r\n return Number.isFinite(parsed) ? parsed : undefined;\r\n}\r\n","/**\r\n * Gli step di uno stage di orchestrazione — FRONTEND.md §5.13.\r\n *\r\n * Tre regole del contratto che non si vedono guardando il tipo, e che qui stanno in un posto\r\n * solo perche' le usano l'inspector, lo spazio dei nomi del documento e la validazione locale:\r\n *\r\n * 1. il `name` di uno step vive nello **stesso spazio dei nomi** di node e risorse (§3.3):\r\n * uno step omonimo di una variabile e' `NAME_DUPLICATED`;\r\n * 2. l'output di uno step e' sempre referenziabile come `<NomeStep>.<NomeOutput>`, ma una\r\n * condizione **non** puo' referenziarlo: finche' lo step non ha girato il riferimento e'\r\n * irrisolvibile, e a runtime un riferimento irrisolvibile e' un errore;\r\n * 3. gli step non sono una sequenza: l'ordine nell'array e' solo l'ordine d'esame.\r\n */\r\n\r\nimport { FlowDefinition, FlowOrchestratedStage, FlowStageStep } from '../model/flow.model';\r\nimport { referenceRoot } from './flow-name.util';\r\n\r\n/** I nomi di tutti gli step del documento: entrano nello spazio dei nomi comune (§3.3). */\r\nexport function stageStepNames(definition: FlowDefinition): string[] {\r\n const names: string[] = [];\r\n for (const stage of definition.orchestratedStages ?? []) {\r\n for (const step of stage.stageSteps ?? []) {\r\n if (step.name) {\r\n names.push(step.name);\r\n }\r\n }\r\n }\r\n return names;\r\n}\r\n\r\n/** Gli step di uno stage, con l'array assente trattato come vuoto. */\r\nexport function stepsOf(stage: FlowOrchestratedStage | undefined): FlowStageStep[] {\r\n return stage?.stageSteps ?? [];\r\n}\r\n\r\n/**\r\n * Il nome dello step il cui output un riferimento sta leggendo, se e' uno degli step passati.\r\n * `undefined` quando il riferimento e' legittimo. Serve a impedire nell'editor la condizione\r\n * che referenzia l'output di un altro step (§5.13, punto 4): la strada corretta e' scrivere\r\n * quel risultato in una variabile con `outputParameters.assignToReference` e condizionare\r\n * su quella.\r\n */\r\nexport function stageStepOutputReferenced(\r\n reference: string | undefined,\r\n steps: FlowStageStep[],\r\n): string | undefined {\r\n if (!reference) {\r\n return undefined;\r\n }\r\n const root = referenceRoot(reference.trim());\r\n return steps.find((step) => !!step.name && step.name === root)?.name;\r\n}\r\n\r\n/**\r\n * L'unico output che il runtime legge da un evaluation flow di condizione. Dichiararne altri\r\n * e' `STAGE_ACTION_INVALID` (§5.13, punto 7).\r\n */\r\nexport const ORCHESTRATION_CONDITION_OUTPUT = 'isOrchestrationConditionMet';\r\n","/**\r\n * Lo store del documento in lavorazione.\r\n *\r\n * Il documento `FlowDefinition` e' la fonte di verita' unica: canvas, inspector e pannelli\r\n * leggono da qui e scrivono qui. Le primitive del backend non vengono chiamate da questo\r\n * store — se ne occupano i pannelli tramite {@link FlowBuilderApi} — così l'editing resta\r\n * sincrono e reattivo anche mentre una validazione e' in volo.\r\n *\r\n * Il flatten delle collection (§3.1) e la mappa delle uscite (§3.5) sono esposti come\r\n * signal derivati: e' cio' che rende il canvas una funzione del documento.\r\n */\r\n\r\nimport { Injectable, computed, signal } from '@angular/core';\r\n\r\nimport {\r\n FLOW_NODE_COLLECTIONS,\r\n FLOW_RESOURCE_COLLECTIONS,\r\n FlowAnyNode,\r\n FlowConnector,\r\n FlowDefinition,\r\n FlowElementType,\r\n FlowNodeCollection,\r\n FlowResourceCollection,\r\n FlowStart,\r\n} from '../model/flow.model';\r\nimport { FlowConnectionKind } from '../model/api.model';\r\nimport { FlowOutlet, START_NODE_NAME, TYPE_BY_COLLECTION, outletsOf } from './element-outlets';\r\nimport { stageStepNames } from './stage-step.util';\r\n\r\n/** Un node come lo vede l'editor: il node piu' da dove viene. */\r\nexport interface FlowNodeRef {\r\n name: string;\r\n type: FlowElementType;\r\n collection: FlowNodeCollection;\r\n index: number;\r\n node: FlowAnyNode;\r\n}\r\n\r\n/** Un arco derivato dal documento, con la sua origine precisa. */\r\nexport interface FlowEdge {\r\n /** Id stabile: `<sorgente>|<chiave uscita>`. */\r\n id: string;\r\n /** `$start` per gli archi uscenti dallo Start. */\r\n from: string;\r\n /** `undefined` → il connector esiste ma non ha destinazione: ramo incompleto (§6.4). */\r\n to?: string;\r\n outletKey: string;\r\n kind: FlowConnectionKind;\r\n label?: string | null;\r\n isGoTo?: boolean;\r\n}\r\n\r\n/** Una risorsa come la vede l'editor. */\r\nexport interface FlowResourceRef {\r\n name: string;\r\n collection: FlowResourceCollection;\r\n index: number;\r\n resource: Record<string, unknown>;\r\n}\r\n\r\n/** Documento minimo per un flow nuovo (§11, \"Creare un flow\"). */\r\nexport function emptyFlowDefinition(fullName: string, label: string, processType: string): FlowDefinition {\r\n return {\r\n fullName,\r\n label,\r\n processType,\r\n // `start` con connector vuoto: il flow appena creato ha errori, ed e' normale (§11).\r\n start: [{ locationX: 60, locationY: 60 }],\r\n };\r\n}\r\n\r\n/** Copia profonda via JSON: il documento e' JSON per contratto (§2). */\r\nfunction clone<T>(value: T): T {\r\n return JSON.parse(JSON.stringify(value)) as T;\r\n}\r\n\r\nconst HISTORY_LIMIT = 100;\r\n\r\n@Injectable()\r\nexport class FlowDocumentStore {\r\n private readonly _document = signal<FlowDefinition>(emptyFlowDefinition('', '', 'Screen'));\r\n private readonly _isDirty = signal(false);\r\n private readonly _undoStack = signal<string[]>([]);\r\n private readonly _redoStack = signal<string[]>([]);\r\n\r\n /** Il documento in lavorazione. Sola lettura: si modifica con i metodi di questo store. */\r\n readonly document = this._document.asReadonly();\r\n readonly isDirty = this._isDirty.asReadonly();\r\n readonly canUndo = computed(() => this._undoStack().length > 0);\r\n readonly canRedo = computed(() => this._redoStack().length > 0);\r\n\r\n /** §3.4 — l'elemento Start: array di uno, usa sempre il primo. */\r\n readonly start = computed<FlowStart>(() => this._document().start?.[0] ?? {});\r\n\r\n /** §3.1 — tutte le collection appiattite in un'unica lista di node. */\r\n readonly nodes = computed<FlowNodeRef[]>(() => {\r\n const document = this._document();\r\n const result: FlowNodeRef[] = [];\r\n for (const collection of FLOW_NODE_COLLECTIONS) {\r\n const list = document[collection] as FlowAnyNode[] | undefined;\r\n list?.forEach((node, index) => {\r\n result.push({\r\n name: node.name ?? '',\r\n type: TYPE_BY_COLLECTION[collection] ?? collection,\r\n collection,\r\n index,\r\n node,\r\n });\r\n });\r\n }\r\n return result;\r\n });\r\n\r\n readonly nodeByName = computed<Map<string, FlowNodeRef>>(\r\n () => new Map(this.nodes().map((reference) => [reference.name, reference])),\r\n );\r\n\r\n readonly resources = computed<FlowResourceRef[]>(() => {\r\n const document = this._document();\r\n const result: FlowResourceRef[] = [];\r\n for (const collection of FLOW_RESOURCE_COLLECTIONS) {\r\n const list = document[collection] as Array<Record<string, unknown>> | undefined;\r\n list?.forEach((resource, index) => {\r\n result.push({\r\n name: (resource['name'] as string) ?? '',\r\n collection,\r\n index,\r\n resource,\r\n });\r\n });\r\n }\r\n return result;\r\n });\r\n\r\n /**\r\n * §3.3 — l'insieme dei nomi già usati: node, risorse **e** step di orchestrazione, un unico\r\n * spazio di nomi. Il controllo di unicita' che guarda solo le variabili lascia passare una\r\n * variabile omonima di un node (§13.5); quello che dimentica gli step lascia passare uno\r\n * step omonimo di una variabile, che e' `NAME_DUPLICATED` allo stesso modo (§5.13).\r\n */\r\n readonly usedNames = computed<string[]>(() => [\r\n ...this.nodes().map((reference) => reference.name),\r\n ...this.resources().map((reference) => reference.name),\r\n ...stageStepNames(this._document()),\r\n ]);\r\n\r\n /** Gli archi derivati dal documento, Start incluso. */\r\n readonly edges = computed<FlowEdge[]>(() => {\r\n const edges: FlowEdge[] = [];\r\n const push = (from: string, node: FlowAnyNode, outlet: FlowOutlet) => {\r\n const connector = outlet.read(node);\r\n if (!connector) {\r\n return;\r\n }\r\n edges.push({\r\n id: `${from}|${outlet.key}`,\r\n from,\r\n to: connector.targetReference || undefined,\r\n outletKey: outlet.key,\r\n kind: outlet.kind,\r\n label: outlet.branchLabel ?? null,\r\n isGoTo: connector.isGoTo,\r\n });\r\n };\r\n\r\n const start = this.start() as FlowAnyNode;\r\n for (const outlet of outletsOf('Start', start)) {\r\n push(START_NODE_NAME, start, outlet);\r\n }\r\n for (const reference of this.nodes()) {\r\n for (const outlet of outletsOf(reference.type, reference.node)) {\r\n push(reference.name, reference.node, outlet);\r\n }\r\n }\r\n return edges;\r\n });\r\n\r\n /**\r\n * Raggiungibilita' calcolata localmente, per un feedback immediato mentre si disegna.\r\n * La fonte autoritativa resta `isReachable` di `POST /flows/outline` (§6.4): questa e'\r\n * un'anticipazione, non un sostituto.\r\n */\r\n readonly reachableNames = computed<ReadonlySet<string>>(() => {\r\n const adjacency = new Map<string, string[]>();\r\n for (const edge of this.edges()) {\r\n if (!edge.to) {\r\n continue;\r\n }\r\n const list = adjacency.get(edge.from) ?? [];\r\n list.push(edge.to);\r\n adjacency.set(edge.from, list);\r\n }\r\n const visited = new Set<string>();\r\n const queue = [START_NODE_NAME];\r\n while (queue.length) {\r\n const current = queue.shift() as string;\r\n for (const next of adjacency.get(current) ?? []) {\r\n if (!visited.has(next)) {\r\n visited.add(next);\r\n queue.push(next);\r\n }\r\n }\r\n }\r\n return visited;\r\n });\r\n\r\n // -------------------------------------------------------------------------\r\n // Caricamento e storico\r\n // -------------------------------------------------------------------------\r\n\r\n /** Carica un documento dal backend: azzera storico e flag di modifica. */\r\n load(definition: FlowDefinition): void {\r\n this._document.set(clone(definition));\r\n this._undoStack.set([]);\r\n this._redoStack.set([]);\r\n this._isDirty.set(false);\r\n }\r\n\r\n /** Dopo un salvataggio riuscito: il documento resta, la modifica non e' piu' pendente. */\r\n markSaved(): void {\r\n this._isDirty.set(false);\r\n }\r\n\r\n /**\r\n * Applica una modifica al documento.\r\n * Il mutatore riceve una **copia** e la modifica liberamente; lo store si occupa di\r\n * storico e di sostituire il riferimento (nuovo oggetto → i signal derivati ricalcolano).\r\n */\r\n update(mutate: (draft: FlowDefinition) => void, options?: { silent?: boolean }): void {\r\n const current = this._document();\r\n if (!options?.silent) {\r\n this.pushHistory(current);\r\n }\r\n const draft = clone(current);\r\n mutate(draft);\r\n this._document.set(draft);\r\n this._isDirty.set(true);\r\n }\r\n\r\n private pushHistory(snapshot: FlowDefinition): void {\r\n const serialized = JSON.stringify(snapshot);\r\n const stack = [...this._undoStack(), serialized];\r\n if (stack.length > HISTORY_LIMIT) {\r\n stack.shift();\r\n }\r\n this._undoStack.set(stack);\r\n this._redoStack.set([]);\r\n }\r\n\r\n undo(): void {\r\n const stack = [...this._undoStack()];\r\n const previous = stack.pop();\r\n if (!previous) {\r\n return;\r\n }\r\n this._redoStack.set([...this._redoStack(), JSON.stringify(this._document())]);\r\n this._undoStack.set(stack);\r\n this._document.set(JSON.parse(previous) as FlowDefinition);\r\n this._isDirty.set(true);\r\n }\r\n\r\n redo(): void {\r\n const stack = [...this._redoStack()];\r\n const next = stack.pop();\r\n if (!next) {\r\n return;\r\n }\r\n this._undoStack.set([...this._undoStack(), JSON.stringify(this._document())]);\r\n this._redoStack.set(stack);\r\n this._document.set(JSON.parse(next) as FlowDefinition);\r\n this._isDirty.set(true);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Node\r\n // -------------------------------------------------------------------------\r\n\r\n /** Inserisce un node nella collection indicata dal dizionario (`metadataProperty`). */\r\n addNode(collection: FlowNodeCollection, node: FlowAnyNode): void {\r\n this.update((draft) => {\r\n const list = (draft[collection] as FlowAnyNode[] | undefined) ?? [];\r\n list.push(node);\r\n (draft as Record<string, unknown>)[collection] = list;\r\n });\r\n }\r\n\r\n /** Modifica un node per nome. Il mutatore riceve la copia di lavoro. */\r\n updateNode(name: string, mutate: (node: FlowAnyNode) => void, options?: { silent?: boolean }): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n const node = list?.[reference.index];\r\n if (node) {\r\n mutate(node);\r\n }\r\n }, options);\r\n }\r\n\r\n /** Modifica lo Start. */\r\n updateStart(mutate: (start: FlowStart) => void, options?: { silent?: boolean }): void {\r\n this.update((draft) => {\r\n const list = draft.start ?? [{}];\r\n mutate(list[0]);\r\n draft.start = list;\r\n }, options);\r\n }\r\n\r\n /**\r\n * Sposta un node sul canvas. `silent` per non riempire lo storico durante il drag:\r\n * il chiamante registra un solo passo alla fine del gesto.\r\n */\r\n moveNode(name: string, x: number, y: number, options?: { silent?: boolean }): void {\r\n const rounded = { x: Math.round(x), y: Math.round(y) };\r\n if (name === START_NODE_NAME) {\r\n this.updateStart((start) => {\r\n start.locationX = rounded.x;\r\n start.locationY = rounded.y;\r\n }, options);\r\n return;\r\n }\r\n this.updateNode(\r\n name,\r\n (node) => {\r\n node.locationX = rounded.x;\r\n node.locationY = rounded.y;\r\n },\r\n options,\r\n );\r\n }\r\n\r\n /**\r\n * Rimuove un node **e** ogni connector che lo referenzia: un `targetReference` orfano\r\n * e' `CONNECTOR_TARGET_UNKNOWN`, cioe' un errore che blocca l'attivazione (§7).\r\n */\r\n removeNode(name: string): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n list?.splice(reference.index, 1);\r\n if (list && list.length === 0) {\r\n delete (draft as Record<string, unknown>)[reference.collection];\r\n }\r\n FlowDocumentStore.clearReferencesTo(draft, name);\r\n });\r\n }\r\n\r\n /** Azzera i connector che puntano a un node scomparso, Start compreso. */\r\n private static clearReferencesTo(draft: FlowDefinition, removedName: string): void {\r\n const visit = (type: FlowElementType, node: FlowAnyNode) => {\r\n for (const outlet of outletsOf(type, node)) {\r\n const connector = outlet.read(node);\r\n if (connector?.targetReference === removedName) {\r\n // Il ramo resta, senza destinazione: e' un ramo incompleto, non un errore\r\n // di riferimento. La UI lo mostra come tale (§6.4, `to: null`).\r\n outlet.write(node, { ...connector, targetReference: undefined });\r\n }\r\n }\r\n };\r\n const start = draft.start?.[0];\r\n if (start) {\r\n visit('Start', start as FlowAnyNode);\r\n }\r\n for (const collection of FLOW_NODE_COLLECTIONS) {\r\n const list = draft[collection] as FlowAnyNode[] | undefined;\r\n const type = TYPE_BY_COLLECTION[collection] ?? collection;\r\n list?.forEach((node) => visit(type, node));\r\n }\r\n }\r\n\r\n /**\r\n * Rinomina un node riscrivendo **tutti** i riferimenti che lo raggiungono.\r\n * Nessuna primitiva del backend lo fa (§13.8): se l'editor offre la rinomina, la\r\n * riscrittura la deve fare lui. Copre `targetReference`, i riferimenti a risorsa e i\r\n * riferimenti a output automatico (`Vecchio.Campo` → `Nuovo.Campo`).\r\n */\r\n renameNode(oldName: string, newName: string): void {\r\n if (!oldName || !newName || oldName === newName) {\r\n return;\r\n }\r\n this.update((draft) => {\r\n const reference = this.nodeByName().get(oldName);\r\n if (reference) {\r\n const list = draft[reference.collection] as FlowAnyNode[] | undefined;\r\n const node = list?.[reference.index];\r\n if (node) {\r\n node.name = newName;\r\n }\r\n }\r\n FlowDocumentStore.rewriteReferences(draft, oldName, newName);\r\n });\r\n }\r\n\r\n /** Rinomina una risorsa, riscrivendo i riferimenti che la usano. */\r\n renameResource(collection: FlowResourceCollection, index: number, newName: string): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n const resource = list?.[index];\r\n if (!resource) {\r\n return;\r\n }\r\n const oldName = resource['name'] as string;\r\n resource['name'] = newName;\r\n if (oldName) {\r\n FlowDocumentStore.rewriteReferences(draft, oldName, newName);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Riscrive ogni occorrenza di un nome nei campi che contengono riferimenti.\r\n * Cammina l'intero documento: e' l'unico modo per non dimenticare un campo, dato che\r\n * i riferimenti compaiono in una ventina di posti diversi (§4).\r\n */\r\n private static rewriteReferences(draft: FlowDefinition, oldName: string, newName: string): void {\r\n /** Campi il cui valore e' un riferimento a risorsa o a node. */\r\n const referenceFields = new Set([\r\n 'targetReference',\r\n 'elementReference',\r\n 'assignToReference',\r\n 'leftValueReference',\r\n 'collectionReference',\r\n 'assignNextValueToReference',\r\n 'outputReference',\r\n 'inputReference',\r\n 'assignRecordIdToReference',\r\n ]);\r\n\r\n const rewrite = (value: string): string => {\r\n if (value === oldName) {\r\n return newName;\r\n }\r\n // Riferimento navigato: `Vecchio.Campo` → `Nuovo.Campo`.\r\n if (value.startsWith(`${oldName}.`)) {\r\n return `${newName}${value.slice(oldName.length)}`;\r\n }\r\n return value;\r\n };\r\n\r\n const walk = (value: unknown): void => {\r\n if (Array.isArray(value)) {\r\n value.forEach(walk);\r\n return;\r\n }\r\n if (!value || typeof value !== 'object') {\r\n return;\r\n }\r\n const record = value as Record<string, unknown>;\r\n for (const [key, child] of Object.entries(record)) {\r\n if (typeof child === 'string' && referenceFields.has(key)) {\r\n record[key] = rewrite(child);\r\n } else {\r\n walk(child);\r\n }\r\n }\r\n };\r\n\r\n walk(draft);\r\n }\r\n\r\n /** Duplica un node con un nome nuovo, senza copiarne le uscite. */\r\n duplicateNode(name: string, newName: string, offset = { x: 40, y: 40 }): void {\r\n const reference = this.nodeByName().get(name);\r\n if (!reference) {\r\n return;\r\n }\r\n const copy = clone(reference.node);\r\n copy.name = newName;\r\n copy.locationX = (copy.locationX ?? 0) + offset.x;\r\n copy.locationY = (copy.locationY ?? 0) + offset.y;\r\n // Le uscite non si copiano: duplicherebbero rami che l'utente non ha disegnato.\r\n for (const outlet of outletsOf(reference.type, copy)) {\r\n outlet.write(copy, undefined);\r\n }\r\n this.addNode(reference.collection, copy);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Connector\r\n // -------------------------------------------------------------------------\r\n\r\n /** Scrive la destinazione di un'uscita. `target` assente → il ramo resta incompleto. */\r\n setConnector(fromName: string, outletKey: string, target: string | undefined, isGoTo?: boolean): void {\r\n const write = (type: FlowElementType, node: FlowAnyNode) => {\r\n const outlet = outletsOf(type, node).find((candidate) => candidate.key === outletKey);\r\n if (!outlet) {\r\n return;\r\n }\r\n const existing = outlet.read(node) ?? {};\r\n const connector: FlowConnector = { ...existing, targetReference: target };\r\n if (isGoTo !== undefined) {\r\n connector.isGoTo = isGoTo;\r\n }\r\n if (!connector.targetReference && !connector.isGoTo) {\r\n // Nessuna destinazione e nessun flag: meglio omettere il connector che scrivere\r\n // un oggetto vuoto (§2, \"proprieta' nulle omesse\").\r\n outlet.write(node, undefined);\r\n return;\r\n }\r\n outlet.write(node, connector);\r\n };\r\n\r\n if (fromName === START_NODE_NAME) {\r\n this.updateStart((start) => write('Start', start as FlowAnyNode));\r\n return;\r\n }\r\n this.updateNode(fromName, (node) => {\r\n const reference = this.nodeByName().get(fromName);\r\n write(reference?.type ?? '', node);\r\n });\r\n }\r\n\r\n /** Rimuove un arco: il percorso finisce lì, che e' legittimo (§3.5). */\r\n removeConnector(fromName: string, outletKey: string): void {\r\n this.setConnector(fromName, outletKey, undefined);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Risorse\r\n // -------------------------------------------------------------------------\r\n\r\n addResource(collection: FlowResourceCollection, resource: Record<string, unknown>): void {\r\n this.update((draft) => {\r\n const list = (draft[collection] as Array<Record<string, unknown>> | undefined) ?? [];\r\n list.push(resource);\r\n (draft as Record<string, unknown>)[collection] = list;\r\n });\r\n }\r\n\r\n updateResource(\r\n collection: FlowResourceCollection,\r\n index: number,\r\n mutate: (resource: Record<string, unknown>) => void,\r\n ): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n const resource = list?.[index];\r\n if (resource) {\r\n mutate(resource);\r\n }\r\n });\r\n }\r\n\r\n removeResource(collection: FlowResourceCollection, index: number): void {\r\n this.update((draft) => {\r\n const list = draft[collection] as Array<Record<string, unknown>> | undefined;\r\n list?.splice(index, 1);\r\n if (list && list.length === 0) {\r\n delete (draft as Record<string, unknown>)[collection];\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Radice\r\n // -------------------------------------------------------------------------\r\n\r\n /** Modifica i campi del documento radice (label, description, processType, …). */\r\n updateHeader(mutate: (definition: FlowDefinition) => void, options?: { silent?: boolean }): void {\r\n this.update(mutate, options);\r\n }\r\n}\r\n","/**\r\n * Cache dei dizionari e dei cataloghi — FRONTEND.md §6.4.\r\n *\r\n * I dizionari sono **quasi** statici: si caricano una volta all'avvio dell'editor e si tengono\r\n * in cache, con un'eccezione — `globalVariables` dipende dal `processType` con cui li si e'\r\n * chiesti, perche' `$Record` non esiste in uno screen flow (§4.1). Qui la cache e' quindi per\r\n * tipo di flow: cambiare `processType` nell'editor ricarica le globali, non tutto il resto\r\n * dell'esperienza.\r\n *\r\n * I cataloghi (oggetti, campi, action, form, script, eventi) cambiano raramente: sono\r\n * memoizzati per chiave, in modo che aprire dieci volte lo stesso inspector non produca dieci\r\n * richieste.\r\n *\r\n * Nessun elenco di enum e' cablato: se il backend aggiunge un operatore, appare nelle\r\n * tendine senza toccare il frontend (§13.11).\r\n */\r\n\r\nimport { Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport {\r\n FlowCatalogEntry,\r\n FlowCatalogParameter,\r\n FlowComparisonOperatorEntry,\r\n FlowDataTypeEntry,\r\n FlowDictionaries,\r\n FlowDictionaryEntry,\r\n FlowElementTypeEntry,\r\n FlowFieldDescription,\r\n FlowFieldUsage,\r\n FlowGlobalVariableEntry,\r\n FlowObjectSummary,\r\n FlowStageStepTypeEntry,\r\n} from '../model/dictionary.model';\r\nimport { FlowDataType, FlowNodeCollection } from '../model/flow.model';\r\nimport {\r\n FALLBACK_COLLECTION_BY_TYPE,\r\n FALLBACK_TYPE_LABEL,\r\n UNSUPPORTED_TYPES,\r\n} from './element-outlets';\r\nimport { variantFieldOf } from './element-variants';\r\n\r\n@Injectable()\r\nexport class FlowDictionaryStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n private readonly _dictionaries = signal<FlowDictionaries>({});\r\n private readonly _isLoaded = signal(false);\r\n private readonly _processType = signal<string | undefined>(undefined);\r\n /** Una copia per tipo di flow: le globali dipendono dal `processType` (§4.1, §6.4). */\r\n private readonly cache = new Map<string, Promise<FlowDictionaries>>();\r\n /** Cresce a ogni `load`: scarta la risposta di un caricamento superato. */\r\n private sequence = 0;\r\n\r\n readonly dictionaries = this._dictionaries.asReadonly();\r\n readonly isLoaded = this._isLoaded.asReadonly();\r\n /** Il `processType` dei dizionari attualmente in uso. */\r\n readonly processType = this._processType.asReadonly();\r\n\r\n /**\r\n * Idempotente: chiamabile da ogni componente che ne ha bisogno.\r\n * Con un `processType` diverso da quello in uso ricarica — dalla cache se c'e' già —\r\n * perche' cambiare tipo di flow cambia quali globali sono proponibili.\r\n */\r\n async load(processType?: string): Promise<void> {\r\n if (this._isLoaded() && processType === this._processType()) {\r\n return;\r\n }\r\n const key = processType ?? '';\r\n const token = ++this.sequence;\r\n let entry = this.cache.get(key);\r\n if (!entry) {\r\n entry = this.api.getDictionaries(processType).then((dictionaries) => dictionaries ?? {});\r\n // Un errore non va memoizzato: al prossimo tentativo si riprova.\r\n entry.catch(() => this.cache.delete(key));\r\n this.cache.set(key, entry);\r\n }\r\n const dictionaries = await entry;\r\n if (token !== this.sequence) {\r\n // Un caricamento piu' recente ha già applicato un altro tipo: questo e' superato.\r\n return;\r\n }\r\n this._dictionaries.set(dictionaries);\r\n this._processType.set(processType);\r\n this._isLoaded.set(true);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Accessori tipizzati\r\n // -------------------------------------------------------------------------\r\n\r\n readonly dataTypes = computed<FlowDataTypeEntry[]>(() => this._dictionaries().dataTypes ?? []);\r\n readonly comparisonOperators = computed<FlowComparisonOperatorEntry[]>(\r\n () => this._dictionaries().comparisonOperators ?? [],\r\n );\r\n readonly assignmentOperators = computed(() => this._dictionaries().assignmentOperators ?? []);\r\n readonly recordFilterOperators = computed(() => this._dictionaries().recordFilterOperators ?? []);\r\n readonly resourceKinds = computed(() => this._dictionaries().resourceKinds ?? []);\r\n readonly globalVariables = computed<FlowGlobalVariableEntry[]>(\r\n () => this._dictionaries().globalVariables ?? [],\r\n );\r\n readonly processTypes = computed(() => this._dictionaries().processTypes ?? []);\r\n readonly triggerTypes = computed(() => this._dictionaries().triggerTypes ?? []);\r\n readonly recordTriggerTypes = computed(() => this._dictionaries().recordTriggerTypes ?? []);\r\n readonly startFrequencies = computed(() => this._dictionaries().startFrequencies ?? []);\r\n readonly offsetUnits = computed(() => this._dictionaries().offsetUnits ?? []);\r\n readonly sortOrders = computed(() => this._dictionaries().sortOrders ?? []);\r\n readonly collectionProcessorTypes = computed(() => this._dictionaries().collectionProcessorTypes ?? []);\r\n readonly transformTypes = computed(() => this._dictionaries().transformTypes ?? []);\r\n readonly transactionModels = computed(() => this._dictionaries().transactionModels ?? []);\r\n readonly waitEventTypes = computed(() => this._dictionaries().waitEventTypes ?? []);\r\n readonly stageStepTypes = computed<FlowStageStepTypeEntry[]>(\r\n () => this._dictionaries().stageStepTypes ?? [],\r\n );\r\n readonly assigneeTypes = computed(() => this._dictionaries().assigneeTypes ?? []);\r\n readonly conditionLogicModes = computed(() => this._dictionaries().conditionLogicModes ?? []);\r\n\r\n readonly elementTypes = computed<FlowElementTypeEntry[]>(() => this._dictionaries().elementTypes ?? []);\r\n\r\n /**\r\n * I tipi mostrabili nella palette: `isSupported: false` va nascosto (§3.2, §13.9).\r\n * Il filtro passa per la colonna del dizionario, non per una lista cablata; l'insieme\r\n * locale {@link UNSUPPORTED_TYPES} interviene solo se il dizionario non dichiara il flag.\r\n */\r\n readonly paletteTypes = computed<FlowElementTypeEntry[]>(() =>\r\n this.elementTypes().filter((entry) => {\r\n if (entry.isSupported === false) {\r\n return false;\r\n }\r\n if (entry.isSupported === undefined && UNSUPPORTED_TYPES.has(entry.value)) {\r\n return false;\r\n }\r\n return true;\r\n }),\r\n );\r\n\r\n /** Le categorie della palette, nell'ordine di prima apparizione nel dizionario. */\r\n readonly paletteCategories = computed<string[]>(() => {\r\n const categories: string[] = [];\r\n for (const entry of this.paletteTypes()) {\r\n const category = entry.category ?? 'Altro';\r\n if (!categories.includes(category)) {\r\n categories.push(category);\r\n }\r\n }\r\n return categories;\r\n });\r\n\r\n elementType(value: string): FlowElementTypeEntry | undefined {\r\n return this.elementTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /**\r\n * Le varianti di un tipo, cioe' i valori del suo discriminatore (§5.5). L'unico oggi e' il\r\n * Collection Processor. Elenco vuoto = tipo senza varianti, **oppure** dizionario non\r\n * disponibile: in entrambi i casi la palette mostra una voce sola, che e' l'unica cosa\r\n * onesta da fare quando non si sa quali varianti esistano.\r\n */\r\n variantsOf(type: string): FlowDictionaryEntry[] {\r\n switch (variantFieldOf(type)) {\r\n case 'collectionProcessorType':\r\n return this.collectionProcessorTypes();\r\n default:\r\n return [];\r\n }\r\n }\r\n\r\n /** L'etichetta di una variante, con fallback sul valore grezzo. */\r\n variantLabelOf(type: string, variant: string | undefined): string {\r\n return FlowDictionaryStore.labelIn(this.variantsOf(type), variant);\r\n }\r\n\r\n /** La collection in cui scrivere un node: `metadataProperty`, con fallback locale (§3.2). */\r\n collectionOf(type: string): FlowNodeCollection | undefined {\r\n const fromDictionary = this.elementType(type)?.metadataProperty;\r\n return (fromDictionary as FlowNodeCollection | undefined) ?? FALLBACK_COLLECTION_BY_TYPE[type];\r\n }\r\n\r\n /** Etichetta di un tipo, con fallback: un tipo sconosciuto mostra il proprio `value`. */\r\n labelOf(type: string): string {\r\n return this.elementType(type)?.label ?? FALLBACK_TYPE_LABEL[type] ?? type;\r\n }\r\n\r\n hasFaultConnector(type: string): boolean {\r\n return this.elementType(type)?.hasFaultConnector ?? false;\r\n }\r\n\r\n hasAutomaticOutput(type: string): boolean {\r\n return this.elementType(type)?.hasAutomaticOutput ?? false;\r\n }\r\n\r\n /** Etichetta di una voce di dizionario, con fallback sul valore grezzo. */\r\n static labelIn(entries: FlowDictionaryEntry[], value: string | undefined | null): string {\r\n if (!value) {\r\n return '';\r\n }\r\n return entries.find((entry) => entry.value === value)?.label ?? value;\r\n }\r\n\r\n operator(value: string | undefined | null): FlowComparisonOperatorEntry | undefined {\r\n if (!value) {\r\n return undefined;\r\n }\r\n return this.comparisonOperators().find((entry) => entry.value === value);\r\n }\r\n\r\n /**\r\n * §13.1 — per gli operatori unari `rightValue` e' l'esito atteso, non un termine di\r\n * confronto. Il flag arriva dal dizionario (`isUnary`).\r\n */\r\n isUnaryOperator(value: string | undefined | null): boolean {\r\n return this.operator(value)?.isUnary ?? false;\r\n }\r\n\r\n /** §4.3 — `WasVisited` e `HasError` vogliono a sinistra il nome di un **node**. */\r\n operatorAppliesToElements(value: string | undefined | null): boolean {\r\n return this.operator(value)?.appliesToElements ?? false;\r\n }\r\n\r\n /** §5.2 — operatore che ha senso solo su destinazioni collection. */\r\n assignmentExpectsCollection(value: string | undefined | null): boolean {\r\n return this.assignmentOperators().find((entry) => entry.value === value)?.expectsCollection ?? false;\r\n }\r\n\r\n /**\r\n * Operatori applicabili al tipo del lato sinistro: `appliesTo` vuoto = qualunque tipo (§4.3).\r\n */\r\n operatorsFor(dataType: FlowDataType | undefined): FlowComparisonOperatorEntry[] {\r\n const operators = this.comparisonOperators();\r\n if (!dataType) {\r\n return operators;\r\n }\r\n return operators.filter(\r\n (entry) => !entry.appliesTo || entry.appliesTo.length === 0 || entry.appliesTo.includes(dataType),\r\n );\r\n }\r\n\r\n /** La voce di `globalVariables` di uno scope: `$User`, `$Flow`, … (§4.1). */\r\n globalScope(scope: string | undefined | null): FlowGlobalVariableEntry | undefined {\r\n if (!scope) {\r\n return undefined;\r\n }\r\n return this.globalVariables().find((entry) => entry.scope === scope || entry.value === scope);\r\n }\r\n\r\n /**\r\n * §4.1 — la verificabilita' e' **per scope**: se lo scope dichiara almeno un percorso, uno\r\n * che non c'e' e' `GLOBAL_UNKNOWN`; se non ne dichiara nessuno, resta non verificabile, che\r\n * significa \"non lo so\", non \"non esiste\".\r\n */\r\n isGlobalScopeVerifiable(scope: string | undefined | null): boolean {\r\n return (this.globalScope(scope)?.paths?.length ?? 0) > 0;\r\n }\r\n\r\n /** I percorsi noti di uno scope, già prefissati: `$User.Email`. */\r\n globalPathsOf(scope: string | undefined | null): string[] {\r\n const entry = this.globalScope(scope);\r\n if (!entry) {\r\n return [];\r\n }\r\n const prefix = entry.scope ?? entry.value;\r\n return (entry.paths ?? []).map((path) => `${prefix}.${path}`);\r\n }\r\n\r\n /** §5.13 — la voce di `stageStepTypes` di un `actionType`. */\r\n stageStepType(value: string | undefined | null): FlowStageStepTypeEntry | undefined {\r\n if (!value) {\r\n return undefined;\r\n }\r\n return this.stageStepTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /** `stepBackground` vuole `actionName`; il fallback serve se il dizionario non lo dichiara. */\r\n stageStepRequiresActionName(actionType: string | undefined | null): boolean {\r\n const entry = this.stageStepType(actionType);\r\n return entry?.requiresActionName ?? actionType === 'stepBackground';\r\n }\r\n\r\n /** `stepInteractive` e `stepApproval` vogliono gli assegnatari (§5.13). */\r\n stageStepRequiresAssignees(actionType: string | undefined | null): boolean {\r\n const entry = this.stageStepType(actionType);\r\n if (entry?.requiresAssignees !== undefined) {\r\n return entry.requiresAssignees;\r\n }\r\n return actionType === 'stepInteractive' || actionType === 'stepApproval';\r\n }\r\n\r\n dataType(value: string | undefined | null): FlowDataTypeEntry | undefined {\r\n return this.dataTypes().find((entry) => entry.value === value);\r\n }\r\n\r\n /** §4.6 — `Object` ed `Enum` richiedono `objectType`. */\r\n requiresObjectType(dataType: string | undefined | null): boolean {\r\n const entry = this.dataType(dataType);\r\n if (entry?.requiresObjectType !== undefined) {\r\n return entry.requiresObjectType;\r\n }\r\n return dataType === 'Object' || dataType === 'Enum';\r\n }\r\n\r\n /** §4.6 — `scale` si applica solo ai numerici. */\r\n supportsScale(dataType: string | undefined | null): boolean {\r\n const entry = this.dataType(dataType);\r\n if (entry?.supportsScale !== undefined) {\r\n return entry.supportsScale;\r\n }\r\n return dataType === 'Number' || dataType === 'Integer';\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cataloghi\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Memoizza per chiave le richieste di catalogo, condividendo la promise in volo. */\r\nclass AsyncCache<T> {\r\n private readonly entries = new Map<string, Promise<T>>();\r\n\r\n get(key: string, load: () => Promise<T>): Promise<T> {\r\n let entry = this.entries.get(key);\r\n if (!entry) {\r\n entry = load().catch((error) => {\r\n // Un errore non va memoizzato: al prossimo tentativo si riprova.\r\n this.entries.delete(key);\r\n throw error;\r\n });\r\n this.entries.set(key, entry);\r\n }\r\n return entry;\r\n }\r\n\r\n clear(): void {\r\n this.entries.clear();\r\n }\r\n}\r\n\r\n@Injectable()\r\nexport class FlowCatalogStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n private readonly objectsCache = new AsyncCache<FlowObjectSummary[]>();\r\n private readonly fieldsCache = new AsyncCache<FlowFieldDescription[]>();\r\n private readonly fieldValuesCache = new AsyncCache<Array<{ value: string; label?: string | null }>>();\r\n private readonly entriesCache = new AsyncCache<FlowCatalogEntry[]>();\r\n private readonly parametersCache = new AsyncCache<FlowCatalogParameter[]>();\r\n\r\n /**\r\n * Una lista vuota significa \"non lo so\", non \"nessuno\": con il catalogo non popolato la\r\n * validazione salta i controlli invece di produrre falsi allarmi (§7). L'editor fa lo\r\n * stesso: se la lista e' vuota, lascia il campo libero invece di bloccarlo.\r\n */\r\n listObjects(): Promise<FlowObjectSummary[]> {\r\n return this.objectsCache.get('objects', () => this.api.listObjects().then((list) => list ?? []));\r\n }\r\n\r\n listFields(object: string, usage: FlowFieldUsage = 'any'): Promise<FlowFieldDescription[]> {\r\n if (!object) {\r\n return Promise.resolve([]);\r\n }\r\n return this.fieldsCache.get(`${object}|${usage}`, () =>\r\n this.api.listFields(object, usage).then((list) => list ?? []),\r\n );\r\n }\r\n\r\n listFieldValues(object: string, field: string): Promise<Array<{ value: string; label?: string | null }>> {\r\n if (!object || !field) {\r\n return Promise.resolve([]);\r\n }\r\n return this.fieldValuesCache.get(`${object}|${field}`, () =>\r\n this.api.listFieldValues(object, field).catch(() => []),\r\n );\r\n }\r\n\r\n listActionTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('action-types', () => this.api.listActionTypes().then((list) => list ?? []));\r\n }\r\n\r\n listActions(actionType?: string): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get(`actions|${actionType ?? ''}`, () =>\r\n this.api.listActions(actionType).then((list) => list ?? []),\r\n );\r\n }\r\n\r\n listActionParameters(actionType: string, actionName: string): Promise<FlowCatalogParameter[]> {\r\n if (!actionType || !actionName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`action|${actionType}|${actionName}`, () =>\r\n this.api.listActionParameters(actionType, actionName).catch(() => []),\r\n );\r\n }\r\n\r\n listScripts(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('scripts', () => this.api.listScripts().then((list) => list ?? []));\r\n }\r\n\r\n listScriptParameters(scriptName: string): Promise<FlowCatalogParameter[]> {\r\n if (!scriptName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`script|${scriptName}`, () =>\r\n this.api.listScriptParameters(scriptName).catch(() => []),\r\n );\r\n }\r\n\r\n listForms(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('forms', () => this.api.listForms().then((list) => list ?? []));\r\n }\r\n\r\n listFormParameters(formName: string): Promise<FlowCatalogParameter[]> {\r\n if (!formName) {\r\n return Promise.resolve([]);\r\n }\r\n return this.parametersCache.get(`form|${formName}`, () =>\r\n this.api.listFormParameters(formName).catch(() => []),\r\n );\r\n }\r\n\r\n listEnumTypes(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('enum-types', () => this.api.listEnumTypes().then((list) => list ?? []));\r\n }\r\n\r\n listEvents(): Promise<FlowCatalogEntry[]> {\r\n return this.entriesCache.get('events', () => this.api.listEvents().then((list) => list ?? []));\r\n }\r\n\r\n /** Da chiamare se lo schema cambia sotto i piedi (raro, ma il comando esiste). */\r\n clear(): void {\r\n this.objectsCache.clear();\r\n this.fieldsCache.clear();\r\n this.fieldValuesCache.clear();\r\n this.entriesCache.clear();\r\n this.parametersCache.clear();\r\n }\r\n}\r\n","/**\r\n * Il pannello dei problemi — FRONTEND.md §7, §11.\r\n *\r\n * La validazione e' un servizio separato dal salvataggio, e questo e' deliberato: si\r\n * salva quando si vuole, i problemi si guardano a parte. Qui vive il debounce (300–500 ms\r\n * su pausa di digitazione, §11.4) e l'indicizzazione dei rilievi per `elementName` e\r\n * `path`, che e' cio' che permette di evidenziare l'elemento sul canvas e il campo\r\n * dentro l'inspector.\r\n *\r\n * `code` e' stabile e si usa per decidere il comportamento; `message` e' testo per\r\n * l'utente e non va interpretato (§7).\r\n */\r\n\r\nimport { DestroyRef, Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowValidationIssue, FlowValidationResult } from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\n\r\nconst DEBOUNCE_MS = 400;\r\n\r\n@Injectable()\r\nexport class FlowValidationStore {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n private readonly _result = signal<FlowValidationResult | null>(null);\r\n private readonly _isRunning = signal(false);\r\n private readonly _lastError = signal<string | null>(null);\r\n\r\n private timer?: ReturnType<typeof setTimeout>;\r\n /** Cresce a ogni richiesta: scarta le risposte di validazioni superate. */\r\n private sequence = 0;\r\n\r\n readonly result = this._result.asReadonly();\r\n readonly isRunning = this._isRunning.asReadonly();\r\n readonly lastError = this._lastError.asReadonly();\r\n\r\n readonly issues = computed<FlowValidationIssue[]>(() => this._result()?.issues ?? []);\r\n readonly errorCount = computed(() => this._result()?.errorCount ?? 0);\r\n readonly warningCount = computed(() => this._result()?.warningCount ?? 0);\r\n readonly infoCount = computed(\r\n () => this.issues().filter((issue) => issue.severity === 'Info').length,\r\n );\r\n\r\n /**\r\n * `false` finche' non e' arrivata una validazione: non presentare l'assenza di rilievi\r\n * come garanzia di correttezza (§7, ultimo capoverso).\r\n */\r\n readonly hasResult = computed(() => this._result() !== null);\r\n\r\n /** Zero errori: e' la condizione che l'attivazione esige (§8.3). */\r\n readonly canActivate = computed(() => this.hasResult() && this.errorCount() === 0);\r\n\r\n /** Rilievi raggruppati per elemento, per l'evidenziazione sul canvas. */\r\n readonly issuesByElement = computed<Map<string, FlowValidationIssue[]>>(() => {\r\n const map = new Map<string, FlowValidationIssue[]>();\r\n for (const issue of this.issues()) {\r\n const key = issue.elementName ?? '';\r\n const list = map.get(key) ?? [];\r\n list.push(issue);\r\n map.set(key, list);\r\n }\r\n return map;\r\n });\r\n\r\n /** I rilievi non ancorati a un elemento: riguardano il documento (§7, famiglia Definizione). */\r\n readonly documentIssues = computed(() => this.issuesByElement().get('') ?? []);\r\n\r\n constructor() {\r\n this.destroyRef.onDestroy(() => this.cancel());\r\n }\r\n\r\n /** La gravita' peggiore su un elemento, per decidere il colore del node sul canvas. */\r\n severityOf(elementName: string): 'Error' | 'Warning' | 'Info' | null {\r\n const issues = this.issuesByElement().get(elementName);\r\n if (!issues?.length) {\r\n return null;\r\n }\r\n if (issues.some((issue) => issue.severity === 'Error')) {\r\n return 'Error';\r\n }\r\n if (issues.some((issue) => issue.severity === 'Warning')) {\r\n return 'Warning';\r\n }\r\n return 'Info';\r\n }\r\n\r\n /**\r\n * I rilievi che riguardano un campo dentro un elemento.\r\n * `path` e' del tipo `rules[Approvato].connector.targetReference`: il confronto e' per\r\n * prefisso, così `rules[Approvato]` cattura anche i rilievi piu' profondi.\r\n */\r\n issuesAt(elementName: string | null, pathPrefix: string): FlowValidationIssue[] {\r\n const issues = this.issuesByElement().get(elementName ?? '') ?? [];\r\n return issues.filter((issue) => issue.path?.startsWith(pathPrefix));\r\n }\r\n\r\n /** Programma una validazione dopo la pausa di digitazione (§11.4). */\r\n schedule(definition: FlowDefinition): void {\r\n this.cancel();\r\n this.timer = setTimeout(() => {\r\n this.timer = undefined;\r\n void this.run(definition);\r\n }, DEBOUNCE_MS);\r\n }\r\n\r\n /** Valida subito, saltando il debounce: prima di attivare, o su richiesta esplicita. */\r\n async run(definition: FlowDefinition): Promise<FlowValidationResult | null> {\r\n const token = ++this.sequence;\r\n this._isRunning.set(true);\r\n this._lastError.set(null);\r\n try {\r\n const result = await this.api.validateDefinition(definition);\r\n if (token !== this.sequence) {\r\n // Una validazione piu' recente e' già partita: questa risposta e' superata.\r\n return null;\r\n }\r\n this._result.set(result);\r\n return result;\r\n } catch (error) {\r\n if (token !== this.sequence) {\r\n return null;\r\n }\r\n const message = FlowApiError.is(error) ? error.message : String(error);\r\n this._lastError.set(message);\r\n return null;\r\n } finally {\r\n if (token === this.sequence) {\r\n this._isRunning.set(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sostituisce il risultato con quello arrivato da un'altra primitiva: il salvataggio\r\n * restituisce `validation` (§6.2) e l'attivazione fallita lo porta nel payload\r\n * dell'errore (§8.3). In entrambi i casi e' il risultato piu' fresco che esista.\r\n */\r\n adopt(result: FlowValidationResult | undefined | null): void {\r\n if (!result) {\r\n return;\r\n }\r\n this.sequence += 1;\r\n this._result.set(result);\r\n this._isRunning.set(false);\r\n }\r\n\r\n clear(): void {\r\n this.cancel();\r\n this.sequence += 1;\r\n this._result.set(null);\r\n this._lastError.set(null);\r\n this._isRunning.set(false);\r\n }\r\n\r\n private cancel(): void {\r\n if (this.timer) {\r\n clearTimeout(this.timer);\r\n this.timer = undefined;\r\n }\r\n }\r\n}\r\n","/**\r\n * Auto-layout con dagre.\r\n *\r\n * Il modello conserva soltanto `locationX`/`locationY` (§3.5): non c'e' nessuna nozione di\r\n * layout automatico da persistere. Il comando \"riordina\" calcola un layout gerarchico e\r\n * **scrive le coordinate risultanti** nel documento, come chiede la specifica (\"se usi un\r\n * auto-layout, scrivi comunque valori coerenti\").\r\n *\r\n * L'ordine delle uscite conta: i rami di una Decision escono nell'ordine delle regole, e\r\n * il ramo di fault viene tenuto a destra, così la lettura del grafo rispecchia la\r\n * semantica invece dell'ordine di inserimento nel JSON.\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport dagre from 'dagre';\r\n\r\nimport { FlowEdge } from './flow-document.store';\r\nimport { START_NODE_NAME } from './element-outlets';\r\n\r\nexport interface FlowLayoutNodeInput {\r\n name: string;\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface FlowLayoutResult {\r\n positions: Map<string, { x: number; y: number }>;\r\n}\r\n\r\nexport type FlowLayoutDirection = 'TB' | 'LR';\r\n\r\nexport interface FlowLayoutOptions {\r\n direction?: FlowLayoutDirection;\r\n /** Distanza fra i livelli. */\r\n rankSeparation?: number;\r\n /** Distanza fra i node dello stesso livello. */\r\n nodeSeparation?: number;\r\n origin?: { x: number; y: number };\r\n}\r\n\r\n@Injectable()\r\nexport class FlowLayoutService {\r\n /**\r\n * Calcola le posizioni. Restituisce l'angolo in alto a sinistra di ogni node, perche'\r\n * e' cio' che `locationX`/`locationY` significano nel modello, mentre dagre ragiona in\r\n * centri.\r\n */\r\n layout(\r\n nodes: FlowLayoutNodeInput[],\r\n edges: FlowEdge[],\r\n options?: FlowLayoutOptions,\r\n ): FlowLayoutResult {\r\n const direction = options?.direction ?? 'TB';\r\n const origin = options?.origin ?? { x: 60, y: 60 };\r\n\r\n const graph = new dagre.graphlib.Graph({ multigraph: true, compound: false });\r\n graph.setGraph({\r\n rankdir: direction,\r\n ranksep: options?.rankSeparation ?? 90,\r\n nodesep: options?.nodeSeparation ?? 60,\r\n marginx: 0,\r\n marginy: 0,\r\n });\r\n graph.setDefaultEdgeLabel(() => ({}));\r\n\r\n const known = new Set<string>();\r\n for (const node of nodes) {\r\n graph.setNode(node.name, { width: node.width, height: node.height });\r\n known.add(node.name);\r\n }\r\n\r\n for (const edge of edges) {\r\n // Un ramo senza destinazione non vincola il layout.\r\n if (!edge.to || !known.has(edge.from) || !known.has(edge.to)) {\r\n continue;\r\n }\r\n // `isGoTo` marca gli archi di ritorno: includerli creerebbe un ciclo che dagre\r\n // spezzerebbe arbitrariamente, allungando il grafo. Il corpo di un Loop si richiude\r\n // sul Loop, quindi questo caso e' la norma, non l'eccezione (§5.4).\r\n if (edge.isGoTo) {\r\n continue;\r\n }\r\n graph.setEdge(edge.from, edge.to, { weight: FlowLayoutService.weightOf(edge) }, edge.id);\r\n }\r\n\r\n dagre.layout(graph);\r\n\r\n const positions = new Map<string, { x: number; y: number }>();\r\n let minX = Number.POSITIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n\r\n for (const node of nodes) {\r\n const laid = graph.node(node.name) as { x?: number; y?: number } | undefined;\r\n if (!laid || laid.x === undefined || laid.y === undefined) {\r\n continue;\r\n }\r\n const x = laid.x - node.width / 2;\r\n const y = laid.y - node.height / 2;\r\n positions.set(node.name, { x, y });\r\n minX = Math.min(minX, x);\r\n minY = Math.min(minY, y);\r\n }\r\n\r\n // Trasla in modo che il grafo cominci dall'origine scelta, con coordinate positive.\r\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\r\n const deltaX = origin.x - minX;\r\n const deltaY = origin.y - minY;\r\n for (const [name, position] of positions) {\r\n positions.set(name, {\r\n x: Math.round(position.x + deltaX),\r\n y: Math.round(position.y + deltaY),\r\n });\r\n }\r\n }\r\n\r\n return { positions };\r\n }\r\n\r\n /**\r\n * Peso dell'arco: piu' alto = piu' dritto. Il percorso principale resta in colonna,\r\n * i rami di errore e di timeout si spostano di lato.\r\n */\r\n private static weightOf(edge: FlowEdge): number {\r\n switch (edge.kind) {\r\n case 'Start':\r\n case 'Next':\r\n case 'LoopNext':\r\n return 10;\r\n case 'Rule':\r\n case 'WaitEvent':\r\n case 'LoopEnd':\r\n case 'Default':\r\n return 4;\r\n case 'Fault':\r\n case 'Timeout':\r\n case 'ScheduledPath':\r\n return 1;\r\n default:\r\n return 3;\r\n }\r\n }\r\n\r\n /** Lo Start apre sempre il grafo: utile per ordinare i node prima del layout. */\r\n static isStart(name: string): boolean {\r\n return name === START_NODE_NAME;\r\n }\r\n}\r\n","/**\r\n * La sessione di editing: quale flow, quale versione, cosa e' permesso farci.\r\n * FRONTEND.md §6.2, §8, §9, §11.\r\n *\r\n * Tre responsabilita' che stanno bene insieme perche' condividono lo stesso stato:\r\n * - il ciclo di vita: si modifica una bozza; su una versione non modificabile il comando\r\n * e' \"Nuova versione\", non \"Salva\" (§8.1);\r\n * - la concorrenza ottimistica: `updatedAt` conservato al caricamento e rimandato come\r\n * `expectedUpdatedAt` al salvataggio (§9);\r\n * - la distinzione fra \"salvato\" e \"sano\": il salvataggio riesce anche con errori, e\r\n * l'esito si legge in `validation` (§6.2).\r\n */\r\n\r\nimport { Injectable, computed, inject, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowSaveResult, FlowValidationResult, FlowVersionSummary } from '../model/api.model';\r\nimport { FlowDefinition } from '../model/flow.model';\r\nimport { FlowApiError } from '../model/error.model';\r\nimport { FlowDocumentStore, emptyFlowDefinition } from './flow-document.store';\r\nimport { FlowValidationStore } from './flow-validation.store';\r\n\r\n/** Cosa mostrare quando il salvataggio incontra una versione modificata da altri (§9). */\r\nexport interface FlowConflictState {\r\n message: string;\r\n conflictingAuthor?: string;\r\n}\r\n\r\n@Injectable()\r\nexport class FlowEditorSession {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly documentStore = inject(FlowDocumentStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n private readonly _flowName = signal<string | null>(null);\r\n private readonly _version = signal<number | null>(null);\r\n private readonly _versions = signal<FlowVersionSummary[]>([]);\r\n /** Conservato al caricamento, rimandato al salvataggio (§9.1, §9.2). */\r\n private readonly _expectedUpdatedAt = signal<string | undefined>(undefined);\r\n private readonly _isBusy = signal(false);\r\n private readonly _lastSaveResult = signal<FlowSaveResult | null>(null);\r\n private readonly _conflict = signal<FlowConflictState | null>(null);\r\n private readonly _author = signal<string | undefined>(undefined);\r\n\r\n readonly flowName = this._flowName.asReadonly();\r\n readonly version = this._version.asReadonly();\r\n readonly versions = this._versions.asReadonly();\r\n readonly isBusy = this._isBusy.asReadonly();\r\n readonly lastSaveResult = this._lastSaveResult.asReadonly();\r\n readonly conflict = this._conflict.asReadonly();\r\n readonly expectedUpdatedAt = this._expectedUpdatedAt.asReadonly();\r\n\r\n /** `true` finche' il flow non e' mai stato salvato: il comando e' \"Crea\", non \"Salva\". */\r\n readonly isNew = computed(() => this._version() === null);\r\n\r\n readonly currentVersionSummary = computed<FlowVersionSummary | undefined>(() => {\r\n const version = this._version();\r\n return version === null ? undefined : this._versions().find((entry) => entry.version === version);\r\n });\r\n\r\n /**\r\n * `isEditable` arriva dal backend e non va ricalcolato lato client (§6.1). Un flow nuovo,\r\n * non ancora salvato, e' modificabile per definizione.\r\n */\r\n readonly isEditable = computed(() => {\r\n if (this.isNew()) {\r\n return true;\r\n }\r\n return this.currentVersionSummary()?.isEditable ?? false;\r\n });\r\n\r\n /** Su una versione non modificabile il comando primario diventa \"Nuova versione\" (§8.1). */\r\n readonly primaryCommand = computed<'create' | 'save' | 'newVersion'>(() => {\r\n if (this.isNew()) {\r\n return 'create';\r\n }\r\n return this.isEditable() ? 'save' : 'newVersion';\r\n });\r\n\r\n readonly isActiveVersion = computed(() => this.currentVersionSummary()?.isActive ?? false);\r\n\r\n /** Attivare esige zero errori (§8.3): il comando resta disabilitato finche' ce ne sono. */\r\n readonly canActivate = computed(\r\n () => !this.isNew() && !this.isActiveVersion() && this.validation.canActivate(),\r\n );\r\n\r\n setAuthor(author: string | undefined): void {\r\n this._author.set(author);\r\n }\r\n\r\n /** Prepara un flow nuovo, non ancora salvato (§11, \"Creare un flow\"). */\r\n startNew(fullName: string, label: string, processType: string): void {\r\n this.documentStore.load(emptyFlowDefinition(fullName, label, processType));\r\n this._flowName.set(fullName || null);\r\n this._version.set(null);\r\n this._versions.set([]);\r\n this._expectedUpdatedAt.set(undefined);\r\n this._lastSaveResult.set(null);\r\n this._conflict.set(null);\r\n this.validation.clear();\r\n }\r\n\r\n /**\r\n * Carica una versione e conserva il suo `updatedAt` (§11, \"Modificare\", passo 1).\r\n * `version` assente → la versione attiva se c'e', altrimenti l'ultima.\r\n */\r\n async open(flowName: string, version?: number): Promise<void> {\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const [definition, versions] = await Promise.all([\r\n this.api.loadFlow(flowName, version),\r\n this.api.listVersions(flowName).catch(() => [] as FlowVersionSummary[]),\r\n ]);\r\n this.documentStore.load(definition);\r\n this._flowName.set(flowName);\r\n this._versions.set(versions);\r\n\r\n // La versione effettivamente caricata: il documento porta `status` ma non il numero,\r\n // quindi si deduce dal parametro o dall'elenco versioni.\r\n const resolved = version ?? FlowEditorSession.pickVersion(versions);\r\n this._version.set(resolved ?? null);\r\n this._expectedUpdatedAt.set(versions.find((entry) => entry.version === resolved)?.updatedAt);\r\n this._lastSaveResult.set(null);\r\n this.validation.clear();\r\n await this.validation.run(this.documentStore.document());\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /** Senza `version` il backend restituisce la versione attiva, altrimenti l'ultima (§6.1). */\r\n private static pickVersion(versions: FlowVersionSummary[]): number | undefined {\r\n const active = versions.find((entry) => entry.isActive);\r\n if (active) {\r\n return active.version;\r\n }\r\n return versions[0]?.version;\r\n }\r\n\r\n /** Ricarica l'elenco versioni: dopo un'attivazione la precedente e' `Obsolete` (§8.4). */\r\n async refreshVersions(): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n const versions = await this.api.listVersions(flowName);\r\n this._versions.set(versions);\r\n const current = this._version();\r\n if (current !== null) {\r\n this._expectedUpdatedAt.set(versions.find((entry) => entry.version === current)?.updatedAt);\r\n }\r\n }\r\n\r\n /**\r\n * Crea o salva, a seconda dello stato. Non lancia su definizione invalida: il\r\n * salvataggio riesce anche con errori e il chiamante legge `validation` (§8.2).\r\n *\r\n * Rilancia `VersionConflict` dopo aver popolato {@link conflict}, perche' la UI deve\r\n * offrire \"ricarica\" o \"salva come nuova versione\" (§9.3).\r\n */\r\n async save(options?: { activate?: boolean; flowName?: string }): Promise<FlowSaveResult> {\r\n const definition = this.documentStore.document();\r\n const targetName = options?.flowName ?? this._flowName() ?? definition.fullName ?? '';\r\n if (!targetName) {\r\n throw new FlowApiError('InvalidRequest', 'Il flow non ha un nome tecnico.');\r\n }\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const result = this.isNew()\r\n ? await this.api.createFlow({\r\n definition,\r\n flowName: targetName,\r\n author: this._author(),\r\n })\r\n : await this.api.saveFlow(this._flowName() as string, {\r\n definition,\r\n // Se indicato vince sul `fullName` del documento: e' così che si rinomina (§6.2).\r\n flowName: options?.flowName,\r\n // Mandare sempre la versione caricata rende prevedibile cosa viene toccato (§8).\r\n version: this._version() ?? undefined,\r\n expectedUpdatedAt: this._expectedUpdatedAt(),\r\n author: this._author(),\r\n activate: options?.activate,\r\n });\r\n this.applySaveResult(result);\r\n return result;\r\n } catch (error) {\r\n if (FlowApiError.is(error) && error.category === 'VersionConflict') {\r\n this._conflict.set({\r\n message: error.message,\r\n conflictingAuthor: error.conflictingAuthor,\r\n });\r\n }\r\n if (FlowApiError.is(error) && error.validation) {\r\n // `activate: true` fallisce senza scrivere nulla se ci sono errori (§6.2).\r\n this.validation.adopt(error.validation);\r\n }\r\n throw error;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n private applySaveResult(result: FlowSaveResult): void {\r\n this._flowName.set(result.flowName);\r\n this._version.set(result.version);\r\n // Da conservare per il salvataggio successivo (§6.2, ultimo capoverso).\r\n this._expectedUpdatedAt.set(result.updatedAt);\r\n this._lastSaveResult.set(result);\r\n // Riflette nel documento cio' che il backend ha deciso, senza sporcare lo storico:\r\n // `fullName` e `status` sono riempiti dal record di versione, non dall'editor (§2).\r\n this.documentStore.updateHeader((definition) => {\r\n definition.fullName = result.flowName;\r\n definition.status = result.status;\r\n }, { silent: true });\r\n this.documentStore.markSaved();\r\n this.validation.adopt(result.validation);\r\n void this.refreshVersions();\r\n }\r\n\r\n /** Copia la versione corrente in una nuova bozza (§8.1): il comando delle versioni chiuse. */\r\n async createNewVersion(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n throw new FlowApiError('InvalidRequest', 'Nessun flow aperto.');\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n const result = await this.api.createVersion(flowName, {\r\n from: this._version() ?? undefined,\r\n author: this._author(),\r\n });\r\n await this.open(flowName, result.version);\r\n return result;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Attiva la versione corrente (§11, \"Attivare\").\r\n * Valida prima in locale per un feedback immediato: se ci sono errori non chiama\r\n * l'attivazione, perche' fallirebbe comunque.\r\n */\r\n async activate(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n const version = this._version();\r\n if (!flowName || version === null) {\r\n throw new FlowApiError('InvalidRequest', 'Salva il flow prima di attivarlo.');\r\n }\r\n const local = await this.validation.run(this.documentStore.document());\r\n if (local && local.errorCount > 0) {\r\n throw new FlowApiError(\r\n 'ValidationFailed',\r\n 'La definizione contiene errori: correggili prima di attivare.',\r\n local,\r\n );\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n const result = await this.api.activateVersion(flowName, version);\r\n this.applySaveResult(result);\r\n return result;\r\n } catch (error) {\r\n // Qualcosa e' cambiato nel frattempo (per esempio un oggetto rinominato nello\r\n // schema): il payload porta l'elenco, che va aperto nel pannello (§11, passo 3).\r\n if (FlowApiError.is(error) && error.validation) {\r\n this.validation.adopt(error.validation);\r\n }\r\n throw error;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n async deactivate(): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n await this.api.deactivateFlow(flowName);\r\n await this.refreshVersions();\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Elimina una versione. Da mettere dietro una conferma esplicita: il numero della versione\r\n * piu' alta viene riassegnato dopo un'eliminazione, e un'esecuzione sospesa nata su quel\r\n * numero riprenderebbe su una definizione diversa (§8, ultimo capoverso).\r\n */\r\n async deleteVersion(version: number): Promise<void> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._isBusy.set(true);\r\n try {\r\n await this.api.deleteVersion(flowName, version);\r\n await this.refreshVersions();\r\n // Se e' stata eliminata la versione aperta, si riapre quella piu' recente.\r\n if (this._version() === version) {\r\n const next = this._versions()[0]?.version;\r\n if (next !== undefined) {\r\n await this.open(flowName, next);\r\n } else {\r\n this._version.set(null);\r\n }\r\n }\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n /** Risoluzione del conflitto, prima opzione: ricarica e perde le modifiche locali (§9.3). */\r\n async reloadAfterConflict(): Promise<void> {\r\n const flowName = this._flowName();\r\n const version = this._version();\r\n if (!flowName) {\r\n return;\r\n }\r\n this._conflict.set(null);\r\n await this.open(flowName, version ?? undefined);\r\n }\r\n\r\n /**\r\n * Risoluzione del conflitto, seconda opzione: salva come nuova versione, conservando\r\n * le modifiche locali (§9.3). Il salvataggio senza `expectedUpdatedAt` e senza `version`\r\n * lascia scegliere al backend, che crea una nuova versione se l'ultima non e' toccabile.\r\n */\r\n async saveAsNewVersionAfterConflict(): Promise<FlowSaveResult> {\r\n const flowName = this._flowName();\r\n if (!flowName) {\r\n throw new FlowApiError('InvalidRequest', 'Nessun flow aperto.');\r\n }\r\n this._isBusy.set(true);\r\n this._conflict.set(null);\r\n try {\r\n const created = await this.api.createVersion(flowName, { author: this._author() });\r\n const result = await this.api.saveFlow(flowName, {\r\n definition: this.documentStore.document(),\r\n version: created.version,\r\n expectedUpdatedAt: created.updatedAt,\r\n author: this._author(),\r\n });\r\n this.applySaveResult(result);\r\n return result;\r\n } finally {\r\n this._isBusy.set(false);\r\n }\r\n }\r\n\r\n dismissConflict(): void {\r\n this._conflict.set(null);\r\n }\r\n\r\n /** L'ultima validazione conosciuta, da qualunque primitiva arrivi. */\r\n get validationResult(): FlowValidationResult | null {\r\n return this.validation.result();\r\n }\r\n\r\n /** Il documento corrente, per chi deve mandarlo a una primitiva. */\r\n get definition(): FlowDefinition {\r\n return this.documentStore.document();\r\n }\r\n}\r\n","/**\r\n * Il view model del canvas.\r\n *\r\n * Gli id dei connettori sono stringhe costruite qui e in nessun altro posto: un mismatch\r\n * fra l'id dichiarato su un connettore e quello usato da una connessione fa sparire l'arco\r\n * **senza errori** — e' il fallimento silenzioso numero uno di @foblex/flow.\r\n */\r\n\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { FlowIssueSeverity } from '../../model/api.model';\r\nimport { FlowOutlet } from '../../core/element-outlets';\r\n\r\n/** Il connettore di ingresso di un node. Lo Start non ne ha. */\r\nexport function targetConnectorId(nodeName: string): string {\r\n return `in:${nodeName}`;\r\n}\r\n\r\n/** Il connettore di uscita di un node, uno per ramo (§3.5). */\r\nexport function sourceConnectorId(nodeName: string, outletKey: string): string {\r\n return `out:${nodeName}:${outletKey}`;\r\n}\r\n\r\n/** Inverso di {@link sourceConnectorId}. */\r\nexport function parseSourceConnectorId(id: string): { nodeName: string; outletKey: string } | null {\r\n if (!id.startsWith('out:')) {\r\n return null;\r\n }\r\n const rest = id.slice(4);\r\n const separator = rest.indexOf(':');\r\n if (separator < 0) {\r\n return null;\r\n }\r\n return { nodeName: rest.slice(0, separator), outletKey: rest.slice(separator + 1) };\r\n}\r\n\r\n/** Inverso di {@link targetConnectorId}. */\r\nexport function parseTargetConnectorId(id: string): string | null {\r\n return id.startsWith('in:') ? id.slice(3) : null;\r\n}\r\n\r\n/** L'id del node sul canvas: prefissato per non collidere con quello dei connettori. */\r\nexport function canvasNodeId(nodeName: string): string {\r\n return `node:${nodeName}`;\r\n}\r\n\r\nexport function parseCanvasNodeId(id: string): string | null {\r\n return id.startsWith('node:') ? id.slice(5) : null;\r\n}\r\n\r\nexport interface FlowCanvasNode {\r\n /** Nome nel documento; `$start` per lo Start, che nel modello non ha nome. */\r\n name: string;\r\n /** Id per il canvas. */\r\n id: string;\r\n /** `'Start'` oppure il discriminatore di `elementTypes`. */\r\n type: FlowElementType | 'Start';\r\n typeLabel: string;\r\n label: string;\r\n description?: string | null;\r\n position: { x: number; y: number };\r\n outlets: FlowOutlet[];\r\n isStart: boolean;\r\n /** Categoria del dizionario: decide il colore dell'icona del node. */\r\n category?: string | null;\r\n /** Glifo mostrato nel badge dell'icona: dipende dal tipo, non dalla categoria. */\r\n icon: string;\r\n /**\r\n * La classe che porta la larghezza del node. Non e' costante: le uscite stanno in fila sul\r\n * bordo inferiore, quindi un elemento con molti rami ha bisogno di piu' spazio perche' le\r\n * etichette restino leggibili. E' una classe e non uno stile inline perche' @foblex/flow\r\n * riscrive l'attributo `style` del node per posizionarlo.\r\n */\r\n widthClass: string;\r\n /**\r\n * Le etichette dei rami si mostrano solo quando i rami sono piu' di uno: su un `next`\r\n * unico l'etichetta direbbe soltanto «Successivo».\r\n */\r\n showsOutletLabels: boolean;\r\n /** `false` → nessun percorso lo raggiunge dallo Start: va reso \"scollegato\" (§6.4). */\r\n isReachable: boolean;\r\n /** La gravita' peggiore dei rilievi sull'elemento (§7). */\r\n severity: FlowIssueSeverity | null;\r\n /** Numero di rilievi, per il badge. */\r\n issueCount: number;\r\n /** L'elemento espone il proprio risultato sotto il proprio nome (§4.5). */\r\n hasAutomaticOutput: boolean;\r\n /** Sintesi di una riga mostrata sul node (l'oggetto letto, il form mostrato, …). */\r\n subtitle?: string | null;\r\n /** Rami dichiarati ma senza destinazione: mostrati come tali, non come archi (§6.4). */\r\n danglingOutlets: FlowOutlet[];\r\n}\r\n\r\nexport interface FlowCanvasEdge {\r\n id: string;\r\n sourceId: string;\r\n targetId: string;\r\n kind: string;\r\n label?: string | null;\r\n isGoTo: boolean;\r\n}\r\n","/**\r\n * Il canvas del grafo.\r\n *\r\n * Il documento e' la fonte di verita': node, archi e raggiungibilita' sono signal derivati\r\n * da {@link FlowDocumentStore}, e ogni gesto dell'utente diventa una mutazione del\r\n * documento. @foblex/flow e' usato in \"classic mode\": la libreria disegna e riconosce i\r\n * gesti, lo stato resta nostro.\r\n *\r\n * Scelta di progetto sulla raggiungibilita': gli archi e la reachability sono calcolati\r\n * **in locale** per il disegno, così trascinare un arco si riflette subito; `isReachable`\r\n * di `POST /flows/outline` (§6.4) resta la fonte autoritativa e, quando arriva, sovrascrive\r\n * il calcolo locale. Chiedere l'outline a ogni movimento del mouse renderebbe il canvas\r\n * dipendente dalla latenza.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\r\nimport { EFConnectableSide, EFMarkerType, FFlowModule } from '@foblex/flow';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { START_NODE_NAME, outletsOf } from '../../core/element-outlets';\r\nimport { elementIcon } from '../../core/element-icons';\r\nimport { variantOf } from '../../core/element-variants';\r\nimport { FlowAnyNode, FlowElementType } from '../../model/flow.model';\r\nimport { FlowOutline } from '../../model/api.model';\r\nimport {\r\n FlowCanvasEdge,\r\n FlowCanvasNode,\r\n canvasNodeId,\r\n parseCanvasNodeId,\r\n parseSourceConnectorId,\r\n parseTargetConnectorId,\r\n sourceConnectorId,\r\n targetConnectorId,\r\n} from './flow-canvas.model';\r\n\r\n/**\r\n * Dimensioni nominali di un node, usate dal layout automatico.\r\n *\r\n * Le uscite stanno in fila sul bordo **inferiore**: e' la larghezza a dipendere dal numero\r\n * di rami, non l'altezza. L'altezza resta quella della card (intestazione, riga del nome\r\n * tecnico e badge, striscia delle uscite) e non cambia con i rami.\r\n */\r\nexport const FLOW_NODE_WIDTH = 240;\r\nexport const FLOW_NODE_HEIGHT = 116;\r\n\r\n/**\r\n * La larghezza del node per numero di rami: le uscite stanno in fila sul bordo inferiore,\r\n * quindi una Decision con quattro regole ha bisogno di piu' spazio di un Assignment.\r\n *\r\n * E' una tabella a scaglioni, non una formula, perche' la larghezza si applica con una\r\n * **classe** e non con uno stile inline: @foblex/flow riscrive l'attributo `style` del node\r\n * per posizionarlo, e qualunque `[style.width]` di Angular verrebbe cancellato al primo\r\n * spostamento. I valori qui e quelli delle classi `.fb-node--outlets-N` nel CSS devono\r\n * restare uguali: la stessa misura serve a disegnare il node e a stimarlo per dagre.\r\n */\r\nconst OUTLET_WIDTHS = [240, 240, 240, 304, 380, 456, 520];\r\n\r\n/** Oltre questo numero di rami il node non cresce piu': le etichette si troncano. */\r\nconst MAX_OUTLET_BUCKET = OUTLET_WIDTHS.length - 1;\r\n\r\nfunction outletBucket(outletCount: number): number {\r\n return Math.min(Math.max(outletCount, 0), MAX_OUTLET_BUCKET);\r\n}\r\n\r\nexport function flowNodeWidth(outletCount: number): number {\r\n return OUTLET_WIDTHS[outletBucket(outletCount)];\r\n}\r\n\r\n/** La classe che porta quella larghezza: unico modo di sopravvivere ai riposizionamenti. */\r\nexport function flowNodeWidthClass(outletCount: number): string {\r\n return `fb-node--outlets-${outletBucket(outletCount)}`;\r\n}\r\n\r\n\r\n@Component({\r\n selector: 'fb-flow-canvas',\r\n standalone: true,\r\n imports: [FFlowModule],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './flow-canvas.component.html',\r\n styleUrl: './flow-canvas.component.css',\r\n})\r\nexport class FlowCanvasComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /**\r\n * Marker di fine arco: la variante \"all states\" crea sia quello normale sia quello\r\n * selezionato, evitando che l'arco selezionato perda la punta.\r\n */\r\n readonly markerEnd = EFMarkerType.END_ALL_STATES;\r\n\r\n /**\r\n * I lati da cui gli archi partono e arrivano: uscite in basso, ingresso in alto.\r\n * Dichiararli e' quello che rende il grafo leggibile dall'alto verso il basso; lasciando\r\n * fare a foblex, il lato viene calcolato dalla posizione relativa e un ramo che risale\r\n * uscirebbe di fianco.\r\n */\r\n readonly sides = EFConnectableSide;\r\n\r\n /** Il nome dell'elemento selezionato, `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n /**\r\n * L'outline del backend, quando disponibile: da' la raggiungibilita' autoritativa (§6.4).\r\n * Assente → si usa il calcolo locale.\r\n */\r\n readonly outline = input<FlowOutline | null>(null);\r\n\r\n readonly selectionChange = output<string | null>();\r\n readonly nodeOpened = output<string>();\r\n readonly nodeRemoveRequested = output<string>();\r\n readonly nodeDuplicateRequested = output<string>();\r\n /** Rilascio di un elemento dalla palette: tipo + punto nel sistema del canvas. */\r\n readonly elementDropped = output<{\r\n type: FlowElementType;\r\n /** La variante scelta sulla palette, dove il tipo ne ha (§5.5). */\r\n variant?: string;\r\n x: number;\r\n y: number;\r\n }>();\r\n\r\n /** Raggiungibilita': backend se c'e', locale altrimenti. */\r\n private readonly reachability = computed<ReadonlySet<string>>(() => {\r\n const outline = this.outline();\r\n if (outline?.nodes?.length) {\r\n const unreachable = new Set(\r\n outline.nodes.filter((node) => node.isReachable === false).map((node) => node.name),\r\n );\r\n const names = new Set(this.store.nodes().map((reference) => reference.name));\r\n for (const name of unreachable) {\r\n names.delete(name);\r\n }\r\n return names;\r\n }\r\n return this.store.reachableNames();\r\n });\r\n\r\n readonly nodes = computed<FlowCanvasNode[]>(() => {\r\n const result: FlowCanvasNode[] = [];\r\n const reachable = this.reachability();\r\n\r\n const start = this.store.start() as FlowAnyNode;\r\n result.push(\r\n this.toCanvasNode({\r\n name: START_NODE_NAME,\r\n type: 'Start',\r\n node: start,\r\n label: 'Start',\r\n typeLabel: 'Avvio',\r\n category: 'Avvio',\r\n isStart: true,\r\n // Lo Start e' raggiungibile per definizione: e' il punto di ingresso.\r\n isReachable: true,\r\n subtitle: this.startSubtitle(),\r\n }),\r\n );\r\n\r\n for (const reference of this.store.nodes()) {\r\n result.push(\r\n this.toCanvasNode({\r\n name: reference.name,\r\n type: reference.type,\r\n node: reference.node,\r\n label: reference.node.label || reference.name,\r\n typeLabel: this.dictionaries.labelOf(reference.type),\r\n category: this.dictionaries.elementType(reference.type)?.category ?? null,\r\n isStart: false,\r\n isReachable: reachable.has(reference.name),\r\n subtitle: this.subtitleOf(reference.type, reference.node),\r\n }),\r\n );\r\n }\r\n return result;\r\n });\r\n\r\n private toCanvasNode(input: {\r\n name: string;\r\n type: FlowElementType | 'Start';\r\n node: FlowAnyNode;\r\n label: string;\r\n typeLabel: string;\r\n category: string | null;\r\n isStart: boolean;\r\n isReachable: boolean;\r\n subtitle: string | null;\r\n }): FlowCanvasNode {\r\n const outlets = outletsOf(input.type, input.node);\r\n const issues = this.validation.issuesByElement().get(input.isStart ? '' : input.name) ?? [];\r\n return {\r\n // La variante decide il glifo come sulla palette: un node «filtra» non deve comparire\r\n // con il simbolo di «ordina» dopo il rilascio (§5.5).\r\n icon: elementIcon(input.type, input.typeLabel, variantOf(input.type, input.node)),\r\n widthClass: flowNodeWidthClass(outlets.length),\r\n showsOutletLabels: outlets.length > 1,\r\n name: input.name,\r\n id: canvasNodeId(input.name),\r\n type: input.type,\r\n typeLabel: input.typeLabel,\r\n label: input.label,\r\n description: (input.node.description as string | undefined) ?? null,\r\n position: { x: input.node.locationX ?? 0, y: input.node.locationY ?? 0 },\r\n outlets,\r\n isStart: input.isStart,\r\n category: input.category,\r\n isReachable: input.isReachable,\r\n severity: input.isStart ? null : this.validation.severityOf(input.name),\r\n issueCount: input.isStart ? 0 : issues.length,\r\n hasAutomaticOutput: !input.isStart && this.dictionaries.hasAutomaticOutput(input.type as string),\r\n subtitle: input.subtitle,\r\n // Un ramo dichiarato senza destinazione non e' un arco: si mostra sul node, perche'\r\n // un arco che non arriva da nessuna parte non e' disegnabile (§6.4, `to: null`).\r\n danglingOutlets: outlets.filter((outlet) => {\r\n const connector = outlet.read(input.node);\r\n return !!connector && !connector.targetReference;\r\n }),\r\n };\r\n }\r\n\r\n /** Gli archi con destinazione: solo questi diventano `<f-connection>`. */\r\n readonly edges = computed<FlowCanvasEdge[]>(() => {\r\n const known = new Set(this.nodes().map((node) => node.name));\r\n return this.store\r\n .edges()\r\n .filter((edge) => !!edge.to && known.has(edge.to))\r\n .map((edge) => ({\r\n id: edge.id,\r\n sourceId: sourceConnectorId(edge.from, edge.outletKey),\r\n targetId: targetConnectorId(edge.to as string),\r\n kind: edge.kind,\r\n label: edge.label,\r\n isGoTo: !!edge.isGoTo,\r\n }));\r\n });\r\n\r\n /** Sintesi mostrata sul node: la cosa che serve sapere senza aprire l'inspector. */\r\n private subtitleOf(type: FlowElementType, node: FlowAnyNode): string | null {\r\n switch (type) {\r\n case 'Screen':\r\n return (node['formName'] as string) || null;\r\n case 'RecordLookup':\r\n case 'RecordCreate':\r\n case 'RecordUpdate':\r\n case 'RecordDelete':\r\n return (node['object'] as string) || (node['inputReference'] as string) || null;\r\n case 'Loop':\r\n return (node['collectionReference'] as string) || null;\r\n case 'CollectionProcessor': {\r\n const kind = node['collectionProcessorType'] as string | undefined;\r\n const collection = node['collectionReference'] as string | undefined;\r\n return [kind, collection].filter(Boolean).join(' · ') || null;\r\n }\r\n case 'Decision': {\r\n const rules = (node['rules'] as unknown[] | undefined)?.length ?? 0;\r\n return rules ? `${rules} ${rules === 1 ? 'regola' : 'regole'}` : null;\r\n }\r\n case 'Assignment': {\r\n const items = (node['assignmentItems'] as unknown[] | undefined)?.length ?? 0;\r\n return items ? `${items} ${items === 1 ? 'operazione' : 'operazioni'}` : null;\r\n }\r\n case 'ActionCall': {\r\n const actionType = node['actionType'] as string | undefined;\r\n const actionName = node['actionName'] as string | undefined;\r\n return [actionType, actionName].filter(Boolean).join(' · ') || null;\r\n }\r\n case 'ScriptCall':\r\n return (node['scriptName'] as string) || null;\r\n case 'Subflow':\r\n return (node['flowName'] as string) || null;\r\n case 'Wait': {\r\n const events = (node['waitEvents'] as unknown[] | undefined)?.length ?? 0;\r\n return events ? `${events} ${events === 1 ? 'evento' : 'eventi'}` : null;\r\n }\r\n case 'Transform':\r\n return (node['objectType'] as string) || null;\r\n case 'OrchestratedStage': {\r\n // Gli step non sono una sequenza: si conta quanti sono, non fino a dove si e' arrivati.\r\n const steps = (node['stageSteps'] as unknown[] | undefined)?.length ?? 0;\r\n return steps ? `${steps} step` : null;\r\n }\r\n case 'CustomError': {\r\n const messages = (node['customErrorMessages'] as unknown[] | undefined)?.length ?? 0;\r\n return messages ? `${messages} ${messages === 1 ? 'messaggio' : 'messaggi'}` : null;\r\n }\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n /** Sullo Start conta il trigger: e' cio' che decide quando il flow parte (§3.4). */\r\n private startSubtitle(): string | null {\r\n const start = this.store.start();\r\n const triggerType = start.triggerType ?? 'None';\r\n const label = FlowDictionaryStore.labelIn(this.dictionaries.triggerTypes(), triggerType);\r\n if (triggerType === 'None') {\r\n return label || 'Su richiesta';\r\n }\r\n return [label, start.object].filter(Boolean).join(' · ');\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Gesti\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Creazione di un arco. `targetId` assente significa rilascio nel vuoto: si lascia il\r\n * ramo dichiarato ma senza destinazione, che e' esattamente il \"ramo incompleto\" del\r\n * modello, invece di scartare il gesto.\r\n */\r\n onCreateConnection(event: { sourceId: string; targetId?: string }): void {\r\n const source = parseSourceConnectorId(event.sourceId);\r\n if (!source) {\r\n return;\r\n }\r\n const target = event.targetId ? parseTargetConnectorId(event.targetId) : null;\r\n if (target === source.nodeName) {\r\n // `CONNECTOR_SELF_LOOP`: un node che punta a se stesso non e' mai voluto.\r\n return;\r\n }\r\n this.store.setConnector(source.nodeName, source.outletKey, target ?? undefined);\r\n }\r\n\r\n /** Riassegnazione di un arco già disegnato, da un capo o dall'altro. */\r\n onReassignConnection(event: {\r\n endpoint: string;\r\n previousSourceId: string;\r\n nextSourceId?: string;\r\n previousTargetId: string;\r\n nextTargetId?: string;\r\n }): void {\r\n const previousSource = parseSourceConnectorId(event.previousSourceId);\r\n if (!previousSource) {\r\n return;\r\n }\r\n if (event.endpoint === 'target') {\r\n const nextTarget = event.nextTargetId ? parseTargetConnectorId(event.nextTargetId) : null;\r\n this.store.setConnector(previousSource.nodeName, previousSource.outletKey, nextTarget ?? undefined);\r\n return;\r\n }\r\n // Capo sorgente spostato: l'arco cambia uscita, la destinazione resta.\r\n const nextSource = event.nextSourceId ? parseSourceConnectorId(event.nextSourceId) : null;\r\n const target = parseTargetConnectorId(event.previousTargetId);\r\n if (!nextSource || !target) {\r\n return;\r\n }\r\n this.store.removeConnector(previousSource.nodeName, previousSource.outletKey);\r\n this.store.setConnector(nextSource.nodeName, nextSource.outletKey, target);\r\n }\r\n\r\n /**\r\n * Spostamento dei node. Un solo passo di storico per l'intero gesto: le posizioni\r\n * intermedie non sono modifiche che l'utente vuole annullare una per una.\r\n */\r\n onMoveNodes(event: { nodes: Array<{ id: string; position: { x: number; y: number } }> }): void {\r\n const moves = event.nodes\r\n .map((moved) => ({ name: parseCanvasNodeId(moved.id), position: moved.position }))\r\n .filter((moved): moved is { name: string; position: { x: number; y: number } } => !!moved.name);\r\n if (!moves.length) {\r\n return;\r\n }\r\n moves.forEach((moved, index) => {\r\n this.store.moveNode(moved.name, moved.position.x, moved.position.y, { silent: index > 0 });\r\n });\r\n }\r\n\r\n onSelectionChange(event: { nodeIds: string[] }): void {\r\n const first = event.nodeIds[0];\r\n this.selectionChange.emit(first ? parseCanvasNodeId(first) : null);\r\n }\r\n\r\n /** `Delete` sulla selezione: lo Start non e' cancellabile, e' uno per flow (§3.4). */\r\n onDeleteSelected(event: { nodeIds: string[] }): void {\r\n for (const id of event.nodeIds) {\r\n const name = parseCanvasNodeId(id);\r\n if (name && name !== START_NODE_NAME) {\r\n this.nodeRemoveRequested.emit(name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Rilascio di un elemento trascinato dalla palette. Il dato e' `{type, variant}`, ma si\r\n * accetta ancora la stringa nuda: un ospite che monta il canvas con una palette propria\r\n * potrebbe passare il solo tipo.\r\n */\r\n onCreateNode(event: { data: unknown; externalItemRect: { x: number; y: number } }): void {\r\n const data = event.data as { type?: string; variant?: string } | string | undefined;\r\n const type = typeof data === 'string' ? data : data?.type;\r\n if (!type) {\r\n return;\r\n }\r\n this.elementDropped.emit({\r\n type,\r\n variant: typeof data === 'string' ? undefined : data?.variant,\r\n x: Math.round(event.externalItemRect.x),\r\n y: Math.round(event.externalItemRect.y),\r\n });\r\n }\r\n\r\n onNodeDoubleClick(name: string): void {\r\n this.nodeOpened.emit(name);\r\n }\r\n\r\n /**\r\n * Il bottone «✎» sul node: apre il dettaglio senza aspettare il doppio click, che e' un\r\n * gesto che non si vede. `stopPropagation` evita che il click valga anche come selezione\r\n * dell'area sottostante.\r\n */\r\n onEditClick(event: Event, name: string): void {\r\n event.stopPropagation();\r\n this.nodeOpened.emit(name);\r\n }\r\n\r\n connectorIdOf(node: FlowCanvasNode, outletKey: string): string {\r\n return sourceConnectorId(node.name, outletKey);\r\n }\r\n\r\n targetIdOf(node: FlowCanvasNode): string {\r\n return targetConnectorId(node.name);\r\n }\r\n\r\n isSelected(node: FlowCanvasNode): boolean {\r\n return this.selectedName() === node.name;\r\n }\r\n\r\n /** Etichette dei rami dichiarati senza destinazione, per il tooltip del badge. */\r\n danglingLabels(node: FlowCanvasNode): string {\r\n return node.danglingOutlets.map((outlet) => outlet.label).join(', ');\r\n }\r\n\r\n /** Classe della fascia colorata, per categoria del dizionario. */\r\n categoryClass(node: FlowCanvasNode): string {\r\n const category = (node.category ?? '').toLowerCase();\r\n if (node.isStart) {\r\n return 'cat-start';\r\n }\r\n if (category.startsWith('inter')) {\r\n return 'cat-screen';\r\n }\r\n if (category.startsWith('log')) {\r\n return 'cat-logic';\r\n }\r\n if (category.startsWith('dat')) {\r\n return 'cat-data';\r\n }\r\n if (category.startsWith('az')) {\r\n return 'cat-action';\r\n }\r\n if (category.startsWith('flow')) {\r\n return 'cat-flow';\r\n }\r\n return 'cat-other';\r\n }\r\n}\r\n","<!--\r\n Gerarchia obbligatoria: f-flow > f-canvas > fNode / f-connection.\r\n I `@for` sono direttamente dentro <f-canvas>: nessun wrapper, quindi non serve\r\n `ngProjectAs` (che sarebbe indispensabile con blocchi annidati).\r\n-->\r\n<f-flow\r\n fDraggable\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n (fReassignConnection)=\"onReassignConnection($event)\"\r\n (fMoveNodes)=\"onMoveNodes($event)\"\r\n (fSelectionChange)=\"onSelectionChange($event)\"\r\n (fDeleteSelected)=\"onDeleteSelected($event)\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n>\r\n <f-canvas fZoom>\r\n <f-background>\r\n <f-circle-pattern />\r\n </f-background>\r\n\r\n @for (edge of edges(); track edge.id) {\r\n <f-connection\r\n [fConnectionId]=\"edge.id\"\r\n [fSourceId]=\"edge.sourceId\"\r\n [fTargetId]=\"edge.targetId\"\r\n fBehavior=\"floating\"\r\n [fType]=\"edge.isGoTo ? 'segment' : 'bezier'\"\r\n [class]=\"'fb-edge fb-edge--' + edge.kind + (edge.isGoTo ? ' fb-edge--goto' : '')\"\r\n >\r\n <f-connection-marker-arrow [type]=\"markerEnd\" />\r\n @if (edge.label) {\r\n <div fConnectionContent class=\"fb-edge-label\">{{ edge.label }}</div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n @for (node of nodes(); track node.id) {\r\n <div\r\n fNode\r\n fDragHandle\r\n [fNodeId]=\"node.id\"\r\n [fNodePosition]=\"node.position\"\r\n [class]=\"'fb-node ' + categoryClass(node) + ' ' + node.widthClass\"\r\n [class.fb-node--start]=\"node.isStart\"\r\n [class.fb-node--selected]=\"isSelected(node)\"\r\n [class.fb-node--unreachable]=\"!node.isReachable\"\r\n [class.fb-node--error]=\"node.severity === 'Error'\"\r\n [class.fb-node--warning]=\"node.severity === 'Warning'\"\r\n (dblclick)=\"onNodeDoubleClick(node.name)\"\r\n >\r\n <!--\r\n Lo Start non ha ingresso: e' il punto di partenza (§3.4).\r\n `fConnectorConnectableSide` e' cio' che fa entrare l'arco dall'alto: senza, foblex\r\n calcola il lato e un arco che scende dal node sopra potrebbe agganciarsi di fianco.\r\n -->\r\n @if (!node.isStart) {\r\n <div\r\n fConnector\r\n fConnectorType=\"target\"\r\n [fConnectorId]=\"targetIdOf(node)\"\r\n [fConnectorConnectableSide]=\"sides.TOP\"\r\n fConnectorMultiple=\"true\"\r\n class=\"fb-connector fb-connector--in\"\r\n title=\"Ingresso\"\r\n ></div>\r\n }\r\n\r\n <div class=\"fb-node__head\">\r\n <span class=\"fb-node__icon\" aria-hidden=\"true\">{{ node.icon }}</span>\r\n <div class=\"fb-node__text\">\r\n <span class=\"fb-node__title\" [title]=\"node.description || node.label\">{{ node.label }}</span>\r\n <span class=\"fb-node__sub\">\r\n {{ node.typeLabel }}\r\n @if (node.subtitle) {\r\n <span class=\"fb-node__sub-dot\">·</span>{{ node.subtitle }}\r\n }\r\n </span>\r\n </div>\r\n @if (node.hasAutomaticOutput) {\r\n <!-- L'elemento espone il proprio risultato sotto il proprio nome (§4.5). -->\r\n <span class=\"fb-node__auto\" title=\"Espone un output automatico referenziabile come «{{ node.name }}»\">\r\n ƒ\r\n </span>\r\n }\r\n <!--\r\n `fDragBlocker` impedisce che il pointerdown sul bottone diventi un trascinamento\r\n del node: senza, aprire il dettaglio sposterebbe l'elemento di qualche pixel.\r\n -->\r\n <button\r\n type=\"button\"\r\n fDragBlocker\r\n class=\"fb-node__edit\"\r\n [attr.aria-label]=\"'Apri il dettaglio di ' + node.label\"\r\n title=\"Apri il dettaglio\"\r\n (click)=\"onEditClick($event, node.name)\"\r\n >\r\n ✎\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-node__meta\">\r\n @if (!node.isStart) {\r\n <span class=\"fb-node__name\" [title]=\"'Nome tecnico: ' + node.name\">{{ node.name }}</span>\r\n }\r\n @if (!node.isReachable) {\r\n <span class=\"fb-badge fb-badge--unreachable\" title=\"Nessun percorso raggiunge questo elemento dallo Start\">\r\n scollegato\r\n </span>\r\n }\r\n @if (node.issueCount > 0) {\r\n <span\r\n class=\"fb-badge\"\r\n [class.fb-badge--error]=\"node.severity === 'Error'\"\r\n [class.fb-badge--warning]=\"node.severity === 'Warning'\"\r\n [class.fb-badge--info]=\"node.severity === 'Info'\"\r\n [title]=\"node.issueCount + ' rilievi di validazione'\"\r\n >\r\n {{ node.issueCount }}\r\n </span>\r\n }\r\n @if (node.danglingOutlets.length > 0) {\r\n <span\r\n class=\"fb-badge fb-badge--dangling\"\r\n [title]=\"'Rami dichiarati senza destinazione: ' + danglingLabels(node)\"\r\n >\r\n ramo incompleto\r\n </span>\r\n }\r\n </div>\r\n\r\n <!--\r\n Le uscite stanno sul bordo **inferiore**, una per ramo, nell'ordine in cui il modello\r\n le dichiara: per una Decision e' l'ordine di valutazione delle regole, che e'\r\n semantico (§5.3), e da sinistra a destra si legge come la lista nell'inspector.\r\n L'etichetta si mostra solo quando i rami sono piu' di uno: su un `next` unico\r\n direbbe soltanto «Successivo».\r\n -->\r\n <div class=\"fb-node__outlets\" [class.fb-node__outlets--labelled]=\"node.showsOutletLabels\">\r\n @for (outlet of node.outlets; track outlet.key) {\r\n <div class=\"fb-outlet\">\r\n @if (node.showsOutletLabels) {\r\n <span class=\"fb-outlet__label\" [title]=\"outlet.label\">{{ outlet.label }}</span>\r\n }\r\n <div\r\n fConnector\r\n fConnectorType=\"source\"\r\n [fConnectorId]=\"connectorIdOf(node, outlet.key)\"\r\n [fConnectorConnectableSide]=\"sides.BOTTOM\"\r\n [class]=\"'fb-connector fb-connector--out fb-connector--' + outlet.kind\"\r\n [title]=\"outlet.label\"\r\n ></div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Anteprima dell'arco durante il trascinamento. -->\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"bezier\" class=\"fb-edge fb-edge--creating\">\r\n <f-connection-marker-arrow [type]=\"markerEnd\" />\r\n </f-connection-for-create>\r\n\r\n <f-selection-area />\r\n </f-canvas>\r\n\r\n <f-minimap [fMinSize]=\"1200\" class=\"fb-minimap\" />\r\n</f-flow>\r\n","/**\r\n * La palette degli elementi — FRONTEND.md §3.2, §11 (\"Aggiungere un elemento\").\r\n *\r\n * L'elenco arriva dal dizionario `elementTypes`: nessun tipo e' cablato qui. I tipi con\r\n * `isSupported: false` sono nascosti, perche' il motore li rifiuta e la validazione li\r\n * segnala come `ELEMENT_NOT_SUPPORTED`: lasciarli disegnare produce un flow che non parte.\r\n *\r\n * Ogni voce e' un `fExternalItem`: si trascina sul canvas e il punto di rilascio diventa\r\n * `locationX`/`locationY`. Il click aggiunge l'elemento al centro della vista.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output, signal } from '@angular/core';\r\nimport { FFlowModule } from '@foblex/flow';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { elementIcon } from '../../core/element-icons';\r\nimport { outletsOf } from '../../core/element-outlets';\r\nimport { FlowElementTypeEntry } from '../../model/dictionary.model';\r\nimport { FlowElementType } from '../../model/flow.model';\r\n\r\n/** Il gesto scelto sulla palette: un tipo e, dove esiste, la sua variante (§5.5). */\r\nexport interface FlowPalettePick {\r\n type: FlowElementType;\r\n variant?: string;\r\n}\r\n\r\n/**\r\n * Una voce della palette. Non coincide con una voce del dizionario: un tipo con varianti ne\r\n * produce una per variante, perche' «ordina» e «filtra» sono due gesti diversi anche se il\r\n * modello li scrive nello stesso node.\r\n */\r\nexport interface PaletteItem {\r\n /** Chiave stabile della voce: serve al `track` e all'id del trascinamento. */\r\n key: string;\r\n entry: FlowElementTypeEntry;\r\n variant?: string;\r\n label: string;\r\n data: FlowPalettePick;\r\n}\r\n\r\nexport interface PaletteGroup {\r\n category: string;\r\n items: PaletteItem[];\r\n}\r\n\r\n@Component({\r\n selector: 'fb-element-palette',\r\n standalone: true,\r\n imports: [FFlowModule],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-palette.component.html',\r\n styleUrl: './element-palette.component.css',\r\n})\r\nexport class ElementPaletteComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n /**\r\n * Il `processType` del flow: un flow `AutoLaunched` che contiene screen e' un errore di\r\n * validazione, perche' non c'e' nessuno a cui mostrarli (§3.1). La palette lo segnala\r\n * prima che l'utente lo scopra dal pannello dei problemi.\r\n */\r\n readonly processType = input<string | undefined>(undefined);\r\n\r\n readonly elementPicked = output<FlowPalettePick>();\r\n\r\n private readonly filter = signal('');\r\n\r\n /** Le voci, con i tipi a varianti già divisi: e' l'elenco che l'utente vede. */\r\n private readonly items = computed<PaletteItem[]>(() => {\r\n const items: PaletteItem[] = [];\r\n for (const entry of this.dictionaries.paletteTypes()) {\r\n const variants = this.dictionaries.variantsOf(entry.value);\r\n if (variants.length === 0) {\r\n items.push({\r\n key: entry.value,\r\n entry,\r\n label: entry.label,\r\n data: { type: entry.value },\r\n });\r\n continue;\r\n }\r\n for (const variant of variants) {\r\n items.push({\r\n key: `${entry.value}:${variant.value}`,\r\n entry,\r\n variant: variant.value,\r\n // L'etichetta e' quella del dizionario: le parole sono dell'ospite, non nostre.\r\n label: variant.label || variant.value,\r\n data: { type: entry.value, variant: variant.value },\r\n });\r\n }\r\n }\r\n return items;\r\n });\r\n\r\n readonly groups = computed<PaletteGroup[]>(() => {\r\n const needle = this.filter().trim().toLowerCase();\r\n const groups: PaletteGroup[] = [];\r\n for (const item of this.items()) {\r\n // La ricerca guarda anche l'etichetta del tipo: cercando «ordina o filtra» si trovano\r\n // entrambe le voci, che e' come l'elemento e' chiamato nel dizionario.\r\n const haystack = `${item.label} ${item.entry.label} ${item.entry.value} ${item.variant ?? ''}`;\r\n if (needle && !haystack.toLowerCase().includes(needle)) {\r\n continue;\r\n }\r\n const category = item.entry.category ?? 'Altro';\r\n let group = groups.find((candidate) => candidate.category === category);\r\n if (!group) {\r\n group = { category, items: [] };\r\n groups.push(group);\r\n }\r\n group.items.push(item);\r\n }\r\n return groups;\r\n });\r\n\r\n readonly isEmpty = computed(() => this.dictionaries.paletteTypes().length === 0);\r\n\r\n onFilter(value: string): void {\r\n this.filter.set(value);\r\n }\r\n\r\n pick(item: PaletteItem): void {\r\n this.elementPicked.emit(item.data);\r\n }\r\n\r\n /** Uno screen in un flow che non mostra nulla: si segnala, non si nasconde (§3.1). */\r\n isIncompatible(item: PaletteItem): boolean {\r\n return item.entry.value === 'Screen' && this.processType() === 'AutoLaunched';\r\n }\r\n\r\n /**\r\n * Il testo del tooltip. Su una voce che nasce da una variante ci va anche il nome del tipo:\r\n * e' l'unico posto in cui si vede che «ordina» e «filtra» sono lo stesso elemento.\r\n */\r\n hintOf(item: PaletteItem): string {\r\n if (this.isIncompatible(item)) {\r\n return 'In un flow AutoLaunched non c’e’ nessuno a cui mostrare uno screen: sarebbe un errore di validazione.';\r\n }\r\n const description = item.entry.description || null;\r\n if (item.variant) {\r\n return description ? `${item.entry.label} · ${description}` : item.entry.label;\r\n }\r\n return description ?? item.label;\r\n }\r\n\r\n /** Lo stesso glifo che l'elemento avra' sul canvas, così il trascinamento e' prevedibile. */\r\n iconOf(item: PaletteItem): string {\r\n return elementIcon(item.entry.value, item.label, item.variant);\r\n }\r\n\r\n /**\r\n * L'etichetta del ramo di fault, presa dalla mappa delle uscite invece di scrivere «ramo di\r\n * errore» per tutti: su uno stage di orchestrazione quel ramo **non** e' un guasto, e' lo step\r\n * rifiutato (§5.13). Un tipo nuovo eredita l'etichetta giusta senza toccare la palette.\r\n */\r\n faultLabel(item: PaletteItem): string | null {\r\n if (!item.entry.hasFaultConnector) {\r\n return null;\r\n }\r\n const outlet = outletsOf(item.entry.value, {}).find((candidate) => candidate.kind === 'Fault');\r\n return outlet ? `ramo «${outlet.label.toLowerCase()}»` : 'ramo di errore';\r\n }\r\n\r\n categoryClass(category: string): string {\r\n const normalized = category.toLowerCase();\r\n if (normalized.startsWith('inter')) {\r\n return 'cat-screen';\r\n }\r\n if (normalized.startsWith('log')) {\r\n return 'cat-logic';\r\n }\r\n if (normalized.startsWith('dat')) {\r\n return 'cat-data';\r\n }\r\n if (normalized.startsWith('az')) {\r\n return 'cat-action';\r\n }\r\n if (normalized.startsWith('flow')) {\r\n return 'cat-flow';\r\n }\r\n return 'cat-other';\r\n }\r\n}\r\n","<div class=\"fb-palette__search\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Cerca un elemento\"\r\n aria-label=\"Cerca un elemento\"\r\n (input)=\"onFilter($any($event.target).value)\"\r\n />\r\n</div>\r\n\r\n@if (isEmpty()) {\r\n <p class=\"fb-palette__empty\">\r\n Il dizionario degli elementi non e’ ancora disponibile.\r\n </p>\r\n}\r\n\r\n<div class=\"fb-palette__groups\">\r\n @for (group of groups(); track group.category) {\r\n <section class=\"fb-palette__group\">\r\n <h3 class=\"fb-palette__category\">{{ group.category }}</h3>\r\n @for (item of group.items; track item.key) {\r\n <!--\r\n `fExternalItem` rende la voce trascinabile sul canvas: il rilascio emette\r\n `fCreateNode` con questo `fData` e la posizione, che diventa locationX/locationY.\r\n Il dato e' l'oggetto {type, variant}, non il solo tipo: due voci dello stesso tipo\r\n si distinguono soltanto per la variante.\r\n -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-palette__item\"\r\n fExternalItem\r\n [fExternalItemId]=\"item.key\"\r\n [fData]=\"item.data\"\r\n [class.fb-palette__item--warn]=\"isIncompatible(item)\"\r\n [title]=\"hintOf(item)\"\r\n (click)=\"pick(item)\"\r\n >\r\n <span class=\"fb-palette__icon\" [class]=\"'fb-palette__icon ' + categoryClass(group.category)\">\r\n {{ iconOf(item) }}\r\n </span>\r\n <span class=\"fb-palette__text\">\r\n <span class=\"fb-palette__label\">{{ item.label }}</span>\r\n @if (item.entry.hasAutomaticOutput) {\r\n <span class=\"fb-palette__flag\" title=\"Espone un output automatico sotto il nome dell’elemento\">\r\n output automatico\r\n </span>\r\n }\r\n @if (faultLabel(item)) {\r\n <span class=\"fb-palette__flag\" title=\"Ha un ramo che l’autore puo’ prevedere e disegnare\">\r\n {{ faultLabel(item) }}\r\n </span>\r\n }\r\n </span>\r\n @if (isIncompatible(item)) {\r\n <span class=\"fb-palette__warn\" aria-hidden=\"true\">!</span>\r\n }\r\n </button>\r\n }\r\n </section>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di riferimento — FRONTEND.md §4.1, §4.5, §6.4, §13.3.\r\n *\r\n * Un riferimento e' testo libero, e un nome sbagliato e' indistinguibile da uno giusto se\r\n * non si conosce l'insieme dei nomi definiti. Questo componente chiede l'insieme a\r\n * `POST /flows/references` (o `.../writable` per le destinazioni) invece di far digitare:\r\n * e' l'unico modo di evitare `REFERENCE_UNKNOWN` prima di scoprirlo dalla validazione.\r\n *\r\n * Include gli **output automatici** (`Leggi_Ordine.Numero`), che sono riferimenti validi\r\n * pur non essendo dichiarati in nessuna collection di risorse: la primitiva li restituisce\r\n * già, ed e' il motivo per cui non si ricostruisce l'elenco lato client.\r\n *\r\n * Resta possibile scrivere a mano: i percorsi di relazione e i campi di un record non sono\r\n * enumerabili. Gli scope del sistema ospite (`$User.X`), invece, sono verificabili **quando\r\n * l'host li dichiara**: se `globalVariables` porta almeno un percorso di quello scope, un\r\n * percorso che non c'e' e' `GLOBAL_UNKNOWN`; se non ne porta nessuno, lo scope resta non\r\n * verificabile — che significa \"non lo so\", non \"non esiste\" (§4.1).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowReference } from '../../model/api.model';\r\nimport { FlowDataType } from '../../model/flow.model';\r\nimport { referenceRoot } from '../../core/flow-name.util';\r\n\r\n@Component({\r\n selector: 'fb-reference-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './reference-picker.component.html',\r\n styleUrl: './reference-picker.component.css',\r\n})\r\nexport class ReferencePickerComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n readonly label = input<string>('Riferimento');\r\n readonly placeholder = input<string>('Scegli o scrivi un riferimento');\r\n readonly disabled = input(false);\r\n\r\n /** Filtra i riferimenti compatibili col campo che si sta compilando (§6.4). */\r\n readonly dataType = input<FlowDataType | undefined>(undefined);\r\n readonly isCollection = input<boolean | undefined>(undefined);\r\n readonly objectType = input<string | undefined>(undefined);\r\n\r\n /**\r\n * `true` → propone solo destinazioni scrivibili. Assegnare a una costante o a una\r\n * formula e' `TARGET_NOT_WRITABLE` (§4.6).\r\n */\r\n readonly writableOnly = input(false);\r\n\r\n /**\r\n * `true` → a sinistra ci va il nome di un **node**, non di una risorsa: e' il caso di\r\n * `WasVisited` e `HasError` (§4.3).\r\n */\r\n readonly elementsOnly = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly references = signal<FlowReference[]>([]);\r\n private readonly isLoading = signal(false);\r\n private readonly loadError = signal<string | null>(null);\r\n\r\n readonly isOpen = signal(false);\r\n readonly query = signal('');\r\n\r\n constructor() {\r\n // Le proposte dipendono dal documento in lavorazione: cambia il documento, cambia\r\n // l'elenco (un elemento appena aggiunto espone subito il suo output automatico).\r\n effect(() => {\r\n const definition = this.store.document();\r\n const writable = this.writableOnly();\r\n const dataType = this.dataType();\r\n const isCollection = this.isCollection();\r\n const objectType = this.objectType();\r\n if (this.elementsOnly()) {\r\n // I node li conosce già il documento: nessuna richiesta necessaria.\r\n this.references.set(\r\n this.store.nodes().map((reference) => ({\r\n name: reference.name,\r\n label: (reference.node.label as string) ?? null,\r\n kind: 'ElementOutput',\r\n description: this.dictionaries.labelOf(reference.type),\r\n isWritable: false,\r\n })),\r\n );\r\n return;\r\n }\r\n /**\r\n * `?? undefined` non e' cosmetico: nei template il safe navigation di Angular\r\n * (`describe(x)?.isCollection`) produce **null**, non `undefined`. Un `isCollection: null`\r\n * che arriva alla primitiva viene letto come \"filtra per valore singolo\" e svuota\r\n * l'elenco: un campo senza filtro deve mandare il campo **assente**.\r\n */\r\n const query = {\r\n definition,\r\n dataType: dataType ?? undefined,\r\n isCollection: isCollection ?? undefined,\r\n objectType: objectType ?? undefined,\r\n };\r\n this.isLoading.set(true);\r\n this.loadError.set(null);\r\n const request = writable ? this.api.getWritableReferences(query) : this.api.getReferences(query);\r\n void request\r\n .then((list) => this.references.set(list ?? []))\r\n .catch((error: unknown) => {\r\n // Senza l'elenco il campo resta scrivibile a mano: e' meglio di un campo bloccato.\r\n this.loadError.set(error instanceof Error ? error.message : String(error));\r\n this.references.set([]);\r\n })\r\n .finally(() => this.isLoading.set(false));\r\n });\r\n }\r\n\r\n readonly options = computed<FlowReference[]>(() => {\r\n const needle = this.query().trim().toLowerCase();\r\n // Le globali assegnabili — `$Flow.CurrentStage`, `$Flow.ActiveStages` e quelle che l'host\r\n // dichiara scrivibili — le comprende già `POST /flows/references/writable`: aggiungerle\r\n // qui le duplicherebbe (§5.2, §6.4).\r\n const all = this.references();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((reference) =>\r\n `${reference.name} ${reference.label ?? ''} ${reference.description ?? ''}`\r\n .toLowerCase()\r\n .includes(needle),\r\n );\r\n });\r\n\r\n /** Le opzioni raggruppate per `kind`, così gli output automatici si distinguono. */\r\n readonly groups = computed<Array<{ kind: string; label: string; items: FlowReference[] }>>(() => {\r\n const groups: Array<{ kind: string; label: string; items: FlowReference[] }> = [];\r\n for (const reference of this.options()) {\r\n const kind = reference.kind ?? 'Variable';\r\n let group = groups.find((candidate) => candidate.kind === kind);\r\n if (!group) {\r\n group = { kind, label: ReferencePickerComponent.kindLabel(kind), items: [] };\r\n groups.push(group);\r\n }\r\n group.items.push(reference);\r\n }\r\n return groups;\r\n });\r\n\r\n private static kindLabel(kind: string): string {\r\n switch (kind) {\r\n case 'Variable':\r\n return 'Variabili';\r\n case 'Constant':\r\n return 'Costanti';\r\n case 'Formula':\r\n return 'Formule';\r\n case 'TextTemplate':\r\n return 'Text template';\r\n case 'Choice':\r\n return 'Choice';\r\n case 'DynamicChoiceSet':\r\n return 'Dynamic choice set';\r\n case 'Stage':\r\n return 'Stage';\r\n case 'ElementOutput':\r\n return 'Output di elementi';\r\n case 'Global':\r\n return 'Variabili globali';\r\n default:\r\n return kind;\r\n }\r\n }\r\n\r\n /**\r\n * Stato del valore corrente rispetto all'elenco.\r\n * - `known`: presente nell'elenco;\r\n * - `navigated`: la radice e' nota ma c'e' un percorso dopo il punto (campo di record,\r\n * output automatico navigato): la validazione non verifica i percorsi con il punto,\r\n * quindi si accetta senza segnalare;\r\n * - `host`: scope del sistema ospite che **non dichiara percorsi**: non verificabile (§4.1);\r\n * - `unknown`: nessuna corrispondenza: si avvisa, senza bloccare. Ci finisce anche il\r\n * percorso inesistente di uno scope che i percorsi li dichiara, perche' lì il backend\r\n * risponderebbe `GLOBAL_UNKNOWN`.\r\n */\r\n readonly valueState = computed<'empty' | 'known' | 'navigated' | 'host' | 'unknown'>(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value) {\r\n return 'empty';\r\n }\r\n const all = this.references();\r\n if (all.some((reference) => reference.name === value)) {\r\n return 'known';\r\n }\r\n const root = referenceRoot(value);\r\n if (this.dictionaries.globalScope(root) && !this.dictionaries.isGlobalScopeVerifiable(root)) {\r\n return 'host';\r\n }\r\n if (all.some((reference) => reference.name === root)) {\r\n return 'navigated';\r\n }\r\n // Se l'elenco non e' arrivato, non si accusa nessuno.\r\n return all.length === 0 && this.isLoading() ? 'empty' : 'unknown';\r\n });\r\n\r\n readonly hint = computed<string | null>(() => {\r\n switch (this.valueState()) {\r\n case 'host':\r\n return 'Scope risolto dal sistema ospite, che non dichiara i suoi percorsi: il backend non puo’ verificarlo.';\r\n case 'navigated':\r\n return 'Percorso su un riferimento noto: la validazione non verifica i campi dopo il punto.';\r\n case 'unknown':\r\n return 'Questo nome non e’ fra i riferimenti disponibili: la validazione lo segnalerebbe.';\r\n default:\r\n return null;\r\n }\r\n });\r\n\r\n readonly errorMessage = computed(() => this.loadError());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set('');\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onQuery(value: string): void {\r\n this.query.set(value);\r\n }\r\n\r\n choose(reference: FlowReference): void {\r\n this.valueChange.emit(reference.name);\r\n this.close();\r\n }\r\n\r\n /** Scrittura libera: indispensabile per i campi di un record e per gli scope dell'host. */\r\n onManualInput(value: string): void {\r\n this.valueChange.emit(value.trim() ? value.trim() : undefined);\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n }\r\n\r\n describe(reference: FlowReference): string {\r\n const parts: string[] = [];\r\n if (reference.dataType) {\r\n parts.push(reference.isCollection ? `${reference.dataType}[]` : reference.dataType);\r\n }\r\n if (reference.objectType) {\r\n parts.push(reference.objectType);\r\n }\r\n if (reference.description) {\r\n parts.push(reference.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-ref\" [class.fb-ref--open]=\"isOpen()\">\r\n <div class=\"fb-ref__control\">\r\n <input\r\n class=\"fb-ref__input\"\r\n type=\"text\"\r\n [value]=\"value() || ''\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n (input)=\"onManualInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-ref__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i riferimenti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-ref__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (hint()) {\r\n <p class=\"fb-ref__hint\" [class.fb-ref__hint--warn]=\"valueState() === 'unknown'\">{{ hint() }}</p>\r\n }\r\n @if (errorMessage()) {\r\n <p class=\"fb-ref__hint fb-ref__hint--warn\">\r\n Elenco dei riferimenti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-ref__panel\" role=\"listbox\">\r\n <input\r\n class=\"fb-ref__search\"\r\n type=\"search\"\r\n placeholder=\"Filtra\"\r\n aria-label=\"Filtra i riferimenti\"\r\n (input)=\"onQuery($any($event.target).value)\"\r\n />\r\n @if (groups().length === 0) {\r\n <p class=\"fb-ref__empty\">Nessun riferimento compatibile.</p>\r\n }\r\n @for (group of groups(); track group.kind) {\r\n <div class=\"fb-ref__group\">\r\n <span class=\"fb-ref__group-label\">{{ group.label }}</span>\r\n @for (item of group.items; track item.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-ref__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"item.name === value()\"\r\n (click)=\"choose(item)\"\r\n >\r\n <span class=\"fb-ref__name\">{{ item.name }}</span>\r\n <span class=\"fb-ref__meta\">{{ describe(item) }}</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n <button type=\"button\" class=\"fb-ref__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di oggetto (entita') — FRONTEND.md §4.2.\r\n *\r\n * Il catalogo degli oggetti (`listObjects()`) puo' essere lungo: un `<select>` obbliga a\r\n * scorrerlo, e quando il catalogo non arriva resta solo un campo di testo cieco. Qui la\r\n * casella e' **una sola** in entrambi i casi — si scrive per filtrare, si scegle dall'elenco —\r\n * e la scrittura libera resta possibile perche' l'host puo' esporre entita' che il catalogo\r\n * non elenca (o non esporlo affatto).\r\n *\r\n * Il valore emesso e' sempre il **nome** dell'oggetto, mai la sua label: la label e' testo\r\n * per l'occhio, il documento porta il nome.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowObjectSummary } from '../../model/dictionary.model';\r\n\r\n@Component({\r\n selector: 'fb-object-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './object-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class ObjectPickerComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n readonly label = input<string>('Oggetto');\r\n readonly placeholder = input<string>('Scrivi o scegli un oggetto');\r\n readonly disabled = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly objects = signal<FlowObjectSummary[]>([]);\r\n private readonly loadFailed = signal(false);\r\n\r\n readonly isOpen = signal(false);\r\n\r\n /**\r\n * Il testo digitato **mentre** il pannello e' aperto: filtra l'elenco. Chiuso il pannello\r\n * torna a null e la casella mostra di nuovo il valore del documento, che e' l'unica\r\n * fonte di verita'.\r\n */\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n void this.catalog\r\n .listObjects()\r\n .then((list) => this.objects.set(list ?? []))\r\n .catch(() => this.loadFailed.set(true));\r\n\r\n /**\r\n * Il filtro sopravvive alla **propria** scrittura — digitare aggiorna il valore a ogni\r\n * tasto — ma non a un valore che arriva da fuori: l'inspector riusa questo componente\r\n * quando si passa a un altro elemento dello stesso tipo, e il testo del precedente\r\n * resterebbe nella casella pur non essendo piu' il valore del documento.\r\n */\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n /** Quel che si vede nella casella: il filtro se si sta digitando, il valore altrimenti. */\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly options = computed<FlowObjectSummary[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.objects();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((object) =>\r\n `${object.name} ${object.label ?? ''} ${object.description ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasCatalog = computed(() => this.objects().length > 0);\r\n\r\n /**\r\n * Nome fuori catalogo: si avvisa e non si blocca. Senza catalogo non si accusa nessuno —\r\n * \"non lo so\" non e' \"non esiste\".\r\n */\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasCatalog()) {\r\n return false;\r\n }\r\n return !this.objects().some((object) => object.name === value);\r\n });\r\n\r\n readonly labelOfValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.objects().find((object) => object.name === value);\r\n return found?.label && found.label !== found.name ? found.label : null;\r\n });\r\n\r\n readonly loadErrored = computed(() => this.loadFailed());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n /** Digitare filtra **e** scrive: il nome puo' non essere in catalogo. */\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(object: FlowObjectSummary): void {\r\n this.valueChange.emit(object.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(object: FlowObjectSummary): string {\r\n const parts: string[] = [];\r\n if (object.label && object.label !== object.name) {\r\n parts.push(object.label);\r\n }\r\n if (object.description) {\r\n parts.push(object.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra gli oggetti disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Questo nome non e’ fra gli oggetti disponibili: la validazione lo segnalerebbe.\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco degli oggetti non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasCatalog() ? 'Nessun oggetto corrisponde.' : 'Catalogo degli oggetti non disponibile.' }}\r\n </p>\r\n }\r\n @for (object of options(); track object.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"object.name === value()\"\r\n (click)=\"choose(object)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ object.name }}</span>\r\n @if (describe(object)) {\r\n <span class=\"fb-pick__meta\">{{ describe(object) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Selettore di campo di un'entita' — FRONTEND.md §4.4, §5.7, §6.4.\r\n *\r\n * L'uso con cui si chiedono i campi non e' un dettaglio: `filterable`, `sortable` e\r\n * `updateable` sono insiemi diversi, e proporre un campo fuori dall'insieme giusto porta\r\n * dritti a `FIELD_NOT_FILTERABLE` / `FIELD_NOT_UPDATEABLE`. L'input `usage` viaggia quindi\r\n * fino alla primitiva **e** decide il testo dell'avviso, che altrimenti direbbe la cosa\r\n * sbagliata (\"non aggiornabile\" su un filtro).\r\n *\r\n * La scrittura libera resta possibile perche' i percorsi di relazione (`Cliente.Citta`) non\r\n * sono enumerabili: su un valore col punto non si accusa nessuno, si avvisa che la\r\n * validazione non lo verifica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription, FlowFieldUsage } from '../../model/dictionary.model';\r\n\r\n@Component({\r\n selector: 'fb-field-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './field-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class FieldPickerComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly value = input<string | undefined>(undefined);\r\n /** L'entita' di cui elencare i campi: senza oggetto non c'e' catalogo. */\r\n readonly object = input<string | undefined>(undefined);\r\n readonly usage = input<FlowFieldUsage>('any');\r\n readonly label = input<string>('Campo');\r\n readonly placeholder = input<string>('Scrivi o scegli un campo');\r\n readonly disabled = input(false);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n private readonly loadFailed = signal(false);\r\n\r\n readonly isOpen = signal(false);\r\n\r\n /** Il testo digitato mentre il pannello e' aperto: filtra l'elenco. */\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n const usage = this.usage();\r\n this.loadFailed.set(false);\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, usage)\r\n .then((list) => this.fields.set(list ?? []))\r\n // Catalogo non disponibile: il campo resta scrivibile a mano, non bloccato.\r\n .catch(() => {\r\n this.fields.set([]);\r\n this.loadFailed.set(true);\r\n });\r\n });\r\n\r\n // Vedi ObjectPickerComponent: il filtro sopravvive alla propria scrittura, non a un\r\n // valore che arriva da fuori (un'altra riga della lista, un altro elemento).\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly options = computed<FlowFieldDescription[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.fields();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((field) =>\r\n `${field.name} ${field.label ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasCatalog = computed(() => this.fields().length > 0);\r\n\r\n /** `true` se il valore e' un percorso di relazione: non enumerabile, non verificato (§4.4). */\r\n readonly isRelationPath = computed(() => (this.value() ?? '').includes('.'));\r\n\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasCatalog() || this.isRelationPath()) {\r\n return false;\r\n }\r\n return !this.fields().some((field) => field.name === value);\r\n });\r\n\r\n /** L'avviso dipende dall'uso: un campo puo' esistere e non essere filtrabile. */\r\n readonly unknownMessage = computed(() => {\r\n switch (this.usage()) {\r\n case 'filterable':\r\n return 'Questo campo non e’ fra quelli filtrabili dell’oggetto.';\r\n case 'sortable':\r\n return 'Questo campo non e’ fra quelli su cui si puo’ ordinare.';\r\n case 'updateable':\r\n return 'Questo campo non e’ fra quelli aggiornabili dell’oggetto.';\r\n default:\r\n return 'Questo campo non e’ fra quelli dell’oggetto.';\r\n }\r\n });\r\n\r\n readonly describeValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.fields().find((field) => field.name === value);\r\n return found ? this.describe(found) || null : null;\r\n });\r\n\r\n readonly loadErrored = computed(() => this.loadFailed());\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(field: FlowFieldDescription): void {\r\n this.valueChange.emit(field.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(field: FlowFieldDescription): string {\r\n const parts: string[] = [];\r\n if (field.label && field.label !== field.name) {\r\n parts.push(field.label);\r\n }\r\n if (field.dataType) {\r\n parts.push(field.objectType ? `${field.dataType} · ${field.objectType}` : field.dataType);\r\n }\r\n if (field.isRequired) {\r\n parts.push('obbligatorio');\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i campi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isRelationPath()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Percorso di relazione: la validazione non lo verifica, un errore si scopre solo eseguendo.\r\n </p>\r\n } @else if (isUnknown()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">{{ unknownMessage() }}</p>\r\n } @else if (describeValue()) {\r\n <p class=\"fb-pick__hint\">{{ describeValue() }}</p>\r\n } @else if (loadErrored()) {\r\n <p class=\"fb-pick__hint fb-pick__hint--warn\">\r\n Elenco dei campi non disponibile: puoi scrivere il nome a mano.\r\n </p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (options().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n @if (!object()) {\r\n Scegli prima un oggetto.\r\n } @else {\r\n {{ hasCatalog() ? 'Nessun campo corrisponde.' : 'Catalogo dei campi non disponibile.' }}\r\n }\r\n </p>\r\n }\r\n @for (field of options(); track field.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"field.name === value()\"\r\n (click)=\"choose(field)\"\r\n >\r\n <span class=\"fb-pick__name\">{{ field.name }}</span>\r\n @if (describe(field)) {\r\n <span class=\"fb-pick__meta\">{{ describe(field) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Combo con autocomplete su un elenco di nomi già in mano al chiamante.\r\n *\r\n * A differenza di {@link ObjectPickerComponent} e {@link FieldPickerComponent} questo non\r\n * sa da dove arrivi l'elenco: lo riceve. Serve dove i candidati non sono un catalogo di\r\n * schema ma dipendono dal contesto — i flow invocabili escludono il flow corrente\r\n * (`listSubflowCandidates`), le variabili di input di un subflow dipendono da quale subflow\r\n * si e' scelto — e dove quindi il componente non puo' chiederli da se'.\r\n *\r\n * Elenco vuoto significa **\"non lo so\"**, non \"nessuno\": il campo resta scrivibile a mano e\r\n * non si accusa il nome scritto (§7). Con l'elenco popolato, invece, un nome che non c'e' e'\r\n * segnalato subito: e' l'unica differenza rispetto a un `datalist`, che accetta qualunque\r\n * cosa in silenzio.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n input,\r\n output,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\nexport interface NamePickerOption {\r\n name: string;\r\n label?: string | null;\r\n description?: string | null;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-name-picker',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './name-picker.component.html',\r\n styleUrl: './picker.css',\r\n})\r\nexport class NamePickerComponent {\r\n readonly value = input<string | undefined>(undefined);\r\n readonly options = input<NamePickerOption[]>([]);\r\n readonly label = input<string>('Nome');\r\n readonly placeholder = input<string>('Scrivi o scegli un nome');\r\n readonly disabled = input(false);\r\n\r\n /** Il testo dell'avviso sul nome fuori elenco: dipende da cosa si sta scegliendo. */\r\n readonly unknownMessage = input<string>('Questo nome non e’ fra quelli disponibili.');\r\n /**\r\n * La gravita' dell'avviso. Non e' cosmetica: un'action o un form che non esistono sono\r\n * **errori** che bloccano l'attivazione (`ACTION_UNKNOWN`, `FORM_UNKNOWN`), mentre un flow\r\n * senza versione attiva e' un avviso. Mostrarli con lo stesso colore direbbe il falso.\r\n */\r\n readonly unknownSeverity = input<'warn' | 'error'>('warn');\r\n /** Cosa dire quando l'elenco e' vuoto: e' il caso \"non lo so\", non un errore. */\r\n readonly emptyMessage = input<string>('Elenco non disponibile: puoi scrivere il nome a mano.');\r\n /** Testo monospazio: i nomi tecnici si leggono meglio, ed e' come li mostra il resto del form. */\r\n readonly isMono = input(true);\r\n\r\n readonly valueChange = output<string | undefined>();\r\n\r\n readonly isOpen = signal(false);\r\n\r\n private readonly query = signal<string | null>(null);\r\n\r\n constructor() {\r\n // Vedi ObjectPickerComponent: il filtro non sopravvive a un valore che arriva da fuori.\r\n effect(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (value !== (untracked(this.query) ?? '').trim()) {\r\n this.query.set(null);\r\n }\r\n });\r\n }\r\n\r\n readonly text = computed(() => this.query() ?? this.value() ?? '');\r\n\r\n readonly visibleOptions = computed<NamePickerOption[]>(() => {\r\n const needle = (this.query() ?? '').trim().toLowerCase();\r\n const all = this.options();\r\n if (!needle) {\r\n return all;\r\n }\r\n return all.filter((option) =>\r\n `${option.name} ${option.label ?? ''} ${option.description ?? ''}`.toLowerCase().includes(needle),\r\n );\r\n });\r\n\r\n readonly hasOptions = computed(() => this.options().length > 0);\r\n\r\n readonly isUnknown = computed(() => {\r\n const value = (this.value() ?? '').trim();\r\n if (!value || !this.hasOptions()) {\r\n return false;\r\n }\r\n return !this.options().some((option) => option.name === value);\r\n });\r\n\r\n readonly labelOfValue = computed<string | null>(() => {\r\n const value = (this.value() ?? '').trim();\r\n const found = this.options().find((option) => option.name === value);\r\n return found ? this.describe(found) || null : null;\r\n });\r\n\r\n open(): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n this.isOpen.set(true);\r\n }\r\n\r\n close(): void {\r\n this.isOpen.set(false);\r\n this.query.set(null);\r\n }\r\n\r\n toggle(): void {\r\n this.isOpen() ? this.close() : this.open();\r\n }\r\n\r\n onInput(text: string): void {\r\n this.query.set(text);\r\n this.open();\r\n this.valueChange.emit(text.trim() ? text.trim() : undefined);\r\n }\r\n\r\n choose(option: NamePickerOption): void {\r\n this.valueChange.emit(option.name);\r\n this.close();\r\n }\r\n\r\n clear(): void {\r\n this.valueChange.emit(undefined);\r\n this.close();\r\n }\r\n\r\n describe(option: NamePickerOption): string {\r\n const parts: string[] = [];\r\n if (option.label && option.label !== option.name) {\r\n parts.push(option.label);\r\n }\r\n if (option.description) {\r\n parts.push(option.description);\r\n }\r\n return parts.join(' · ');\r\n }\r\n}\r\n","<div class=\"fb-pick\" [class.fb-pick--open]=\"isOpen()\">\r\n <div class=\"fb-pick__control\">\r\n <input\r\n class=\"fb-pick__input\"\r\n [class.fb-pick__input--mono]=\"isMono()\"\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n [value]=\"text()\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open()\"\r\n (keydown.escape)=\"close()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__toggle\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-label=\"Mostra i nomi disponibili\"\r\n (click)=\"toggle()\"\r\n >\r\n ▾\r\n </button>\r\n @if (value()) {\r\n <button type=\"button\" class=\"fb-pick__clear\" aria-label=\"Svuota\" (click)=\"clear()\">×</button>\r\n }\r\n </div>\r\n\r\n @if (isUnknown()) {\r\n <p\r\n class=\"fb-pick__hint\"\r\n [class.fb-pick__hint--warn]=\"unknownSeverity() === 'warn'\"\r\n [class.fb-pick__hint--error]=\"unknownSeverity() === 'error'\"\r\n >\r\n {{ unknownMessage() }}\r\n </p>\r\n } @else if (labelOfValue()) {\r\n <p class=\"fb-pick__hint\">{{ labelOfValue() }}</p>\r\n } @else if (!hasOptions()) {\r\n <p class=\"fb-pick__hint\">{{ emptyMessage() }}</p>\r\n }\r\n\r\n @if (isOpen()) {\r\n <div class=\"fb-pick__panel\" role=\"listbox\">\r\n @if (visibleOptions().length === 0) {\r\n <p class=\"fb-pick__empty\">\r\n {{ hasOptions() ? 'Nessun nome corrisponde.' : 'Nessun candidato da proporre.' }}\r\n </p>\r\n }\r\n @for (option of visibleOptions(); track option.name) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-pick__option\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"option.name === value()\"\r\n (click)=\"choose(option)\"\r\n >\r\n <span class=\"fb-pick__name\" [class.fb-pick__name--mono]=\"isMono()\">{{ option.name }}</span>\r\n @if (describe(option)) {\r\n <span class=\"fb-pick__meta\">{{ describe(option) }}</span>\r\n }\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-pick__close\" (click)=\"close()\">Chiudi</button>\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * `[fbValue]` su un `<select>`.\r\n *\r\n * Perche' esiste: quasi tutte le tendine dell'editor hanno opzioni che arrivano dopo il\r\n * primo render — dizionari, cataloghi, destinazioni dei connector, campi di un oggetto.\r\n * Un `[value]` normale viene applicato quando le `<option>` non esistono ancora, il browser\r\n * lo scarta, e Angular non lo riapplica perche' il valore del binding non e' cambiato: il\r\n * risultato e' una tendina che mostra «— scegli —» su un campo che nel documento ha un\r\n * valore. Succedeva, per esempio, sulla destinazione dello Start.\r\n *\r\n * La direttiva riallinea l'elemento al valore dichiarato a ogni giro di change detection,\r\n * così quando le opzioni compaiono la selezione si sistema da se'.\r\n */\r\n\r\nimport { AfterViewChecked, Directive, ElementRef, inject, input } from '@angular/core';\r\n\r\n@Directive({\r\n selector: 'select[fbValue]',\r\n standalone: true,\r\n})\r\nexport class SelectValueDirective implements AfterViewChecked {\r\n private readonly element = inject<ElementRef<HTMLSelectElement>>(ElementRef);\r\n\r\n readonly fbValue = input<string | number | null | undefined>('');\r\n\r\n ngAfterViewChecked(): void {\r\n const select = this.element.nativeElement;\r\n const value = this.fbValue();\r\n const normalized = value === null || value === undefined ? '' : String(value);\r\n if (select.value !== normalized) {\r\n select.value = normalized;\r\n }\r\n }\r\n}\r\n","/**\r\n * `FlowElementReferenceOrValue` — FRONTEND.md §4.2.\r\n *\r\n * La struttura accetta \"un riferimento **oppure** un valore letterale\", e va valorizzato\r\n * **uno e un solo** campo. Valorizzarne piu' di uno e' `VALUE_AMBIGUOUS`: non e' un errore\r\n * bloccante, ma rende il comportamento a runtime dipendente dall'ordine di lettura.\r\n *\r\n * Questo editor rende quella regola strutturale invece che sperata: ogni scrittura\r\n * costruisce un oggetto nuovo con **una** chiave. `formulaExpression` e' l'unico caso a\r\n * due campi (espressione + tipo atteso del risultato) e viene trattato come tale.\r\n *\r\n * Il tipo del letterale deve corrispondere al tipo della destinazione: quando il tipo e'\r\n * noto, l'editor mostra il controllo giusto e propone quella modalita' per default.\r\n *\r\n * Due dettagli di formato che il contratto tratta come sostanza, non come presentazione:\r\n *\r\n * - i numeri viaggiano in **cultura invariante** (§4.3): il separatore decimale e' il punto, e\r\n * `1234,50` viene tradotto in `1234.50` invece di essere troncato in silenzio;\r\n * - un valore data **senza fuso** significa \"ora locale dell'applicazione\", non \"UTC\"\r\n * (§4.2, §13.15): sono due istanti diversi, quindi il fuso e' una scelta esplicita\r\n * dell'utente e non un effetto collaterale del datepicker.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { parseInvariantNumber } from '../../core/condition-types.util';\r\nimport { FlowDataType, FlowValue } from '../../model/flow.model';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n/** Le modalita' offerte: una per campo del modello. */\r\nexport type ValueMode = 'reference' | 'literal' | 'formula' | 'globalConstant' | 'empty';\r\n\r\n@Component({\r\n selector: 'fb-value-editor',\r\n standalone: true,\r\n imports: [ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './value-editor.component.html',\r\n styleUrl: './value-editor.component.css',\r\n})\r\nexport class ValueEditorComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly value = input<FlowValue | undefined>(undefined);\r\n readonly label = input<string>('Valore');\r\n /** Il tipo atteso dalla destinazione: guida il controllo del letterale. */\r\n readonly dataType = input<FlowDataType | undefined>(undefined);\r\n readonly objectType = input<string | undefined>(undefined);\r\n readonly isCollection = input<boolean | undefined>(undefined);\r\n readonly disabled = input(false);\r\n /** Nasconde la modalita' formula dove il modello non la prevede. */\r\n readonly allowFormula = input(true);\r\n\r\n readonly valueChange = output<FlowValue | undefined>();\r\n\r\n /** La modalita' dedotta dal campo effettivamente valorizzato. */\r\n readonly mode = computed<ValueMode>(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return this.dataType() ? 'literal' : 'reference';\r\n }\r\n if (value.formulaExpression !== undefined) {\r\n return 'formula';\r\n }\r\n if (value.elementReference !== undefined) {\r\n return value.elementReference.startsWith('$GlobalConstant.') ? 'globalConstant' : 'reference';\r\n }\r\n if (\r\n value.stringValue !== undefined ||\r\n value.integerValue !== undefined ||\r\n value.numberValue !== undefined ||\r\n value.dateValue !== undefined ||\r\n value.booleanValue !== undefined ||\r\n value.enumValue !== undefined\r\n ) {\r\n return 'literal';\r\n }\r\n return 'empty';\r\n });\r\n\r\n /**\r\n * Quanti campi di valore sono valorizzati: piu' di uno e' `VALUE_AMBIGUOUS` (§4.2).\r\n * Puo' capitare su un documento arrivato da un altro editor: si segnala e si offre\r\n * di normalizzarlo, invece di nasconderlo.\r\n */\r\n readonly filledFieldCount = computed(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return 0;\r\n }\r\n const keys: Array<keyof FlowValue> = [\r\n 'elementReference',\r\n 'stringValue',\r\n 'integerValue',\r\n 'numberValue',\r\n 'dateValue',\r\n 'booleanValue',\r\n 'enumValue',\r\n 'formulaExpression',\r\n ];\r\n return keys.filter((key) => value[key] !== undefined).length;\r\n });\r\n\r\n readonly isAmbiguous = computed(() => this.filledFieldCount() > 1);\r\n\r\n /** Il campo del valore che corrisponde al `dataType` (§4.2, tabella dei sette tipi). */\r\n readonly literalField = computed<keyof FlowValue>(() => {\r\n switch (this.dataType()) {\r\n case 'Integer':\r\n return 'integerValue';\r\n case 'Number':\r\n return 'numberValue';\r\n case 'Date':\r\n return 'dateValue';\r\n case 'Boolean':\r\n return 'booleanValue';\r\n case 'Enum':\r\n return 'enumValue';\r\n case 'String':\r\n return 'stringValue';\r\n default:\r\n return 'stringValue';\r\n }\r\n });\r\n\r\n /**\r\n * `Object` non ha un campo letterale: un record si passa per riferimento (§4.2).\r\n * Lo stesso vale per una collection.\r\n */\r\n readonly literalAllowed = computed(() => {\r\n if (this.isCollection()) {\r\n return false;\r\n }\r\n return this.dataType() !== 'Object';\r\n });\r\n\r\n readonly literalInputType = computed<string>(() => {\r\n switch (this.dataType()) {\r\n case 'Integer':\r\n case 'Number':\r\n return 'number';\r\n case 'Date':\r\n // `Date` porta data **e** ora insieme: non esiste un tipo \"ora\" separato (§4.2).\r\n return 'datetime-local';\r\n default:\r\n return 'text';\r\n }\r\n });\r\n\r\n readonly literalText = computed<string>(() => {\r\n const value = this.value();\r\n if (!value) {\r\n return '';\r\n }\r\n const field = this.literalField();\r\n if (field === 'dateValue' && value.dateValue !== undefined) {\r\n // `datetime-local` rifiuta un valore col fuso e resterebbe **vuoto** pur avendo un\r\n // valore: il suffisso si toglie qui e si riscrive in uscita. Se il documento porta un\r\n // campo diverso da quello atteso si passa al fallback qui sotto, che lo mostra comunque.\r\n return ValueEditorComponent.stripZone(value.dateValue);\r\n }\r\n const raw = value[field];\r\n if (raw === undefined || raw === null) {\r\n // Se il documento porta un tipo diverso da quello atteso, mostralo comunque:\r\n // nasconderlo farebbe sparire un valore che esiste.\r\n const fallback =\r\n value.stringValue ??\r\n value.integerValue ??\r\n value.numberValue ??\r\n value.dateValue ??\r\n value.enumValue;\r\n return fallback === undefined || fallback === null ? '' : String(fallback);\r\n }\r\n return String(raw);\r\n });\r\n\r\n readonly booleanValue = computed(() => this.value()?.booleanValue === true);\r\n\r\n /** Il fuso dichiarato nel valore data: `Z`, un offset, oppure niente = ora locale (§4.2). */\r\n readonly dateIsUtc = computed(() => ValueEditorComponent.hasZone(this.value()?.dateValue));\r\n\r\n private static readonly ZONE_PATTERN = /(Z|[+-]\\d{2}:?\\d{2})$/;\r\n\r\n private static hasZone(value: string | undefined): boolean {\r\n return !!value && ValueEditorComponent.ZONE_PATTERN.test(value);\r\n }\r\n\r\n private static stripZone(value: string | undefined): string {\r\n return (value ?? '').replace(ValueEditorComponent.ZONE_PATTERN, '');\r\n }\r\n\r\n readonly globalConstants = computed(() => {\r\n const entry = this.dictionaries\r\n .globalVariables()\r\n .find((candidate) => candidate.scope === '$GlobalConstant' || candidate.value === '$GlobalConstant');\r\n // Fuori dai quattro percorsi noti e' un errore di validazione: si propongono, non si\r\n // fanno digitare (§4.1).\r\n return (entry?.paths ?? []).map((path) => `$GlobalConstant.${path}`);\r\n });\r\n\r\n readonly numericHint = computed<string | null>(() => {\r\n switch (this.dataType()) {\r\n case 'Number':\r\n // Il punto decimale non e' una preferenza di formato: la virgola non e' accettata (§4.3).\r\n return 'Separatore decimale: il punto. Usa Number per importi e quantita’: Integer troncherebbe i decimali.';\r\n case 'Integer':\r\n return 'Numero intero, senza separatore delle migliaia.';\r\n default:\r\n return null;\r\n }\r\n });\r\n\r\n setMode(mode: ValueMode): void {\r\n switch (mode) {\r\n case 'reference':\r\n this.emit({ elementReference: '' });\r\n break;\r\n case 'literal':\r\n this.emit(this.dataType() === 'Boolean' ? { booleanValue: false } : { [this.literalField()]: '' });\r\n break;\r\n case 'formula':\r\n // L'unico caso con due campi: espressione + tipo atteso del risultato.\r\n this.emit({ formulaExpression: '', formulaDataType: this.dataType() ?? 'String' });\r\n break;\r\n case 'globalConstant':\r\n this.emit({ elementReference: this.globalConstants()[0] ?? '$GlobalConstant.Null' });\r\n break;\r\n case 'empty':\r\n this.emit(undefined);\r\n break;\r\n }\r\n }\r\n\r\n onReferenceChange(reference: string | undefined): void {\r\n this.emit(reference === undefined ? undefined : { elementReference: reference });\r\n }\r\n\r\n onLiteralChange(raw: string): void {\r\n const field = this.literalField();\r\n if (raw === '') {\r\n this.emit(undefined);\r\n return;\r\n }\r\n switch (field) {\r\n case 'integerValue': {\r\n // Cultura invariante anche sugli interi: `1.234` non e' milleduecentotrentaquattro.\r\n const parsed = parseInvariantNumber(raw);\r\n this.emit(parsed === undefined ? undefined : { integerValue: Math.trunc(parsed) });\r\n return;\r\n }\r\n case 'numberValue': {\r\n const parsed = parseInvariantNumber(raw);\r\n this.emit(parsed === undefined ? undefined : { numberValue: parsed });\r\n return;\r\n }\r\n case 'dateValue':\r\n // L'input `datetime-local` produce `2026-08-15T00:00` senza fuso: si completano i\r\n // secondi e si riscrive il fuso scelto, perche' senza `Z` il valore significa\r\n // \"ora locale\" e il motore lo converte prima di confrontarlo (§4.2).\r\n this.emit({ dateValue: this.withDateZone(raw.length === 16 ? `${raw}:00` : raw) });\r\n return;\r\n case 'enumValue':\r\n this.emit({ enumValue: raw });\r\n return;\r\n default:\r\n this.emit({ stringValue: raw });\r\n }\r\n }\r\n\r\n onBooleanChange(checked: boolean): void {\r\n this.emit({ booleanValue: checked });\r\n }\r\n\r\n private withDateZone(local: string, utc = this.dateIsUtc()): string {\r\n return utc ? `${ValueEditorComponent.stripZone(local)}Z` : ValueEditorComponent.stripZone(local);\r\n }\r\n\r\n /**\r\n * Cambia il fuso **dichiarato**, non l'istante: `09:00Z` e `09:00` sono le nove in due fusi\r\n * diversi, e l'editor non converte al posto dell'utente. Riscrivere lo stesso orario con\r\n * l'altro fuso e' esattamente cio' che serve quando il valore e' stato inserito sbagliato.\r\n */\r\n setDateZone(utc: boolean): void {\r\n const current = this.value()?.dateValue;\r\n if (!current) {\r\n return;\r\n }\r\n this.emit({ dateValue: this.withDateZone(current, utc) });\r\n }\r\n\r\n onFormulaChange(expression: string): void {\r\n this.emit({\r\n formulaExpression: expression,\r\n formulaDataType: this.value()?.formulaDataType ?? this.dataType() ?? 'String',\r\n });\r\n }\r\n\r\n onFormulaTypeChange(dataType: string): void {\r\n this.emit({\r\n formulaExpression: this.value()?.formulaExpression ?? '',\r\n formulaDataType: dataType,\r\n });\r\n }\r\n\r\n onGlobalConstantChange(value: string): void {\r\n this.emit({ elementReference: value });\r\n }\r\n\r\n /** Normalizza un valore ambiguo tenendo il campo della modalita' corrente. */\r\n normalize(): void {\r\n const value = this.value();\r\n if (!value) {\r\n return;\r\n }\r\n switch (this.mode()) {\r\n case 'formula':\r\n this.emit({\r\n formulaExpression: value.formulaExpression,\r\n formulaDataType: value.formulaDataType ?? this.dataType() ?? 'String',\r\n });\r\n return;\r\n case 'reference':\r\n case 'globalConstant':\r\n this.emit({ elementReference: value.elementReference });\r\n return;\r\n default: {\r\n const field = this.literalField();\r\n this.emit({ [field]: value[field] } as FlowValue);\r\n }\r\n }\r\n }\r\n\r\n private emit(value: FlowValue | undefined): void {\r\n this.valueChange.emit(value);\r\n }\r\n\r\n readonly dataTypeOptions = computed(() => this.dictionaries.dataTypes());\r\n}\r\n","<div class=\"fb-value\">\r\n <div class=\"fb-value__modes\" role=\"group\" [attr.aria-label]=\"label() + ': modalita’'\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'reference'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Riferimento a una risorsa o all’output di un elemento\"\r\n (click)=\"setMode('reference')\"\r\n >\r\n Riferimento\r\n </button>\r\n @if (literalAllowed()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'literal'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Valore letterale del tipo della destinazione\"\r\n (click)=\"setMode('literal')\"\r\n >\r\n Valore\r\n </button>\r\n }\r\n @if (allowFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'formula'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Espressione calcolata dal motore di regole\"\r\n (click)=\"setMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n @if (globalConstants().length) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"mode() === 'globalConstant'\"\r\n [disabled]=\"disabled()\"\r\n title=\"Costante globale\"\r\n (click)=\"setMode('globalConstant')\"\r\n >\r\n Costante globale\r\n </button>\r\n }\r\n @if (mode() !== 'empty') {\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode fb-value__mode--clear\"\r\n [disabled]=\"disabled()\"\r\n title=\"Nessun valore\"\r\n (click)=\"setMode('empty')\"\r\n >\r\n ×\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (isAmbiguous()) {\r\n <!-- Piu' campi di valore insieme: il comportamento a runtime dipende dall'ordine di lettura. -->\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo valore ha {{ filledFieldCount() }} campi valorizzati insieme: a runtime conta l’ordine di lettura.\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"normalize()\">\r\n Tieni solo «{{ mode() === 'formula' ? 'formula' : mode() === 'literal' ? 'valore' : 'riferimento' }}»\r\n </button>\r\n </p>\r\n }\r\n\r\n @switch (mode()) {\r\n @case ('reference') {\r\n <fb-reference-picker\r\n [value]=\"value()?.elementReference\"\r\n [label]=\"label()\"\r\n [dataType]=\"dataType()\"\r\n [isCollection]=\"isCollection()\"\r\n [objectType]=\"objectType()\"\r\n [disabled]=\"disabled()\"\r\n (valueChange)=\"onReferenceChange($event)\"\r\n />\r\n }\r\n\r\n @case ('globalConstant') {\r\n <select\r\n class=\"fb-select\"\r\n [disabled]=\"disabled()\"\r\n [fbValue]=\"value()?.elementReference || ''\"\r\n (change)=\"onGlobalConstantChange($any($event.target).value)\"\r\n >\r\n @for (constant of globalConstants(); track constant) {\r\n <option [value]=\"constant\">{{ constant }}</option>\r\n }\r\n </select>\r\n }\r\n\r\n @case ('literal') {\r\n @if (dataType() === 'Boolean') {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"booleanValue()\"\r\n [disabled]=\"disabled()\"\r\n (change)=\"onBooleanChange($any($event.target).checked)\"\r\n />\r\n {{ booleanValue() ? 'vero' : 'falso' }}\r\n </label>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [type]=\"literalInputType()\"\r\n [value]=\"literalText()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [placeholder]=\"dataType() === 'Enum' ? 'Nome del valore di enum' : ''\"\r\n (input)=\"onLiteralChange($any($event.target).value)\"\r\n />\r\n @if (numericHint()) {\r\n <p class=\"fb-field__hint\">{{ numericHint() }}</p>\r\n }\r\n @if (dataType() === 'Date') {\r\n <!--\r\n Il fuso e' una scelta, non un dettaglio: `09:00Z` e `09:00` sono due istanti\r\n diversi, e il motore converte in UTC prima di ogni confronto (§4.2).\r\n -->\r\n <div class=\"fb-value__modes\" role=\"group\" aria-label=\"Fuso del valore data\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"!dateIsUtc()\"\r\n [disabled]=\"disabled()\"\r\n title=\"Interpretato nel fuso dell’applicazione\"\r\n (click)=\"setDateZone(false)\"\r\n >\r\n Ora locale\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-value__mode\"\r\n [class.fb-value__mode--active]=\"dateIsUtc()\"\r\n [disabled]=\"disabled()\"\r\n title=\"Scrive il suffisso Z: l’orario e’ in UTC\"\r\n (click)=\"setDateZone(true)\"\r\n >\r\n UTC (Z)\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Data e ora insieme.\r\n {{\r\n dateIsUtc()\r\n ? 'Con «UTC» l’orario e’ assoluto.'\r\n : 'Senza fuso l’orario e’ interpretato nel fuso dell’applicazione, non in UTC.'\r\n }}\r\n Cambiare fuso riscrive l’orario, non lo converte.\r\n </p>\r\n }\r\n }\r\n }\r\n\r\n @case ('formula') {\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"value()?.formulaExpression || ''\"\r\n [disabled]=\"disabled()\"\r\n placeholder=\"Importo * 1.22\"\r\n [attr.aria-label]=\"label() + ': espressione'\"\r\n (input)=\"onFormulaChange($any($event.target).value)\"\r\n ></textarea>\r\n <div class=\"fb-field__row\">\r\n <label class=\"fb-field__hint\">Tipo del risultato</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"value()?.formulaDataType || ''\"\r\n [disabled]=\"disabled()\"\r\n (change)=\"onFormulaTypeChange($any($event.target).value)\"\r\n >\r\n @for (type of dataTypeOptions(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n L’espressione va al motore di regole: il backend non ne verifica la sintassi.\r\n </p>\r\n }\r\n\r\n @case ('empty') {\r\n <p class=\"fb-field__hint\">Nessun valore.</p>\r\n }\r\n }\r\n</div>\r\n","/**\r\n * Editor delle condizioni — FRONTEND.md §4.3 e trappole §13.1, §13.4, §13.13, §13.14.\r\n *\r\n * Quattro cose che questo componente fa deliberatamente, perche' un editor che non le fa\r\n * produce condizioni che fanno il contrario di quello che l'utente crede:\r\n *\r\n * 1. **Operatori unari.** Sette operatori non confrontano due valori: per loro\r\n * `rightValue` e' l'**esito atteso**, non il termine di confronto. Qui il lato destro\r\n * diventa un selettore \"è / non è\", e il testo mostrato dice esplicitamente cosa\r\n * verra' scritto. Il flag arriva da `isUnary` del dizionario, non da una lista cablata.\r\n *\r\n * 2. **`conditionLogic`.** Cancellare o spostare una condizione riscrive l'espressione,\r\n * perche' gli indici sono 1-based e scalano. La riscrittura sta in\r\n * {@link removeCondition} / {@link moveCondition}.\r\n *\r\n * 3. **Testo e numero non si confrontano** (`CONDITION_TYPE_MISMATCH`, errore che blocca\r\n * l'attivazione). Il tipo del lato sinistro arriva da `POST /flows/references` e guida il\r\n * secondo operando: il letterale finisce nel campo giusto e una risorsa incompatibile e'\r\n * segnalata. Il backend segnala solo quando conosce **entrambi** i tipi, e su un campo di\r\n * un record non li conosce: fermare qui e' il solo modo di fermare in tempo.\r\n *\r\n * 4. **`None` non e' un operatore, e' un \"da completare\"**: la bozza si salva, l'attivazione\r\n * no. La condizione e' evidenziata come incompleta, non presentata come valida.\r\n *\r\n * Inoltre: `WasVisited` e `HasError` vogliono a sinistra il nome di un **node**, non di una\r\n * risorsa (`appliesToElements`), e il selettore cambia di conseguenza.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowReference } from '../../model/api.model';\r\nimport { FlowCondition, FlowConditionHolder, FlowDataType, FlowValue } from '../../model/flow.model';\r\nimport {\r\n checkConditionLogic,\r\n isCustomConditionLogic,\r\n moveCondition as moveConditionInPlace,\r\n removeCondition as removeConditionInPlace,\r\n} from '../../core/condition-logic.util';\r\nimport { areTypesComparable, isTypeCheckedOperator } from '../../core/condition-types.util';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-condition-editor',\r\n standalone: true,\r\n imports: [ReferencePickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './condition-editor.component.html',\r\n styleUrl: './condition-editor.component.css',\r\n})\r\nexport class ConditionEditorComponent {\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n\r\n /** Il contenitore: porta `conditions`, `conditionLogic` e, se serve, `formula`. */\r\n readonly holder = input.required<FlowConditionHolder>();\r\n readonly title = input<string>('Condizioni');\r\n /** `false` dove il modello non prevede la modalita' formula sull'elemento. */\r\n readonly allowFormula = input(true);\r\n /**\r\n * `false` dove il modello porta **solo** la lista di condizioni, senza un campo per la\r\n * logica: gli `entryConditions` / `exitConditions` di uno step di orchestrazione (§5.13).\r\n * Mostrare i pulsanti della logica lì scriverebbe un campo che il contratto non prevede.\r\n */\r\n readonly allowLogic = input(true);\r\n /** Path per ancorare i rilievi di validazione, es. `rules[Approvato]`. */\r\n readonly issuePath = input<string>('');\r\n\r\n /** Emesso a ogni modifica: il chiamante applica la mutazione allo store. */\r\n readonly changed = output<(holder: FlowConditionHolder) => void>();\r\n\r\n readonly conditions = computed<FlowCondition[]>(() => this.holder().conditions ?? []);\r\n\r\n /**\r\n * I riferimenti del documento, per conoscere il tipo del lato sinistro. Non e' un doppione\r\n * del picker: serve **il tipo**, che e' l'unica cosa che permette di impedire il confronto\r\n * fra testo e numero prima che lo dica la validazione (§4.3).\r\n */\r\n private readonly references = signal<FlowReference[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n const definition = this.store.document();\r\n // Senza condizioni non serve conoscere nessun tipo: in un form con molti blocchi di\r\n // condizioni vuoti (uno stage con dieci step) risparmia altrettante richieste.\r\n if (!this.conditions().length) {\r\n return;\r\n }\r\n void this.api\r\n .getReferences({ definition })\r\n .then((list) => this.references.set(list ?? []))\r\n // Senza l'elenco non si segnala nulla: non sapere non e' sapere che e' sbagliato.\r\n .catch(() => this.references.set([]));\r\n });\r\n }\r\n\r\n /** Il tipo di un riferimento, `undefined` se navigato o ignoto: lì non si segnala (§4.3). */\r\n private typeOfReference(reference: string | undefined): FlowDataType | undefined {\r\n if (!reference) {\r\n return undefined;\r\n }\r\n return this.references().find((entry) => entry.name === reference)?.dataType ?? undefined;\r\n }\r\n\r\n /** Il tipo del lato sinistro: guida il secondo operando. */\r\n leftDataType(condition: FlowCondition): FlowDataType | undefined {\r\n return this.typeOfReference(condition.leftValueReference);\r\n }\r\n\r\n /** Il tipo del lato destro, dedotto dal campo valorizzato o dal riferimento scelto. */\r\n private rightDataType(condition: FlowCondition): FlowDataType | undefined {\r\n const value = condition.rightValue;\r\n if (!value) {\r\n return undefined;\r\n }\r\n if (value.formulaExpression !== undefined) {\r\n return value.formulaDataType;\r\n }\r\n if (value.elementReference !== undefined) {\r\n return this.typeOfReference(value.elementReference);\r\n }\r\n if (value.stringValue !== undefined) {\r\n return 'String';\r\n }\r\n if (value.integerValue !== undefined) {\r\n return 'Integer';\r\n }\r\n if (value.numberValue !== undefined) {\r\n return 'Number';\r\n }\r\n if (value.dateValue !== undefined) {\r\n return 'Date';\r\n }\r\n if (value.booleanValue !== undefined) {\r\n return 'Boolean';\r\n }\r\n if (value.enumValue !== undefined) {\r\n return 'Enum';\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * `true` quando i due lati sono incompatibili: e' `CONDITION_TYPE_MISMATCH`, un errore che\r\n * blocca l'attivazione. L'unica coppia vietata e' testo con numero (§4.3).\r\n */\r\n hasTypeMismatch(condition: FlowCondition): boolean {\r\n if (!isTypeCheckedOperator(condition.operator, this.isUnary(condition))) {\r\n return false;\r\n }\r\n return !areTypesComparable(this.leftDataType(condition), this.rightDataType(condition));\r\n }\r\n\r\n typeMismatchMessage(condition: FlowCondition): string {\r\n const left = this.leftDataType(condition) ?? '?';\r\n const right = this.rightDataType(condition) ?? '?';\r\n return `Un valore ${left} non si confronta con un valore ${right}: e’ CONDITION_TYPE_MISMATCH e blocca l’attivazione.`;\r\n }\r\n\r\n readonly logicMode = computed<'and' | 'or' | 'custom' | 'formula'>(() => {\r\n const logic = this.holder().conditionLogic;\r\n if (!logic) {\r\n // Assente = tutte le condizioni devono essere vere (§4.3).\r\n return 'and';\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n if (normalized === 'and') {\r\n return 'and';\r\n }\r\n if (normalized === 'or') {\r\n return 'or';\r\n }\r\n if (normalized === 'formula') {\r\n return 'formula';\r\n }\r\n return 'custom';\r\n });\r\n\r\n readonly customLogic = computed(() =>\r\n isCustomConditionLogic(this.holder().conditionLogic) ? (this.holder().conditionLogic as string) : '',\r\n );\r\n\r\n /** Feedback immediato sull'espressione: la verita' resta della validazione backend. */\r\n readonly customLogicError = computed(() => {\r\n const logic = this.customLogic();\r\n return logic ? checkConditionLogic(logic, this.conditions().length) : null;\r\n });\r\n\r\n /** Con `Formula` il campo `conditions` viene **ignorato** dal motore (§4.3). */\r\n readonly conditionsIgnored = computed(() => this.logicMode() === 'formula');\r\n\r\n /**\r\n * Gli operatori applicabili al tipo del lato sinistro: `appliesTo` del dizionario, vuoto =\r\n * qualunque tipo (§4.3). L'operatore già scritto si tiene comunque nell'elenco, altrimenti\r\n * il `select` resterebbe vuoto pur avendo un valore.\r\n */\r\n operatorsFor(condition: FlowCondition): ReturnType<FlowDictionaryStore['operatorsFor']> {\r\n const applicable = this.dictionaries.operatorsFor(this.leftDataType(condition));\r\n if (!condition.operator || applicable.some((entry) => entry.value === condition.operator)) {\r\n return applicable;\r\n }\r\n const current = this.dictionaries.operator(condition.operator);\r\n return current ? [...applicable, current] : applicable;\r\n }\r\n\r\n isUnary(condition: FlowCondition): boolean {\r\n return this.dictionaries.isUnaryOperator(condition.operator);\r\n }\r\n\r\n appliesToElements(condition: FlowCondition): boolean {\r\n return this.dictionaries.operatorAppliesToElements(condition.operator);\r\n }\r\n\r\n /** L'esito atteso di un operatore unario: assente equivale a `true` (§4.3). */\r\n unaryExpectation(condition: FlowCondition): boolean {\r\n return condition.rightValue?.booleanValue !== false;\r\n }\r\n\r\n /**\r\n * Testo che dice cosa e' stato scritto, in italiano. Serve perche' la differenza fra\r\n * `IsNull` + `true` e `IsNull` + `false` e' invisibile nel JSON e capitale a runtime.\r\n */\r\n unarySummary(condition: FlowCondition): string {\r\n const label = this.operatorLabel(condition.operator).toLowerCase();\r\n const left = condition.leftValueReference || '…';\r\n return this.unaryExpectation(condition) ? `${left} ${label}` : `${left} NON ${label}`;\r\n }\r\n\r\n operatorLabel(operator: string | undefined): string {\r\n if (!operator) {\r\n return '';\r\n }\r\n return this.dictionaries.operator(operator)?.label ?? operator;\r\n }\r\n\r\n operatorDescription(operator: string | undefined): string | null {\r\n return this.dictionaries.operator(operator)?.description ?? null;\r\n }\r\n\r\n /**\r\n * `None` e' uno stato dell'editor, non un operatore: la **bozza si salva, l'attivazione no**\r\n * (`CONDITION_INCOMPLETE`, errore). A runtime vale sempre falso (§4.3, §13.14).\r\n */\r\n isPlaceholderOperator(condition: FlowCondition): boolean {\r\n return condition.operator === 'None';\r\n }\r\n\r\n /** Quante condizioni sono da completare: si dice in testa, non solo riga per riga. */\r\n readonly incompleteCount = computed(\r\n () => this.conditions().filter((condition) => condition.operator === 'None').length,\r\n );\r\n\r\n // -------------------------------------------------------------------------\r\n // Mutazioni\r\n // -------------------------------------------------------------------------\r\n\r\n addCondition(): void {\r\n this.changed.emit((holder) => {\r\n holder.conditions ??= [];\r\n holder.conditions.push({ operator: 'EqualTo' });\r\n });\r\n }\r\n\r\n removeCondition(index: number): void {\r\n this.changed.emit((holder) => {\r\n // Riscrive `conditionLogic`: gli indici sono 1-based e scalano (§13.4).\r\n removeConditionInPlace(holder, index);\r\n });\r\n }\r\n\r\n moveCondition(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.conditions().length) {\r\n return;\r\n }\r\n this.changed.emit((holder) => moveConditionInPlace(holder, index, target));\r\n }\r\n\r\n setLogicMode(mode: 'and' | 'or' | 'custom' | 'formula'): void {\r\n this.changed.emit((holder) => {\r\n switch (mode) {\r\n case 'and':\r\n holder.conditionLogic = 'and';\r\n break;\r\n case 'or':\r\n holder.conditionLogic = 'or';\r\n break;\r\n case 'custom': {\r\n // Espressione iniziale che riproduce l'AND corrente: cambiarla e' un passo\r\n // esplicito dell'utente, non un effetto collaterale del cambio di modalita'.\r\n const count = holder.conditions?.length ?? 0;\r\n holder.conditionLogic = count\r\n ? Array.from({ length: count }, (_, index) => index + 1).join(' AND ')\r\n : '1';\r\n break;\r\n }\r\n case 'formula':\r\n holder.conditionLogic = 'Formula';\r\n holder.formula ??= '';\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setCustomLogic(logic: string): void {\r\n this.changed.emit((holder) => {\r\n holder.conditionLogic = logic;\r\n });\r\n }\r\n\r\n setFormula(formula: string): void {\r\n this.changed.emit((holder) => {\r\n holder.formula = formula;\r\n });\r\n }\r\n\r\n setLeft(index: number, reference: string | undefined): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n condition.leftValueReference = reference;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n const becomesUnary = this.dictionaries.isUnaryOperator(operator);\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (!condition) {\r\n return;\r\n }\r\n condition.operator = operator;\r\n if (becomesUnary) {\r\n // Passando a un unario, il vecchio termine di confronto non significa piu'\r\n // \"confronta con questo\" ma \"l'esito atteso e' questo\": va riscritto, non tenuto.\r\n condition.rightValue = { booleanValue: true };\r\n } else if (condition.rightValue?.booleanValue !== undefined && operator !== 'EqualTo') {\r\n condition.rightValue = undefined;\r\n }\r\n });\r\n }\r\n\r\n setRightValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n condition.rightValue = value;\r\n }\r\n });\r\n }\r\n\r\n setUnaryExpectation(index: number, expectation: boolean): void {\r\n this.changed.emit((holder) => {\r\n const condition = holder.conditions?.[index];\r\n if (condition) {\r\n // Esplicito in entrambi i casi: `false` significa \"non è\", e omettere il campo\r\n // significherebbe \"è\".\r\n condition.rightValue = { booleanValue: expectation };\r\n }\r\n });\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (allowLogic()) {\r\n <div class=\"fb-cond__logic\">\r\n <label class=\"fb-field__label\">Come si combinano</label>\r\n <div class=\"fb-cond__modes\" role=\"group\" aria-label=\"Logica delle condizioni\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'and'\"\r\n title=\"Tutte le condizioni devono essere vere\"\r\n (click)=\"setLogicMode('and')\"\r\n >\r\n Tutte (AND)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'or'\"\r\n title=\"Almeno una condizione deve essere vera\"\r\n (click)=\"setLogicMode('or')\"\r\n >\r\n Almeno una (OR)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'custom'\"\r\n title=\"Espressione sugli indici delle condizioni, es. 1 AND (2 OR 3)\"\r\n (click)=\"setLogicMode('custom')\"\r\n >\r\n Espressione\r\n </button>\r\n @if (allowFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"logicMode() === 'formula'\"\r\n title=\"L’esito lo determina una formula: le condizioni vengono ignorate\"\r\n (click)=\"setLogicMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Devono essere vere <strong>tutte</strong>: qui il modello non prevede una logica separata.\r\n </p>\r\n }\r\n\r\n @if (logicMode() === 'custom') {\r\n <div class=\"fb-field\">\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!customLogicError()\"\r\n [value]=\"customLogic()\"\r\n placeholder=\"1 AND (2 OR 3)\"\r\n aria-label=\"Espressione sugli indici delle condizioni\"\r\n (input)=\"setCustomLogic($any($event.target).value)\"\r\n />\r\n @if (customLogicError()) {\r\n <p class=\"fb-field__error\">{{ customLogicError() }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint\">\r\n Gli indici sono 1-based e si riferiscono all’ordine sotto. Cancellare una condizione riscrive\r\n l’espressione automaticamente.\r\n </p>\r\n }\r\n </div>\r\n }\r\n\r\n @if (logicMode() === 'formula') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Formula</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"holder().formula || ''\"\r\n placeholder=\"AND(Esito = 'KO', Importo > 1000)\"\r\n (input)=\"setFormula($any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">\r\n Con la modalita’ Formula le condizioni sotto vengono ignorate dal motore.\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (conditionsIgnored() && conditions().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Ci sono {{ conditions().length }} condizioni ma la logica e’ «Formula»: il motore le ignora.\r\n </p>\r\n }\r\n\r\n @if (incompleteCount()) {\r\n <!-- `None` blocca l'attivazione: la bozza si salva, la versione attiva no (§13.14). -->\r\n <p class=\"fb-callout fb-callout--error\">\r\n {{ incompleteCount() === 1 ? 'Una condizione e’' : incompleteCount() + ' condizioni sono' }} da\r\n completare: la bozza si salva, l’attivazione no (CONDITION_INCOMPLETE).\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (condition of conditions(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <!-- L'indice e' 1-based perche' e' quello che l'espressione referenzia. -->\r\n <span class=\"fb-list__index\" [title]=\"'Indice ' + ($index + 1) + ' nell’espressione'\">\r\n {{ $index + 1 }}\r\n </span>\r\n @if (isPlaceholderOperator(condition)) {\r\n <span\r\n class=\"fb-cond__placeholder\"\r\n title=\"A runtime vale sempre falso, e l’attivazione la rifiuta: va completata\"\r\n >\r\n da completare\r\n </span>\r\n }\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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveCondition($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveCondition($index, 1)\"\r\n >\r\n ↓\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 la condizione\"\r\n (click)=\"removeCondition($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ appliesToElements(condition) ? 'Elemento' : 'Risorsa' }}\r\n </label>\r\n <fb-reference-picker\r\n [value]=\"condition.leftValueReference\"\r\n [elementsOnly]=\"appliesToElements(condition)\"\r\n [placeholder]=\"appliesToElements(condition) ? 'Scegli un elemento del flow' : 'Scegli una risorsa'\"\r\n (valueChange)=\"setLeft($index, $event)\"\r\n />\r\n @if (appliesToElements(condition)) {\r\n <p class=\"fb-field__hint\">\r\n Questo operatore si applica a un elemento del flow, non a una risorsa.\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operatore</label>\r\n <select\r\n class=\"fb-select\"\r\n [class.fb-input--invalid]=\"isPlaceholderOperator(condition)\"\r\n [fbValue]=\"condition.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n <!-- Filtrati per il tipo del lato sinistro: `appliesTo` del dizionario (§4.3). -->\r\n @for (operator of operatorsFor(condition); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n @if (isPlaceholderOperator(condition)) {\r\n <p class=\"fb-field__error\">\r\n Segnaposto: a runtime vale sempre falso e l’attivazione lo rifiuta\r\n (CONDITION_INCOMPLETE). Scegli un operatore.\r\n </p>\r\n } @else if (operatorDescription(condition.operator)) {\r\n <p class=\"fb-field__hint\">{{ operatorDescription(condition.operator) }}</p>\r\n }\r\n </div>\r\n\r\n @if (isUnary(condition)) {\r\n <!--\r\n Trappola numero uno: per gli operatori unari `rightValue` non e' il termine di\r\n confronto ma l'esito atteso. Qui non c'e' un campo \"valore da confrontare\":\r\n c'e' un selettore che dice quale delle due cose si sta chiedendo.\r\n -->\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Esito atteso</label>\r\n <div class=\"fb-cond__unary\" role=\"group\" aria-label=\"Esito atteso\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"unaryExpectation(condition)\"\r\n (click)=\"setUnaryExpectation($index, true)\"\r\n >\r\n {{ operatorLabel(condition.operator) }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-cond__mode\"\r\n [class.fb-cond__mode--active]=\"!unaryExpectation(condition)\"\r\n (click)=\"setUnaryExpectation($index, false)\"\r\n >\r\n NON {{ operatorLabel(condition.operator) }}\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Questa condizione e’ vera quando: <strong>{{ unarySummary(condition) }}</strong>.\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Confronta con</label>\r\n <!--\r\n Il tipo del lato sinistro guida il secondo operando: il letterale finisce nel\r\n campo giusto e le risorse proposte sono quelle compatibili. Testo con numero e'\r\n CONDITION_TYPE_MISMATCH e blocca l'attivazione (§4.3).\r\n -->\r\n <fb-value-editor\r\n [value]=\"condition.rightValue\"\r\n label=\"Valore di confronto\"\r\n [dataType]=\"leftDataType(condition)\"\r\n (valueChange)=\"setRightValue($index, $event)\"\r\n />\r\n @if (hasTypeMismatch(condition)) {\r\n <p class=\"fb-field__error\">{{ typeMismatchMessage(condition) }}</p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna condizione.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addCondition()\">Aggiungi condizione</button>\r\n</fieldset>\r\n","/**\r\n * Editor dei filtri sui record — FRONTEND.md §4.4.\r\n *\r\n * I filtri sono una struttura **diversa** dalle condizioni: agiscono su campi di un'entita',\r\n * non su risorse, e il loro operatore e' un altro enum (`recordFilterOperators`).\r\n *\r\n * Due dettagli che il modello impone e che qui sono espliciti:\r\n *\r\n * - **`filterLogic` non esiste su tutti gli elementi che hanno `filters`.** C'e' su Get\r\n * Records, Create Records, Start e sugli eventi di un Wait; **non** c'e' su Update\r\n * Records, Delete Records e sui dynamic choice set, dove i filtri sono sempre in AND.\r\n * Inviarlo dove non esiste significa perderlo silenziosamente al primo salvataggio:\r\n * l'input `supportsLogic` decide se il controllo viene mostrato.\r\n *\r\n * - I campi proposti passano da `GET /schema/{object}/fields?usage=filterable`, così un\r\n * campo non filtrabile non arriva nemmeno alla validazione (`FIELD_NOT_FILTERABLE`).\r\n * La scrittura libera resta possibile, perche' i percorsi di relazione\r\n * (`Cliente.Citta`) non sono enumerabili — e la validazione non li verifica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription, FlowFieldUsage } from '../../model/dictionary.model';\r\nimport { FlowRecordFilter, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from './field-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n/** Il contenitore dei filtri, qualunque elemento sia. */\r\nexport interface FilterHolder {\r\n filters?: FlowRecordFilter[];\r\n filterLogic?: string;\r\n filterFormula?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-record-filter-editor',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-filter-editor.component.html',\r\n styleUrl: './record-filter-editor.component.css',\r\n})\r\nexport class RecordFilterEditorComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n readonly holder = input.required<FilterHolder>();\r\n readonly object = input<string | undefined>(undefined);\r\n readonly title = input<string>('Filtri');\r\n /** L'uso con cui chiedere i campi: `filterable` per i filtri, `updateable` altrove. */\r\n readonly usage = input<FlowFieldUsage>('filterable');\r\n\r\n /** `false` dove il modello non ha `filterLogic`: i filtri sono sempre in AND (§4.4). */\r\n readonly supportsLogic = input(true);\r\n /** `true` dove esiste `filterFormula` come alternativa ai filtri. */\r\n readonly supportsFormula = input(false);\r\n\r\n /**\r\n * Avviso da mostrare quando la lista e' vuota. Un Delete senza filtri e' un **errore**,\r\n * un Update senza filtri e' solo un avviso — ma aggiorna tutti i record dell'entita'\r\n * (§5.7, §13.10).\r\n */\r\n readonly emptyWarning = input<string | null>(null);\r\n readonly emptyWarningSeverity = input<'warn' | 'error'>('warn');\r\n\r\n readonly changed = output<(holder: FilterHolder) => void>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n\r\n readonly filters = computed<FlowRecordFilter[]>(() => this.holder().filters ?? []);\r\n readonly operators = computed(() => this.dictionaries.recordFilterOperators());\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n const usage = this.usage();\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, usage)\r\n .then((list) => this.fields.set(list ?? []))\r\n // Catalogo non disponibile: il campo resta scrivibile a mano.\r\n .catch(() => this.fields.set([]));\r\n });\r\n }\r\n\r\n readonly logicMode = computed<'and' | 'or' | 'custom' | 'formula'>(() => {\r\n const logic = this.holder().filterLogic;\r\n if (!logic) {\r\n return 'and';\r\n }\r\n const normalized = logic.trim().toLowerCase();\r\n if (normalized === 'and') {\r\n return 'and';\r\n }\r\n if (normalized === 'or') {\r\n return 'or';\r\n }\r\n if (normalized === 'formula') {\r\n return 'formula';\r\n }\r\n return 'custom';\r\n });\r\n\r\n readonly customLogic = computed(() => {\r\n const mode = this.logicMode();\r\n return mode === 'custom' ? (this.holder().filterLogic as string) : '';\r\n });\r\n\r\n readonly showEmptyWarning = computed(() => !!this.emptyWarning() && this.filters().length === 0);\r\n\r\n addFilter(): void {\r\n this.changed.emit((holder) => {\r\n holder.filters ??= [];\r\n holder.filters.push({ operator: 'EqualTo' });\r\n });\r\n }\r\n\r\n removeFilter(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.filters?.splice(index, 1);\r\n if (holder.filters && holder.filters.length === 0) {\r\n // Lista vuota dichiarata vs assente: il backend le distingue, ma per un diff\r\n // pulito conviene omettere le liste vuote (§2).\r\n delete holder.filters;\r\n }\r\n });\r\n }\r\n\r\n setField(index: number, field: string): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (!filter) {\r\n return;\r\n }\r\n filter.operator = operator;\r\n if (operator === 'IsNull') {\r\n // `IsNull` fra i filtri sui record e' l'unico unario: `value` e' l'esito atteso.\r\n filter.value = { booleanValue: true };\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.value = value;\r\n }\r\n });\r\n }\r\n\r\n isNullOperator(filter: FlowRecordFilter): boolean {\r\n return filter.operator === 'IsNull';\r\n }\r\n\r\n nullExpectation(filter: FlowRecordFilter): boolean {\r\n return filter.value?.booleanValue !== false;\r\n }\r\n\r\n setNullExpectation(index: number, expectation: boolean): void {\r\n this.changed.emit((holder) => {\r\n const filter = holder.filters?.[index];\r\n if (filter) {\r\n filter.value = { booleanValue: expectation };\r\n }\r\n });\r\n }\r\n\r\n setLogicMode(mode: 'and' | 'or' | 'custom' | 'formula'): void {\r\n this.changed.emit((holder) => {\r\n switch (mode) {\r\n case 'and':\r\n holder.filterLogic = 'and';\r\n break;\r\n case 'or':\r\n holder.filterLogic = 'or';\r\n break;\r\n case 'custom': {\r\n const count = holder.filters?.length ?? 0;\r\n holder.filterLogic = count\r\n ? Array.from({ length: count }, (_, index) => index + 1).join(' AND ')\r\n : '1';\r\n break;\r\n }\r\n case 'formula':\r\n holder.filterLogic = 'Formula';\r\n holder.filterFormula ??= '';\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setCustomLogic(logic: string): void {\r\n this.changed.emit((holder) => {\r\n holder.filterLogic = logic;\r\n });\r\n }\r\n\r\n setFormula(formula: string): void {\r\n this.changed.emit((holder) => {\r\n holder.filterFormula = formula;\r\n });\r\n }\r\n\r\n /**\r\n * Il tipo del campo, per proporre il controllo giusto sul valore: e' il motivo per cui il\r\n * catalogo resta caricato qui, e non solo dentro il picker.\r\n */\r\n fieldDataType(filter: FlowRecordFilter): string | undefined {\r\n return this.fields().find((field) => field.name === filter.field)?.dataType;\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (!object()) {\r\n <p class=\"fb-field__hint\">Scegli prima un oggetto per poter filtrare sui suoi campi.</p>\r\n }\r\n\r\n @if (supportsLogic()) {\r\n <div class=\"fb-filter__modes\" role=\"group\" aria-label=\"Logica dei filtri\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'and'\"\r\n (click)=\"setLogicMode('and')\"\r\n >\r\n Tutti (AND)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'or'\"\r\n (click)=\"setLogicMode('or')\"\r\n >\r\n Almeno uno (OR)\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'custom'\"\r\n (click)=\"setLogicMode('custom')\"\r\n >\r\n Espressione\r\n </button>\r\n @if (supportsFormula()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"logicMode() === 'formula'\"\r\n (click)=\"setLogicMode('formula')\"\r\n >\r\n Formula\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Qui il modello non ha `filterLogic`: mostrarlo lo farebbe perdere al salvataggio. -->\r\n <p class=\"fb-field__hint\">Su questo elemento i filtri sono sempre combinati in AND.</p>\r\n }\r\n\r\n @if (supportsLogic() && logicMode() === 'custom') {\r\n <div class=\"fb-field\">\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [value]=\"customLogic()\"\r\n placeholder=\"1 AND (2 OR 3)\"\r\n aria-label=\"Espressione sugli indici dei filtri\"\r\n (input)=\"setCustomLogic($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (supportsFormula() && logicMode() === 'formula') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Formula di filtro</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"holder().filterFormula || ''\"\r\n (input)=\"setFormula($any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">Valutata dal motore di regole, in alternativa ai filtri.</p>\r\n </div>\r\n }\r\n\r\n @if (showEmptyWarning()) {\r\n <p\r\n class=\"fb-callout\"\r\n [class.fb-callout--warn]=\"emptyWarningSeverity() === 'warn'\"\r\n [class.fb-callout--error]=\"emptyWarningSeverity() === 'error'\"\r\n >\r\n {{ emptyWarning() }}\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (filter of filters(); 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 il filtro\"\r\n (click)=\"removeFilter($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo</label>\r\n <fb-field-picker\r\n [value]=\"filter.field\"\r\n [object]=\"object()\"\r\n [usage]=\"usage()\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setField($index, $event ?? '')\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operatore</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"filter.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n @for (operator of operators(); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (isNullOperator(filter)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Esito atteso</label>\r\n <div class=\"fb-filter__modes\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"nullExpectation(filter)\"\r\n (click)=\"setNullExpectation($index, true)\"\r\n >\r\n è vuoto\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-filter__mode\"\r\n [class.fb-filter__mode--active]=\"!nullExpectation(filter)\"\r\n (click)=\"setNullExpectation($index, false)\"\r\n >\r\n non è vuoto\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor\r\n [value]=\"filter.value\"\r\n [dataType]=\"fieldDataType(filter)\"\r\n label=\"Valore del filtro\"\r\n [allowFormula]=\"false\"\r\n (valueChange)=\"setValue($index, $event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun filtro.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addFilter()\">Aggiungi filtro</button>\r\n</fieldset>\r\n","/**\r\n * Editor dei parametri di input e output — FRONTEND.md §5.1, §5.8, §5.9.\r\n *\r\n * I nomi dei parametri sono quelli che il form, l'action o lo script si aspettano. Quando\r\n * il catalogo li espone (`.../parameters`) vengono proposti, e con il catalogo popolato un\r\n * nome inesistente e' un **errore** di validazione (`PARAMETER_UNKNOWN`). Con il catalogo\r\n * vuoto — che significa \"non lo so\", non \"nessuno\" — la scrittura resta libera.\r\n *\r\n * Gli output vanno in `assignToReference`, che deve essere una destinazione **scrivibile**:\r\n * il selettore chiede `POST /flows/references/writable`, così una costante o una formula\r\n * non sono nemmeno proponibili (`TARGET_NOT_WRITABLE`).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n input,\r\n output,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowInputParameter, FlowOutputParameter, FlowValue } from '../../model/flow.model';\r\nimport { NamePickerComponent, NamePickerOption } from './name-picker.component';\r\nimport { ReferencePickerComponent } from './reference-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\n\r\n/** Contenitore generico: gli input hanno `value`, gli output `assignToReference`. */\r\nexport interface ParameterHolder {\r\n inputParameters?: FlowInputParameter[];\r\n outputParameters?: FlowOutputParameter[];\r\n}\r\n\r\n/** Un parametro del catalogo come opzione: nome, label, tipo, obbligatorieta' e descrizione. */\r\nfunction describeParameter(parameter: FlowCatalogParameter): NamePickerOption {\r\n const parts: string[] = [];\r\n if (parameter.dataType) {\r\n const type = parameter.isCollection ? `${parameter.dataType}[]` : parameter.dataType;\r\n parts.push(parameter.objectType ? `${type} · ${parameter.objectType}` : type);\r\n }\r\n if (parameter.isRequired) {\r\n parts.push('obbligatorio');\r\n }\r\n if (parameter.description) {\r\n parts.push(parameter.description);\r\n }\r\n return {\r\n name: parameter.name,\r\n label: parameter.label,\r\n description: parts.join(' · ') || null,\r\n };\r\n}\r\n\r\n@Component({\r\n selector: 'fb-parameter-editor',\r\n standalone: true,\r\n imports: [NamePickerComponent, ReferencePickerComponent, ValueEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './parameter-editor.component.html',\r\n styleUrl: './parameter-editor.component.css',\r\n})\r\nexport class ParameterEditorComponent {\r\n readonly holder = input.required<ParameterHolder>();\r\n /** Parametri dichiarati dal catalogo; vuoto = catalogo non popolato. */\r\n readonly catalogParameters = input<FlowCatalogParameter[]>([]);\r\n readonly inputTitle = input<string>('Parametri di ingresso');\r\n readonly outputTitle = input<string>('Parametri di uscita');\r\n readonly showInputs = input(true);\r\n readonly showOutputs = input(true);\r\n /** `true` → gli output vanno all'output automatico, e i parametri sono ignorati. */\r\n readonly outputsDisabledReason = input<string | null>(null);\r\n\r\n readonly changed = output<(holder: ParameterHolder) => void>();\r\n\r\n readonly inputs = computed<FlowInputParameter[]>(() => this.holder().inputParameters ?? []);\r\n readonly outputs = computed<FlowOutputParameter[]>(() => this.holder().outputParameters ?? []);\r\n\r\n readonly hasCatalog = computed(() => this.catalogParameters().length > 0);\r\n\r\n readonly inputCatalog = computed(() =>\r\n this.catalogParameters().filter((parameter) => parameter.isOutput !== true),\r\n );\r\n readonly outputCatalog = computed(() =>\r\n this.catalogParameters().filter((parameter) => parameter.isOutput === true),\r\n );\r\n\r\n /**\r\n * I candidati come li vuole il picker. Il tipo e l'obbligatorieta' finiscono nella\r\n * descrizione: nel `<select>` erano un asterisco muto, che non diceva quale valore ci sta.\r\n */\r\n readonly inputOptions = computed<NamePickerOption[]>(() => this.inputCatalog().map(describeParameter));\r\n readonly outputOptions = computed<NamePickerOption[]>(() => this.outputCatalog().map(describeParameter));\r\n\r\n /** Parametri obbligatori dichiarati dal catalogo e non ancora presenti. */\r\n readonly missingRequired = computed<FlowCatalogParameter[]>(() => {\r\n if (!this.hasCatalog()) {\r\n return [];\r\n }\r\n const present = new Set(this.inputs().map((parameter) => parameter.name));\r\n return this.inputCatalog().filter((parameter) => parameter.isRequired && !present.has(parameter.name));\r\n });\r\n\r\n /**\r\n * Il parametro fuori catalogo (`PARAMETER_UNKNOWN`) lo segnala il picker, che ha in mano sia\r\n * l'elenco sia il valore. Qui resta la descrizione, che serve all'editor di valore.\r\n */\r\n describe(name: string | undefined): FlowCatalogParameter | undefined {\r\n return this.catalogParameters().find((parameter) => parameter.name === name);\r\n }\r\n\r\n addInput(name?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.inputParameters ??= [];\r\n holder.inputParameters.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n addOutput(name?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.outputParameters ??= [];\r\n holder.outputParameters.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeInput(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.inputParameters?.splice(index, 1);\r\n if (holder.inputParameters?.length === 0) {\r\n delete holder.inputParameters;\r\n }\r\n });\r\n }\r\n\r\n removeOutput(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.outputParameters?.splice(index, 1);\r\n if (holder.outputParameters?.length === 0) {\r\n delete holder.outputParameters;\r\n }\r\n });\r\n }\r\n\r\n setInputName(index: number, name: string): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.inputParameters?.[index];\r\n if (parameter) {\r\n parameter.name = name;\r\n }\r\n });\r\n }\r\n\r\n setInputValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.inputParameters?.[index];\r\n if (parameter) {\r\n parameter.value = value;\r\n }\r\n });\r\n }\r\n\r\n setOutputName(index: number, name: string): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.outputParameters?.[index];\r\n if (parameter) {\r\n parameter.name = name;\r\n }\r\n });\r\n }\r\n\r\n setOutputTarget(index: number, reference: string | undefined): void {\r\n this.changed.emit((holder) => {\r\n const parameter = holder.outputParameters?.[index];\r\n if (parameter) {\r\n parameter.assignToReference = reference;\r\n }\r\n });\r\n }\r\n}\r\n","@if (showInputs()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ inputTitle() }}</legend>\r\n\r\n @if (missingRequired().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Parametri obbligatori non ancora impostati:\r\n @for (parameter of missingRequired(); track parameter.name) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"addInput(parameter.name)\">\r\n + {{ parameter.name }}\r\n </button>\r\n }\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (parameter of inputs(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"parameter.name\"\r\n [options]=\"inputOptions()\"\r\n label=\"Nome del parametro\"\r\n placeholder=\"Scrivi o scegli un parametro\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Il catalogo non dichiara questo parametro: la validazione lo segnalerebbe come errore.\"\r\n unknownSeverity=\"error\"\r\n emptyMessage=\"Parametri dichiarati non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setInputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il parametro\"\r\n (click)=\"removeInput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <fb-value-editor\r\n [value]=\"parameter.value\"\r\n [dataType]=\"describe(parameter.name)?.dataType\"\r\n [objectType]=\"describe(parameter.name)?.objectType || undefined\"\r\n [isCollection]=\"describe(parameter.name)?.isCollection\"\r\n label=\"Valore del parametro\"\r\n (valueChange)=\"setInputValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun parametro di ingresso.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addInput()\">Aggiungi parametro</button>\r\n </fieldset>\r\n}\r\n\r\n@if (showOutputs()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ outputTitle() }}</legend>\r\n\r\n @if (outputsDisabledReason()) {\r\n <p class=\"fb-callout\">{{ outputsDisabledReason() }}</p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (parameter of outputs(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"parameter.name\"\r\n [options]=\"outputOptions()\"\r\n label=\"Nome del parametro di uscita\"\r\n placeholder=\"Scrivi o scegli un parametro\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Il catalogo non dichiara questo parametro di uscita.\"\r\n unknownSeverity=\"error\"\r\n emptyMessage=\"Parametri di uscita dichiarati non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setOutputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il parametro\"\r\n (click)=\"removeOutput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <!-- Solo variabili: assegnare a una costante o a una formula e' un errore. -->\r\n <fb-reference-picker\r\n [value]=\"parameter.assignToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"describe(parameter.name)?.dataType\"\r\n [isCollection]=\"describe(parameter.name)?.isCollection\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun parametro di uscita.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutput()\">Aggiungi parametro</button>\r\n </fieldset>\r\n}\r\n","/**\r\n * Editor di `inputAssignments` — FRONTEND.md §5.7.\r\n *\r\n * Campo dell'entita' → valore. I campi proposti passano da\r\n * `GET /schema/{object}/fields?usage=updateable`, perche' scrivere su un campo non\r\n * aggiornabile e' `FIELD_NOT_UPDATEABLE`.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription } from '../../model/dictionary.model';\r\nimport { FlowInputFieldAssignment, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from './field-picker.component';\r\nimport { ValueEditorComponent } from './value-editor.component';\r\n\r\nexport interface FieldAssignmentHolder {\r\n inputAssignments?: FlowInputFieldAssignment[];\r\n}\r\n\r\n@Component({\r\n selector: 'fb-field-assignment-editor',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ValueEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './field-assignment-editor.component.html',\r\n styleUrl: './field-assignment-editor.component.css',\r\n})\r\nexport class FieldAssignmentEditorComponent {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly holder = input.required<FieldAssignmentHolder>();\r\n readonly object = input<string | undefined>(undefined);\r\n readonly title = input<string>('Valori dei campi');\r\n readonly disabledReason = input<string | null>(null);\r\n\r\n readonly changed = output<(holder: FieldAssignmentHolder) => void>();\r\n\r\n private readonly fields = signal<FlowFieldDescription[]>([]);\r\n\r\n readonly assignments = computed<FlowInputFieldAssignment[]>(() => this.holder().inputAssignments ?? []);\r\n readonly hasCatalog = computed(() => this.fields().length > 0);\r\n\r\n /** Campi obbligatori dell'entita' non ancora valorizzati. */\r\n readonly missingRequired = computed<FlowFieldDescription[]>(() => {\r\n if (!this.hasCatalog()) {\r\n return [];\r\n }\r\n const present = new Set(this.assignments().map((assignment) => assignment.field));\r\n return this.fields().filter((field) => field.isRequired && !present.has(field.name));\r\n });\r\n\r\n constructor() {\r\n effect(() => {\r\n const object = this.object();\r\n if (!object) {\r\n this.fields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, 'updateable')\r\n .then((list) => this.fields.set(list ?? []))\r\n .catch(() => this.fields.set([]));\r\n });\r\n }\r\n\r\n add(field?: string): void {\r\n this.changed.emit((holder) => {\r\n holder.inputAssignments ??= [];\r\n holder.inputAssignments.push({ field: field ?? '' });\r\n });\r\n }\r\n\r\n remove(index: number): void {\r\n this.changed.emit((holder) => {\r\n holder.inputAssignments?.splice(index, 1);\r\n if (holder.inputAssignments?.length === 0) {\r\n delete holder.inputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setField(index: number, field: string): void {\r\n this.changed.emit((holder) => {\r\n const assignment = holder.inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.changed.emit((holder) => {\r\n const assignment = holder.inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.value = value;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Il tipo del campo serve all'editor di valore: e' il motivo per cui il catalogo resta\r\n * caricato anche qui, oltre che dentro il picker.\r\n */\r\n describe(name: string | undefined): FlowFieldDescription | undefined {\r\n return this.fields().find((field) => field.name === name);\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @if (disabledReason()) {\r\n <p class=\"fb-callout\">{{ disabledReason() }}</p>\r\n }\r\n @if (!object()) {\r\n <p class=\"fb-field__hint\">Scegli prima un oggetto per poterne valorizzare i campi.</p>\r\n }\r\n @if (missingRequired().length) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Campi obbligatori non valorizzati:\r\n @for (field of missingRequired(); track field.name) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"add(field.name)\">\r\n + {{ field.label || field.name }}\r\n </button>\r\n }\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (assignment of assignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-field-picker\r\n [value]=\"assignment.field\"\r\n [object]=\"object()\"\r\n usage=\"updateable\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setField($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"remove($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <fb-value-editor\r\n [value]=\"assignment.value\"\r\n [dataType]=\"describe(assignment.field)?.dataType\"\r\n [objectType]=\"describe(assignment.field)?.objectType || undefined\"\r\n label=\"Valore del campo\"\r\n (valueChange)=\"setValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun campo valorizzato.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"add()\">Aggiungi campo</button>\r\n</fieldset>\r\n","/**\r\n * Editor delle uscite di un elemento — FRONTEND.md §3.5.\r\n *\r\n * Le destinazioni arrivano da `POST /flows/connector-targets?excluding={nome del node}`:\r\n * escludendo l'elemento stesso si evita `CONNECTOR_SELF_LOOP` senza dover ricordare la\r\n * regola in dieci form diversi.\r\n *\r\n * Tre cose che questo editor dice a voce alta, perche' nel JSON non si vedono:\r\n * - un connector assente e' **legittimo**: il percorso finisce lì (Info, non errore);\r\n * - tranne dove il ramo e' strutturale, come il corpo di un Loop;\r\n * - `isGoTo` e' solo un suggerimento di disegno: la semantica di esecuzione e' identica.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowOutlet } from '../../core/element-outlets';\r\nimport { FlowConnectorTarget } from '../../model/api.model';\r\nimport { FlowAnyNode } from '../../model/flow.model';\r\nimport { SelectValueDirective } from './select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-connector-editor',\r\n standalone: true,\r\n imports: [SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './connector-editor.component.html',\r\n styleUrl: './connector-editor.component.css',\r\n})\r\nexport class ConnectorEditorComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n\r\n /** Il node di cui si editano le uscite; per lo Start passa il nome fittizio. */\r\n readonly nodeName = input.required<string>();\r\n readonly node = input.required<FlowAnyNode>();\r\n readonly outlets = input.required<FlowOutlet[]>();\r\n readonly title = input<string>('Uscite');\r\n\r\n readonly connectorChanged = output<{ outletKey: string; target?: string; isGoTo?: boolean }>();\r\n\r\n private readonly targets = signal<FlowConnectorTarget[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n const definition = this.store.document();\r\n const excluding = this.nodeName();\r\n void this.api\r\n .getConnectorTargets(definition, excluding)\r\n .then((list) => this.targets.set(list ?? []))\r\n .catch(() => {\r\n // Senza la primitiva si ripiega sui node del documento, che il client conosce.\r\n this.targets.set(\r\n this.store\r\n .nodes()\r\n .filter((reference) => reference.name !== excluding)\r\n .map((reference) => ({ name: reference.name, label: (reference.node.label as string) ?? null })),\r\n );\r\n });\r\n });\r\n }\r\n\r\n readonly targetOptions = computed(() => this.targets());\r\n\r\n currentTarget(outlet: FlowOutlet): string {\r\n return outlet.read(this.node())?.targetReference ?? '';\r\n }\r\n\r\n isGoTo(outlet: FlowOutlet): boolean {\r\n return outlet.read(this.node())?.isGoTo === true;\r\n }\r\n\r\n /** Il connector esiste ma non ha destinazione: ramo incompleto, da mostrare come tale. */\r\n isDangling(outlet: FlowOutlet): boolean {\r\n const connector = outlet.read(this.node());\r\n return !!connector && !connector.targetReference;\r\n }\r\n\r\n /** Nessun connector: il percorso finisce lì. Legittimo, tranne sui rami strutturali. */\r\n isTerminal(outlet: FlowOutlet): boolean {\r\n return !outlet.read(this.node());\r\n }\r\n\r\n hintFor(outlet: FlowOutlet): string | null {\r\n if (this.isDangling(outlet)) {\r\n return 'Ramo dichiarato senza destinazione: scegline una o rimuovi il ramo.';\r\n }\r\n if (this.isTerminal(outlet)) {\r\n return outlet.isStructural\r\n ? 'Questo ramo e’ strutturale: senza destinazione l’elemento non funziona.'\r\n : 'Nessuna destinazione: il percorso finisce qui, e l’esecuzione termina.';\r\n }\r\n return null;\r\n }\r\n\r\n setTarget(outlet: FlowOutlet, target: string): void {\r\n this.connectorChanged.emit({ outletKey: outlet.key, target: target || undefined });\r\n }\r\n\r\n setGoTo(outlet: FlowOutlet, isGoTo: boolean): void {\r\n this.connectorChanged.emit({\r\n outletKey: outlet.key,\r\n target: this.currentTarget(outlet) || undefined,\r\n isGoTo,\r\n });\r\n }\r\n\r\n clear(outlet: FlowOutlet): void {\r\n this.connectorChanged.emit({ outletKey: outlet.key, target: undefined, isGoTo: false });\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">{{ title() }}</legend>\r\n\r\n @for (outlet of outlets(); track outlet.key) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\" [class.fb-field__label--required]=\"outlet.isStructural\">\r\n {{ outlet.label }}\r\n <span class=\"fb-conn__kind\" [attr.data-kind]=\"outlet.kind\">{{ outlet.kind }}</span>\r\n </label>\r\n\r\n <div class=\"fb-field__row\">\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"currentTarget(outlet)\"\r\n [attr.aria-label]=\"'Destinazione di ' + outlet.label\"\r\n (change)=\"setTarget(outlet, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— nessuna destinazione —</option>\r\n @for (target of targetOptions(); track target.name) {\r\n <option [value]=\"target.name\">{{ target.label || target.name }}</option>\r\n }\r\n </select>\r\n @if (!isTerminal(outlet)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi il ramo\"\r\n title=\"Rimuove il ramo: il percorso finira’ qui\"\r\n (click)=\"clear(outlet)\"\r\n >\r\n ×\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (currentTarget(outlet)) {\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"isGoTo(outlet)\" (change)=\"setGoTo(outlet, $any($event.target).checked)\" />\r\n Disegna come salto indietro (isGoTo)\r\n </label>\r\n }\r\n\r\n @if (hintFor(outlet)) {\r\n <p\r\n class=\"fb-field__hint\"\r\n [class.fb-field__hint--warn]=\"isDangling(outlet) || (isTerminal(outlet) && outlet.isStructural)\"\r\n >\r\n {{ hintFor(outlet) }}\r\n </p>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-field__hint\">Questo elemento non ha uscite: interrompe l’esecuzione.</p>\r\n }\r\n</fieldset>\r\n","/**\r\n * Base comune degli inspector.\r\n *\r\n * Ogni inspector riceve il nome dell'elemento e il node, e scrive nel documento attraverso\r\n * {@link FlowDocumentStore}: il node passato in input e' una vista di sola lettura sulla\r\n * copia corrente, e le mutazioni passano sempre per `patch()`, che lavora sulla copia di\r\n * lavoro dello store. Nessun inspector modifica l'oggetto che riceve.\r\n */\r\n\r\nimport { Directive, computed, inject, input } from '@angular/core';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowOutlet, outletsOf } from '../../core/element-outlets';\r\nimport { FlowAnyNode, FlowElementType } from '../../model/flow.model';\r\nimport { FlowValidationIssue } from '../../model/api.model';\r\n\r\n/**\r\n * `@Directive()` senza selettore: e' il modo in cui Angular riconosce come input quelli\r\n * dichiarati su una classe base ereditata da piu' componenti.\r\n */\r\n@Directive()\r\nexport abstract class NodeInspectorBase {\r\n protected readonly store = inject(FlowDocumentStore);\r\n protected readonly dictionaries = inject(FlowDictionaryStore);\r\n protected readonly validation = inject(FlowValidationStore);\r\n\r\n readonly name = input.required<string>();\r\n readonly node = input.required<FlowAnyNode>();\r\n\r\n /** Il tipo dell'elemento: ogni inspector sa il proprio, ma serve alle uscite. */\r\n abstract readonly elementType: FlowElementType;\r\n\r\n readonly outlets = computed<FlowOutlet[]>(() => outletsOf(this.elementType, this.node()));\r\n\r\n /** I rilievi ancorati a questo elemento (§7). */\r\n readonly issues = computed<FlowValidationIssue[]>(\r\n () => this.validation.issuesByElement().get(this.name()) ?? [],\r\n );\r\n\r\n /** I rilievi su un campo preciso, per evidenziarlo nel form. */\r\n issuesAt(pathPrefix: string): FlowValidationIssue[] {\r\n return this.validation.issuesAt(this.name(), pathPrefix);\r\n }\r\n\r\n hasIssueCode(code: string): boolean {\r\n return this.issues().some((issue) => issue.code === code);\r\n }\r\n\r\n /** Applica una modifica al node. */\r\n protected patch(mutate: (node: FlowAnyNode) => void): void {\r\n this.store.updateNode(this.name(), mutate);\r\n }\r\n\r\n /** Scorciatoia per i campi semplici: valore vuoto → chiave omessa (§2). */\r\n protected setField(field: string, value: unknown): void {\r\n this.patch((node) => {\r\n if (value === undefined || value === null || value === '') {\r\n delete node[field];\r\n } else {\r\n node[field] = value;\r\n }\r\n });\r\n }\r\n\r\n /** Scrive la destinazione di un'uscita. */\r\n onConnectorChanged(event: { outletKey: string; target?: string; isGoTo?: boolean }): void {\r\n this.store.setConnector(this.name(), event.outletKey, event.target, event.isGoTo);\r\n }\r\n}\r\n","/**\r\n * Action — FRONTEND.md §5.8.\r\n *\r\n * `actionType` + `actionName` identificano l'action, e i parametri arrivano dal catalogo:\r\n * con il catalogo popolato, un nome inesistente o un parametro inesistente sono **errori**.\r\n *\r\n * L'Action ha **tre uscite**: `connector`, `faultConnector`, `timeoutConnector`. Il ramo di\r\n * timeout esiste solo se `timeoutPathUsage: 'EnableTimeoutPath'`, e dichiararne uno senza\r\n * l'altro e' un avviso: qui i due controlli sono legati, come chiede la specifica.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowActionCall, FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent } from '../shared/name-picker.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-action-call-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, NamePickerComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './action-call-inspector.component.html',\r\n})\r\nexport class ActionCallInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'ActionCall';\r\n\r\n readonly action = computed<FlowActionCall>(() => this.node() as FlowActionCall);\r\n readonly transactionModels = computed(() => this.dictionaries.transactionModels());\r\n readonly offsetUnits = computed(() => this.dictionaries.offsetUnits());\r\n\r\n private readonly actionTypes = signal<FlowCatalogEntry[]>([]);\r\n private readonly actions = signal<FlowCatalogEntry[]>([]);\r\n private readonly parameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listActionTypes()\r\n .then((list) => this.actionTypes.set(list ?? []))\r\n .catch(() => this.actionTypes.set([]));\r\n\r\n effect(() => {\r\n const actionType = this.action().actionType;\r\n if (!actionType) {\r\n this.actions.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listActions(actionType)\r\n .then((list) => this.actions.set(list ?? []))\r\n .catch(() => this.actions.set([]));\r\n });\r\n\r\n effect(() => {\r\n const action = this.action();\r\n if (!action.actionType || !action.actionName) {\r\n this.parameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listActionParameters(action.actionType, action.actionName)\r\n .then((list) => this.parameters.set(list ?? []))\r\n .catch(() => this.parameters.set([]));\r\n });\r\n }\r\n\r\n readonly actionTypeOptions = computed(() => this.actionTypes());\r\n readonly actionOptions = computed(() => this.actions());\r\n readonly parameterCatalog = computed(() => this.parameters());\r\n\r\n /**\r\n * L'action fuori catalogo (`ACTION_UNKNOWN`) la segnala il picker: riceve l'elenco e il\r\n * valore, e sa già dire se il secondo e' nel primo.\r\n */\r\n readonly timeoutEnabled = computed(() => this.action().timeoutPathUsage === 'EnableTimeoutPath');\r\n\r\n /** Un ramo di timeout senza il flag, o il flag senza il ramo: avviso da segnalare (§5.8). */\r\n readonly timeoutMismatch = computed(() => {\r\n const action = this.action();\r\n const hasBranch = !!action.timeoutConnector?.targetReference;\r\n return hasBranch !== this.timeoutEnabled();\r\n });\r\n\r\n readonly storeOutputAutomatically = computed(() => this.action().storeOutputAutomatically === true);\r\n\r\n setActionType(value: string): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (action.actionType === value) {\r\n return;\r\n }\r\n action.actionType = value || undefined;\r\n // Cambiare tipo cambia l'insieme delle action e dei loro parametri.\r\n delete action.actionName;\r\n delete action.inputParameters;\r\n delete action.outputParameters;\r\n });\r\n }\r\n\r\n setActionName(value: string): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (action.actionName === value) {\r\n return;\r\n }\r\n action.actionName = value || undefined;\r\n delete action.inputParameters;\r\n delete action.outputParameters;\r\n });\r\n }\r\n\r\n setTransactionModel(value: string): void {\r\n this.setField('flowTransactionModel', value);\r\n }\r\n\r\n setWaitUntilCompleted(value: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (value) {\r\n action.isWaitUntilCompleted = true;\r\n } else {\r\n delete action.isWaitUntilCompleted;\r\n }\r\n });\r\n }\r\n\r\n setOffset(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('offset', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n setOffsetUnit(value: string): void {\r\n this.setField('offsetUnit', value);\r\n }\r\n\r\n /** Il flag e il ramo si accendono insieme: sono la stessa decisione. */\r\n setTimeoutEnabled(enabled: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (enabled) {\r\n action.timeoutPathUsage = 'EnableTimeoutPath';\r\n } else {\r\n delete action.timeoutPathUsage;\r\n // Spegnere il ramo di timeout rimuove anche la destinazione: lasciarla darebbe un\r\n // connector che il motore non percorrera' mai.\r\n delete action.timeoutConnector;\r\n }\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const action = node as FlowActionCall;\r\n if (value) {\r\n action.storeOutputAutomatically = true;\r\n delete action.outputParameters;\r\n } else {\r\n delete action.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo di action</label>\r\n <fb-name-picker\r\n [value]=\"action().actionType\"\r\n [options]=\"actionTypeOptions()\"\r\n label=\"Tipo di action\"\r\n placeholder=\"Scrivi o scegli un tipo\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Questo tipo di action non e’ fra quelli dichiarati dal sistema ospite.\"\r\n emptyMessage=\"Catalogo dei tipi di action non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setActionType($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Action</label>\r\n <fb-name-picker\r\n [value]=\"action().actionName\"\r\n [options]=\"actionOptions()\"\r\n label=\"Action\"\r\n placeholder=\"Scrivi o scegli un’action\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Questa action non esiste nel catalogo del tipo scelto: la validazione la segnala come errore.\"\r\n unknownSeverity=\"error\"\r\n emptyMessage=\"Scegli prima il tipo di action, oppure scrivi il nome a mano.\"\r\n (valueChange)=\"setActionName($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Esecuzione</legend>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Modello transazionale</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action().flowTransactionModel || ''\"\r\n (change)=\"setTransactionModel($any($event.target).value)\"\r\n >\r\n <option value=\"\">— predefinito —</option>\r\n @for (model of transactionModels(); track model.value) {\r\n <option [value]=\"model.value\">{{ model.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"action().isWaitUntilCompleted === true\"\r\n (change)=\"setWaitUntilCompleted($any($event.target).checked)\"\r\n />\r\n Attendi il completamento\r\n </label>\r\n\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Attesa</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"0\"\r\n [value]=\"action().offset ?? ''\"\r\n (input)=\"setOffset($any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Unita’</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action().offsetUnit || ''\"\r\n (change)=\"setOffsetUnit($any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (unit of offsetUnits(); track unit.value) {\r\n <option [value]=\"unit.value\">{{ unit.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <p class=\"fb-field__hint\">Definiscono l’attesa di un’action asincrona.</p>\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Ramo di timeout</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"timeoutEnabled()\"\r\n (change)=\"setTimeoutEnabled($any($event.target).checked)\"\r\n />\r\n Abilita il ramo di timeout\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n Il ramo esiste solo con questo flag: qui il flag e la destinazione sono legati, così non possono\r\n contraddirsi.\r\n </p>\r\n @if (timeoutMismatch()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Il flag e il ramo di timeout non sono coerenti fra loro.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Output</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (storeOutputAutomatically()) {\r\n <p class=\"fb-field__hint\">\r\n Gli output dell’action si referenziano col nome dell’elemento: <code>{{ name() }}.NomeOutput</code>.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"action()\"\r\n [catalogParameters]=\"parameterCatalog()\"\r\n [showOutputs]=\"!storeOutputAutomatically()\"\r\n [outputsDisabledReason]=\"\r\n storeOutputAutomatically() ? 'Con l’output automatico i parametri di uscita non servono.' : null\r\n \"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Le tre uscite\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Assignment — FRONTEND.md §5.2.\r\n *\r\n * Tre cose che il modello impone e che questo form rende visibili:\r\n *\r\n * 1. **Le operazioni sono eseguite nell'ordine dichiarato**, quindi devono essere\r\n * riordinabili: un'interfaccia che le presenta come un insieme nasconde la semantica.\r\n * 2. **Cosa puo' stare in `assignToReference`**: una variabile, un campo di una variabile\r\n * record, un campo di `$Record` e, fra le globali, `$Flow.CurrentStage`,\r\n * `$Flow.ActiveStages` e quelle che il sistema ospite dichiara scrivibili — le propone\r\n * già `POST /flows/references/writable`. Tutto il resto e' di sola lettura.\r\n * 3. Gli operatori marcati `expectsCollection` hanno senso **solo** su destinazioni\r\n * collection: su una variabile singola non falliscono, non fanno nulla.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowAssignment, FlowAssignmentItem, FlowElementType, FlowValue } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-assignment-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ReferencePickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './assignment-inspector.component.html',\r\n})\r\nexport class AssignmentInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Assignment';\r\n\r\n readonly assignment = computed<FlowAssignment>(() => this.node() as FlowAssignment);\r\n readonly items = computed<FlowAssignmentItem[]>(() => this.assignment().assignmentItems ?? []);\r\n readonly operators = computed(() => this.dictionaries.assignmentOperators());\r\n\r\n operatorLabel(value: string | undefined): string {\r\n if (!value) {\r\n return '';\r\n }\r\n return this.operators().find((entry) => entry.value === value)?.label ?? value;\r\n }\r\n\r\n operatorDescription(value: string | undefined): string | null {\r\n return this.operators().find((entry) => entry.value === value)?.description ?? null;\r\n }\r\n\r\n expectsCollection(item: FlowAssignmentItem): boolean {\r\n return this.dictionaries.assignmentExpectsCollection(item.operator);\r\n }\r\n\r\n /**\r\n * `Add` cambia significato col tipo della destinazione: numero → somma, data → giorni,\r\n * testo → concatena, collection → accoda. Vale la pena dirlo accanto al campo.\r\n */\r\n addSemanticsHint(item: FlowAssignmentItem): string | null {\r\n if (item.operator !== 'Add') {\r\n return null;\r\n }\r\n return 'Su un numero somma, su una data aggiunge giorni, su un testo concatena, su una collection accoda.';\r\n }\r\n\r\n addItem(): void {\r\n this.patch((node) => {\r\n const assignment = node as FlowAssignment;\r\n assignment.assignmentItems ??= [];\r\n assignment.assignmentItems.push({ operator: 'Assign' });\r\n });\r\n }\r\n\r\n removeItem(index: number): void {\r\n this.patch((node) => {\r\n const assignment = node as FlowAssignment;\r\n assignment.assignmentItems?.splice(index, 1);\r\n if (assignment.assignmentItems?.length === 0) {\r\n delete assignment.assignmentItems;\r\n }\r\n });\r\n }\r\n\r\n /** L'ordine e' semantico: spostare un'operazione cambia il risultato. */\r\n moveItem(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.items().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const items = (node as FlowAssignment).assignmentItems;\r\n if (!items) {\r\n return;\r\n }\r\n const [moved] = items.splice(index, 1);\r\n items.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.assignToReference = reference;\r\n }\r\n });\r\n }\r\n\r\n setOperator(index: number, operator: string): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.operator = operator;\r\n }\r\n });\r\n }\r\n\r\n setValue(index: number, value: FlowValue | undefined): void {\r\n this.patch((node) => {\r\n const item = (node as FlowAssignment).assignmentItems?.[index];\r\n if (item) {\r\n item.value = value;\r\n }\r\n });\r\n }\r\n\r\n /** Gli operatori di rimozione non prendono un valore da assegnare. */\r\n needsValue(item: FlowAssignmentItem): boolean {\r\n const operator = item.operator ?? '';\r\n return !operator.startsWith('Remove') || operator === 'RemovePosition' || operator === 'RemoveUncommon';\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Operazioni</legend>\r\n <p class=\"fb-section__note\">\r\n Le operazioni sono eseguite <strong>nell’ordine in cui compaiono</strong>: spostarne una cambia il\r\n risultato.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n @for (item of items(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveItem($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveItem($index, 1)\"\r\n >\r\n ↓\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 l’operazione\"\r\n (click)=\"removeItem($index)\"\r\n >\r\n ×\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\">Destinazione</label>\r\n <!--\r\n Solo destinazioni scrivibili: una costante o una formula produrrebbero\r\n TARGET_NOT_WRITABLE. Le globali assegnabili — `$Flow.CurrentStage`,\r\n `$Flow.ActiveStages` e quelle dichiarate scrivibili dall'host — arrivano già\r\n dalla primitiva, non si aggiungono qui.\r\n -->\r\n <fb-reference-picker\r\n [value]=\"item.assignToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setTarget($index, $event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Puoi scrivere anche un campo di un record: <code>Cliente.Email</code>, <code>$Record.Stato</code>.\r\n </p>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"item.operator || ''\"\r\n (change)=\"setOperator($index, $any($event.target).value)\"\r\n >\r\n @for (operator of operators(); track operator.value) {\r\n <option [value]=\"operator.value\">{{ operator.label }}</option>\r\n }\r\n </select>\r\n @if (operatorDescription(item.operator)) {\r\n <p class=\"fb-field__hint\">{{ operatorDescription(item.operator) }}</p>\r\n }\r\n @if (addSemanticsHint(item)) {\r\n <p class=\"fb-field__hint\">{{ addSemanticsHint(item) }}</p>\r\n }\r\n @if (expectsCollection(item)) {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n Questa operazione ha senso solo su una destinazione collection: su una variabile singola non\r\n fallisce, semplicemente non fa nulla.\r\n </p>\r\n }\r\n </div>\r\n\r\n @if (needsValue(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor [value]=\"item.value\" label=\"Valore\" (valueChange)=\"setValue($index, $event)\" />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Nessuna operazione: un Assignment senza operazioni non fa nulla (ASSIGNMENT_WITHOUT_ITEMS).\r\n </p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addItem()\">Aggiungi operazione</button>\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Collection Processor — FRONTEND.md §5.5 e trappola §13.2.\r\n *\r\n * Un solo tipo di node con un discriminatore: `collectionProcessorType` vale `Sort` o\r\n * `Filter`, e i campi rilevanti cambiano.\r\n *\r\n * La trappola: **`assignNextValueToReference` non e' la destinazione del risultato.** È la\r\n * variabile che espone alle condizioni l'elemento in esame, come nel Loop. Il risultato e'\r\n * l'output automatico dell'elemento, cioe' il suo nome. Confonderle e' un errore classico,\r\n * e l'unico rimedio e' etichettare quel campo per quello che e': \"elemento in esame\".\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport {\r\n FlowCollectionProcessor,\r\n FlowConditionHolder,\r\n FlowElementType,\r\n FlowSortOption,\r\n} from '../../model/flow.model';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-collection-processor-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent, ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './collection-processor-inspector.component.html',\r\n})\r\nexport class CollectionProcessorInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'CollectionProcessor';\r\n\r\n readonly processor = computed<FlowCollectionProcessor>(() => this.node() as FlowCollectionProcessor);\r\n readonly kinds = computed(() => this.dictionaries.collectionProcessorTypes());\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n readonly isSort = computed(() => this.processor().collectionProcessorType === 'Sort');\r\n readonly isFilter = computed(() => this.processor().collectionProcessorType === 'Filter');\r\n readonly hasKind = computed(() => !!this.processor().collectionProcessorType);\r\n\r\n readonly sortOptions = computed<FlowSortOption[]>(() => this.processor().sortOptions ?? []);\r\n\r\n /** Il tipo degli elementi: serve alla variabile dell'elemento in esame. */\r\n readonly elementDataType = computed(() => {\r\n const reference = this.processor().collectionReference;\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.dataType;\r\n });\r\n\r\n readonly elementObjectType = computed(() => {\r\n const reference = this.processor().collectionReference;\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.objectType;\r\n });\r\n\r\n setKind(kind: string): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.collectionProcessorType = kind;\r\n // Cambiare tipo lascia campi che il nuovo tipo non usa: si rimuovono, perche'\r\n // un `Sort` con `conditions` non e' un documento che qualcuno voglia salvare.\r\n if (kind === 'Sort') {\r\n delete processor.conditions;\r\n delete processor.conditionLogic;\r\n delete processor.formula;\r\n delete processor.assignNextValueToReference;\r\n } else if (kind === 'Filter') {\r\n delete processor.sortOptions;\r\n }\r\n });\r\n }\r\n\r\n setCollection(reference: string | undefined): void {\r\n this.setField('collectionReference', reference);\r\n }\r\n\r\n setCurrentElementVariable(reference: string | undefined): void {\r\n this.setField('assignNextValueToReference', reference);\r\n }\r\n\r\n setLimit(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('limit', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n addSortOption(): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.sortOptions ??= [];\r\n processor.sortOptions.push({ sortOrder: 'Asc' });\r\n });\r\n }\r\n\r\n removeSortOption(index: number): void {\r\n this.patch((node) => {\r\n const processor = node as FlowCollectionProcessor;\r\n processor.sortOptions?.splice(index, 1);\r\n if (processor.sortOptions?.length === 0) {\r\n delete processor.sortOptions;\r\n }\r\n });\r\n }\r\n\r\n moveSortOption(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.sortOptions().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const options = (node as FlowCollectionProcessor).sortOptions;\r\n if (!options) {\r\n return;\r\n }\r\n const [moved] = options.splice(index, 1);\r\n options.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setSortField(index: number, field: string): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.sortField = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setSortOrder(index: number, order: string): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.sortOrder = order;\r\n }\r\n });\r\n }\r\n\r\n setEmptyFirst(index: number, value: boolean): void {\r\n this.patch((node) => {\r\n const option = (node as FlowCollectionProcessor).sortOptions?.[index];\r\n if (option) {\r\n option.doesPutEmptyStringAndNullFirst = value;\r\n }\r\n });\r\n }\r\n\r\n onConditionsChanged(mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => mutate(node as FlowConditionHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Cosa fa</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"processor().collectionProcessorType || ''\"\r\n (change)=\"setKind($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (kind of kinds(); track kind.value) {\r\n <option [value]=\"kind.value\">{{ kind.label }}</option>\r\n }\r\n </select>\r\n @if (!hasKind()) {\r\n <p class=\"fb-field__error\">Senza questo valore l’elemento non e’ eseguibile (PROCESSOR_TYPE_MISSING).</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\">Collection di partenza</label>\r\n <fb-reference-picker\r\n [value]=\"processor().collectionReference\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setCollection($event)\"\r\n />\r\n</div>\r\n\r\n<p class=\"fb-callout\">\r\n Il risultato non si assegna a una variabile: e’ l’<strong>output automatico</strong> dell’elemento, e si\r\n referenzia col suo nome — <code>{{ name() }}</code>.\r\n</p>\r\n\r\n@if (isSort()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Ordinamento</legend>\r\n <div class=\"fb-list\">\r\n @for (option of sortOptions(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveSortOption($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveSortOption($index, 1)\"\r\n >\r\n ↓\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\"\r\n (click)=\"removeSortOption($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"option.sortField || ''\"\r\n placeholder=\"Nome del campo degli elementi\"\r\n (input)=\"setSortField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"option.sortOrder || ''\"\r\n (change)=\"setSortOrder($index, $any($event.target).value)\"\r\n >\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"option.doesPutEmptyStringAndNullFirst === true\"\r\n (change)=\"setEmptyFirst($index, $any($event.target).checked)\"\r\n />\r\n Metti prima i valori vuoti e nulli\r\n </label>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Un Sort senza criteri di ordinamento e’ un errore (SORT_OPTIONS_MISSING).</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addSortOption()\">Aggiungi criterio</button>\r\n </fieldset>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo di elementi</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"processor().limit ?? ''\"\r\n (input)=\"setLimit($any($event.target).value)\"\r\n />\r\n </div>\r\n}\r\n\r\n@if (isFilter()) {\r\n <div class=\"fb-field\">\r\n <!--\r\n Trappola: questo NON e' dove finisce il risultato. È la variabile che espone alle\r\n condizioni l'elemento che si sta esaminando, esattamente come nel Loop.\r\n -->\r\n <label class=\"fb-field__label fb-field__label--required\">Elemento in esame</label>\r\n <fb-reference-picker\r\n [value]=\"processor().assignNextValueToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"elementDataType()\"\r\n [objectType]=\"elementObjectType()\"\r\n [isCollection]=\"false\"\r\n placeholder=\"Variabile che espone l’elemento alle condizioni\"\r\n (valueChange)=\"setCurrentElementVariable($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Questa variabile serve <strong>a scrivere le condizioni</strong> qui sotto: non e’ la destinazione del\r\n risultato.\r\n </p>\r\n </div>\r\n\r\n <fb-condition-editor\r\n [holder]=\"processor()\"\r\n title=\"Tieni gli elementi per cui\"\r\n (changed)=\"onConditionsChanged($event)\"\r\n />\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Custom Error — FRONTEND.md §5.11.\r\n *\r\n * Il Custom Error **interrompe** l'esecuzione e restituisce i messaggi al chiamante: sono il\r\n * suo prodotto principale, e almeno uno e' obbligatorio (`CUSTOM_ERROR_WITHOUT_MESSAGES`).\r\n * Non ha uscite: per questo il form non mostra nessun connector.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCustomError, FlowCustomErrorMessage, FlowElementType } from '../../model/flow.model';\r\n\r\n@Component({\r\n selector: 'fb-custom-error-inspector',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './custom-error-inspector.component.html',\r\n})\r\nexport class CustomErrorInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'CustomError';\r\n\r\n readonly customError = computed<FlowCustomError>(() => this.node() as FlowCustomError);\r\n readonly messages = computed<FlowCustomErrorMessage[]>(() => this.customError().customErrorMessages ?? []);\r\n\r\n addMessage(): void {\r\n this.patch((node) => {\r\n const customError = node as FlowCustomError;\r\n customError.customErrorMessages ??= [];\r\n customError.customErrorMessages.push({ errorMessage: '' });\r\n });\r\n }\r\n\r\n removeMessage(index: number): void {\r\n this.patch((node) => {\r\n const customError = node as FlowCustomError;\r\n customError.customErrorMessages?.splice(index, 1);\r\n if (customError.customErrorMessages?.length === 0) {\r\n delete customError.customErrorMessages;\r\n }\r\n });\r\n }\r\n\r\n setMessage(index: number, message: string): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (entry) {\r\n entry.errorMessage = message;\r\n }\r\n });\r\n }\r\n\r\n setIsFieldError(index: number, value: boolean): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (!entry) {\r\n return;\r\n }\r\n if (value) {\r\n entry.isFieldError = true;\r\n } else {\r\n delete entry.isFieldError;\r\n // Senza `isFieldError` il campo indicato non ha significato.\r\n delete entry.fieldSelection;\r\n }\r\n });\r\n }\r\n\r\n setFieldSelection(index: number, field: string): void {\r\n this.patch((node) => {\r\n const entry = (node as FlowCustomError).customErrorMessages?.[index];\r\n if (entry) {\r\n entry.fieldSelection = field || undefined;\r\n }\r\n });\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Questo elemento <strong>interrompe</strong> l’esecuzione e restituisce i messaggi al chiamante. Non ha\r\n uscite: quello che c’e’ dopo non verra’ eseguito.\r\n</p>\r\n\r\n<div class=\"fb-list\">\r\n @for (message of messages(); 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 il messaggio\"\r\n (click)=\"removeMessage($index)\"\r\n >\r\n ×\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\">Messaggio</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"message.errorMessage || ''\"\r\n placeholder=\"L’importo supera il limite consentito.\"\r\n (input)=\"setMessage($index, $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"message.isFieldError === true\"\r\n (change)=\"setIsFieldError($index, $any($event.target).checked)\"\r\n />\r\n Mostra accanto a un campo\r\n </label>\r\n\r\n @if (message.isFieldError) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"message.fieldSelection || ''\"\r\n placeholder=\"Importo\"\r\n (input)=\"setFieldSelection($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Almeno un messaggio e’ obbligatorio: sono il prodotto di questo elemento\r\n (CUSTOM_ERROR_WITHOUT_MESSAGES).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addMessage()\">Aggiungi messaggio</button>\r\n","/**\r\n * Decision — FRONTEND.md §5.3 e trappola §13.7.\r\n *\r\n * **Le regole sono valutate in ordine e ci si ferma alla prima vera.** L'ordine e' quindi\r\n * semantico, e questo form lo rende evidente: le regole sono numerate, riordinabili, e il\r\n * testo dice cosa accade quando nessuna e' vera. Un'interfaccia che le presenta come un\r\n * insieme non ordinato nasconde una parte del significato del flow.\r\n *\r\n * `label` di una regola e' l'etichetta del ramo sul canvas: senza, l'arco resta senza nome.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowConditionHolder, FlowDecision, FlowDecisionRule, FlowElementType } from '../../model/flow.model';\r\nimport { checkFlowName, slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-decision-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './decision-inspector.component.html',\r\n})\r\nexport class DecisionInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Decision';\r\n\r\n readonly decision = computed<FlowDecision>(() => this.node() as FlowDecision);\r\n readonly rules = computed<FlowDecisionRule[]>(() => this.decision().rules ?? []);\r\n\r\n /** Se nessuna regola e' vera si prende il ramo di default; se manca, l'esecuzione finisce. */\r\n readonly defaultLabel = computed(() => this.decision().defaultConnectorLabel ?? '');\r\n readonly hasDefaultTarget = computed(() => !!this.decision().defaultConnector?.targetReference);\r\n\r\n /** I nomi delle regole vivono nello spazio dei nomi delle regole, non del flow. */\r\n ruleNameError(index: number): string | null {\r\n const rules = this.rules();\r\n const rule = rules[index];\r\n if (!rule?.name) {\r\n return 'Il nome della regola e’ obbligatorio.';\r\n }\r\n const others = rules.filter((_, position) => position !== index).map((candidate) => candidate.name ?? '');\r\n const check = checkFlowName(rule.name, others);\r\n return check.isValid ? null : (check.message ?? 'Nome non valido.');\r\n }\r\n\r\n addRule(): void {\r\n this.patch((node) => {\r\n const decision = node as FlowDecision;\r\n decision.rules ??= [];\r\n const existing = decision.rules.map((rule) => rule.name ?? '');\r\n const name = uniqueFlowName('Regola', existing);\r\n decision.rules.push({\r\n name,\r\n label: `Regola ${decision.rules.length + 1}`,\r\n conditionLogic: 'and',\r\n conditions: [{ operator: 'EqualTo' }],\r\n });\r\n });\r\n }\r\n\r\n removeRule(index: number): void {\r\n this.patch((node) => {\r\n const decision = node as FlowDecision;\r\n decision.rules?.splice(index, 1);\r\n if (decision.rules?.length === 0) {\r\n delete decision.rules;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Sposta una regola. L'ordine e' l'ordine di valutazione: la prima vera vince, quindi\r\n * spostare una regola piu' in alto puo' cambiare quale ramo viene preso.\r\n */\r\n moveRule(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.rules().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const rules = (node as FlowDecision).rules;\r\n if (!rules) {\r\n return;\r\n }\r\n const [moved] = rules.splice(index, 1);\r\n rules.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setRuleLabel(index: number, label: string): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (!rule) {\r\n return;\r\n }\r\n rule.label = label || undefined;\r\n // Il nome tecnico si genera dalla label solo se non e' ancora stato personalizzato.\r\n if (!rule.name && label) {\r\n rule.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setRuleName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (rule) {\r\n rule.name = name;\r\n }\r\n });\r\n }\r\n\r\n onRuleConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => {\r\n const rule = (node as FlowDecision).rules?.[index];\r\n if (rule) {\r\n mutate(rule);\r\n }\r\n });\r\n }\r\n\r\n setDefaultLabel(label: string): void {\r\n this.setField('defaultConnectorLabel', label);\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Le regole sono valutate <strong>dall’alto verso il basso</strong> e si ferma alla prima vera. L’ordine e’\r\n parte del significato del flow: usa le frecce per cambiarlo.\r\n</p>\r\n\r\n<div class=\"fb-list\">\r\n @for (rule of rules(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__index\" [title]=\"'Valutata per ' + ($index + 1) + 'ª'\">{{ $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=\"Valuta prima\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveRule($index, -1)\"\r\n >\r\n ↑\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=\"Valuta dopo\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveRule($index, 1)\"\r\n >\r\n ↓\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 la regola\"\r\n (click)=\"removeRule($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"rule.label || ''\"\r\n placeholder=\"Approvato\"\r\n (input)=\"setRuleLabel($index, $any($event.target).value)\"\r\n />\r\n @if (!rule.label) {\r\n <p class=\"fb-field__hint\">Senza etichetta l’arco resta senza nome sul canvas.</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\">Nome tecnico</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!ruleNameError($index)\"\r\n [value]=\"rule.name || ''\"\r\n (input)=\"setRuleName($index, $any($event.target).value)\"\r\n />\r\n @if (ruleNameError($index)) {\r\n <p class=\"fb-field__error\">{{ ruleNameError($index) }}</p>\r\n }\r\n </div>\r\n\r\n <fb-condition-editor\r\n [holder]=\"rule\"\r\n title=\"Quando prendere questo ramo\"\r\n [issuePath]=\"'rules[' + (rule.name || $index) + ']'\"\r\n (changed)=\"onRuleConditionsChanged($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Nessuna regola: una Decision senza regole prende sempre il ramo di default\r\n (DECISION_WITHOUT_RULES).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addRule()\">Aggiungi regola</button>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Se nessuna regola e’ vera</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo di default</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"defaultLabel()\"\r\n placeholder=\"Rifiutato\"\r\n (input)=\"setDefaultLabel($any($event.target).value)\"\r\n />\r\n </div>\r\n @if (!hasDefaultTarget()) {\r\n <p class=\"fb-field__hint\">\r\n Nessuna destinazione di default: se nessuna regola e’ vera l’esecuzione finisce qui.\r\n </p>\r\n }\r\n</fieldset>\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","/**\r\n * Loop — FRONTEND.md §5.4.\r\n *\r\n * - `collectionReference` deve puntare a una **collection**: il selettore filtra su\r\n * `isCollection`, così una variabile singola non e' nemmeno proponibile.\r\n * - `assignNextValueToReference` e' la variabile che riceve l'elemento corrente: senza,\r\n * il corpo del ciclo non ha modo di leggerlo.\r\n * - il corpo deve **richiudersi sul Loop** perche' il ciclo prosegua. Nel disegno e' l'arco\r\n * di ritorno, tipicamente marcato `isGoTo`: il form lo verifica e lo dice.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType, FlowLoop } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-loop-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, ReferencePickerComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './loop-inspector.component.html',\r\n})\r\nexport class LoopInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'Loop';\r\n\r\n readonly loop = computed<FlowLoop>(() => this.node() as FlowLoop);\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n /** Il tipo degli elementi della collection: guida il tipo della variabile del ciclo. */\r\n readonly collectionType = computed(() => {\r\n const reference = this.loop().collectionReference;\r\n if (!reference) {\r\n return undefined;\r\n }\r\n const variable = this.store.document().variables?.find((candidate) => candidate.name === reference);\r\n return variable?.dataType;\r\n });\r\n\r\n readonly collectionObjectType = computed(() => {\r\n const reference = this.loop().collectionReference;\r\n if (!reference) {\r\n return undefined;\r\n }\r\n return this.store.document().variables?.find((candidate) => candidate.name === reference)?.objectType;\r\n });\r\n\r\n /**\r\n * Verifica che il corpo si richiuda sul Loop. Il cursore si azzera all'uscita, quindi un\r\n * corpo che non torna indietro esegue una sola iterazione: e' un errore logico che la\r\n * validazione non puo' distinguere da una scelta.\r\n */\r\n readonly bodyReturnsToLoop = computed(() => {\r\n const bodyStart = this.loop().nextValueConnector?.targetReference;\r\n if (!bodyStart) {\r\n return false;\r\n }\r\n const edges = this.store.edges();\r\n const visited = new Set<string>();\r\n const queue = [bodyStart];\r\n while (queue.length) {\r\n const current = queue.shift() as string;\r\n if (current === this.name()) {\r\n return true;\r\n }\r\n if (visited.has(current)) {\r\n continue;\r\n }\r\n visited.add(current);\r\n for (const edge of edges) {\r\n if (edge.from === current && edge.to) {\r\n queue.push(edge.to);\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n\r\n readonly hasBody = computed(() => !!this.loop().nextValueConnector?.targetReference);\r\n\r\n setCollection(reference: string | undefined): void {\r\n this.setField('collectionReference', reference);\r\n }\r\n\r\n setCurrentValueVariable(reference: string | undefined): void {\r\n this.setField('assignNextValueToReference', reference);\r\n }\r\n\r\n setIterationOrder(order: string): void {\r\n this.setField('iterationOrder', order);\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Collection da iterare</label>\r\n <!-- Solo collection: iterare una variabile singola e' un errore (LOOP_COLLECTION_MISSING). -->\r\n <fb-reference-picker\r\n [value]=\"loop().collectionReference\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setCollection($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Anche l’output automatico di un Get Records senza «solo il primo record» e’ iterabile.\r\n </p>\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Elemento corrente</label>\r\n <fb-reference-picker\r\n [value]=\"loop().assignNextValueToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"collectionType()\"\r\n [objectType]=\"collectionObjectType()\"\r\n [isCollection]=\"false\"\r\n placeholder=\"Variabile che riceve l’elemento\"\r\n (valueChange)=\"setCurrentValueVariable($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Deve essere una variabile <strong>singola</strong> dello stesso tipo degli elementi: senza, il corpo del\r\n ciclo non ha modo di leggere l’elemento corrente.\r\n </p>\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordine di iterazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"loop().iterationOrder || ''\"\r\n (change)=\"setIterationOrder($any($event.target).value)\"\r\n >\r\n <option value=\"\">— predefinito —</option>\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n</div>\r\n\r\n@if (hasBody() && !bodyReturnsToLoop()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Il corpo del ciclo non torna sul Loop: nessun percorso dal ramo «per ogni valore» rientra qui, quindi\r\n verrebbe eseguita una sola iterazione. Collega l’ultimo elemento del corpo di nuovo al Loop, marcando\r\n l’arco come salto indietro.\r\n </p>\r\n}\r\n@if (!hasBody()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Il ramo «per ogni valore» non ha destinazione: il ciclo non ha corpo.\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 del ciclo\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n\r\n<p class=\"fb-field__hint\">\r\n Il cursore si azzera all’uscita: rientrare nello stesso Loop ricomincia da capo.\r\n</p>\r\n","/**\r\n * Orchestrated Stage — FRONTEND.md §5.13.\r\n *\r\n * Un gruppo di step, alcuni affidati a una persona. Quello che questo form fa di diverso da un\r\n * elenco di sotto-elementi, e che il modello impone:\r\n *\r\n * 1. **Gli step non sono una sequenza.** L'ordine nell'array e' solo l'ordine d'esame: uno\r\n * step parte appena le sue `entryConditions` sono vere. Non sono numerati come passi, e le\r\n * frecce dicono di riordinare l'*esame*, non l'esecuzione.\r\n * 2. **Il `name` di uno step sta nello stesso spazio dei nomi** di node e risorse (§3.3): un\r\n * omonimo di una variabile e' `NAME_DUPLICATED`, e il controllo e' lo stesso dell'inspector.\r\n * 3. **Una condizione non puo' referenziare l'output di un altro step**: finche' quello step\r\n * non ha girato il riferimento e' irrisolvibile, e a runtime un riferimento irrisolvibile\r\n * e' un errore. Qui e' segnalato con la via d'uscita: scrivere il risultato in una\r\n * variabile e condizionare su quella.\r\n * 4. **`entryConditions` e `exitConditions` non sono simmetriche**: se le prime non si\r\n * avverano lo step viene saltato, se le seconde restano false lo stage va in **stallo** e\r\n * l'esecuzione fallisce. Sono due cose diverse che si assomigliano, quindi e' scritto.\r\n * 5. **`faultConnector` e' il ramo dello step rifiutato**, non un ramo di guasto: senza, un\r\n * rifiuto fa fallire l'interview. Per un flow di approvazione va quasi sempre disegnato.\r\n *\r\n * `runAsUser` viene ignorato dal runtime e `canAssigneeEdit` / `shouldLock` /\r\n * `requiresAsyncProcessing` sono riservati: non sono esposti.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { checkFlowName, slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport {\r\n ORCHESTRATION_CONDITION_OUTPUT,\r\n stageStepOutputReferenced,\r\n stepsOf,\r\n} from '../../core/stage-step.util';\r\nimport { FlowSummary } from '../../model/api.model';\r\nimport {\r\n FlowConditionHolder,\r\n FlowElementType,\r\n FlowOrchestratedStage,\r\n FlowStageStep,\r\n FlowStageStepAssignee,\r\n FlowValue,\r\n} from '../../model/flow.model';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent, NamePickerOption } from '../shared/name-picker.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I due contenitori di condizioni di uno step, come li vuole l'editor condiviso. */\r\ninterface StepConditionHolders {\r\n entry: FlowConditionHolder;\r\n exit: FlowConditionHolder;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-orchestrated-stage-inspector',\r\n standalone: true,\r\n imports: [\r\n ConditionEditorComponent,\r\n ConnectorEditorComponent,\r\n NamePickerComponent,\r\n ParameterEditorComponent,\r\n ValueEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './orchestrated-stage-inspector.component.html',\r\n})\r\nexport class OrchestratedStageInspectorComponent extends NodeInspectorBase {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n readonly elementType: FlowElementType = 'OrchestratedStage';\r\n\r\n readonly stage = computed<FlowOrchestratedStage>(() => this.node() as FlowOrchestratedStage);\r\n readonly steps = computed<FlowStageStep[]>(() => stepsOf(this.stage()));\r\n\r\n /** I tre tipi di step: `stageStepTypes` e' l'elenco autoritativo (§6.4). */\r\n readonly stepTypes = computed(() => this.dictionaries.stageStepTypes());\r\n readonly assigneeTypes = computed(() => this.dictionaries.assigneeTypes());\r\n\r\n /** L'output che il runtime legge da un evaluation flow di condizione. */\r\n readonly conditionOutputName = ORCHESTRATION_CONDITION_OUTPUT;\r\n\r\n /**\r\n * I flow proponibili come step in background o come evaluation flow. Una lista vuota\r\n * significa \"non lo so\": in quel caso il campo resta scrivibile a mano (§5.9, §7).\r\n */\r\n private readonly flowCandidates = signal<FlowSummary[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.api\r\n .listSubflowCandidates(this.store.document().fullName ?? undefined)\r\n .then((list) => this.flowCandidates.set(list ?? []))\r\n .catch(() => this.flowCandidates.set([]));\r\n }\r\n\r\n /** I candidati come li vuole il picker: il nome del flow e' il suo `flowName`. */\r\n readonly candidateOptions = computed<NamePickerOption[]>(() =>\r\n this.flowCandidates().map((candidate) => ({\r\n name: candidate.flowName,\r\n label: candidate.label,\r\n description: candidate.description,\r\n })),\r\n );\r\n\r\n /**\r\n * I contenitori di condizioni, uno per step, calcolati **una volta** per documento: costruirli\r\n * nel template creerebbe un oggetto nuovo a ogni ciclo di change detection.\r\n */\r\n readonly conditionHolders = computed<StepConditionHolders[]>(() =>\r\n this.steps().map((step) => ({\r\n entry: { conditions: step.entryConditions ?? [] },\r\n exit: { conditions: step.exitConditions ?? [] },\r\n })),\r\n );\r\n\r\n // -------------------------------------------------------------------------\r\n // Diagnostica locale\r\n // -------------------------------------------------------------------------\r\n\r\n requiresActionName(step: FlowStageStep): boolean {\r\n return this.dictionaries.stageStepRequiresActionName(step.actionType);\r\n }\r\n\r\n requiresAssignees(step: FlowStageStep): boolean {\r\n return this.dictionaries.stageStepRequiresAssignees(step.actionType);\r\n }\r\n\r\n /** Il rifiuto e' un esito previsto solo per l'approvazione: e' lì che serve il ramo. */\r\n supportsRejection(step: FlowStageStep): boolean {\r\n const entry = this.dictionaries.stageStepType(step.actionType);\r\n return entry?.supportsRejection ?? step.actionType === 'stepApproval';\r\n }\r\n\r\n stepTypeDescription(step: FlowStageStep): string | null {\r\n return this.dictionaries.stageStepType(step.actionType)?.description ?? null;\r\n }\r\n\r\n /** Un `actionType` che il dizionario non conosce: sarebbe `STAGE_STEP_TYPE_UNKNOWN`. */\r\n isUnknownStepType(step: FlowStageStep): boolean {\r\n if (!step.actionType || !this.stepTypes().length) {\r\n return false;\r\n }\r\n return !this.dictionaries.stageStepType(step.actionType);\r\n }\r\n\r\n /**\r\n * Il nome dello step: stessa regola dei node, sullo spazio dei nomi comune (§3.3).\r\n * L'unicita' si conta sulle occorrenze in `usedNames`, che gli step li comprende già: una\r\n * sola occorrenza e' questo step, due sono un omonimo.\r\n */\r\n stepNameError(step: FlowStageStep): string | null {\r\n const check = checkFlowName(step.name, [], step.name);\r\n if (!check.isValid) {\r\n return check.message ?? 'Nome non valido.';\r\n }\r\n const key = (step.name ?? '').toLowerCase();\r\n const occurrences = this.store.usedNames().filter((name) => name.toLowerCase() === key).length;\r\n return occurrences > 1\r\n ? 'Questo nome e’ già usato da un elemento, una risorsa o un altro step (NAME_DUPLICATED).'\r\n : null;\r\n }\r\n\r\n /**\r\n * Il nome dello step il cui output una condizione sta leggendo: e' irrisolvibile finche'\r\n * quello step non ha girato (§5.13, punto 4). `undefined` quando va tutto bene.\r\n */\r\n stepOutputInConditions(step: FlowStageStep): string | undefined {\r\n const conditions = [...(step.entryConditions ?? []), ...(step.exitConditions ?? [])];\r\n for (const condition of conditions) {\r\n const referenced =\r\n stageStepOutputReferenced(condition.leftValueReference, this.steps()) ??\r\n stageStepOutputReferenced(condition.rightValue?.elementReference, this.steps());\r\n if (referenced) {\r\n return referenced;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /** Lo step tiene un output senza destinazione: e' lecito, ma vale la pena dirlo. */\r\n hasSimulatedOutputs(step: FlowStageStep): boolean {\r\n return step.debugSimulateStep === true;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Step\r\n // -------------------------------------------------------------------------\r\n\r\n addStep(): void {\r\n const name = uniqueFlowName('Step', this.store.usedNames());\r\n this.patch((node) => {\r\n const stage = node as FlowOrchestratedStage;\r\n stage.stageSteps ??= [];\r\n stage.stageSteps.push({\r\n name,\r\n label: `Step ${stage.stageSteps.length + 1}`,\r\n // Il tipo lo scelga l'utente: senza, e' `STAGE_STEP_TYPE_MISSING` e si vede subito.\r\n });\r\n });\r\n }\r\n\r\n removeStep(index: number): void {\r\n this.patch((node) => {\r\n const stage = node as FlowOrchestratedStage;\r\n stage.stageSteps?.splice(index, 1);\r\n if (stage.stageSteps?.length === 0) {\r\n delete stage.stageSteps;\r\n }\r\n });\r\n }\r\n\r\n /** Sposta lo step nell'ordine d'**esame**: non e' un ordine di esecuzione (§5.13). */\r\n moveStep(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.steps().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const steps = (node as FlowOrchestratedStage).stageSteps;\r\n if (!steps) {\r\n return;\r\n }\r\n const [moved] = steps.splice(index, 1);\r\n steps.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n private patchStep(index: number, mutate: (step: FlowStageStep) => void): void {\r\n this.patch((node) => {\r\n const step = (node as FlowOrchestratedStage).stageSteps?.[index];\r\n if (step) {\r\n mutate(step);\r\n }\r\n });\r\n }\r\n\r\n setStepLabel(index: number, label: string): void {\r\n this.patchStep(index, (step) => {\r\n step.label = label || undefined;\r\n if (!step.name && label) {\r\n step.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setStepName(index: number, name: string): void {\r\n this.patchStep(index, (step) => {\r\n step.name = name || undefined;\r\n });\r\n }\r\n\r\n setStepDescription(index: number, description: string): void {\r\n this.patchStep(index, (step) => {\r\n step.description = description || undefined;\r\n });\r\n }\r\n\r\n /**\r\n * Cambiare tipo cambia cosa lo step pretende: gli assegnatari non hanno senso su uno step in\r\n * background, e `actionName` non ne ha su uno assegnato. I campi che il nuovo tipo non\r\n * prevede si rimuovono, invece di restare nel documento a dire una cosa che non vale piu'.\r\n */\r\n setStepType(index: number, actionType: string): void {\r\n const requiresActionName = this.dictionaries.stageStepRequiresActionName(actionType);\r\n const requiresAssignees = this.dictionaries.stageStepRequiresAssignees(actionType);\r\n this.patchStep(index, (step) => {\r\n step.actionType = actionType || undefined;\r\n if (!requiresActionName) {\r\n delete step.actionName;\r\n }\r\n if (!requiresAssignees) {\r\n delete step.assignees;\r\n delete step.requiresMultiMemberApproval;\r\n } else {\r\n step.assignees ??= [{}];\r\n }\r\n });\r\n }\r\n\r\n setStepActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n step.actionName = actionName || undefined;\r\n });\r\n }\r\n\r\n setMultiMemberApproval(index: number, required: boolean): void {\r\n this.patchStep(index, (step) => {\r\n // Il modello lo porta come stringa: `\"1\"` oppure `\"0\"` (§5.13).\r\n step.requiresMultiMemberApproval = required ? '1' : '0';\r\n });\r\n }\r\n\r\n isMultiMemberApproval(step: FlowStageStep): boolean {\r\n return step.requiresMultiMemberApproval === '1';\r\n }\r\n\r\n setSimulateStep(index: number, simulate: boolean): void {\r\n this.patchStep(index, (step) => {\r\n if (simulate) {\r\n step.debugSimulateStep = true;\r\n } else {\r\n delete step.debugSimulateStep;\r\n delete step.outputConfigParams;\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Assegnatari\r\n // -------------------------------------------------------------------------\r\n\r\n assigneesOf(step: FlowStageStep): FlowStageStepAssignee[] {\r\n return step.assignees ?? [];\r\n }\r\n\r\n addAssignee(index: number): void {\r\n this.patchStep(index, (step) => {\r\n step.assignees ??= [];\r\n step.assignees.push({});\r\n });\r\n }\r\n\r\n removeAssignee(stepIndex: number, assigneeIndex: number): void {\r\n this.patchStep(stepIndex, (step) => {\r\n step.assignees?.splice(assigneeIndex, 1);\r\n if (step.assignees?.length === 0) {\r\n delete step.assignees;\r\n }\r\n });\r\n }\r\n\r\n setAssigneeType(stepIndex: number, assigneeIndex: number, assigneeType: string): void {\r\n this.patchStep(stepIndex, (step) => {\r\n const assignee = step.assignees?.[assigneeIndex];\r\n if (assignee) {\r\n assignee.assigneeType = assigneeType || undefined;\r\n }\r\n });\r\n }\r\n\r\n setAssigneeValue(stepIndex: number, assigneeIndex: number, value: FlowValue | undefined): void {\r\n this.patchStep(stepIndex, (step) => {\r\n const assignee = step.assignees?.[assigneeIndex];\r\n if (assignee) {\r\n assignee.assignee = value;\r\n }\r\n });\r\n }\r\n\r\n /** Assegnatario senza tipo o senza valore: e' `STAGE_STEP_ASSIGNEE_INVALID`. */\r\n isAssigneeIncomplete(assignee: FlowStageStepAssignee): boolean {\r\n return !assignee.assigneeType || !assignee.assignee;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Condizioni ed evaluation flow\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Le condizioni di uno step sono condizioni come le altre (§4.3), ma il modello porta solo\r\n * la lista: `conditionLogic` e `formula` non esistono e non vanno scritti.\r\n */\r\n onEntryConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.applyConditions(index, 'entryConditions', mutate);\r\n }\r\n\r\n onExitConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.applyConditions(index, 'exitConditions', mutate);\r\n }\r\n\r\n private applyConditions(\r\n index: number,\r\n field: 'entryConditions' | 'exitConditions',\r\n mutate: (holder: FlowConditionHolder) => void,\r\n ): void {\r\n this.patchStep(index, (step) => {\r\n const holder: FlowConditionHolder = { conditions: step[field] ?? [] };\r\n mutate(holder);\r\n const conditions = holder.conditions ?? [];\r\n if (conditions.length) {\r\n step[field] = conditions;\r\n } else {\r\n // Lista vuota omessa, non scritta come `[]` (§2).\r\n delete step[field];\r\n }\r\n });\r\n }\r\n\r\n setEntryActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n if (actionName) {\r\n step.entryActionName = actionName;\r\n // Il tipo e' implicito: la condizione la decide un evaluation flow (§5.13).\r\n step.entryActionType = 'EvaluationFlow';\r\n } else {\r\n delete step.entryActionName;\r\n delete step.entryActionType;\r\n }\r\n });\r\n }\r\n\r\n setExitActionName(index: number, actionName: string): void {\r\n this.patchStep(index, (step) => {\r\n if (actionName) {\r\n step.exitActionName = actionName;\r\n step.exitActionType = 'EvaluationFlow';\r\n } else {\r\n delete step.exitActionName;\r\n delete step.exitActionType;\r\n }\r\n });\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Parametri\r\n // -------------------------------------------------------------------------\r\n\r\n onParametersChanged(index: number, mutate: (holder: ParameterHolder) => void): void {\r\n this.patchStep(index, (step) => mutate(step));\r\n }\r\n\r\n /** Il ramo del rifiuto e' disegnato: senza, un rifiuto fa fallire l'interview (§5.13). */\r\n readonly hasRejectionBranch = computed(() => !!this.stage().faultConnector);\r\n\r\n /** C'e' almeno uno step il cui rifiuto e' un esito previsto. */\r\n readonly hasApprovalStep = computed(() => this.steps().some((step) => this.supportsRejection(step)));\r\n}\r\n","<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’ingresso sono vere, e\r\n l’ordine qui sotto e’ solo l’ordine 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 || '—' }}</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’ordine d’esame, non l’ordine di esecuzione\"\r\n [disabled]=\"isFirst\"\r\n (click)=\"moveStep(stepIndex, -1)\"\r\n >\r\n ↑\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’ordine d’esame, non l’ordine di esecuzione\"\r\n [disabled]=\"isLast\"\r\n (click)=\"moveStep(stepIndex, 1)\"\r\n >\r\n ↓\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 ×\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=\"\">— scegli —</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’ valido (STAGE_STEP_TYPE_MISSING).</p>\r\n } @else if (isUnknownStepType(step)) {\r\n <p class=\"fb-field__error\">\r\n «{{ step.actionType }}» non e’ 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 (§7).\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’ 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’ 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’interview si <strong>sospende</strong>: resta aperto un work item finche’\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’assegnatario\"\r\n (click)=\"removeAssignee(stepIndex, $index)\"\r\n >\r\n ×\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=\"\">— scegli —</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’ 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’approvazione 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 (§5.13).\r\n -->\r\n <fb-condition-editor\r\n [holder]=\"conditionHolders()[stepIndex].entry\"\r\n title=\"Condizioni d’ingresso (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’uscita (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’e’ piu’ niente in esecuzione, lo stage e’ in stallo e\r\n l’esecuzione <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’output dello step «{{ stepOutputInConditions(step) }}»: finche’\r\n quello step non ha girato il riferimento e’ irrisolvibile, e a runtime e’ un errore. Fai\r\n scrivere quel risultato in una variabile (parametro di uscita → 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’ingresso</label>\r\n <fb-name-picker\r\n [value]=\"step.entryActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l’ingresso\"\r\n placeholder=\"Valuta_Ingresso\"\r\n unknownMessage=\"Questo flow non e’ 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’output booleano <code>{{ conditionOutputName }}</code>: e’ l’unico che il\r\n runtime legge, dichiararne altri e’ 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’uscita</label>\r\n <fb-name-picker\r\n [value]=\"step.exitActionName\"\r\n [options]=\"candidateOptions()\"\r\n label=\"Evaluation flow per l’uscita\"\r\n placeholder=\"Valuta_Uscita\"\r\n unknownMessage=\"Questo flow non e’ 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’ <strong>facoltativa</strong>: l’output e’ già 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’ 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’ 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’e’ uno step di approvazione ma il ramo «Step rifiutato» non e’ disegnato: senza, un rifiuto fa\r\n <strong>fallire</strong> l’interview. Non e’ un ramo di guasto, e’ l’esito 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","/**\r\n * Get Records — FRONTEND.md §5.6.\r\n *\r\n * Due modi di raccogliere il risultato, **alternativi**:\r\n * 1. `storeOutputAutomatically: true` → il risultato e' l'output automatico\r\n * (`Leggi_Ordine.Numero`). È il modo consigliato, e quello proposto per default.\r\n * 2. `outputReference` (una variabile) oppure `outputAssignments` (campo → variabile).\r\n *\r\n * Dichiarare entrambi e' `OUTPUT_CONFIGURATION_CONFLICT`; non dichiarare nessuno dei due e'\r\n * `LOOKUP_RESULT_DISCARDED`, cioe' interrogare il database e buttare via il risultato.\r\n * Il form modella le tre modalita' come mutuamente esclusive, così il conflitto non e'\r\n * rappresentabile.\r\n *\r\n * `getFirstRecordOnly` decide se il risultato e' un record singolo o una collection:\r\n * e' l'informazione che dice se questo elemento e' iterabile da un Loop.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowFieldDescription } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowRecordLookup } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\ntype OutputMode = 'automatic' | 'variable' | 'assignments' | 'discard';\r\n\r\n@Component({\r\n selector: 'fb-record-lookup-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n FieldPickerComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n ReferencePickerComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-lookup-inspector.component.html',\r\n})\r\nexport class RecordLookupInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'RecordLookup';\r\n\r\n readonly lookup = computed<FlowRecordLookup>(() => this.node() as FlowRecordLookup);\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n /**\r\n * Serve solo alla griglia dei «campi da leggere»: gli altri elenchi (oggetti, campi di\r\n * ordinamento, campi di output) li carica il picker che li mostra.\r\n */\r\n private readonly allFields = signal<FlowFieldDescription[]>([]);\r\n\r\n constructor() {\r\n super();\r\n effect(() => {\r\n const object = this.lookup().object;\r\n if (!object) {\r\n this.allFields.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFields(object, 'any')\r\n .then((list) => this.allFields.set(list ?? []))\r\n .catch(() => this.allFields.set([]));\r\n });\r\n }\r\n\r\n readonly fieldOptions = computed(() => this.allFields());\r\n\r\n readonly queriedFields = computed<string[]>(() => this.lookup().queriedFields ?? []);\r\n\r\n /** La modalita' di output dedotta dai campi valorizzati. */\r\n readonly outputMode = computed<OutputMode>(() => {\r\n const lookup = this.lookup();\r\n if (lookup.storeOutputAutomatically) {\r\n return 'automatic';\r\n }\r\n if (lookup.outputAssignments?.length) {\r\n return 'assignments';\r\n }\r\n if (lookup.outputReference) {\r\n return 'variable';\r\n }\r\n return 'discard';\r\n });\r\n\r\n /** Entrambi dichiarati: capita su documenti arrivati da altri editor. */\r\n readonly hasOutputConflict = computed(() => {\r\n const lookup = this.lookup();\r\n return (\r\n lookup.storeOutputAutomatically === true &&\r\n (!!lookup.outputReference || (lookup.outputAssignments?.length ?? 0) > 0)\r\n );\r\n });\r\n\r\n readonly returnsCollection = computed(() => this.lookup().getFirstRecordOnly !== true);\r\n\r\n readonly outputAssignments = computed(() => this.lookup().outputAssignments ?? []);\r\n\r\n setObject(object: string): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n if (lookup.object === object) {\r\n return;\r\n }\r\n lookup.object = object || undefined;\r\n // Cambiare oggetto invalida campi, filtri e ordinamento: tenerli produrrebbe\r\n // FIELD_UNKNOWN su ogni riga.\r\n delete lookup.queriedFields;\r\n delete lookup.filters;\r\n delete lookup.sortField;\r\n delete lookup.outputAssignments;\r\n });\r\n }\r\n\r\n setFirstOnly(value: boolean): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n if (value) {\r\n lookup.getFirstRecordOnly = true;\r\n } else {\r\n delete lookup.getFirstRecordOnly;\r\n }\r\n });\r\n }\r\n\r\n setSortField(field: string): void {\r\n this.setField('sortField', field);\r\n }\r\n\r\n setSortOrder(order: string): void {\r\n this.setField('sortOrder', order);\r\n }\r\n\r\n setLimit(value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setField('limit', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n toggleQueriedField(field: string, checked: boolean): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n const fields = new Set(lookup.queriedFields ?? []);\r\n if (checked) {\r\n fields.add(field);\r\n } else {\r\n fields.delete(field);\r\n }\r\n if (fields.size) {\r\n lookup.queriedFields = Array.from(fields);\r\n } else {\r\n delete lookup.queriedFields;\r\n }\r\n });\r\n }\r\n\r\n isQueried(field: string): boolean {\r\n return this.queriedFields().includes(field);\r\n }\r\n\r\n /** Il passaggio fra modalita' azzera i campi delle altre: il conflitto non e' scrivibile. */\r\n setOutputMode(mode: OutputMode): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n delete lookup.storeOutputAutomatically;\r\n delete lookup.outputReference;\r\n delete lookup.outputAssignments;\r\n switch (mode) {\r\n case 'automatic':\r\n lookup.storeOutputAutomatically = true;\r\n break;\r\n case 'variable':\r\n lookup.outputReference = '';\r\n break;\r\n case 'assignments':\r\n lookup.outputAssignments = [{}];\r\n break;\r\n case 'discard':\r\n break;\r\n }\r\n });\r\n }\r\n\r\n setOutputReference(reference: string | undefined): void {\r\n this.setField('outputReference', reference);\r\n }\r\n\r\n addOutputAssignment(): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n lookup.outputAssignments ??= [];\r\n lookup.outputAssignments.push({});\r\n });\r\n }\r\n\r\n removeOutputAssignment(index: number): void {\r\n this.patch((node) => {\r\n const lookup = node as FlowRecordLookup;\r\n lookup.outputAssignments?.splice(index, 1);\r\n if (lookup.outputAssignments?.length === 0) {\r\n delete lookup.outputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setOutputAssignmentField(index: number, field: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowRecordLookup).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.field = field || undefined;\r\n }\r\n });\r\n }\r\n\r\n setOutputAssignmentTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowRecordLookup).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.assignToReference = reference;\r\n }\r\n });\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.patch((node) => mutate(node as FilterHolder));\r\n }\r\n\r\n /** `relatedRecords` e' modellato ma non tradotto in query: se c'e', si avvisa (§5.6). */\r\n readonly hasRelatedRecords = computed(() => (this.lookup().relatedRecords?.length ?? 0) > 0);\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"lookup().object\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<fb-record-filter-editor\r\n [holder]=\"lookup()\"\r\n [object]=\"lookup().object\"\r\n title=\"Quali record leggere\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"true\"\r\n [supportsFormula]=\"true\"\r\n emptyWarning=\"Senza filtri legge tutti i record dell’oggetto.\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n/>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Quanti e in che ordine</legend>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"lookup().getFirstRecordOnly === true\"\r\n (change)=\"setFirstOnly($any($event.target).checked)\"\r\n />\r\n Solo il primo record\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n @if (returnsCollection()) {\r\n Il risultato e’ una <strong>collection</strong>: puo’ essere iterata da un Loop.\r\n } @else {\r\n Il risultato e’ un <strong>record singolo</strong>: non e’ iterabile da un Loop.\r\n }\r\n </p>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordina per</label>\r\n <fb-field-picker\r\n [value]=\"lookup().sortField\"\r\n [object]=\"lookup().object\"\r\n usage=\"sortable\"\r\n label=\"Campo di ordinamento\"\r\n placeholder=\"Nessun ordinamento\"\r\n (valueChange)=\"setSortField($event ?? '')\"\r\n />\r\n </div>\r\n\r\n @if (lookup().sortField) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select class=\"fb-select\" [fbValue]=\"lookup().sortOrder || ''\" (change)=\"setSortOrder($any($event.target).value)\">\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n\r\n @if (returnsCollection()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo di record</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"lookup().limit ?? ''\"\r\n (input)=\"setLimit($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n</fieldset>\r\n\r\n@if (fieldOptions().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Campi da leggere</legend>\r\n <p class=\"fb-section__note\">Nessuna selezione = tutti i campi disponibili.</p>\r\n <div class=\"fb-fields-grid\">\r\n @for (field of fieldOptions(); track field.name) {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isQueried(field.name)\"\r\n (change)=\"toggleQueriedField(field.name, $any($event.target).checked)\"\r\n />\r\n {{ field.label || field.name }}\r\n </label>\r\n }\r\n </div>\r\n </fieldset>\r\n}\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Dove finisce il risultato</legend>\r\n\r\n @if (hasOutputConflict()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Sono dichiarati insieme l’output automatico e una destinazione esplicita: e’ un conflitto\r\n (OUTPUT_CONFIGURATION_CONFLICT). Scegli una sola modalita’ qui sotto.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'automatic'\"\r\n (change)=\"setOutputMode('automatic')\"\r\n />\r\n Output automatico <em>(consigliato)</em>\r\n </label>\r\n @if (outputMode() === 'automatic') {\r\n <p class=\"fb-field__hint\">\r\n Il risultato si referenzia con il nome dell’elemento: <code>{{ name() }}</code>,\r\n <code>{{ name() }}.Campo</code>. Non serve dichiarare nessuna variabile.\r\n </p>\r\n }\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'variable'\"\r\n (change)=\"setOutputMode('variable')\"\r\n />\r\n In una variabile\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'assignments'\"\r\n (change)=\"setOutputMode('assignments')\"\r\n />\r\n Campo per campo\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"output-mode\"\r\n [checked]=\"outputMode() === 'discard'\"\r\n (change)=\"setOutputMode('discard')\"\r\n />\r\n Scarta il risultato\r\n </label>\r\n </div>\r\n\r\n @if (outputMode() === 'variable') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Variabile di destinazione</label>\r\n <fb-reference-picker\r\n [value]=\"lookup().outputReference\"\r\n [writableOnly]=\"true\"\r\n [isCollection]=\"returnsCollection()\"\r\n [objectType]=\"lookup().object\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputReference($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (outputMode() === 'assignments') {\r\n <div class=\"fb-list\">\r\n @for (assignment of outputAssignments(); 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\"\r\n (click)=\"removeOutputAssignment($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo del record</label>\r\n <fb-field-picker\r\n [value]=\"assignment.field\"\r\n [object]=\"lookup().object\"\r\n usage=\"any\"\r\n placeholder=\"Scrivi o scegli un campo\"\r\n (valueChange)=\"setOutputAssignmentField($index, $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <fb-reference-picker\r\n [value]=\"assignment.assignToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputAssignmentTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutputAssignment()\">Aggiungi campo</button>\r\n }\r\n\r\n @if (outputMode() === 'discard') {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n L’elemento interroga il database e butta via il risultato (LOOKUP_RESULT_DISCARDED).\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n@if (hasRelatedRecords()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo elemento dichiara <code>relatedRecords</code>: il campo e’ modellato ma non viene tradotto in\r\n query, quindi non ha effetto.\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 (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Roll Back Records — FRONTEND.md §5.11, ultimo capoverso.\r\n *\r\n * Non ha campi oltre a `connector`: annulla le modifiche pendenti. Ha senso solo in uno\r\n * screen flow, dove esiste una transazione aperta fra due schermate — e il form lo dice,\r\n * perche' altrove non annulla nulla senza segnalare niente.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-record-rollback-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-rollback-inspector.component.html',\r\n})\r\nexport class RecordRollbackInspectorComponent extends NodeInspectorBase {\r\n readonly elementType: FlowElementType = 'RecordRollback';\r\n\r\n /** Fuori da uno screen flow non c'e' una transazione aperta da annullare. */\r\n readonly isScreenFlow = computed(() => this.store.document().processType === 'Screen');\r\n}\r\n","<p class=\"fb-callout\">\r\n Annulla le modifiche ai record ancora pendenti. Non ha altri campi da configurare.\r\n</p>\r\n\r\n@if (!isScreenFlow()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Questo elemento ha senso in uno screen flow, dove esiste una transazione aperta fra due schermate. In un\r\n flow «{{ store.document().processType }}» non c’e’ nulla da annullare.\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 (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Create / Update / Delete Records — FRONTEND.md §5.7 e trappola §13.10.\r\n *\r\n * Un solo componente per i tre, perche' condividono la stessa scelta di fondo — un record\r\n * già in memoria (`inputReference`) **oppure** oggetto piu' campi — e differiscono su tre\r\n * punti precisi, che qui sono espliciti invece di essere dedotti:\r\n *\r\n * - **Create**: serve `inputReference` oppure `object` + `inputAssignments`. Con\r\n * `doesUpsert` serve `upsertExternalIdField` **o** `upsertStandardIdField`, mai entrambi.\r\n * - **Update**: serve `inputReference` oppure `object` + `filters` + `inputAssignments`.\r\n * Un update per filtro **senza filtri** aggiornerebbe tutti i record dell'entita': e' un\r\n * avviso, e l'editor chiede una conferma esplicita.\r\n * - **Delete**: serve `inputReference` oppure `object` + `filters`. Senza filtri e' un\r\n * **errore**: cancellare un'intera tabella non e' un'operazione che si fa per distrazione.\r\n *\r\n * Inoltre Update e Delete **non hanno `filterLogic`**: i filtri sono sempre in AND, e\r\n * mostrare il controllo lo farebbe perdere silenziosamente al primo salvataggio (§4.4).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowElementType } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport {\r\n FieldAssignmentEditorComponent,\r\n FieldAssignmentHolder,\r\n} from '../shared/field-assignment-editor.component';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\n\r\ntype RecordWriteType = 'RecordCreate' | 'RecordUpdate' | 'RecordDelete';\r\n\r\n/** Vista unificata sui tre node: i campi assenti su un tipo restano semplicemente vuoti. */\r\ninterface RecordWriteNode {\r\n object?: string;\r\n inputReference?: string;\r\n inputAssignments?: unknown[];\r\n filters?: unknown[];\r\n doesUpsert?: boolean;\r\n upsertExternalIdField?: string;\r\n upsertStandardIdField?: string;\r\n storeOutputAutomatically?: boolean;\r\n assignRecordIdToReference?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-record-write-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n FieldAssignmentEditorComponent,\r\n FieldPickerComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n ReferencePickerComponent,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './record-write-inspector.component.html',\r\n})\r\nexport class RecordWriteInspectorComponent extends NodeInspectorBase {\r\n /** Passato dall'host: distingue Create, Update e Delete. */\r\n readonly type = input.required<RecordWriteType>();\r\n\r\n get elementType(): FlowElementType {\r\n return this.type();\r\n }\r\n\r\n readonly record = computed<RecordWriteNode>(() => this.node() as RecordWriteNode);\r\n\r\n /**\r\n * La modalita' scelta col radio, finche' il documento non la rende evidente da se'.\r\n *\r\n * Non si puo' dedurre solo da `inputReference`: appena scelta la modalita' «record in\r\n * memoria» il riferimento non c'e' ancora, e scriverlo vuoto per ricordarsene sarebbe una\r\n * chiave vuota nel documento (§2). Senza questo, il radio tornava indietro da solo e i\r\n * campi per oggetto restavano visibili.\r\n */\r\n private readonly chosenMode = signal<'reference' | 'object' | null>(null);\r\n\r\n constructor() {\r\n super();\r\n // Cambiare elemento azzera le scelte locali al form: sono di questo node, non del prossimo.\r\n effect(() => {\r\n this.name();\r\n this.chosenMode.set(null);\r\n this.bulkUpdateConfirmed.set(false);\r\n });\r\n }\r\n\r\n readonly isCreate = computed(() => this.type() === 'RecordCreate');\r\n readonly isUpdate = computed(() => this.type() === 'RecordUpdate');\r\n readonly isDelete = computed(() => this.type() === 'RecordDelete');\r\n\r\n /** Le due modalita' alternative del modello. */\r\n readonly mode = computed<'reference' | 'object'>(() =>\r\n this.record().inputReference ? 'reference' : (this.chosenMode() ?? 'object'),\r\n );\r\n\r\n /** Update e Delete non hanno `filterLogic`: i filtri sono sempre in AND (§4.4). */\r\n readonly supportsFilterLogic = computed(() => this.isCreate());\r\n\r\n readonly needsFilters = computed(() => this.isUpdate() || this.isDelete());\r\n\r\n readonly filterCount = computed(() => this.record().filters?.length ?? 0);\r\n\r\n /** Un Delete senza filtri e' un errore; un Update senza filtri e' un avviso (§13.10). */\r\n readonly emptyFilterWarning = computed<string | null>(() => {\r\n if (this.mode() === 'reference' || !this.needsFilters()) {\r\n return null;\r\n }\r\n if (this.isDelete()) {\r\n return 'Un Delete senza filtri cancellerebbe tutti i record dell’oggetto: e’ un errore e blocca l’attivazione.';\r\n }\r\n return 'Un Update senza filtri aggiornerebbe tutti i record dell’oggetto. Se e’ quello che vuoi, confermalo qui sotto.';\r\n });\r\n\r\n readonly emptyFilterSeverity = computed<'warn' | 'error'>(() => (this.isDelete() ? 'error' : 'warn'));\r\n\r\n /** Conferma esplicita per l'update di massa: locale al form, non finisce nel documento. */\r\n readonly bulkUpdateConfirmed = signal(false);\r\n\r\n readonly showsBulkConfirm = computed(\r\n () => this.isUpdate() && this.mode() === 'object' && this.filterCount() === 0,\r\n );\r\n\r\n readonly upsertMode = computed<'none' | 'external' | 'standard'>(() => {\r\n const record = this.record();\r\n if (!record.doesUpsert) {\r\n return 'none';\r\n }\r\n return record.upsertStandardIdField ? 'standard' : 'external';\r\n });\r\n\r\n /** Entrambi i campi di upsert insieme e' `UPSERT_CONFIGURATION_INVALID`. */\r\n readonly hasUpsertConflict = computed(() => {\r\n const record = this.record();\r\n return !!record.upsertExternalIdField && !!record.upsertStandardIdField;\r\n });\r\n\r\n readonly title = computed(() => {\r\n switch (this.type()) {\r\n case 'RecordCreate':\r\n return 'record da creare';\r\n case 'RecordUpdate':\r\n return 'record da aggiornare';\r\n default:\r\n return 'record da cancellare';\r\n }\r\n });\r\n\r\n setMode(mode: 'reference' | 'object'): void {\r\n this.chosenMode.set(mode);\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (mode === 'reference') {\r\n // Le due modalita' sono alternative: tenere entrambe rende ambiguo cosa fara'.\r\n delete record.object;\r\n delete record.inputAssignments;\r\n delete record.filters;\r\n } else {\r\n delete record.inputReference;\r\n }\r\n });\r\n }\r\n\r\n setInputReference(reference: string | undefined): void {\r\n this.setField('inputReference', reference);\r\n }\r\n\r\n setObject(object: string): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (record.object === object) {\r\n return;\r\n }\r\n record.object = object || undefined;\r\n delete record.inputAssignments;\r\n delete record.filters;\r\n delete record.upsertExternalIdField;\r\n delete record.upsertStandardIdField;\r\n });\r\n }\r\n\r\n setDoesUpsert(value: boolean): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (value) {\r\n record.doesUpsert = true;\r\n } else {\r\n delete record.doesUpsert;\r\n delete record.upsertExternalIdField;\r\n delete record.upsertStandardIdField;\r\n }\r\n });\r\n }\r\n\r\n setUpsertMode(mode: 'external' | 'standard'): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n record.doesUpsert = true;\r\n // Mai entrambi: scegliere l'uno cancella l'altro.\r\n if (mode === 'external') {\r\n delete record.upsertStandardIdField;\r\n record.upsertExternalIdField ??= '';\r\n } else {\r\n delete record.upsertExternalIdField;\r\n record.upsertStandardIdField ??= '';\r\n }\r\n });\r\n }\r\n\r\n setUpsertExternalField(value: string): void {\r\n this.setField('upsertExternalIdField', value);\r\n }\r\n\r\n setUpsertStandardField(value: string): void {\r\n this.setField('upsertStandardIdField', value);\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n if (value) {\r\n record.storeOutputAutomatically = true;\r\n delete record.assignRecordIdToReference;\r\n } else {\r\n delete record.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n setAssignRecordId(reference: string | undefined): void {\r\n this.patch((node) => {\r\n const record = node as RecordWriteNode;\r\n record.assignRecordIdToReference = reference;\r\n if (reference) {\r\n delete record.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n confirmBulkUpdate(value: boolean): void {\r\n this.bulkUpdateConfirmed.set(value);\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.patch((node) => mutate(node as FilterHolder));\r\n }\r\n\r\n onAssignmentsChanged(mutate: (holder: FieldAssignmentHolder) => void): void {\r\n this.patch((node) => mutate(node as FieldAssignmentHolder));\r\n }\r\n}\r\n","<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Come indicare i {{ title() }}</legend>\r\n <label class=\"fb-check\">\r\n <input type=\"radio\" name=\"write-mode\" [checked]=\"mode() === 'object'\" (change)=\"setMode('object')\" />\r\n Per oggetto{{ needsFilters() ? ' e filtri' : ' e valori' }}\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"radio\" name=\"write-mode\" [checked]=\"mode() === 'reference'\" (change)=\"setMode('reference')\" />\r\n Un record già in memoria\r\n </label>\r\n</fieldset>\r\n\r\n@if (mode() === 'reference') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Record</label>\r\n <fb-reference-picker\r\n [value]=\"record().inputReference\"\r\n dataType=\"Object\"\r\n placeholder=\"Variabile di tipo record\"\r\n (valueChange)=\"setInputReference($event)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Il record porta con se’ i propri valori: non serve indicare oggetto ne’ campi.\r\n </p>\r\n </div>\r\n} @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"record().object\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n </div>\r\n\r\n @if (needsFilters()) {\r\n <fb-record-filter-editor\r\n [holder]=\"$any(record())\"\r\n [object]=\"record().object\"\r\n [title]=\"isDelete() ? 'Quali record cancellare' : 'Quali record aggiornare'\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"supportsFilterLogic()\"\r\n [emptyWarning]=\"emptyFilterWarning()\"\r\n [emptyWarningSeverity]=\"emptyFilterSeverity()\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n />\r\n\r\n @if (showsBulkConfirm()) {\r\n <label class=\"fb-check fb-confirm\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"bulkUpdateConfirmed()\"\r\n (change)=\"confirmBulkUpdate($any($event.target).checked)\"\r\n />\r\n Confermo di voler aggiornare <strong>tutti</strong> i record di «{{ record().object || 'questo oggetto' }}»\r\n </label>\r\n }\r\n }\r\n\r\n @if (!isDelete()) {\r\n <fb-field-assignment-editor\r\n [holder]=\"$any(record())\"\r\n [object]=\"record().object\"\r\n [title]=\"isCreate() ? 'Valori del nuovo record' : 'Valori da scrivere'\"\r\n (changed)=\"onAssignmentsChanged($event)\"\r\n />\r\n }\r\n}\r\n\r\n@if (isCreate()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Upsert</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"record().doesUpsert === true\"\r\n (change)=\"setDoesUpsert($any($event.target).checked)\"\r\n />\r\n Aggiorna il record se esiste già\r\n </label>\r\n\r\n @if (record().doesUpsert) {\r\n @if (hasUpsertConflict()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Sono indicati insieme il campo di id esterno e quello standard: va scelto uno solo\r\n (UPSERT_CONFIGURATION_INVALID).\r\n </p>\r\n }\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"upsert-mode\"\r\n [checked]=\"upsertMode() === 'external'\"\r\n (change)=\"setUpsertMode('external')\"\r\n />\r\n Riconosci il record da un id esterno\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"radio\"\r\n name=\"upsert-mode\"\r\n [checked]=\"upsertMode() === 'standard'\"\r\n (change)=\"setUpsertMode('standard')\"\r\n />\r\n Riconosci il record dall’id standard\r\n </label>\r\n\r\n @if (upsertMode() === 'external') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo id esterno</label>\r\n <fb-field-picker\r\n [value]=\"record().upsertExternalIdField\"\r\n [object]=\"record().object\"\r\n usage=\"any\"\r\n label=\"Campo id esterno\"\r\n (valueChange)=\"setUpsertExternalField($event ?? '')\"\r\n />\r\n </div>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo id standard</label>\r\n <fb-field-picker\r\n [value]=\"record().upsertStandardIdField\"\r\n [object]=\"record().object\"\r\n usage=\"any\"\r\n label=\"Campo id standard\"\r\n (valueChange)=\"setUpsertStandardField($event ?? '')\"\r\n />\r\n </div>\r\n }\r\n }\r\n </fieldset>\r\n\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Identificativo creato</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"record().storeOutputAutomatically === true\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (record().storeOutputAutomatically) {\r\n <p class=\"fb-field__hint\">\r\n L’identificativo creato si referenzia col nome dell’elemento: <code>{{ name() }}</code>.\r\n </p>\r\n } @else {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna l’identificativo a</label>\r\n <fb-reference-picker\r\n [value]=\"record().assignRecordIdToReference\"\r\n [writableOnly]=\"true\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setAssignRecordId($event)\"\r\n />\r\n </div>\r\n }\r\n </fieldset>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Screen — FRONTEND.md §5.1.\r\n *\r\n * Lo screen **non descrive i propri campi**: dichiara *quale* form mostrare e il contratto\r\n * di dati con cui parlarci. Il form e' un componente scritto a mano nel frontend\r\n * applicativo, e il flow lo referenzia per nome esattamente come referenzia un'action.\r\n * Non c'e' un albero di componenti da disegnare, e non serve.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowScreen } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent } from '../shared/name-picker.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-screen-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, NamePickerComponent, ParameterEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './screen-inspector.component.html',\r\n})\r\nexport class ScreenInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Screen';\r\n\r\n readonly screen = computed<FlowScreen>(() => this.node() as FlowScreen);\r\n\r\n private readonly forms = signal<FlowCatalogEntry[]>([]);\r\n private readonly formParameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listForms()\r\n .then((list) => this.forms.set(list ?? []))\r\n .catch(() => this.forms.set([]));\r\n\r\n effect(() => {\r\n const formName = this.screen().formName;\r\n if (!formName) {\r\n this.formParameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listFormParameters(formName)\r\n .then((list) => this.formParameters.set(list ?? []))\r\n .catch(() => this.formParameters.set([]));\r\n });\r\n }\r\n\r\n readonly formOptions = computed(() => this.forms());\r\n readonly parameters = computed(() => this.formParameters());\r\n\r\n /**\r\n * Il form fuori catalogo (`FORM_UNKNOWN`) lo segnala il picker, che riceve l'elenco. Catalogo\r\n * vuoto resta \"non lo so\": nessun controllo, nessun falso allarme (§7).\r\n */\r\n\r\n /**\r\n * `allowBack`, `allowFinish`, `allowPause` hanno default `true`: un valore assente\r\n * significa concesso, non negato.\r\n */\r\n allowBack = computed(() => this.screen().allowBack !== false);\r\n allowFinish = computed(() => this.screen().allowFinish !== false);\r\n allowPause = computed(() => this.screen().allowPause !== false);\r\n\r\n /**\r\n * Uno screen senza `connector` e con `allowFinish: false` e' un vicolo cieco:\r\n * `SCREEN_DEAD_END`. Vale la pena dirlo prima che lo dica la validazione.\r\n */\r\n readonly isDeadEnd = computed(() => {\r\n const screen = this.screen();\r\n return !screen.connector?.targetReference && screen.allowFinish === false;\r\n });\r\n\r\n setFormName(value: string): void {\r\n this.setField('formName', value);\r\n }\r\n\r\n setHelpText(value: string): void {\r\n this.setField('helpText', value);\r\n }\r\n\r\n setPausedText(value: string): void {\r\n this.setField('pausedText', value);\r\n }\r\n\r\n setFlag(flag: 'allowBack' | 'allowFinish' | 'allowPause', value: boolean): void {\r\n this.patch((node) => {\r\n // Il default e' `true`: si scrive solo quando si nega, per non sporcare il diff.\r\n if (value) {\r\n delete node[flag];\r\n } else {\r\n node[flag] = false;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<p class=\"fb-callout\">\r\n Lo screen dichiara <strong>quale form</strong> mostrare, non i suoi campi: il form e’ un componente del\r\n frontend applicativo, e qui si definisce solo il contratto di dati.\r\n</p>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Form</label>\r\n <fb-name-picker\r\n [value]=\"screen().formName\"\r\n [options]=\"formOptions()\"\r\n label=\"Form\"\r\n placeholder=\"Scrivi o scegli un form\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Questo form non esiste nel catalogo: la validazione lo segnala come errore.\"\r\n unknownSeverity=\"error\"\r\n emptyMessage=\"Il catalogo dei form non e’ popolato: il nome non viene verificato.\"\r\n (valueChange)=\"setFormName($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Testo di aiuto</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"screen().helpText || ''\"\r\n (input)=\"setHelpText($any($event.target).value)\"\r\n ></textarea>\r\n</div>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Navigazione</legend>\r\n <p class=\"fb-section__note\">\r\n Questi flag sono un’intenzione, non la verita’ finale: a runtime il motore comunica\r\n <code>canGoBack</code>, <code>canFinish</code> e <code>canPause</code> nella richiesta del form —\r\n per esempio «indietro» conta solo se esiste uno screen precedente nel percorso.\r\n </p>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowBack()\" (change)=\"setFlag('allowBack', $any($event.target).checked)\" />\r\n Consenti «indietro»\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowFinish()\" (change)=\"setFlag('allowFinish', $any($event.target).checked)\" />\r\n Consenti «fine»\r\n </label>\r\n <label class=\"fb-check\">\r\n <input type=\"checkbox\" [checked]=\"allowPause()\" (change)=\"setFlag('allowPause', $any($event.target).checked)\" />\r\n Consenti «pausa»\r\n </label>\r\n\r\n @if (allowPause()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Testo mostrato alla pausa</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"screen().pausedText || ''\"\r\n (input)=\"setPausedText($any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (isDeadEnd()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Questo screen non ha una destinazione e non consente «fine»: e’ un vicolo cieco, e l’utente resterebbe\r\n bloccato.\r\n </p>\r\n }\r\n</fieldset>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"screen()\"\r\n [catalogParameters]=\"parameters()\"\r\n inputTitle=\"Valori passati al form\"\r\n outputTitle=\"Valori raccolti dal form\"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Script — FRONTEND.md §5.8, ultimo capoverso.\r\n *\r\n * Piu' semplice dell'Action: `scriptName`, parametri, `connector`, `faultConnector`.\r\n * Nessun timeout, nessun modello transazionale.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry, FlowCatalogParameter } from '../../model/dictionary.model';\r\nimport { FlowElementType, FlowScriptPluginCall } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent } from '../shared/name-picker.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\n\r\n@Component({\r\n selector: 'fb-script-call-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, NamePickerComponent, ParameterEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './script-call-inspector.component.html',\r\n})\r\nexport class ScriptCallInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'ScriptCall';\r\n\r\n readonly script = computed<FlowScriptPluginCall>(() => this.node() as FlowScriptPluginCall);\r\n\r\n private readonly scripts = signal<FlowCatalogEntry[]>([]);\r\n private readonly parameters = signal<FlowCatalogParameter[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listScripts()\r\n .then((list) => this.scripts.set(list ?? []))\r\n .catch(() => this.scripts.set([]));\r\n\r\n effect(() => {\r\n const scriptName = this.script().scriptName;\r\n if (!scriptName) {\r\n this.parameters.set([]);\r\n return;\r\n }\r\n void this.catalog\r\n .listScriptParameters(scriptName)\r\n .then((list) => this.parameters.set(list ?? []))\r\n .catch(() => this.parameters.set([]));\r\n });\r\n }\r\n\r\n readonly scriptOptions = computed(() => this.scripts());\r\n readonly parameterCatalog = computed(() => this.parameters());\r\n\r\n readonly storeOutputAutomatically = computed(() => this.script().storeOutputAutomatically === true);\r\n\r\n setScriptName(value: string): void {\r\n this.patch((node) => {\r\n const script = node as FlowScriptPluginCall;\r\n if (script.scriptName === value) {\r\n return;\r\n }\r\n script.scriptName = value || undefined;\r\n delete script.inputParameters;\r\n delete script.outputParameters;\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const script = node as FlowScriptPluginCall;\r\n if (value) {\r\n script.storeOutputAutomatically = true;\r\n delete script.outputParameters;\r\n } else {\r\n delete script.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n onParametersChanged(mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => mutate(node as ParameterHolder));\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Script</label>\r\n <fb-name-picker\r\n [value]=\"script().scriptName\"\r\n [options]=\"scriptOptions()\"\r\n label=\"Script\"\r\n placeholder=\"Scrivi o scegli uno script\"\r\n [isMono]=\"false\"\r\n unknownMessage=\"Questo script non esiste nel catalogo: la validazione lo segnala come errore.\"\r\n unknownSeverity=\"error\"\r\n emptyMessage=\"Catalogo degli script non disponibile: puoi scrivere il nome a mano.\"\r\n (valueChange)=\"setScriptName($event ?? '')\"\r\n />\r\n</div>\r\n\r\n<label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n</label>\r\n\r\n<fb-parameter-editor\r\n [holder]=\"script()\"\r\n [catalogParameters]=\"parameterCatalog()\"\r\n [showOutputs]=\"!storeOutputAutomatically()\"\r\n (changed)=\"onParametersChanged($event)\"\r\n/>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * L'elemento Start — FRONTEND.md §3.4.\r\n *\r\n * Dice **quando** il flow parte e **da dove** comincia. I campi obbligatori dipendono dal\r\n * trigger, e il form li mostra di conseguenza:\r\n * - `object` e' obbligatorio con i trigger su record (`START_OBJECT_MISSING`);\r\n * - `schedule` e' obbligatorio con `Scheduled` (`START_SCHEDULE_MISSING`);\r\n * - `connector.targetReference` serve **sempre**: senza, `START_NO_ENTRY_POINT`.\r\n *\r\n * Con un trigger su record il flow espone `$Record` e `$Record__Prior`; senza, quei\r\n * riferimenti non sono disponibili e la validazione lo segnala. Il form lo dice, perche' e'\r\n * la differenza fra un riferimento che funziona e uno che no.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowAnyNode, FlowScheduledPath, FlowStart } from '../../model/flow.model';\r\nimport { outletsOf } from '../../core/element-outlets';\r\nimport { uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { FilterHolder, RecordFilterEditorComponent } from '../shared/record-filter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I trigger che lavorano su un record e abilitano `$Record`. */\r\nconst RECORD_TRIGGERS = new Set(['RecordBeforeSave', 'RecordAfterSave', 'RecordBeforeDelete']);\r\n\r\n@Component({\r\n selector: 'fb-start-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n ObjectPickerComponent,\r\n RecordFilterEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './start-inspector.component.html',\r\n})\r\nexport class StartInspectorComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n readonly start = computed<FlowStart>(() => this.store.start());\r\n readonly startNode = computed<FlowAnyNode>(() => this.start() as FlowAnyNode);\r\n readonly outlets = computed(() => outletsOf('Start', this.startNode()));\r\n\r\n readonly triggerTypes = computed(() => this.dictionaries.triggerTypes());\r\n readonly recordTriggerTypes = computed(() => this.dictionaries.recordTriggerTypes());\r\n readonly frequencies = computed(() => this.dictionaries.startFrequencies());\r\n readonly offsetUnits = computed(() => this.dictionaries.offsetUnits());\r\n\r\n readonly triggerType = computed(() => this.start().triggerType ?? 'None');\r\n readonly isRecordTrigger = computed(() => RECORD_TRIGGERS.has(this.triggerType()));\r\n readonly isScheduled = computed(() => this.triggerType() === 'Scheduled');\r\n readonly isEvent = computed(() => this.triggerType() === 'Event');\r\n\r\n readonly hasEntryPoint = computed(() => !!this.start().connector?.targetReference);\r\n\r\n readonly scheduledPaths = computed<FlowScheduledPath[]>(() => this.start().scheduledPaths ?? []);\r\n\r\n /** I rilievi sul documento, che e' dove finiscono quelli dello Start (§7). */\r\n readonly issues = computed(() => this.validation.documentIssues());\r\n\r\n setTriggerType(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.triggerType = value === 'None' ? undefined : value;\r\n if (!RECORD_TRIGGERS.has(value)) {\r\n // Campi che appartengono ai soli trigger su record: tenerli sarebbe rumore che il\r\n // motore ignora e che sporca il diff.\r\n delete start.object;\r\n delete start.recordTriggerType;\r\n delete start.filters;\r\n delete start.filterLogic;\r\n delete start.filterFormula;\r\n delete start.doesRequireRecordChangedToMeetCriteria;\r\n }\r\n if (value !== 'Scheduled') {\r\n delete start.schedule;\r\n delete start.scheduledPaths;\r\n } else {\r\n start.schedule ??= { frequency: this.frequencies()[0]?.value ?? 'Once' };\r\n }\r\n });\r\n }\r\n\r\n setObject(value: string): void {\r\n this.store.updateStart((start) => {\r\n if (start.object === value) {\r\n return;\r\n }\r\n start.object = value || undefined;\r\n delete start.filters;\r\n });\r\n }\r\n\r\n setRecordTriggerType(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.recordTriggerType = value || undefined;\r\n });\r\n }\r\n\r\n setRequireChanged(value: boolean): void {\r\n this.store.updateStart((start) => {\r\n if (value) {\r\n start.doesRequireRecordChangedToMeetCriteria = true;\r\n } else {\r\n delete start.doesRequireRecordChangedToMeetCriteria;\r\n }\r\n });\r\n }\r\n\r\n setFrequency(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n start.schedule.frequency = value || undefined;\r\n });\r\n }\r\n\r\n setStartDate(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n // Data senza fuso, come chiede il contratto: `2026-08-01T00:00:00`.\r\n start.schedule.startDate = value ? `${value}T00:00:00` : undefined;\r\n });\r\n }\r\n\r\n setStartTime(value: string): void {\r\n this.store.updateStart((start) => {\r\n start.schedule ??= {};\r\n start.schedule.startTime = value ? (value.length === 5 ? `${value}:00` : value) : undefined;\r\n });\r\n }\r\n\r\n /** La data arriva come `2026-08-01T00:00:00`; l'input `date` vuole solo la parte data. */\r\n readonly startDateValue = computed(() => (this.start().schedule?.startDate ?? '').slice(0, 10));\r\n readonly startTimeValue = computed(() => (this.start().schedule?.startTime ?? '').slice(0, 5));\r\n\r\n addScheduledPath(): void {\r\n this.store.updateStart((start) => {\r\n start.scheduledPaths ??= [];\r\n const existing = start.scheduledPaths.map((path) => path.name ?? '');\r\n start.scheduledPaths.push({\r\n name: uniqueFlowName('Percorso', existing),\r\n label: `Percorso differito ${start.scheduledPaths.length + 1}`,\r\n offsetNumber: 1,\r\n offsetUnit: 'Days',\r\n });\r\n });\r\n }\r\n\r\n removeScheduledPath(index: number): void {\r\n this.store.updateStart((start) => {\r\n start.scheduledPaths?.splice(index, 1);\r\n if (start.scheduledPaths?.length === 0) {\r\n delete start.scheduledPaths;\r\n }\r\n });\r\n }\r\n\r\n setPathField(index: number, field: keyof FlowScheduledPath, value: unknown): void {\r\n this.store.updateStart((start) => {\r\n const path = start.scheduledPaths?.[index] as Record<string, unknown> | undefined;\r\n if (!path) {\r\n return;\r\n }\r\n if (value === undefined || value === null || value === '') {\r\n delete path[field as string];\r\n } else {\r\n path[field as string] = value;\r\n }\r\n });\r\n }\r\n\r\n setPathOffsetNumber(index: number, value: string): void {\r\n const parsed = Number.parseInt(value, 10);\r\n this.setPathField(index, 'offsetNumber', Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n onFiltersChanged(mutate: (holder: FilterHolder) => void): void {\r\n this.store.updateStart((start) => mutate(start as FilterHolder));\r\n }\r\n\r\n onConnectorChanged(event: { outletKey: string; target?: string; isGoTo?: boolean }): void {\r\n this.store.setConnector('$start', event.outletKey, event.target, event.isGoTo);\r\n }\r\n}\r\n","@if (!hasEntryPoint()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Lo Start non punta a nessun elemento: il flow non ha un punto di ingresso e non e’ eseguibile\r\n (START_NO_ENTRY_POINT).\r\n </p>\r\n}\r\n\r\n<div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Quando parte</label>\r\n <select class=\"fb-select\" [fbValue]=\"triggerType()\" (change)=\"setTriggerType($any($event.target).value)\">\r\n @for (trigger of triggerTypes(); track trigger.value) {\r\n <option [value]=\"trigger.value\">{{ trigger.label }}</option>\r\n }\r\n </select>\r\n</div>\r\n\r\n@if (isRecordTrigger()) {\r\n <p class=\"fb-callout\">\r\n Con un trigger su record il flow espone <code>$Record</code> e <code>$Record__Prior</code>.\r\n </p>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto che innesca</label>\r\n <fb-object-picker\r\n [value]=\"start().object\"\r\n label=\"Oggetto che innesca\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObject($event ?? '')\"\r\n />\r\n @if (!start().object) {\r\n <p class=\"fb-field__error\">Obbligatorio con i trigger su record (START_OBJECT_MISSING).</p>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Su quale operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"start().recordTriggerType || ''\"\r\n (change)=\"setRecordTriggerType($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (type of recordTriggerTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <fb-record-filter-editor\r\n [holder]=\"$any(start())\"\r\n [object]=\"start().object\"\r\n title=\"Criteri di ingresso\"\r\n usage=\"filterable\"\r\n [supportsLogic]=\"true\"\r\n [supportsFormula]=\"true\"\r\n emptyWarning=\"Senza criteri il flow parte su ogni record.\"\r\n (changed)=\"onFiltersChanged($event)\"\r\n />\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"start().doesRequireRecordChangedToMeetCriteria === true\"\r\n (change)=\"setRequireChanged($any($event.target).checked)\"\r\n />\r\n Solo se il record <em>non</em> soddisfaceva i criteri prima del salvataggio\r\n </label>\r\n}\r\n\r\n@if (isScheduled()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Pianificazione</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Frequenza</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"start().schedule?.frequency || ''\"\r\n (change)=\"setFrequency($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (frequency of frequencies(); track frequency.value) {\r\n <option [value]=\"frequency.value\">{{ frequency.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Data di inizio</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"date\"\r\n [value]=\"startDateValue()\"\r\n (input)=\"setStartDate($any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ora</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"time\"\r\n [value]=\"startTimeValue()\"\r\n (input)=\"setStartTime($any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n @if (!start().schedule?.frequency) {\r\n <p class=\"fb-field__error\">La pianificazione e’ obbligatoria con questo trigger (START_SCHEDULE_MISSING).</p>\r\n }\r\n </fieldset>\r\n\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Percorsi differiti</legend>\r\n <p class=\"fb-section__note\">\r\n Ogni percorso e’ un ramo che parte dopo un intervallo, calcolato da un istante di riferimento.\r\n </p>\r\n\r\n <div class=\"fb-list\">\r\n @for (path of scheduledPaths(); 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 il percorso\"\r\n (click)=\"removeScheduledPath($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.label || ''\"\r\n (input)=\"setPathField($index, 'label', $any($event.target).value)\"\r\n />\r\n </div>\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 [value]=\"path.name || ''\"\r\n (input)=\"setPathField($index, 'name', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Dopo</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n [value]=\"path.offsetNumber ?? ''\"\r\n (input)=\"setPathOffsetNumber($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Unita’</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"path.offsetUnit || ''\"\r\n (change)=\"setPathField($index, 'offsetUnit', $any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (unit of offsetUnits(); track unit.value) {\r\n <option [value]=\"unit.value\">{{ unit.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Istante di riferimento</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.timeSource || ''\"\r\n placeholder=\"Es. RecordTriggerEvent\"\r\n (input)=\"setPathField($index, 'timeSource', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Campo data del record</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"path.recordField || ''\"\r\n (input)=\"setPathField($index, 'recordField', $any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun percorso differito.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addScheduledPath()\">Aggiungi percorso</button>\r\n </fieldset>\r\n}\r\n\r\n@if (triggerType() === 'None') {\r\n <p class=\"fb-field__hint\">\r\n Il flow parte solo su richiesta. I valori iniziali si passano nelle variabili di input.\r\n </p>\r\n}\r\n\r\n@if (isEvent()) {\r\n <p class=\"fb-field__hint\">Il flow parte alla ricezione di un evento.</p>\r\n}\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"'$start'\"\r\n [node]=\"startNode()\"\r\n [outlets]=\"outlets()\"\r\n title=\"Da dove comincia\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Subflow — FRONTEND.md §5.9.\r\n *\r\n * `flowName` e' l'API name di un altro flow, proposto da `GET /flows/subflow-candidates`,\r\n * che restituisce **solo i flow con una versione attiva** ed esclude quello corrente: un\r\n * subflow che invoca il flow che lo contiene e' `SUBFLOW_RECURSIVE`.\r\n *\r\n * I nomi degli input e degli output sono quelli delle variabili `isInput`/`isOutput` **del\r\n * flow invocato**: per proporli si carica la definizione attiva di quel flow e se ne leggono\r\n * le variabili, che e' esattamente quello che fa questo componente.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowSummary } from '../../model/api.model';\r\nimport { FlowElementType, FlowSubflow, FlowValue, FlowVariable } from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { NamePickerComponent, NamePickerOption } from '../shared/name-picker.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\n\r\n/** Una variabile del flow invocato come opzione: nome piu' tipo, collection compresa. */\r\nfunction describeVariable(variable: FlowVariable): NamePickerOption {\r\n const dataType = variable.dataType ?? 'Sconosciuto';\r\n const type = variable.isCollection ? `${dataType}[]` : dataType;\r\n return {\r\n // Il nome di una variabile e' facoltativo nel tipo, ma una senza nome non e' proponibile.\r\n name: variable.name ?? '',\r\n description: variable.objectType ? `${type} · ${variable.objectType}` : type,\r\n };\r\n}\r\n\r\n@Component({\r\n selector: 'fb-subflow-inspector',\r\n standalone: true,\r\n imports: [ConnectorEditorComponent, NamePickerComponent, ReferencePickerComponent, ValueEditorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './subflow-inspector.component.html',\r\n})\r\nexport class SubflowInspectorComponent extends NodeInspectorBase {\r\n private readonly api = inject(FlowBuilderApi);\r\n\r\n readonly elementType: FlowElementType = 'Subflow';\r\n\r\n readonly subflow = computed<FlowSubflow>(() => this.node() as FlowSubflow);\r\n\r\n private readonly flowCandidates = signal<FlowSummary[]>([]);\r\n /** Le variabili del flow invocato: il contratto verso cui si passano i valori. */\r\n private readonly targetVariables = signal<FlowVariable[]>([]);\r\n private readonly targetLoadFailed = signal(false);\r\n\r\n constructor() {\r\n super();\r\n effect(() => {\r\n const current = this.store.document().fullName;\r\n void this.api\r\n .listSubflowCandidates(current)\r\n .then((list) => this.flowCandidates.set(list ?? []))\r\n .catch(() => this.flowCandidates.set([]));\r\n });\r\n\r\n effect(() => {\r\n const flowName = this.subflow().flowName;\r\n if (!flowName) {\r\n this.targetVariables.set([]);\r\n this.targetLoadFailed.set(false);\r\n return;\r\n }\r\n this.targetLoadFailed.set(false);\r\n void this.api\r\n // Senza `version` si ottiene la versione attiva, che e' quella che verra' eseguita.\r\n .loadFlow(flowName)\r\n .then((definition) => this.targetVariables.set(definition.variables ?? []))\r\n .catch(() => {\r\n this.targetVariables.set([]);\r\n this.targetLoadFailed.set(true);\r\n });\r\n });\r\n }\r\n\r\n /** I candidati come li vuole il picker: il nome di un flow e' il suo `flowName`. */\r\n readonly candidates = computed<NamePickerOption[]>(() =>\r\n this.flowCandidates().map((candidate) => ({\r\n name: candidate.flowName,\r\n label: candidate.label,\r\n description: candidate.description,\r\n })),\r\n );\r\n readonly hasCandidates = computed(() => this.flowCandidates().length > 0);\r\n readonly couldNotLoadTarget = computed(() => this.targetLoadFailed());\r\n\r\n readonly inputVariables = computed(() => this.targetVariables().filter((variable) => variable.isInput));\r\n readonly outputVariables = computed(() => this.targetVariables().filter((variable) => variable.isOutput));\r\n\r\n /** Il tipo della variabile fa da descrizione: dice subito se il valore ci sta dentro. */\r\n readonly inputOptions = computed<NamePickerOption[]>(() =>\r\n this.inputVariables().map(describeVariable).filter((option) => !!option.name),\r\n );\r\n readonly outputOptions = computed<NamePickerOption[]>(() =>\r\n this.outputVariables().map(describeVariable).filter((option) => !!option.name),\r\n );\r\n\r\n readonly inputAssignments = computed(() => this.subflow().inputAssignments ?? []);\r\n readonly outputAssignments = computed(() => this.subflow().outputAssignments ?? []);\r\n\r\n /** Il flow invocato coincide con questo: `SUBFLOW_RECURSIVE`. */\r\n readonly isRecursive = computed(() => {\r\n const flowName = this.subflow().flowName;\r\n return !!flowName && flowName === this.store.document().fullName;\r\n });\r\n\r\n readonly storeOutputAutomatically = computed(() => this.subflow().storeOutputAutomatically === true);\r\n\r\n variableOf(name: string | undefined): FlowVariable | undefined {\r\n return this.targetVariables().find((variable) => variable.name === name);\r\n }\r\n\r\n setFlowName(value: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n if (subflow.flowName === value) {\r\n return;\r\n }\r\n subflow.flowName = value || undefined;\r\n // Il contratto cambia con il flow invocato: gli assegnamenti vecchi non valgono piu'.\r\n delete subflow.inputAssignments;\r\n delete subflow.outputAssignments;\r\n });\r\n }\r\n\r\n setStoreOutputAutomatically(value: boolean): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n if (value) {\r\n subflow.storeOutputAutomatically = true;\r\n delete subflow.outputAssignments;\r\n } else {\r\n delete subflow.storeOutputAutomatically;\r\n }\r\n });\r\n }\r\n\r\n addInput(name?: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.inputAssignments ??= [];\r\n subflow.inputAssignments.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeInput(index: number): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.inputAssignments?.splice(index, 1);\r\n if (subflow.inputAssignments?.length === 0) {\r\n delete subflow.inputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setInputName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.name = name;\r\n }\r\n });\r\n }\r\n\r\n setInputValue(index: number, value: FlowValue | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).inputAssignments?.[index];\r\n if (assignment) {\r\n assignment.value = value;\r\n }\r\n });\r\n }\r\n\r\n addOutput(name?: string): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.outputAssignments ??= [];\r\n subflow.outputAssignments.push({ name: name ?? '' });\r\n });\r\n }\r\n\r\n removeOutput(index: number): void {\r\n this.patch((node) => {\r\n const subflow = node as FlowSubflow;\r\n subflow.outputAssignments?.splice(index, 1);\r\n if (subflow.outputAssignments?.length === 0) {\r\n delete subflow.outputAssignments;\r\n }\r\n });\r\n }\r\n\r\n setOutputName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.name = name;\r\n }\r\n });\r\n }\r\n\r\n setOutputTarget(index: number, reference: string | undefined): void {\r\n this.patch((node) => {\r\n const assignment = (node as FlowSubflow).outputAssignments?.[index];\r\n if (assignment) {\r\n assignment.assignToReference = reference;\r\n }\r\n });\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Flow da invocare</label>\r\n <fb-name-picker\r\n [value]=\"subflow().flowName\"\r\n [options]=\"candidates()\"\r\n label=\"Flow da invocare\"\r\n placeholder=\"API name del flow\"\r\n unknownMessage=\"Questo flow non e’ fra quelli invocabili: solo i flow con una versione attiva lo sono.\"\r\n emptyMessage=\"Nessun flow attivo disponibile come subflow: attivane uno, oppure scrivi il nome a mano.\"\r\n (valueChange)=\"setFlowName($event ?? '')\"\r\n />\r\n @if (hasCandidates()) {\r\n <p class=\"fb-field__hint\">Solo i flow con una versione attiva possono essere invocati.</p>\r\n }\r\n @if (isRecursive()) {\r\n <p class=\"fb-field__error\">Un flow non puo’ invocare se stesso (SUBFLOW_RECURSIVE).</p>\r\n }\r\n</div>\r\n\r\n@if (couldNotLoadTarget()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Non e’ stato possibile leggere la definizione del flow invocato: i nomi di input e output non vengono\r\n proposti, ma puoi scriverli a mano.\r\n </p>\r\n}\r\n\r\n<p class=\"fb-callout\">\r\n Un subflow che si sospende — cioe’ che contiene screen o Wait — non e’ supportato dal motore.\r\n</p>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori passati al subflow</legend>\r\n @if (inputVariables().length) {\r\n <p class=\"fb-section__note\">\r\n Sono le variabili di input del flow invocato: {{ inputVariables().length }} disponibili.\r\n </p>\r\n }\r\n\r\n <div class=\"fb-list\">\r\n @for (assignment of inputAssignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"assignment.name\"\r\n [options]=\"inputOptions()\"\r\n label=\"Variabile del subflow\"\r\n placeholder=\"Nome della variabile di input\"\r\n unknownMessage=\"Questa variabile non e’ fra gli input del flow invocato.\"\r\n emptyMessage=\"Input del flow invocato non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setInputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"removeInput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <fb-value-editor\r\n [value]=\"assignment.value\"\r\n [dataType]=\"variableOf(assignment.name)?.dataType\"\r\n [objectType]=\"variableOf(assignment.name)?.objectType\"\r\n [isCollection]=\"variableOf(assignment.name)?.isCollection\"\r\n label=\"Valore\"\r\n (valueChange)=\"setInputValue($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun valore passato.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addInput()\">Aggiungi valore</button>\r\n</fieldset>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori restituiti</legend>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"storeOutputAutomatically()\"\r\n (change)=\"setStoreOutputAutomatically($any($event.target).checked)\"\r\n />\r\n Output automatico\r\n </label>\r\n @if (storeOutputAutomatically()) {\r\n <p class=\"fb-field__hint\">\r\n Le variabili di output del subflow si referenziano col nome dell’elemento:\r\n <code>{{ name() }}.NomeVariabile</code>.\r\n </p>\r\n } @else {\r\n <div class=\"fb-list\">\r\n @for (assignment of outputAssignments(); track $index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <fb-name-picker\r\n [value]=\"assignment.name\"\r\n [options]=\"outputOptions()\"\r\n label=\"Variabile di output del subflow\"\r\n placeholder=\"Nome della variabile di output\"\r\n unknownMessage=\"Questa variabile non e’ fra gli output del flow invocato.\"\r\n emptyMessage=\"Output del flow invocato non disponibili: scrivi il nome a mano.\"\r\n (valueChange)=\"setOutputName($index, $event ?? '')\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n aria-label=\"Rimuovi\"\r\n (click)=\"removeOutput($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Assegna a</label>\r\n <fb-reference-picker\r\n [value]=\"assignment.assignToReference\"\r\n [writableOnly]=\"true\"\r\n [dataType]=\"variableOf(assignment.name)?.dataType\"\r\n [isCollection]=\"variableOf(assignment.name)?.isCollection\"\r\n placeholder=\"Scegli una variabile\"\r\n (valueChange)=\"setOutputTarget($index, $event)\"\r\n />\r\n </div>\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessun valore raccolto.</p>\r\n }\r\n </div>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addOutput()\">Aggiungi valore</button>\r\n }\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Transform — FRONTEND.md §5.12.\r\n *\r\n * Tre tipi di trasformazione: `Map` (assegna un valore), `Sum` (somma un campo degli\r\n * elementi di una collection), `Count` (conta gli elementi). `Sum` e `Count` richiedono\r\n * l'input `aggregationValues`; `Sum` anche `aggregationField`. Il form li gestisce come\r\n * campi propri, invece di lasciare all'utente il compito di indovinare i nomi dei parametri.\r\n *\r\n * Nota: `connector` qui e' un **array** — la mappa delle uscite lo nasconde al resto.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport {\r\n FlowElementType,\r\n FlowTransform,\r\n FlowTransformValueAction,\r\n FlowValue,\r\n} from '../../model/flow.model';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { ReferencePickerComponent } from '../shared/reference-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n/** I nomi dei parametri che le aggregazioni richiedono, fissati dal modello. */\r\nconst AGGREGATION_VALUES = 'aggregationValues';\r\nconst AGGREGATION_FIELD = 'aggregationField';\r\n\r\n@Component({\r\n selector: 'fb-transform-inspector',\r\n standalone: true,\r\n imports: [\r\n ConnectorEditorComponent,\r\n ObjectPickerComponent,\r\n ReferencePickerComponent,\r\n ValueEditorComponent,\r\n SelectValueDirective,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './transform-inspector.component.html',\r\n})\r\nexport class TransformInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Transform';\r\n\r\n readonly transform = computed<FlowTransform>(() => this.node() as FlowTransform);\r\n readonly transformTypes = computed(() => this.dictionaries.transformTypes());\r\n readonly dataTypes = computed(() => this.dictionaries.dataTypes());\r\n\r\n private readonly enumTypes = signal<FlowCatalogEntry[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog.listEnumTypes().then((list) => this.enumTypes.set(list ?? []));\r\n }\r\n\r\n readonly enumOptions = computed(() => this.enumTypes());\r\n\r\n readonly requiresObjectType = computed(() => this.dictionaries.requiresObjectType(this.transform().dataType));\r\n\r\n /** Il modello prevede una lista di liste; l'editor lavora sulla prima, che e' il caso d'uso. */\r\n readonly actions = computed<FlowTransformValueAction[]>(\r\n () => this.transform().transformValues?.[0]?.transformValueActions ?? [],\r\n );\r\n\r\n setDataType(dataType: string): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n transform.dataType = dataType || undefined;\r\n if (!this.dictionaries.requiresObjectType(dataType)) {\r\n delete transform.objectType;\r\n }\r\n });\r\n }\r\n\r\n setObjectType(objectType: string): void {\r\n this.setField('objectType', objectType);\r\n }\r\n\r\n setIsCollection(value: boolean): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n if (value) {\r\n transform.isCollection = true;\r\n } else {\r\n delete transform.isCollection;\r\n }\r\n });\r\n }\r\n\r\n addAction(): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n transform.transformValues ??= [{}];\r\n const first = transform.transformValues[0];\r\n first.transformValueActions ??= [];\r\n first.transformValueActions.push({ transformType: 'Map' });\r\n });\r\n }\r\n\r\n removeAction(index: number): void {\r\n this.patch((node) => {\r\n const transform = node as FlowTransform;\r\n const actions = transform.transformValues?.[0]?.transformValueActions;\r\n actions?.splice(index, 1);\r\n if (actions?.length === 0) {\r\n delete transform.transformValues;\r\n }\r\n });\r\n }\r\n\r\n private mutateAction(index: number, mutate: (action: FlowTransformValueAction) => void): void {\r\n this.patch((node) => {\r\n const action = (node as FlowTransform).transformValues?.[0]?.transformValueActions?.[index];\r\n if (action) {\r\n mutate(action);\r\n }\r\n });\r\n }\r\n\r\n setActionType(index: number, transformType: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.transformType = transformType;\r\n // Map usa `value`, Sum e Count usano `inputParameters`: tenere entrambi renderebbe\r\n // ambiguo cosa viene applicato.\r\n if (transformType === 'Map') {\r\n delete action.inputParameters;\r\n } else {\r\n delete action.value;\r\n action.inputParameters ??= [{ name: AGGREGATION_VALUES }];\r\n if (transformType === 'Sum' && !action.inputParameters.some((p) => p.name === AGGREGATION_FIELD)) {\r\n action.inputParameters.push({ name: AGGREGATION_FIELD });\r\n }\r\n if (transformType === 'Count') {\r\n action.inputParameters = action.inputParameters.filter((p) => p.name === AGGREGATION_VALUES);\r\n }\r\n }\r\n });\r\n }\r\n\r\n setOutputField(index: number, field: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.outputFieldApiName = field || undefined;\r\n });\r\n }\r\n\r\n setMapValue(index: number, value: FlowValue | undefined): void {\r\n this.mutateAction(index, (action) => {\r\n action.value = value;\r\n });\r\n }\r\n\r\n aggregationCollection(action: FlowTransformValueAction): string | undefined {\r\n return action.inputParameters?.find((parameter) => parameter.name === AGGREGATION_VALUES)?.value\r\n ?.elementReference;\r\n }\r\n\r\n aggregationField(action: FlowTransformValueAction): string {\r\n return (\r\n action.inputParameters?.find((parameter) => parameter.name === AGGREGATION_FIELD)?.value?.stringValue ?? ''\r\n );\r\n }\r\n\r\n setAggregationCollection(index: number, reference: string | undefined): void {\r\n this.mutateAction(index, (action) => {\r\n action.inputParameters ??= [];\r\n const existing = action.inputParameters.find((parameter) => parameter.name === AGGREGATION_VALUES);\r\n if (existing) {\r\n existing.value = reference ? { elementReference: reference } : undefined;\r\n } else {\r\n action.inputParameters.push({\r\n name: AGGREGATION_VALUES,\r\n value: reference ? { elementReference: reference } : undefined,\r\n });\r\n }\r\n });\r\n }\r\n\r\n setAggregationField(index: number, field: string): void {\r\n this.mutateAction(index, (action) => {\r\n action.inputParameters ??= [];\r\n const existing = action.inputParameters.find((parameter) => parameter.name === AGGREGATION_FIELD);\r\n if (existing) {\r\n existing.value = field ? { stringValue: field } : undefined;\r\n } else {\r\n action.inputParameters.push({\r\n name: AGGREGATION_FIELD,\r\n value: field ? { stringValue: field } : undefined,\r\n });\r\n }\r\n });\r\n }\r\n\r\n isMap(action: FlowTransformValueAction): boolean {\r\n return (action.transformType ?? 'Map') === 'Map';\r\n }\r\n\r\n needsAggregationField(action: FlowTransformValueAction): boolean {\r\n return action.transformType === 'Sum';\r\n }\r\n\r\n needsAggregationValues(action: FlowTransformValueAction): boolean {\r\n return action.transformType === 'Sum' || action.transformType === 'Count';\r\n }\r\n}\r\n","<div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo del risultato</label>\r\n <select class=\"fb-select\" [fbValue]=\"transform().dataType || ''\" (change)=\"setDataType($any($event.target).value)\">\r\n <option value=\"\">— scegli —</option>\r\n @for (type of dataTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n @if (!transform().dataType) {\r\n <p class=\"fb-field__error\">Obbligatorio (TRANSFORM_DATA_TYPE_MISSING).</p>\r\n }\r\n</div>\r\n\r\n@if (requiresObjectType()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Tipo dell’oggetto</label>\r\n @if (transform().dataType === 'Enum') {\r\n <!-- Le enumerazioni sono un dizionario chiuso: non c'e' scrittura libera da concedere. -->\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"transform().objectType || ''\"\r\n (change)=\"setObjectType($any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of enumOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n } @else {\r\n <fb-object-picker\r\n [value]=\"transform().objectType\"\r\n label=\"Tipo dell’oggetto\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setObjectType($event ?? '')\"\r\n />\r\n }\r\n </div>\r\n}\r\n\r\n<label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"transform().isCollection === true\"\r\n (change)=\"setIsCollection($any($event.target).checked)\"\r\n />\r\n Il risultato e’ una collection\r\n</label>\r\n\r\n<p class=\"fb-callout\">\r\n Il risultato e’ l’<strong>output automatico</strong> dell’elemento: si referenzia con\r\n <code>{{ name() }}</code>.\r\n</p>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Trasformazioni</legend>\r\n\r\n <div class=\"fb-list\">\r\n @for (action of actions(); 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\"\r\n (click)=\"removeAction($index)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Operazione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"action.transformType || 'Map'\"\r\n (change)=\"setActionType($index, $any($event.target).value)\"\r\n >\r\n @for (type of transformTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo di destinazione</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"action.outputFieldApiName || ''\"\r\n placeholder=\"Totale\"\r\n (input)=\"setOutputField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n @if (isMap(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Valore</label>\r\n <fb-value-editor\r\n [value]=\"action.value\"\r\n label=\"Valore\"\r\n (valueChange)=\"setMapValue($index, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (needsAggregationValues(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Collection su cui aggregare</label>\r\n <fb-reference-picker\r\n [value]=\"aggregationCollection(action)\"\r\n [isCollection]=\"true\"\r\n placeholder=\"Scegli una collection\"\r\n (valueChange)=\"setAggregationCollection($index, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (needsAggregationField(action)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo da sommare</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"aggregationField(action)\"\r\n placeholder=\"Importo\"\r\n (input)=\"setAggregationField($index, $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna trasformazione: l’elemento non produce nulla (TRANSFORM_WITHOUT_VALUES).</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"addAction()\">Aggiungi trasformazione</button>\r\n</fieldset>\r\n\r\n<fb-connector-editor\r\n [nodeName]=\"name()\"\r\n [node]=\"node()\"\r\n [outlets]=\"outlets()\"\r\n (connectorChanged)=\"onConnectorChanged($event)\"\r\n/>\r\n","/**\r\n * Wait — FRONTEND.md §5.10.\r\n *\r\n * - almeno un evento e' obbligatorio (`WAIT_WITHOUT_EVENTS`); ogni evento vuole `eventType`\r\n * e una `label`, che e' l'etichetta del ramo sul canvas;\r\n * - `defaultConnector` e' il ramo percorso se le condizioni di **tutti** gli eventi sono\r\n * false;\r\n * - ogni evento puo' avere condizioni, filtri e parametri.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\r\n\r\nimport { NodeInspectorBase } from './node-inspector-base';\r\nimport { FlowCatalogStore } from '../../core/flow-dictionary.store';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport { FlowConditionHolder, FlowElementType, FlowWait, FlowWaitEvent } from '../../model/flow.model';\r\nimport { slugifyFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { ConditionEditorComponent } from '../shared/condition-editor.component';\r\nimport { ConnectorEditorComponent } from '../shared/connector-editor.component';\r\nimport { ParameterEditorComponent, ParameterHolder } from '../shared/parameter-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\n@Component({\r\n selector: 'fb-wait-inspector',\r\n standalone: true,\r\n imports: [ConditionEditorComponent, ConnectorEditorComponent, ParameterEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './wait-inspector.component.html',\r\n})\r\nexport class WaitInspectorComponent extends NodeInspectorBase {\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly elementType: FlowElementType = 'Wait';\r\n\r\n readonly wait = computed<FlowWait>(() => this.node() as FlowWait);\r\n readonly events = computed<FlowWaitEvent[]>(() => this.wait().waitEvents ?? []);\r\n /** I tipi noti al motore: `AlarmEvent` per un istante, `DateRefAlarmEvent` per un campo. */\r\n readonly eventTypes = computed(() => this.dictionaries.waitEventTypes());\r\n\r\n private readonly catalogEvents = signal<FlowCatalogEntry[]>([]);\r\n\r\n constructor() {\r\n super();\r\n void this.catalog\r\n .listEvents()\r\n .then((list) => this.catalogEvents.set(list ?? []))\r\n .catch(() => this.catalogEvents.set([]));\r\n }\r\n\r\n readonly catalogEventOptions = computed(() => this.catalogEvents());\r\n\r\n addEvent(): void {\r\n this.patch((node) => {\r\n const wait = node as FlowWait;\r\n wait.waitEvents ??= [];\r\n const existing = wait.waitEvents.map((event) => event.name ?? '');\r\n wait.waitEvents.push({\r\n name: uniqueFlowName('Evento', existing),\r\n label: `Evento ${wait.waitEvents.length + 1}`,\r\n eventType: this.eventTypes()[0]?.value,\r\n });\r\n });\r\n }\r\n\r\n removeEvent(index: number): void {\r\n this.patch((node) => {\r\n const wait = node as FlowWait;\r\n wait.waitEvents?.splice(index, 1);\r\n if (wait.waitEvents?.length === 0) {\r\n delete wait.waitEvents;\r\n }\r\n });\r\n }\r\n\r\n moveEvent(index: number, direction: -1 | 1): void {\r\n const target = index + direction;\r\n if (target < 0 || target >= this.events().length) {\r\n return;\r\n }\r\n this.patch((node) => {\r\n const events = (node as FlowWait).waitEvents;\r\n if (!events) {\r\n return;\r\n }\r\n const [moved] = events.splice(index, 1);\r\n events.splice(target, 0, moved);\r\n });\r\n }\r\n\r\n setEventLabel(index: number, label: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (!event) {\r\n return;\r\n }\r\n event.label = label || undefined;\r\n if (!event.name && label) {\r\n event.name = slugifyFlowName(label);\r\n }\r\n });\r\n }\r\n\r\n setEventName(index: number, name: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n event.name = name;\r\n }\r\n });\r\n }\r\n\r\n setEventType(index: number, eventType: string): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n event.eventType = eventType || undefined;\r\n }\r\n });\r\n }\r\n\r\n onEventConditionsChanged(index: number, mutate: (holder: FlowConditionHolder) => void): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n mutate(event);\r\n }\r\n });\r\n }\r\n\r\n onEventParametersChanged(index: number, mutate: (holder: ParameterHolder) => void): void {\r\n this.patch((node) => {\r\n const event = (node as FlowWait).waitEvents?.[index];\r\n if (event) {\r\n mutate(event);\r\n }\r\n });\r\n }\r\n\r\n setDefaultLabel(label: string): void {\r\n this.setField('defaultConnectorLabel', label);\r\n }\r\n}\r\n","<div class=\"fb-list\">\r\n @for (event of events(); 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=\"Sposta su\"\r\n [disabled]=\"$first\"\r\n (click)=\"moveEvent($index, -1)\"\r\n >\r\n ↑\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=\"Sposta giu’\"\r\n [disabled]=\"$last\"\r\n (click)=\"moveEvent($index, 1)\"\r\n >\r\n ↓\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 l’evento\"\r\n (click)=\"removeEvent($index)\"\r\n >\r\n ×\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 del ramo</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"event.label || ''\"\r\n placeholder=\"Alla scadenza\"\r\n (input)=\"setEventLabel($index, $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 [value]=\"event.name || ''\"\r\n (input)=\"setEventName($index, $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\">Tipo di evento</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"event.eventType || ''\"\r\n (change)=\"setEventType($index, $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (type of eventTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n @for (entry of catalogEventOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n @if (!event.eventType) {\r\n <p class=\"fb-field__error\">Senza tipo l’evento non e’ valido (WAIT_EVENT_TYPE_MISSING).</p>\r\n }\r\n </div>\r\n\r\n <fb-parameter-editor\r\n [holder]=\"event\"\r\n inputTitle=\"Parametri dell’evento\"\r\n [showOutputs]=\"true\"\r\n outputTitle=\"Valori prodotti dall’evento\"\r\n (changed)=\"onEventParametersChanged($index, $event)\"\r\n />\r\n\r\n <fb-condition-editor\r\n [holder]=\"event\"\r\n title=\"Condizioni dell’evento\"\r\n (changed)=\"onEventConditionsChanged($index, $event)\"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">\r\n Almeno un evento e’ obbligatorio: un Wait senza eventi non e’ eseguibile (WAIT_WITHOUT_EVENTS).\r\n </p>\r\n }\r\n</div>\r\n\r\n<button type=\"button\" class=\"fb-btn\" (click)=\"addEvent()\">Aggiungi evento</button>\r\n\r\n<fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Se nessun evento si verifica</legend>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta del ramo di default</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"wait().defaultConnectorLabel || ''\"\r\n (input)=\"setDefaultLabel($any($event.target).value)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n È il ramo percorso quando le condizioni di <strong>tutti</strong> gli eventi sono false.\r\n </p>\r\n </div>\r\n</fieldset>\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","/**\r\n * L'inspector: intestazione comune piu' il form del tipo selezionato.\r\n *\r\n * L'intestazione tiene i campi comuni a ogni node (`label`, `name`, `description`) e la\r\n * rinomina, che e' il punto delicato: **rinominare un elemento non aggiorna i riferimenti**,\r\n * e nessuna primitiva del backend lo fa (§13.8). Qui la riscrittura la fa il client, tramite\r\n * `FlowDocumentStore.renameNode`, e il form dice quanti riferimenti verranno riscritti prima\r\n * di farlo.\r\n *\r\n * Il corpo e' scelto per tipo. I tipi non supportati (`Step`, `Experiment`) non sono creabili\r\n * dalla palette, ma possono arrivare da un documento importato: in quel caso l'inspector li\r\n * mostra in sola lettura, dicendo perche'.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output, signal } from '@angular/core';\r\n\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { START_NODE_NAME, UNSUPPORTED_TYPES } from '../../core/element-outlets';\r\nimport { checkFlowName, slugifyFlowName } from '../../core/flow-name.util';\r\nimport { FlowAnyNode } from '../../model/flow.model';\r\nimport { ActionCallInspectorComponent } from './action-call-inspector.component';\r\nimport { AssignmentInspectorComponent } from './assignment-inspector.component';\r\nimport { CollectionProcessorInspectorComponent } from './collection-processor-inspector.component';\r\nimport { CustomErrorInspectorComponent } from './custom-error-inspector.component';\r\nimport { DecisionInspectorComponent } from './decision-inspector.component';\r\nimport { LoopInspectorComponent } from './loop-inspector.component';\r\nimport { OrchestratedStageInspectorComponent } from './orchestrated-stage-inspector.component';\r\nimport { RecordLookupInspectorComponent } from './record-lookup-inspector.component';\r\nimport { RecordRollbackInspectorComponent } from './record-rollback-inspector.component';\r\nimport { RecordWriteInspectorComponent } from './record-write-inspector.component';\r\nimport { ScreenInspectorComponent } from './screen-inspector.component';\r\nimport { ScriptCallInspectorComponent } from './script-call-inspector.component';\r\nimport { StartInspectorComponent } from './start-inspector.component';\r\nimport { SubflowInspectorComponent } from './subflow-inspector.component';\r\nimport { TransformInspectorComponent } from './transform-inspector.component';\r\nimport { WaitInspectorComponent } from './wait-inspector.component';\r\n\r\n@Component({\r\n selector: 'fb-element-inspector',\r\n standalone: true,\r\n imports: [\r\n ActionCallInspectorComponent,\r\n AssignmentInspectorComponent,\r\n CollectionProcessorInspectorComponent,\r\n CustomErrorInspectorComponent,\r\n DecisionInspectorComponent,\r\n LoopInspectorComponent,\r\n OrchestratedStageInspectorComponent,\r\n RecordLookupInspectorComponent,\r\n RecordRollbackInspectorComponent,\r\n RecordWriteInspectorComponent,\r\n ScreenInspectorComponent,\r\n ScriptCallInspectorComponent,\r\n StartInspectorComponent,\r\n SubflowInspectorComponent,\r\n TransformInspectorComponent,\r\n WaitInspectorComponent,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-inspector.component.html',\r\n styleUrl: './element-inspector.component.css',\r\n})\r\nexport class ElementInspectorComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /** Il nome dell'elemento selezionato; `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n /**\r\n * `false` quando l'inspector e' dentro la dialog: lì il tipo e il titolo sono già\r\n * nell'intestazione della dialog, e ripeterli sprecherebbe la riga piu' preziosa.\r\n */\r\n readonly showHeader = input(true);\r\n\r\n readonly closed = output<void>();\r\n readonly removeRequested = output<string>();\r\n readonly duplicateRequested = output<string>();\r\n\r\n readonly isStart = computed(() => this.selectedName() === START_NODE_NAME);\r\n\r\n readonly reference = computed(() => {\r\n const name = this.selectedName();\r\n return name && name !== START_NODE_NAME ? this.store.nodeByName().get(name) : undefined;\r\n });\r\n\r\n readonly node = computed<FlowAnyNode | undefined>(() => this.reference()?.node);\r\n readonly type = computed(() => this.reference()?.type ?? '');\r\n readonly typeLabel = computed(() => (this.isStart() ? 'Avvio' : this.dictionaries.labelOf(this.type())));\r\n\r\n readonly isUnsupported = computed(() => {\r\n const type = this.type();\r\n if (!type) {\r\n return false;\r\n }\r\n const entry = this.dictionaries.elementType(type);\r\n if (entry?.isSupported === false) {\r\n return true;\r\n }\r\n return entry?.isSupported === undefined && UNSUPPORTED_TYPES.has(type);\r\n });\r\n\r\n /** I rilievi ancorati all'elemento (§7). */\r\n readonly issues = computed(() => {\r\n const name = this.selectedName();\r\n if (!name) {\r\n return [];\r\n }\r\n return this.validation.issuesByElement().get(this.isStart() ? '' : name) ?? [];\r\n });\r\n\r\n /** Il nome tecnico in modifica: si applica con un comando esplicito, non a ogni tasto. */\r\n readonly pendingName = signal<string | null>(null);\r\n\r\n readonly nameError = computed(() => {\r\n const pending = this.pendingName();\r\n if (pending === null) {\r\n return null;\r\n }\r\n const check = checkFlowName(pending, this.store.usedNames(), this.selectedName());\r\n return check.isValid ? null : (check.message ?? 'Nome non valido.');\r\n });\r\n\r\n /**\r\n * Quanti riferimenti verrebbero riscritti dalla rinomina. Serve a rendere visibile che\r\n * l'operazione tocca il resto del documento, non solo questo elemento.\r\n */\r\n readonly referenceCount = computed(() => {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return 0;\r\n }\r\n const serialized = JSON.stringify(this.store.document());\r\n // Conta le occorrenze del nome come valore di un campo di riferimento, incluso il caso\r\n // navigato (`Nome.Campo`).\r\n const pattern = new RegExp(`\"(${name})(\\\\.[A-Za-z0-9_.]+)?\"`, 'g');\r\n return (serialized.match(pattern) ?? []).length;\r\n });\r\n\r\n readonly canRename = computed(() => {\r\n const pending = this.pendingName();\r\n return pending !== null && pending !== this.selectedName() && !this.nameError();\r\n });\r\n\r\n startRename(): void {\r\n this.pendingName.set(this.selectedName());\r\n }\r\n\r\n onPendingNameInput(value: string): void {\r\n this.pendingName.set(value);\r\n }\r\n\r\n cancelRename(): void {\r\n this.pendingName.set(null);\r\n }\r\n\r\n /** Applica la rinomina riscrivendo tutti i riferimenti che raggiungono l'elemento. */\r\n applyRename(): void {\r\n const pending = this.pendingName();\r\n const current = this.selectedName();\r\n if (!pending || !current || !this.canRename()) {\r\n return;\r\n }\r\n this.store.renameNode(current, pending);\r\n this.pendingName.set(null);\r\n }\r\n\r\n setLabel(value: string): void {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return;\r\n }\r\n this.store.updateNode(name, (node) => {\r\n node.label = value || undefined;\r\n });\r\n }\r\n\r\n setDescription(value: string): void {\r\n const name = this.selectedName();\r\n if (!name || this.isStart()) {\r\n return;\r\n }\r\n this.store.updateNode(name, (node) => {\r\n node.description = value || undefined;\r\n });\r\n }\r\n\r\n /** Suggerisce il nome tecnico dalla label, come fa la creazione. */\r\n suggestNameFromLabel(): void {\r\n const node = this.node();\r\n if (!node?.label) {\r\n return;\r\n }\r\n this.pendingName.set(slugifyFlowName(node.label as string));\r\n }\r\n\r\n requestRemove(): void {\r\n const name = this.selectedName();\r\n if (name && !this.isStart()) {\r\n this.removeRequested.emit(name);\r\n }\r\n }\r\n\r\n requestDuplicate(): void {\r\n const name = this.selectedName();\r\n if (name && !this.isStart()) {\r\n this.duplicateRequested.emit(name);\r\n }\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n /** Le coordinate sono l'unica informazione di layout che il modello conserva (§3.5). */\r\n readonly position = computed(() => {\r\n const node = this.isStart() ? (this.store.start() as FlowAnyNode) : this.node();\r\n return { x: node?.locationX ?? 0, y: node?.locationY ?? 0 };\r\n });\r\n}\r\n","@if (!selectedName()) {\r\n <p class=\"fb-inspector__empty\">\r\n Seleziona un elemento sul canvas per modificarlo, oppure trascina un elemento dalla palette.\r\n </p>\r\n} @else {\r\n @if (showHeader()) {\r\n <header class=\"fb-inspector__header\">\r\n <div>\r\n <span class=\"fb-inspector__type\">{{ typeLabel() }}</span>\r\n <h2 class=\"fb-inspector__title\">\r\n {{ isStart() ? 'Avvio del flow' : node()?.label || selectedName() }}\r\n </h2>\r\n </div>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">\r\n ×\r\n </button>\r\n </header>\r\n }\r\n\r\n <div class=\"fb-inspector__body\">\r\n @if (issues().length) {\r\n <ul class=\"fb-inspector__issues\">\r\n <!-- `$index`: due rilievi con lo stesso codice e lo stesso path sono possibili. -->\r\n @for (issue of issues(); track $index) {\r\n <li\r\n class=\"fb-inspector__issue\"\r\n [class.fb-inspector__issue--error]=\"issue.severity === 'Error'\"\r\n [class.fb-inspector__issue--warning]=\"issue.severity === 'Warning'\"\r\n >\r\n <span class=\"fb-inspector__issue-code\">{{ issue.code }}</span>\r\n {{ issue.message }}\r\n @if (issue.path) {\r\n <span class=\"fb-inspector__issue-path\">{{ issue.path }}</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n\r\n @if (isUnsupported()) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Questo tipo di elemento non e’ supportato dal motore: il flow che lo contiene non parte\r\n (ELEMENT_NOT_SUPPORTED). Non e’ creabile dalla palette; se e’ arrivato da un documento importato,\r\n va rimosso.\r\n </p>\r\n }\r\n\r\n @if (!isStart()) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"$any(node()?.label) || ''\"\r\n placeholder=\"Nome mostrato sul canvas\"\r\n (input)=\"setLabel($any($event.target).value)\"\r\n />\r\n </div>\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Nome tecnico</label>\r\n @if (pendingName() === null) {\r\n <div class=\"fb-field__row\">\r\n <input class=\"fb-input fb-input--mono\" [value]=\"selectedName() || ''\" readonly />\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"startRename()\">Rinomina</button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n È l’identificatore con cui i riferimenti raggiungono questo elemento.\r\n @if (referenceCount() > 1) {\r\n Compare {{ referenceCount() }} volte nel documento.\r\n }\r\n </p>\r\n } @else {\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [class.fb-input--invalid]=\"!!nameError()\"\r\n [value]=\"pendingName() || ''\"\r\n (input)=\"onPendingNameInput($any($event.target).value)\"\r\n />\r\n @if (nameError()) {\r\n <p class=\"fb-field__error\">{{ nameError() }}</p>\r\n } @else {\r\n <p class=\"fb-field__hint fb-field__hint--warn\">\r\n La rinomina riscrive tutti i riferimenti che puntano a questo elemento\r\n ({{ referenceCount() }} occorrenze): nessuna primitiva del backend lo fa, lo fa l’editor.\r\n </p>\r\n }\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"!canRename()\" (click)=\"applyRename()\">\r\n Applica\r\n </button>\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"suggestNameFromLabel()\">Genera dalla label</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost\" (click)=\"cancelRename()\">Annulla</button>\r\n </div>\r\n }\r\n </div>\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]=\"$any(node()?.description) || ''\"\r\n (input)=\"setDescription($any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n }\r\n\r\n <p class=\"fb-inspector__position\">\r\n Posizione sul canvas: {{ position().x }}, {{ position().y }}\r\n </p>\r\n\r\n <hr class=\"fb-inspector__divider\" />\r\n\r\n @if (isStart()) {\r\n <fb-start-inspector />\r\n } @else if (node()) {\r\n @switch (type()) {\r\n @case ('Screen') {\r\n <fb-screen-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Assignment') {\r\n <fb-assignment-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Decision') {\r\n <fb-decision-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Loop') {\r\n <fb-loop-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('CollectionProcessor') {\r\n <fb-collection-processor-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('CustomError') {\r\n <fb-custom-error-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Wait') {\r\n <fb-wait-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('RecordLookup') {\r\n <fb-record-lookup-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('RecordCreate') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordCreate\" />\r\n }\r\n @case ('RecordUpdate') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordUpdate\" />\r\n }\r\n @case ('RecordDelete') {\r\n <fb-record-write-inspector [name]=\"selectedName()!\" [node]=\"node()!\" type=\"RecordDelete\" />\r\n }\r\n @case ('RecordRollback') {\r\n <fb-record-rollback-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('ActionCall') {\r\n <fb-action-call-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('ScriptCall') {\r\n <fb-script-call-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Subflow') {\r\n <fb-subflow-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('Transform') {\r\n <fb-transform-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @case ('OrchestratedStage') {\r\n <fb-orchestrated-stage-inspector [name]=\"selectedName()!\" [node]=\"node()!\" />\r\n }\r\n @default {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Nessun form specifico per il tipo «{{ type() }}»: i campi comuni sono modificabili qui sopra.\r\n </p>\r\n }\r\n }\r\n }\r\n\r\n @if (!isStart()) {\r\n <hr class=\"fb-inspector__divider\" />\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn\" (click)=\"requestDuplicate()\">Duplica</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger\" (click)=\"requestRemove()\">Elimina</button>\r\n </div>\r\n }\r\n </div>\r\n}\r\n","/**\r\n * Il dettaglio dell'elemento in una dialog, come nel flow builder di Salesforce.\r\n *\r\n * Perche' una dialog e non solo il pannello laterale: i form degli elementi non hanno tutti\r\n * la stessa taglia. Uno Screen, una Decision con quattro regole o un Get Records con filtri\r\n * e ordinamento occupano piu' spazio di quanto ne abbia una colonna da 340px, e nel pannello\r\n * si scorreva molto. La dialog da' la larghezza necessaria e, mentre e' aperta, dichiara che\r\n * si sta configurando **quell'** elemento.\r\n *\r\n * Non c'e' un «Annulla»: le modifiche entrano nel documento mentre si digita, esattamente\r\n * come nel pannello, e tornare indietro e' compito dell'annulla generale dell'editor. Un\r\n * bottone che promettesse di scartare le modifiche solo di questa dialog mentirebbe, perche'\r\n * il documento e' uno e le modifiche sono già dentro.\r\n *\r\n * La dialog vive **dentro** il componente builder, non in fondo al `body`: la libreria e'\r\n * innestabile in una pagina qualsiasi e appropriarsi del `body` sarebbe una sorpresa per\r\n * l'applicazione ospite (dialog dell'ospite, `overflow`, stacking context).\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\n\r\nimport { FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { START_NODE_NAME } from '../../core/element-outlets';\r\nimport { ElementInspectorComponent } from './element-inspector.component';\r\n\r\n@Component({\r\n selector: 'fb-element-dialog',\r\n standalone: true,\r\n imports: [ElementInspectorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './element-dialog.component.html',\r\n styleUrl: './element-dialog.component.css',\r\n})\r\nexport class ElementDialogComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n\r\n /** L'elemento da configurare; `$start` per lo Start. */\r\n readonly selectedName = input<string | null>(null);\r\n\r\n readonly closed = output<void>();\r\n readonly removeRequested = output<string>();\r\n readonly duplicateRequested = output<string>();\r\n\r\n private readonly panel = viewChild<ElementRef<HTMLElement>>('panel');\r\n\r\n readonly isStart = computed(() => this.selectedName() === START_NODE_NAME);\r\n\r\n private readonly reference = computed(() => {\r\n const name = this.selectedName();\r\n return name && !this.isStart() ? this.store.nodeByName().get(name) : undefined;\r\n });\r\n\r\n readonly typeLabel = computed(() =>\r\n this.isStart() ? 'Avvio del flow' : this.dictionaries.labelOf(this.reference()?.type ?? ''),\r\n );\r\n\r\n readonly title = computed(() => {\r\n if (this.isStart()) {\r\n return 'Avvio del flow';\r\n }\r\n const node = this.reference()?.node;\r\n return (node?.label as string) || this.selectedName() || '';\r\n });\r\n\r\n constructor() {\r\n // Il focus entra nella dialog quando cambia elemento: da tastiera si arriva subito ai\r\n // campi, e `Esc` chiude senza dover prima cliccare dentro.\r\n effect(() => {\r\n const name = this.selectedName();\r\n const panel = this.panel()?.nativeElement;\r\n if (name && panel) {\r\n panel.focus({ preventScroll: true });\r\n }\r\n });\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n onRemoveRequested(name: string): void {\r\n this.removeRequested.emit(name);\r\n }\r\n\r\n onDuplicateRequested(name: string): void {\r\n this.duplicateRequested.emit(name);\r\n }\r\n}\r\n","<!--\r\n Il backdrop chiude: e' il gesto che tutti si aspettano. Il pannello ferma la propagazione\r\n del click, altrimenti configurare un campo chiuderebbe la dialog.\r\n-->\r\n<div class=\"fb-dialog__backdrop\" (click)=\"close()\"></div>\r\n\r\n<div\r\n #panel\r\n class=\"fb-dialog__panel\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n [attr.aria-label]=\"typeLabel() + ': ' + title()\"\r\n tabindex=\"-1\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown.escape)=\"close()\"\r\n>\r\n <header class=\"fb-dialog__head\">\r\n <div class=\"fb-dialog__identity\">\r\n <span class=\"fb-dialog__type\">{{ typeLabel() }}</span>\r\n <h2 class=\"fb-dialog__title\">{{ title() }}</h2>\r\n </div>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n </header>\r\n\r\n <div class=\"fb-dialog__body\">\r\n <!-- L'intestazione dell'inspector qui e' quella della dialog: non si ripete. -->\r\n <fb-element-inspector\r\n [selectedName]=\"selectedName()\"\r\n [showHeader]=\"false\"\r\n (removeRequested)=\"onRemoveRequested($event)\"\r\n (duplicateRequested)=\"onDuplicateRequested($event)\"\r\n (closed)=\"close()\"\r\n />\r\n </div>\r\n\r\n <footer class=\"fb-dialog__foot\">\r\n <span class=\"fb-dialog__note\">\r\n Le modifiche sono già nel documento: per tornare indietro c’è l’annulla dell’editor.\r\n </span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" (click)=\"close()\">Fatto</button>\r\n </footer>\r\n</div>\r\n","/**\r\n * Le risorse — FRONTEND.md §4.6.\r\n *\r\n * Sette tipi, ognuno nella propria collection. **Solo le variabili sono scrivibili**:\r\n * assegnare a una costante o a una formula e' `TARGET_NOT_WRITABLE`, e per questo il\r\n * pannello mostra quali risorse possono comparire come destinazione e quali no.\r\n *\r\n * Il nome vive nello stesso spazio dei nomi dei node (§3.3): una variabile chiamata come un\r\n * elemento e' un errore, non una stranezza tollerata, e il controllo qui guarda **entrambi**\r\n * gli insiemi — e' la trappola §13.5.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../../core/flow-dictionary.store';\r\nimport { FlowDocumentStore, FlowResourceRef } from '../../core/flow-document.store';\r\nimport { checkFlowName, uniqueFlowName } from '../../core/flow-name.util';\r\nimport { FlowCatalogEntry } from '../../model/dictionary.model';\r\nimport { FlowResourceCollection, FlowValue } from '../../model/flow.model';\r\nimport { FieldPickerComponent } from '../shared/field-picker.component';\r\nimport { ObjectPickerComponent } from '../shared/object-picker.component';\r\nimport { ValueEditorComponent } from '../shared/value-editor.component';\r\nimport { SelectValueDirective } from '../shared/select-value.directive';\r\n\r\ninterface ResourceKindDescriptor {\r\n collection: FlowResourceCollection;\r\n label: string;\r\n singular: string;\r\n isWritable: boolean;\r\n /** Cosa serve dichiarare, in una riga. */\r\n note: string;\r\n}\r\n\r\n/**\r\n * Le sette collection. `resourceKinds` del dizionario le descrive, ma la mappa\r\n * collection → comportamento del form resta qui perche' i campi cambiano per tipo.\r\n */\r\nconst RESOURCE_KINDS: ResourceKindDescriptor[] = [\r\n {\r\n collection: 'variables',\r\n label: 'Variabili',\r\n singular: 'variabile',\r\n isWritable: true,\r\n note: 'Le sole risorse scrivibili: solo queste possono essere una destinazione.',\r\n },\r\n {\r\n collection: 'constants',\r\n label: 'Costanti',\r\n singular: 'costante',\r\n isWritable: false,\r\n note: 'Valore fisso: una costante non puo’ referenziare altre risorse.',\r\n },\r\n {\r\n collection: 'formulas',\r\n label: 'Formule',\r\n singular: 'formula',\r\n isWritable: false,\r\n note: 'L’espressione va al motore di regole: il backend non ne verifica la sintassi.',\r\n },\r\n {\r\n collection: 'textTemplates',\r\n label: 'Text template',\r\n singular: 'text template',\r\n isWritable: false,\r\n note: 'Testo con segnaposto, es. «Gentile {!Cliente.Nome},».',\r\n },\r\n {\r\n collection: 'choices',\r\n label: 'Choice',\r\n singular: 'choice',\r\n isWritable: false,\r\n note: 'Una singola scelta: testo mostrato piu’ valore.',\r\n },\r\n {\r\n collection: 'dynamicChoiceSets',\r\n label: 'Dynamic choice set',\r\n singular: 'dynamic choice set',\r\n isWritable: false,\r\n note: 'Scelte lette dal database. I filtri sono sempre in AND.',\r\n },\r\n {\r\n collection: 'stages',\r\n label: 'Stage',\r\n singular: 'stage',\r\n isWritable: false,\r\n note: 'Gli stage si fanno avanzare con un Assignment su $Flow.CurrentStage.',\r\n },\r\n];\r\n\r\n@Component({\r\n selector: 'fb-resource-panel',\r\n standalone: true,\r\n imports: [FieldPickerComponent, ObjectPickerComponent, ValueEditorComponent, SelectValueDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './resource-panel.component.html',\r\n styleUrl: './resource-panel.component.css',\r\n})\r\nexport class ResourcePanelComponent {\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly dictionaries = inject(FlowDictionaryStore);\r\n private readonly catalog = inject(FlowCatalogStore);\r\n\r\n readonly closed = output<void>();\r\n\r\n readonly kinds = RESOURCE_KINDS;\r\n readonly dataTypes = computed(() => this.dictionaries.dataTypes());\r\n readonly sortOrders = computed(() => this.dictionaries.sortOrders());\r\n\r\n private readonly enumTypes = signal<FlowCatalogEntry[]>([]);\r\n\r\n /** La collection aperta nel pannello. */\r\n readonly activeCollection = signal<FlowResourceCollection>('variables');\r\n /** L'indice della risorsa in modifica, o `null`. */\r\n readonly editingIndex = signal<number | null>(null);\r\n\r\n constructor() {\r\n void this.catalog.listEnumTypes().then((list) => this.enumTypes.set(list ?? []));\r\n }\r\n\r\n readonly enumOptions = computed(() => this.enumTypes());\r\n\r\n readonly activeKind = computed<ResourceKindDescriptor>(\r\n () => RESOURCE_KINDS.find((kind) => kind.collection === this.activeCollection()) ?? RESOURCE_KINDS[0],\r\n );\r\n\r\n readonly items = computed<FlowResourceRef[]>(() =>\r\n this.store.resources().filter((reference) => reference.collection === this.activeCollection()),\r\n );\r\n\r\n countOf(collection: FlowResourceCollection): number {\r\n return this.store.resources().filter((reference) => reference.collection === collection).length;\r\n }\r\n\r\n select(collection: FlowResourceCollection): void {\r\n this.activeCollection.set(collection);\r\n this.editingIndex.set(null);\r\n }\r\n\r\n toggleEdit(index: number): void {\r\n this.editingIndex.set(this.editingIndex() === index ? null : index);\r\n }\r\n\r\n /** Nome valido e libero nello spazio dei nomi condiviso con i node (§3.3, §13.5). */\r\n nameError(reference: FlowResourceRef): string | null {\r\n const check = checkFlowName(reference.name, this.store.usedNames(), reference.name);\r\n if (!check.isValid) {\r\n return check.message ?? 'Nome non valido.';\r\n }\r\n // Un omonimo di un node: il controllo di unicita' che guarda solo le risorse lo manca.\r\n const clashes = this.store\r\n .usedNames()\r\n .filter((name) => name.toLowerCase() === reference.name.toLowerCase());\r\n return clashes.length > 1 ? 'Questo nome e’ usato anche da un altro elemento o risorsa.' : null;\r\n }\r\n\r\n add(): void {\r\n const kind = this.activeKind();\r\n const name = uniqueFlowName(kind.singular.replace(/\\s+/g, '_'), this.store.usedNames());\r\n const resource: Record<string, unknown> = { name };\r\n // `dataType` e' obbligatorio su variabili, costanti, formule, choice e choice set (§4.6).\r\n if (kind.collection !== 'textTemplates' && kind.collection !== 'stages') {\r\n resource['dataType'] = 'String';\r\n }\r\n if (kind.collection === 'stages') {\r\n // Gli `stageOrder` devono essere distinti: si parte dal primo libero.\r\n const used = new Set(\r\n this.store\r\n .resources()\r\n .filter((entry) => entry.collection === 'stages')\r\n .map((entry) => entry.resource['stageOrder'] as number),\r\n );\r\n let order = 1;\r\n while (used.has(order)) {\r\n order += 1;\r\n }\r\n resource['stageOrder'] = order;\r\n resource['isActive'] = true;\r\n resource['label'] = name;\r\n }\r\n this.store.addResource(kind.collection, resource);\r\n this.editingIndex.set(this.items().length);\r\n }\r\n\r\n remove(reference: FlowResourceRef): void {\r\n this.store.removeResource(reference.collection, reference.index);\r\n this.editingIndex.set(null);\r\n }\r\n\r\n rename(reference: FlowResourceRef, name: string): void {\r\n // Rinominare riscrive i riferimenti: nessuna primitiva lo fa per noi (§13.8).\r\n this.store.renameResource(reference.collection, reference.index, name);\r\n }\r\n\r\n setField(reference: FlowResourceRef, field: string, value: unknown): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value === undefined || value === null || value === '') {\r\n delete resource[field];\r\n } else {\r\n resource[field] = value;\r\n }\r\n });\r\n }\r\n\r\n setNumberField(reference: FlowResourceRef, field: string, raw: string): void {\r\n const parsed = Number.parseInt(raw, 10);\r\n this.setField(reference, field, Number.isNaN(parsed) ? undefined : parsed);\r\n }\r\n\r\n setBooleanField(reference: FlowResourceRef, field: string, value: boolean): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value) {\r\n resource[field] = true;\r\n } else {\r\n delete resource[field];\r\n }\r\n });\r\n }\r\n\r\n setValue(reference: FlowResourceRef, value: FlowValue | undefined): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n if (value) {\r\n resource['value'] = value;\r\n } else {\r\n delete resource['value'];\r\n }\r\n });\r\n }\r\n\r\n setDataType(reference: FlowResourceRef, dataType: string): void {\r\n this.store.updateResource(reference.collection, reference.index, (resource) => {\r\n resource['dataType'] = dataType;\r\n if (!this.dictionaries.requiresObjectType(dataType)) {\r\n delete resource['objectType'];\r\n }\r\n // `scale` si applica solo ai numerici: altrove e' `SCALE_NOT_APPLICABLE`.\r\n if (!this.dictionaries.supportsScale(dataType)) {\r\n delete resource['scale'];\r\n }\r\n });\r\n }\r\n\r\n requiresObjectType(reference: FlowResourceRef): boolean {\r\n return this.dictionaries.requiresObjectType(reference.resource['dataType'] as string);\r\n }\r\n\r\n supportsScale(reference: FlowResourceRef): boolean {\r\n return this.dictionaries.supportsScale(reference.resource['dataType'] as string);\r\n }\r\n\r\n isEnum(reference: FlowResourceRef): boolean {\r\n return reference.resource['dataType'] === 'Enum';\r\n }\r\n\r\n /** Una costante che referenzia una risorsa e' `CONSTANT_REFERENCES_RESOURCE`. */\r\n constantReferencesResource(reference: FlowResourceRef): boolean {\r\n if (reference.collection !== 'constants') {\r\n return false;\r\n }\r\n const value = reference.resource['value'] as FlowValue | undefined;\r\n return !!value?.elementReference || !!value?.formulaExpression;\r\n }\r\n\r\n /** `stageOrder` duplicati: quale stage sia il corrente all'avvio diventa arbitrario. */\r\n duplicateStageOrder(reference: FlowResourceRef): boolean {\r\n if (reference.collection !== 'stages') {\r\n return false;\r\n }\r\n const order = reference.resource['stageOrder'];\r\n if (order === undefined) {\r\n return false;\r\n }\r\n return (\r\n this.store\r\n .resources()\r\n .filter((entry) => entry.collection === 'stages' && entry.resource['stageOrder'] === order).length > 1\r\n );\r\n }\r\n\r\n string(reference: FlowResourceRef, field: string): string {\r\n const value = reference.resource[field];\r\n return value === undefined || value === null ? '' : String(value);\r\n }\r\n\r\n boolean(reference: FlowResourceRef, field: string): boolean {\r\n return reference.resource[field] === true;\r\n }\r\n\r\n value(reference: FlowResourceRef): FlowValue | undefined {\r\n return reference.resource['value'] as FlowValue | undefined;\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-res__header\">\r\n <h2 class=\"fb-res__title\">Risorse</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<nav class=\"fb-res__tabs\" aria-label=\"Tipi di risorsa\">\r\n @for (kind of kinds; track kind.collection) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-res__tab\"\r\n [class.fb-res__tab--active]=\"activeCollection() === kind.collection\"\r\n (click)=\"select(kind.collection)\"\r\n >\r\n {{ kind.label }}\r\n <span class=\"fb-res__count\">{{ countOf(kind.collection) }}</span>\r\n </button>\r\n }\r\n</nav>\r\n\r\n<div class=\"fb-res__body\">\r\n <p class=\"fb-section__note\">{{ activeKind().note }}</p>\r\n\r\n <div class=\"fb-list\">\r\n @for (item of items(); track item.collection + ':' + item.index) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <button type=\"button\" class=\"fb-res__name\" (click)=\"toggleEdit($index)\">\r\n <span class=\"fb-res__name-text\">{{ item.name || '(senza nome)' }}</span>\r\n <span class=\"fb-res__meta\">\r\n {{ string(item, 'dataType') }}{{ boolean(item, 'isCollection') ? '[]' : '' }}\r\n @if (boolean(item, 'isInput')) {\r\n · input\r\n }\r\n @if (boolean(item, 'isOutput')) {\r\n · output\r\n }\r\n </span>\r\n </button>\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 la risorsa\"\r\n (click)=\"remove(item)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n @if (nameError(item)) {\r\n <p class=\"fb-field__error\">{{ nameError(item) }}</p>\r\n }\r\n @if (constantReferencesResource(item)) {\r\n <p class=\"fb-callout fb-callout--error\">\r\n Una costante deve essere un valore fisso: non puo’ referenziare altre risorse\r\n (CONSTANT_REFERENCES_RESOURCE).\r\n </p>\r\n }\r\n @if (duplicateStageOrder(item)) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Due stage con lo stesso ordine: quale sia il corrente all’avvio diventa arbitrario\r\n (STAGE_ORDER_DUPLICATED).\r\n </p>\r\n }\r\n\r\n @if (editingIndex() === $index) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Nome</label>\r\n <input\r\n class=\"fb-input fb-input--mono\"\r\n [value]=\"item.name\"\r\n (change)=\"rename(item, $any($event.target).value)\"\r\n />\r\n <p class=\"fb-field__hint\">\r\n Il nome vive nello stesso spazio dei nomi degli elementi. Rinominare riscrive i riferimenti.\r\n </p>\r\n </div>\r\n\r\n @if (item.collection === 'stages') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Etichetta</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'label')\"\r\n (input)=\"setField(item, 'label', $any($event.target).value)\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Ordine</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"string(item, 'stageOrder')\"\r\n (input)=\"setNumberField(item, 'stageOrder', $any($event.target).value)\"\r\n />\r\n </div>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isActive')\"\r\n (change)=\"setBooleanField(item, 'isActive', $any($event.target).checked)\"\r\n />\r\n Attivo all’avvio\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n All’avvio lo stage corrente e’ il primo attivo per ordine. Si avanza con un Assignment su\r\n <code>$Flow.CurrentStage</code>.\r\n </p>\r\n }\r\n\r\n @if (item.collection === 'textTemplates') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Testo</label>\r\n <textarea\r\n class=\"fb-textarea\"\r\n [value]=\"string(item, 'text')\"\r\n placeholder=\"Gentile {!Cliente.Nome},\"\r\n (input)=\"setField(item, 'text', $any($event.target).value)\"\r\n ></textarea>\r\n </div>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isViewedAsPlainText')\"\r\n (change)=\"setBooleanField(item, 'isViewedAsPlainText', $any($event.target).checked)\"\r\n />\r\n Testo semplice\r\n </label>\r\n }\r\n\r\n @if (item.collection !== 'textTemplates' && item.collection !== 'stages') {\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]=\"string(item, 'dataType')\"\r\n (change)=\"setDataType(item, $any($event.target).value)\"\r\n >\r\n @for (type of dataTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n @if (requiresObjectType(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">\r\n {{ isEnum(item) ? 'Tipo di enumerazione' : 'Oggetto' }}\r\n </label>\r\n @if (isEnum(item)) {\r\n <!-- Dizionario chiuso: qui la scrittura libera non serve. -->\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"string(item, 'objectType')\"\r\n (change)=\"setField(item, 'objectType', $any($event.target).value)\"\r\n >\r\n <option value=\"\">— scegli —</option>\r\n @for (entry of enumOptions(); track entry.name) {\r\n <option [value]=\"entry.name\">{{ entry.label || entry.name }}</option>\r\n }\r\n </select>\r\n } @else {\r\n <fb-object-picker\r\n [value]=\"string(item, 'objectType') || undefined\"\r\n label=\"Oggetto\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setField(item, 'objectType', $event ?? '')\"\r\n />\r\n }\r\n <p class=\"fb-field__hint\">Obbligatorio per Object ed Enum (OBJECT_TYPE_MISSING).</p>\r\n </div>\r\n }\r\n\r\n @if (supportsScale(item)) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Decimali</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"0\"\r\n [value]=\"string(item, 'scale')\"\r\n (input)=\"setNumberField(item, 'scale', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n @if (item.collection === 'variables') {\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isCollection')\"\r\n (change)=\"setBooleanField(item, 'isCollection', $any($event.target).checked)\"\r\n />\r\n È una collection\r\n </label>\r\n <p class=\"fb-field__hint\">Solo una collection puo’ essere iterata da un Loop.</p>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isInput')\"\r\n (change)=\"setBooleanField(item, 'isInput', $any($event.target).checked)\"\r\n />\r\n Valorizzabile all’avvio (input)\r\n </label>\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"boolean(item, 'isOutput')\"\r\n (change)=\"setBooleanField(item, 'isOutput', $any($event.target).checked)\"\r\n />\r\n Leggibile alla fine (output)\r\n </label>\r\n <p class=\"fb-field__hint\">\r\n Input e output sono il contratto del flow verso chi lo invoca, subflow compresi.\r\n </p>\r\n }\r\n\r\n @if (item.collection === 'formulas') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Espressione</label>\r\n <textarea\r\n class=\"fb-textarea fb-input--mono\"\r\n [value]=\"string(item, 'expression')\"\r\n placeholder=\"Importo * 1.22\"\r\n (input)=\"setField(item, 'expression', $any($event.target).value)\"\r\n ></textarea>\r\n <p class=\"fb-field__hint\">\r\n Passata verbatim al motore di regole: il backend non la valida.\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (item.collection === 'choices') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Testo mostrato</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'choiceText')\"\r\n (input)=\"setField(item, 'choiceText', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (item.collection === 'dynamicChoiceSets') {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Oggetto</label>\r\n <fb-object-picker\r\n [value]=\"string(item, 'object') || undefined\"\r\n placeholder=\"Scrivi o scegli un oggetto\"\r\n (valueChange)=\"setField(item, 'object', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo mostrato</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'displayField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"any\"\r\n label=\"Campo mostrato\"\r\n (valueChange)=\"setField(item, 'displayField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label fb-field__label--required\">Campo del valore</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'valueField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"any\"\r\n label=\"Campo del valore\"\r\n (valueChange)=\"setField(item, 'valueField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field__row\">\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Ordina per</label>\r\n <fb-field-picker\r\n [value]=\"string(item, 'sortField') || undefined\"\r\n [object]=\"string(item, 'object') || undefined\"\r\n usage=\"sortable\"\r\n label=\"Campo di ordinamento\"\r\n placeholder=\"Nessun ordinamento\"\r\n (valueChange)=\"setField(item, 'sortField', $event ?? '')\"\r\n />\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Direzione</label>\r\n <select\r\n class=\"fb-select\"\r\n [fbValue]=\"string(item, 'sortOrder')\"\r\n (change)=\"setField(item, 'sortOrder', $any($event.target).value)\"\r\n >\r\n <option value=\"\">—</option>\r\n @for (order of sortOrders(); track order.value) {\r\n <option [value]=\"order.value\">{{ order.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Numero massimo</label>\r\n <input\r\n class=\"fb-input\"\r\n type=\"number\"\r\n min=\"1\"\r\n [value]=\"string(item, 'limit')\"\r\n (input)=\"setNumberField(item, 'limit', $any($event.target).value)\"\r\n />\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n I filtri di un dynamic choice set sono sempre in AND: non c’e’ logica personalizzata.\r\n </p>\r\n }\r\n\r\n @if (\r\n item.collection === 'variables' || item.collection === 'constants' || item.collection === 'choices'\r\n ) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ item.collection === 'variables' ? 'Valore iniziale' : 'Valore' }}\r\n </label>\r\n <fb-value-editor\r\n [value]=\"value(item)\"\r\n [dataType]=\"$any(item.resource['dataType'])\"\r\n [objectType]=\"$any(item.resource['objectType'])\"\r\n [isCollection]=\"boolean(item, 'isCollection')\"\r\n [allowFormula]=\"item.collection !== 'constants'\"\r\n label=\"Valore\"\r\n (valueChange)=\"setValue(item, $event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">Descrizione</label>\r\n <input\r\n class=\"fb-input\"\r\n [value]=\"string(item, 'description')\"\r\n (input)=\"setField(item, 'description', $any($event.target).value)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n } @empty {\r\n <p class=\"fb-empty\">Nessuna risorsa di questo tipo.</p>\r\n }\r\n </div>\r\n\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" (click)=\"add()\">\r\n Aggiungi {{ activeKind().singular }}\r\n </button>\r\n</div>\r\n","/**\r\n * Il pannello dei problemi — FRONTEND.md §7.\r\n *\r\n * I rilievi arrivano ordinati per gravita' decrescente. `code` e' stabile e si usa per\r\n * raggruppare e per decidere il comportamento; `message` e' testo per l'utente e non va\r\n * interpretato. `elementName` e' l'ancora per portare l'utente sull'elemento con un clic.\r\n *\r\n * Tre effetti che l'interfaccia deve rispettare:\r\n * - `Error` blocca l'**attivazione**, non il salvataggio;\r\n * - `Warning` non blocca nulla, ma dice che qualcosa non fara' cio' che sembra;\r\n * - l'assenza di rilievi **non** e' una garanzia di correttezza: la validazione non verifica\r\n * i percorsi di relazione, la sintassi delle formule, ne' i cataloghi non popolati.\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowValidationStore } from '../../core/flow-validation.store';\r\nimport { FlowValidationIssue } from '../../model/api.model';\r\nimport { START_NODE_NAME } from '../../core/element-outlets';\r\n\r\ntype SeverityFilter = 'all' | 'Error' | 'Warning' | 'Info';\r\n\r\n@Component({\r\n selector: 'fb-problems-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './problems-panel.component.html',\r\n styleUrl: './problems-panel.component.css',\r\n})\r\nexport class ProblemsPanelComponent {\r\n private readonly validation = inject(FlowValidationStore);\r\n\r\n /** Chiede di selezionare l'elemento: `$start` per i rilievi sul documento. */\r\n readonly elementFocused = output<string>();\r\n readonly closed = output<void>();\r\n\r\n readonly filter = signal<SeverityFilter>('all');\r\n\r\n readonly isRunning = computed(() => this.validation.isRunning());\r\n readonly hasResult = computed(() => this.validation.hasResult());\r\n readonly lastError = computed(() => this.validation.lastError());\r\n readonly errorCount = computed(() => this.validation.errorCount());\r\n readonly warningCount = computed(() => this.validation.warningCount());\r\n readonly infoCount = computed(() => this.validation.infoCount());\r\n\r\n readonly issues = computed<FlowValidationIssue[]>(() => {\r\n const filter = this.filter();\r\n const issues = this.validation.issues();\r\n return filter === 'all' ? issues : issues.filter((issue) => issue.severity === filter);\r\n });\r\n\r\n readonly isClean = computed(() => this.hasResult() && this.validation.issues().length === 0);\r\n\r\n setFilter(filter: SeverityFilter): void {\r\n this.filter.set(filter);\r\n }\r\n\r\n focus(issue: FlowValidationIssue): void {\r\n // Un rilievo senza `elementName` riguarda il documento: l'ancora piu' vicina e' lo Start.\r\n this.elementFocused.emit(issue.elementName || START_NODE_NAME);\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-prob__header\">\r\n <h2 class=\"fb-prob__title\">\r\n Problemi\r\n @if (isRunning()) {\r\n <span class=\"fb-prob__running\">validazione in corso…</span>\r\n }\r\n </h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<nav class=\"fb-prob__filters\" aria-label=\"Filtra per gravita’\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter\"\r\n [class.fb-prob__filter--active]=\"filter() === 'all'\"\r\n (click)=\"setFilter('all')\"\r\n >\r\n Tutti\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter fb-prob__filter--error\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Error'\"\r\n (click)=\"setFilter('Error')\"\r\n >\r\n Errori <span class=\"fb-prob__count\">{{ errorCount() }}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter fb-prob__filter--warning\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Warning'\"\r\n (click)=\"setFilter('Warning')\"\r\n >\r\n Avvisi <span class=\"fb-prob__count\">{{ warningCount() }}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-prob__filter\"\r\n [class.fb-prob__filter--active]=\"filter() === 'Info'\"\r\n (click)=\"setFilter('Info')\"\r\n >\r\n Note <span class=\"fb-prob__count\">{{ infoCount() }}</span>\r\n </button>\r\n</nav>\r\n\r\n<div class=\"fb-prob__body\">\r\n @if (lastError()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n Non e’ stato possibile validare: {{ lastError() }}\r\n </p>\r\n }\r\n\r\n @if (!hasResult() && !isRunning()) {\r\n <p class=\"fb-empty\">La validazione non e’ ancora stata eseguita.</p>\r\n }\r\n\r\n @if (isClean()) {\r\n <p class=\"fb-empty\">\r\n Nessun rilievo. Attenzione: non e’ una garanzia di correttezza — la validazione non verifica i percorsi\r\n di relazione nei campi, la sintassi delle formule, ne’ action, form e parametri quando il catalogo\r\n corrispondente non e’ popolato.\r\n </p>\r\n }\r\n\r\n <ul class=\"fb-prob__list\">\r\n <!-- `$index`: due rilievi possono avere codice, elemento e path identici (due condizioni\r\n incomplete nella stessa regola), e una chiave duplicata e' un errore di Angular. -->\r\n @for (issue of issues(); track $index) {\r\n <li\r\n class=\"fb-prob__item\"\r\n [class.fb-prob__item--error]=\"issue.severity === 'Error'\"\r\n [class.fb-prob__item--warning]=\"issue.severity === 'Warning'\"\r\n >\r\n <button type=\"button\" class=\"fb-prob__link\" (click)=\"focus(issue)\">\r\n <span class=\"fb-prob__message\">{{ issue.message }}</span>\r\n <span class=\"fb-prob__meta\">\r\n <code>{{ issue.code }}</code>\r\n @if (issue.elementName) {\r\n · {{ issue.elementName }}\r\n }\r\n @if (issue.path) {\r\n · {{ issue.path }}\r\n }\r\n </span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n\r\n @if (errorCount() > 0) {\r\n <p class=\"fb-prob__note\">\r\n Gli errori bloccano l’<strong>attivazione</strong>, non il salvataggio: puoi interrompere il lavoro a\r\n metà e riprenderlo.\r\n </p>\r\n }\r\n</div>\r\n","/**\r\n * Versioni e ciclo di vita — FRONTEND.md §8, §9.\r\n *\r\n * Le quattro regole che l'interfaccia deve rispettare, tutte visibili qui:\r\n * 1. **si modifica una bozza**: su una versione non modificabile il comando e' \"Nuova\r\n * versione\", non \"Salva\" — `isEditable` arriva dal backend e non si ricalcola;\r\n * 2. una bozza si salva anche con errori, e finisce in `InvalidDraft`;\r\n * 3. **attivare esige zero errori**;\r\n * 4. una sola versione attiva: attivarne una rende `Obsolete` la precedente.\r\n *\r\n * L'eliminazione di una versione e' offerta dietro conferma esplicita, perche' il numero\r\n * piu' alto viene riassegnato e un'esecuzione sospesa nata su quel numero riprenderebbe su\r\n * una definizione diversa (§8, ultimo capoverso).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowEditorSession } from '../../core/flow-editor-session';\r\nimport { FlowVersionSummary } from '../../model/api.model';\r\n\r\n@Component({\r\n selector: 'fb-version-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './version-panel.component.html',\r\n styleUrl: './version-panel.component.css',\r\n})\r\nexport class VersionPanelComponent {\r\n private readonly session = inject(FlowEditorSession);\r\n\r\n readonly closed = output<void>();\r\n readonly versionOpened = output<number>();\r\n /** Comunica un esito all'host, che lo mostra come notifica. */\r\n readonly notice = output<{ kind: 'info' | 'error'; message: string }>();\r\n\r\n readonly versions = computed(() => this.session.versions());\r\n readonly currentVersion = computed(() => this.session.version());\r\n readonly isBusy = computed(() => this.session.isBusy());\r\n readonly canActivate = computed(() => this.session.canActivate());\r\n\r\n /** La versione per cui e' stata chiesta l'eliminazione: conferma in due passi. */\r\n readonly pendingDelete = signal<number | null>(null);\r\n\r\n isCurrent(version: FlowVersionSummary): boolean {\r\n return version.version === this.currentVersion();\r\n }\r\n\r\n statusLabel(version: FlowVersionSummary): string {\r\n switch (version.status) {\r\n case 'Draft':\r\n return 'Bozza';\r\n case 'InvalidDraft':\r\n return 'Bozza con errori';\r\n case 'UnderReview':\r\n return 'In approvazione';\r\n case 'Active':\r\n return 'Attiva';\r\n case 'Obsolete':\r\n return 'Superata';\r\n default:\r\n return version.status ?? '';\r\n }\r\n }\r\n\r\n open(version: FlowVersionSummary): void {\r\n this.versionOpened.emit(version.version);\r\n }\r\n\r\n async activate(version: FlowVersionSummary): Promise<void> {\r\n if (version.version !== this.currentVersion()) {\r\n // L'attivazione agisce sulla versione caricata: prima la si apre.\r\n this.versionOpened.emit(version.version);\r\n return;\r\n }\r\n try {\r\n const result = await this.session.activate();\r\n this.notice.emit({ kind: 'info', message: `Versione ${result.version} attivata.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Attivazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n async deactivate(): Promise<void> {\r\n try {\r\n await this.session.deactivate();\r\n this.notice.emit({ kind: 'info', message: 'Flow disattivato: non e’ piu’ eseguibile.' });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Disattivazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n async createNewVersion(): Promise<void> {\r\n try {\r\n const result = await this.session.createNewVersion();\r\n this.notice.emit({ kind: 'info', message: `Creata la versione ${result.version}.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Creazione della versione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n requestDelete(version: FlowVersionSummary): void {\r\n this.pendingDelete.set(version.version);\r\n }\r\n\r\n cancelDelete(): void {\r\n this.pendingDelete.set(null);\r\n }\r\n\r\n async confirmDelete(version: number): Promise<void> {\r\n this.pendingDelete.set(null);\r\n try {\r\n await this.session.deleteVersion(version);\r\n this.notice.emit({ kind: 'info', message: `Versione ${version} eliminata.` });\r\n } catch (error) {\r\n this.notice.emit({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : 'Eliminazione non riuscita.',\r\n });\r\n }\r\n }\r\n\r\n readonly hasActiveVersion = computed(() => this.versions().some((version) => version.isActive));\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n}\r\n","<header class=\"fb-ver__header\">\r\n <h2 class=\"fb-ver__title\">Versioni</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<div class=\"fb-ver__body\">\r\n <div class=\"fb-field__row\">\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isBusy()\" (click)=\"createNewVersion()\">\r\n Nuova versione dalla corrente\r\n </button>\r\n @if (hasActiveVersion()) {\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger\" [disabled]=\"isBusy()\" (click)=\"deactivate()\">\r\n Disattiva\r\n </button>\r\n }\r\n </div>\r\n\r\n <ul class=\"fb-ver__list\">\r\n @for (version of versions(); track version.version) {\r\n <li class=\"fb-ver__item\" [class.fb-ver__item--current]=\"isCurrent(version)\">\r\n <div class=\"fb-ver__row\">\r\n <button type=\"button\" class=\"fb-ver__open\" (click)=\"open(version)\">\r\n <span class=\"fb-ver__number\">v{{ version.version }}</span>\r\n <span\r\n class=\"fb-ver__status\"\r\n [class.fb-ver__status--active]=\"version.isActive\"\r\n [class.fb-ver__status--invalid]=\"version.status === 'InvalidDraft'\"\r\n >\r\n {{ statusLabel(version) }}\r\n </span>\r\n @if (isCurrent(version)) {\r\n <span class=\"fb-ver__badge\">aperta</span>\r\n }\r\n </button>\r\n </div>\r\n\r\n <p class=\"fb-ver__meta\">\r\n @if (version.updatedAt) {\r\n aggiornata {{ version.updatedAt }}\r\n }\r\n @if (version.updatedBy) {\r\n da {{ version.updatedBy }}\r\n }\r\n </p>\r\n\r\n <div class=\"fb-ver__actions\">\r\n @if (version.isEditable) {\r\n <span class=\"fb-ver__hint\">Modificabile</span>\r\n } @else {\r\n <!-- Salvare su una versione Active o Obsolete verrebbe rifiutato con NotEditable. -->\r\n <span class=\"fb-ver__hint\">Sola lettura: per modificarla, creane una nuova</span>\r\n }\r\n\r\n @if (!version.isActive && isCurrent(version)) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary fb-btn--icon\"\r\n [disabled]=\"isBusy() || !canActivate()\"\r\n [title]=\"canActivate() ? 'Attiva questa versione' : 'Ci sono errori da correggere prima di attivare'\"\r\n (click)=\"activate(version)\"\r\n >\r\n Attiva\r\n </button>\r\n }\r\n\r\n @if (!version.isActive) {\r\n @if (pendingDelete() === version.version) {\r\n <span class=\"fb-ver__confirm\">\r\n Le esecuzioni sospese nate su questo numero riprenderebbero su una definizione diversa.\r\n <button type=\"button\" class=\"fb-btn fb-btn--danger fb-btn--icon\" (click)=\"confirmDelete(version.version)\">\r\n Elimina comunque\r\n </button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"cancelDelete()\">\r\n Annulla\r\n </button>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost fb-btn--icon\"\r\n [disabled]=\"isBusy()\"\r\n (click)=\"requestDelete(version)\"\r\n >\r\n Elimina\r\n </button>\r\n }\r\n }\r\n </div>\r\n </li>\r\n } @empty {\r\n <li class=\"fb-empty\">Nessuna versione: il flow non e’ ancora stato salvato.</li>\r\n }\r\n </ul>\r\n\r\n <p class=\"fb-ver__note\">\r\n Una sola versione e’ attiva: attivarne una rende superata la precedente, senza doverla disattivare prima.\r\n Le versioni superate costano poco — lo stato «Superata» esiste per questo.\r\n </p>\r\n</div>\r\n","/**\r\n * Provare un flow dall'editor — FRONTEND.md §6.5, §11 (\"Provare\").\r\n *\r\n * Sei cose che questo pannello tratta come dette:\r\n * 1. `status: 'Failed'` **non** e' un errore di trasporto: la richiesta e' riuscita, il flow\r\n * e' fallito. E `NotStarted` significa che i criteri dello Start non erano soddisfatti,\r\n * che non e' un errore.\r\n * 2. il `continuationToken` va rimandato **tale e quale**: e' opaco, non viene letto ne'\r\n * modificato, e non finisce in nessun URL.\r\n * 3. `canGoBack`/`canFinish`/`canPause` di `pendingScreen` sono la verita' su cosa\r\n * abilitare, piu' precisa dei flag del metadata.\r\n * 4. con `Previous` e `Pause` gli output **non** vengono memorizzati: i valori inseriti non\r\n * sono definitivi, e il pannello lo dice.\r\n * 5. `debug: true` popola `trace` e `resources` — **e riporta anche i dati personali**:\r\n * l'avviso e' in chiaro, non nascosto in una tooltip.\r\n * 6. `Suspended` copre due attese diverse — un evento e uno step di orchestrazione — e le\r\n * distinguono `isWaitingForEvent` / `isWaitingForStageStep`. Nel secondo caso si puo'\r\n * concludere lo step da qui, e la risposta puo' portare una `interviewKey` **nuova**: la\r\n * vecchia non e' piu' valida, quindi si sostituisce invece di conservarla (§5.13).\r\n */\r\n\r\nimport { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../../api/flow-builder-api';\r\nimport { FlowDocumentStore } from '../../core/flow-document.store';\r\nimport { FlowEditorSession } from '../../core/flow-editor-session';\r\nimport {\r\n FlowInterviewResult,\r\n FlowScreenNavigation,\r\n FlowStageStepState,\r\n FlowStageStepStatus,\r\n FlowTypedValue,\r\n} from '../../model/api.model';\r\nimport { FlowApiError } from '../../model/error.model';\r\nimport { FlowVariable } from '../../model/flow.model';\r\n\r\n@Component({\r\n selector: 'fb-debug-panel',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './debug-panel.component.html',\r\n styleUrl: './debug-panel.component.css',\r\n})\r\nexport class DebugPanelComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly store = inject(FlowDocumentStore);\r\n private readonly session = inject(FlowEditorSession);\r\n\r\n readonly closed = output<void>();\r\n /** Chiede all'host di evidenziare l'elemento corrente dell'esecuzione. */\r\n readonly elementFocused = output<string>();\r\n\r\n readonly result = signal<FlowInterviewResult | null>(null);\r\n readonly isRunning = signal(false);\r\n readonly errorMessage = signal<string | null>(null);\r\n readonly debugEnabled = signal(true);\r\n\r\n /** I valori che l'utente compila nel piccolo form generato dalle variabili di input. */\r\n readonly inputValues = signal<Record<string, string>>({});\r\n /** I valori raccolti per lo screen corrente, per nome di `outputParameters`. */\r\n readonly screenOutputs = signal<Record<string, string>>({});\r\n\r\n /** Le variabili `isInput` del flow: il contratto verso chi lo invoca (§4.6). */\r\n readonly inputVariables = computed<FlowVariable[]>(\r\n () => this.store.document().variables?.filter((variable) => variable.isInput) ?? [],\r\n );\r\n\r\n readonly canRun = computed(() => !this.session.isNew() && !this.isRunning());\r\n\r\n readonly status = computed(() => this.result()?.status ?? null);\r\n readonly pendingScreen = computed(() => this.result()?.pendingScreen ?? null);\r\n readonly isWaitingForScreen = computed(() => this.status() === 'WaitingForScreen');\r\n\r\n /** §5.13 — l'attesa e' su uno step assegnato a una persona, non su un evento. */\r\n readonly isWaitingForStageStep = computed(() => this.result()?.isWaitingForStageStep === true);\r\n readonly stageSteps = computed<FlowStageStepState[]>(() => this.result()?.stageSteps ?? []);\r\n /** Lo step su cui c'e' un work item aperto: e' quello che si puo' concludere. */\r\n readonly waitingStageSteps = computed(() => this.stageSteps().filter((step) => step.isWaiting));\r\n\r\n /** I valori con cui si conclude uno step, per nome di output. */\r\n readonly stepOutputs = signal<Record<string, string>>({});\r\n\r\n readonly trace = computed(() => this.result()?.trace ?? []);\r\n\r\n /** Le risorse come righe ordinate: il tipo dichiarato vince in lettura (§6.5). */\r\n readonly resourceRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const resources = this.result()?.resources ?? {};\r\n return Object.entries(resources)\r\n .map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }))\r\n .sort((left, right) => left.name.localeCompare(right.name));\r\n });\r\n\r\n readonly outputRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const outputs = this.result()?.outputs ?? {};\r\n return Object.entries(outputs).map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }));\r\n });\r\n\r\n /** Gli input che lo screen corrente riceve, per mostrarli accanto al form generico. */\r\n readonly screenInputRows = computed<Array<{ name: string; type: string; value: string }>>(() => {\r\n const inputs = this.pendingScreen()?.inputs ?? {};\r\n return Object.entries(inputs).map(([name, typed]) => ({\r\n name,\r\n type: typed?.type ?? '',\r\n value: DebugPanelComponent.render(typed),\r\n }));\r\n });\r\n\r\n /** I nomi degli output dichiarati dallo screen, per generare i campi da compilare. */\r\n readonly screenOutputNames = computed<string[]>(() => {\r\n const elementName = this.pendingScreen()?.elementName;\r\n if (!elementName) {\r\n return [];\r\n }\r\n const screen = this.store.document().screens?.find((candidate) => candidate.name === elementName);\r\n return (screen?.outputParameters ?? []).map((parameter) => parameter.name ?? '').filter(Boolean);\r\n });\r\n\r\n private static render(typed: FlowTypedValue | undefined): string {\r\n if (!typed || typed.value === undefined || typed.value === null) {\r\n return '—';\r\n }\r\n if (typeof typed.value === 'object') {\r\n return JSON.stringify(typed.value);\r\n }\r\n return String(typed.value);\r\n }\r\n\r\n setDebugEnabled(value: boolean): void {\r\n this.debugEnabled.set(value);\r\n }\r\n\r\n setInputValue(name: string, value: string): void {\r\n this.inputValues.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n setScreenOutput(name: string, value: string): void {\r\n this.screenOutputs.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n /** Converte i valori del form nel tipo dichiarato dalla variabile. */\r\n private coerceInputs(): Record<string, unknown> {\r\n const values = this.inputValues();\r\n const result: Record<string, unknown> = {};\r\n for (const variable of this.inputVariables()) {\r\n const name = variable.name;\r\n if (!name) {\r\n continue;\r\n }\r\n const raw = values[name];\r\n if (raw === undefined || raw === '') {\r\n continue;\r\n }\r\n switch (variable.dataType) {\r\n case 'Integer': {\r\n const parsed = Number.parseInt(raw, 10);\r\n if (!Number.isNaN(parsed)) {\r\n result[name] = parsed;\r\n }\r\n break;\r\n }\r\n case 'Number': {\r\n const parsed = Number.parseFloat(raw);\r\n if (!Number.isNaN(parsed)) {\r\n result[name] = parsed;\r\n }\r\n break;\r\n }\r\n case 'Boolean':\r\n result[name] = raw === 'true';\r\n break;\r\n default:\r\n result[name] = raw;\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async start(): Promise<void> {\r\n const flowName = this.session.flowName();\r\n if (!flowName) {\r\n this.errorMessage.set('Salva il flow prima di provarlo.');\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n this.screenOutputs.set({});\r\n try {\r\n const result = await this.api.startInterview({\r\n flowName,\r\n version: this.session.version() ?? undefined,\r\n inputs: this.coerceInputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n async respond(navigation: FlowScreenNavigation): Promise<void> {\r\n const current = this.result();\r\n // Opaco: si rimanda tale e quale, senza leggerlo.\r\n const token = current?.continuationToken;\r\n if (!token) {\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n try {\r\n const result = await this.api.respondToScreen({\r\n continuationToken: token,\r\n screenElementName: current?.pendingScreen?.elementName,\r\n navigation,\r\n // Con `Previous` e `Pause` il motore non memorizza gli output: si mandano comunque,\r\n // ma il pannello avverte che non sono definitivi.\r\n outputs: this.screenOutputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.screenOutputs.set({});\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n setStepOutput(name: string, value: string): void {\r\n this.stepOutputs.update((values) => ({ ...values, [name]: value }));\r\n }\r\n\r\n /** Gli output dichiarati dallo step, per generare i campi da compilare. */\r\n stepOutputNames(stepName: string | undefined): string[] {\r\n if (!stepName) {\r\n return [];\r\n }\r\n for (const stage of this.store.document().orchestratedStages ?? []) {\r\n const step = stage.stageSteps?.find((candidate) => candidate.name === stepName);\r\n if (step) {\r\n return (step.outputParameters ?? []).map((parameter) => parameter.name ?? '').filter(Boolean);\r\n }\r\n }\r\n return [];\r\n }\r\n\r\n /**\r\n * Conclude uno step come farebbe l'assegnatario. `Rejected` non e' un errore: e' l'esito che\r\n * prende il ramo «Step rifiutato» dello stage — e se quel ramo non c'e', l'interview fallisce.\r\n */\r\n async completeStep(stepName: string | undefined, status: FlowStageStepStatus): Promise<void> {\r\n const key = this.result()?.interviewKey;\r\n if (!key || !stepName) {\r\n return;\r\n }\r\n this.isRunning.set(true);\r\n this.errorMessage.set(null);\r\n try {\r\n const result = await this.api.completeStageStep({\r\n interviewKey: key,\r\n stepName,\r\n status,\r\n stepOutputs: this.stepOutputs(),\r\n debug: this.debugEnabled(),\r\n });\r\n this.stepOutputs.set({});\r\n // La risposta puo' portare una chiave nuova: `apply` sostituisce il risultato intero,\r\n // quindi la vecchia chiave non resta in giro.\r\n this.apply(result);\r\n } catch (error) {\r\n this.handleError(error);\r\n } finally {\r\n this.isRunning.set(false);\r\n }\r\n }\r\n\r\n private apply(result: FlowInterviewResult): void {\r\n this.result.set(result);\r\n if (result.currentElementName) {\r\n this.elementFocused.emit(result.currentElementName);\r\n }\r\n }\r\n\r\n private handleError(error: unknown): void {\r\n if (FlowApiError.is(error)) {\r\n // `InvalidToken` significa che la sessione di prova non e' piu' valida: si riavvia.\r\n this.errorMessage.set(error.message);\r\n return;\r\n }\r\n this.errorMessage.set(error instanceof Error ? error.message : String(error));\r\n }\r\n\r\n reset(): void {\r\n this.result.set(null);\r\n this.errorMessage.set(null);\r\n this.screenOutputs.set({});\r\n this.stepOutputs.set({});\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n /** L'etichetta dello stato, che non e' un errore anche quando dice \"Failed\" (§6.5). */\r\n statusLabel(): string {\r\n switch (this.status()) {\r\n case 'Completed':\r\n return 'Completata';\r\n case 'WaitingForScreen':\r\n return 'In attesa di un form';\r\n case 'Paused':\r\n return 'In pausa';\r\n case 'Suspended':\r\n return 'Sospesa';\r\n case 'Failed':\r\n return 'Fallita';\r\n case 'NotStarted':\r\n return 'Non avviata';\r\n default:\r\n return '';\r\n }\r\n }\r\n\r\n statusNote(): string | null {\r\n switch (this.status()) {\r\n case 'Failed':\r\n return 'Il flow e’ fallito: la richiesta e’ andata a buon fine, l’esecuzione no.';\r\n case 'NotStarted':\r\n return 'I criteri dello Start non erano soddisfatti: non e’ un errore.';\r\n case 'Paused':\r\n return 'L’esecuzione e’ in pausa: puo’ essere ripresa dalla sua chiave.';\r\n case 'Suspended':\r\n // Due attese diverse sotto lo stesso stato: dirlo evita di cercare l'evento sbagliato.\r\n if (this.isWaitingForStageStep()) {\r\n return 'Sospesa su uno step di orchestrazione: aspetta che un assegnatario lo concluda.';\r\n }\r\n return this.result()?.isWaitingForEvent\r\n ? 'Sospesa in attesa di un evento: puo’ essere ripresa dalla sua chiave.'\r\n : 'L’esecuzione e’ sospesa: puo’ essere ripresa dalla sua chiave.';\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n canGoBack(): boolean {\r\n return this.pendingScreen()?.canGoBack === true;\r\n }\r\n\r\n canFinish(): boolean {\r\n return this.pendingScreen()?.canFinish === true;\r\n }\r\n\r\n canPause(): boolean {\r\n return this.pendingScreen()?.canPause === true;\r\n }\r\n}\r\n","<header class=\"fb-dbg__header\">\r\n <h2 class=\"fb-dbg__title\">Prova</h2>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"close()\">×</button>\r\n</header>\r\n\r\n<div class=\"fb-dbg__body\">\r\n @if (errorMessage()) {\r\n <p class=\"fb-callout fb-callout--error\">{{ errorMessage() }}</p>\r\n }\r\n\r\n @if (!result()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Valori iniziali</legend>\r\n @if (inputVariables().length) {\r\n @for (variable of inputVariables(); track variable.name) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">\r\n {{ variable.name }}\r\n <span class=\"fb-dbg__type\">{{ variable.dataType }}{{ variable.isCollection ? '[]' : '' }}</span>\r\n </label>\r\n @if (variable.dataType === 'Boolean') {\r\n <select class=\"fb-select\" (change)=\"setInputValue(variable.name!, $any($event.target).value)\">\r\n <option value=\"\">—</option>\r\n <option value=\"true\">vero</option>\r\n <option value=\"false\">falso</option>\r\n </select>\r\n } @else {\r\n <input\r\n class=\"fb-input\"\r\n [type]=\"variable.dataType === 'Number' || variable.dataType === 'Integer' ? 'number' : 'text'\"\r\n (input)=\"setInputValue(variable.name!, $any($event.target).value)\"\r\n />\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <p class=\"fb-field__hint\">Il flow non dichiara variabili di input.</p>\r\n }\r\n </fieldset>\r\n\r\n <label class=\"fb-check\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"debugEnabled()\"\r\n (change)=\"setDebugEnabled($any($event.target).checked)\"\r\n />\r\n Traccia di debug\r\n </label>\r\n @if (debugEnabled()) {\r\n <p class=\"fb-callout fb-callout--warn\">\r\n La traccia riporta i valori di <strong>tutte</strong> le risorse, dati personali compresi: non usarla\r\n su dati reali.\r\n </p>\r\n }\r\n\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"!canRun()\" (click)=\"start()\">\r\n Avvia\r\n </button>\r\n @if (!canRun() && !isRunning()) {\r\n <p class=\"fb-field__hint\">Salva il flow prima di provarlo.</p>\r\n }\r\n }\r\n\r\n @if (result()) {\r\n <div class=\"fb-dbg__status\">\r\n <span\r\n class=\"fb-dbg__badge\"\r\n [class.fb-dbg__badge--ok]=\"status() === 'Completed'\"\r\n [class.fb-dbg__badge--fail]=\"status() === 'Failed'\"\r\n [class.fb-dbg__badge--wait]=\"isWaitingForScreen()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n @if (result()?.currentElementName) {\r\n <span class=\"fb-dbg__current\">su {{ result()?.currentElementName }}</span>\r\n }\r\n <span class=\"fb-dbg__steps\">{{ result()?.steps || 0 }} passi</span>\r\n <span class=\"fb-list__spacer\"></span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"reset()\">Riavvia</button>\r\n </div>\r\n\r\n @if (statusNote()) {\r\n <p class=\"fb-callout\">{{ statusNote() }}</p>\r\n }\r\n\r\n @if (result()?.fault) {\r\n <p class=\"fb-callout fb-callout--error\">{{ result()?.fault }}</p>\r\n }\r\n @for (message of result()?.errors || []; track message) {\r\n <p class=\"fb-callout fb-callout--error\">{{ message }}</p>\r\n }\r\n\r\n @if (isWaitingForScreen() && pendingScreen()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">\r\n Form «{{ pendingScreen()?.formName }}»\r\n </legend>\r\n <p class=\"fb-section__note\">\r\n Nell’editor basta un form generico: qui vedi i valori che il form riceve e puoi compilare quelli\r\n che dichiara di restituire.\r\n </p>\r\n\r\n @if (pendingScreen()?.label) {\r\n <p class=\"fb-dbg__screen-label\">{{ pendingScreen()?.label }}</p>\r\n }\r\n @if (pendingScreen()?.helpText) {\r\n <p class=\"fb-field__hint\">{{ pendingScreen()?.helpText }}</p>\r\n }\r\n\r\n @if (screenInputRows().length) {\r\n <table class=\"fb-dbg__table\">\r\n <caption>\r\n Valori in ingresso\r\n </caption>\r\n <tbody>\r\n @for (row of screenInputRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n @for (output of screenOutputNames(); track output) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">{{ output }}</label>\r\n <input class=\"fb-input\" (input)=\"setScreenOutput(output, $any($event.target).value)\" />\r\n </div>\r\n }\r\n @if (!screenOutputNames().length) {\r\n <p class=\"fb-field__hint\">Lo screen non dichiara parametri di uscita.</p>\r\n }\r\n\r\n <div class=\"fb-field__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"respond('Next')\"\r\n >\r\n Avanti\r\n </button>\r\n <!-- canGoBack/canFinish/canPause sono la verita', piu' precisa dei flag del metadata. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning() || !canGoBack()\"\r\n title=\"Con «indietro» gli output non vengono memorizzati\"\r\n (click)=\"respond('Previous')\"\r\n >\r\n Indietro\r\n </button>\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isRunning() || !canFinish()\" (click)=\"respond('Finish')\">\r\n Fine\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning() || !canPause()\"\r\n title=\"Con «pausa» gli output non vengono memorizzati\"\r\n (click)=\"respond('Pause')\"\r\n >\r\n Pausa\r\n </button>\r\n </div>\r\n <p class=\"fb-field__hint\">\r\n Con «indietro» e «pausa» i valori inseriti <strong>non</strong> vengono memorizzati.\r\n </p>\r\n </fieldset>\r\n }\r\n\r\n @if (isWaitingForStageStep()) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Step di orchestrazione</legend>\r\n <p class=\"fb-section__note\">\r\n L’interview e’ sospesa su uno step assegnato: qui si conclude al posto dell’assegnatario.\r\n Concludere puo’ far <strong>sospendere di nuovo</strong> lo stage, con una chiave nuova.\r\n </p>\r\n\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (step of stageSteps(); track step.stepName) {\r\n <tr>\r\n <th scope=\"row\">{{ step.label || step.stepName }}</th>\r\n <td class=\"fb-dbg__type\">{{ step.actionType }}</td>\r\n <td>{{ step.isWaiting ? 'in attesa' : step.status }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n\r\n @for (step of waitingStageSteps(); track step.stepName) {\r\n <div class=\"fb-list__item\">\r\n <div class=\"fb-list__header\">\r\n <span class=\"fb-list__title\">{{ step.label || step.stepName }}</span>\r\n </div>\r\n @for (output of stepOutputNames(step.stepName); track output) {\r\n <div class=\"fb-field\">\r\n <label class=\"fb-field__label\">{{ output }}</label>\r\n <input class=\"fb-input\" (input)=\"setStepOutput(output, $any($event.target).value)\" />\r\n </div>\r\n }\r\n <div class=\"fb-field__row\">\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--primary\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"completeStep(step.stepName, 'Completed')\"\r\n >\r\n Concludi\r\n </button>\r\n <!-- Il rifiuto non e' un errore: prende il ramo «Step rifiutato» dello stage. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isRunning()\"\r\n title=\"Prende il ramo «Step rifiutato»; senza quel ramo l’interview fallisce\"\r\n (click)=\"completeStep(step.stepName, 'Rejected')\"\r\n >\r\n Rifiuta\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn fb-btn--ghost\"\r\n [disabled]=\"isRunning()\"\r\n (click)=\"completeStep(step.stepName, 'Cancelled')\"\r\n >\r\n Annulla lo step\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n </fieldset>\r\n }\r\n\r\n @if (outputRows().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Output del flow</legend>\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (row of outputRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </fieldset>\r\n }\r\n\r\n @if (trace().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Traccia</legend>\r\n <ol class=\"fb-dbg__trace\">\r\n @for (entry of trace(); track entry.sequence) {\r\n <li class=\"fb-dbg__trace-item\">\r\n <span class=\"fb-dbg__trace-seq\">{{ entry.sequence }}</span>\r\n @if (entry.elementName) {\r\n <button type=\"button\" class=\"fb-dbg__trace-el\" (click)=\"elementFocused.emit(entry.elementName!)\">\r\n {{ entry.elementName }}\r\n </button>\r\n }\r\n <span class=\"fb-dbg__trace-msg\">{{ entry.message }}</span>\r\n </li>\r\n }\r\n </ol>\r\n </fieldset>\r\n }\r\n\r\n @if (resourceRows().length) {\r\n <fieldset class=\"fb-section\">\r\n <legend class=\"fb-section__title\">Risorse</legend>\r\n <table class=\"fb-dbg__table\">\r\n <tbody>\r\n @for (row of resourceRows(); track row.name) {\r\n <tr>\r\n <th scope=\"row\">{{ row.name }}</th>\r\n <td class=\"fb-dbg__type\">{{ row.type }}</td>\r\n <td>{{ row.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </fieldset>\r\n }\r\n\r\n @if (result()?.interviewKey) {\r\n <p class=\"fb-field__hint\">\r\n Chiave dell’esecuzione sospesa: <code>{{ result()?.interviewKey }}</code>\r\n </p>\r\n }\r\n }\r\n</div>\r\n","/**\r\n * Il builder: il componente standalone da innestare nell'applicazione ospite.\r\n *\r\n * Uso minimo:\r\n *\r\n * ```html\r\n * <fb-flow-builder [flowName]=\"'ApprovazioneOrdine'\" [author]=\"utente\" />\r\n * ```\r\n *\r\n * L'unica dipendenza da fornire e' {@link FlowBuilderApi}: tutto il traffico da e verso il\r\n * backend passa da lì.\r\n *\r\n * ```ts\r\n * providers: [{ provide: FlowBuilderApi, useClass: HttpFlowBuilderApi }]\r\n * ```\r\n *\r\n * Gli store del documento e della sessione sono provider **del componente**, non della\r\n * radice: due builder sulla stessa pagina editano due flow indipendenti.\r\n *\r\n * Il ciclo di lavoro della §11 e' implementato qui: carica, disegna, valida su pausa di\r\n * digitazione, salva con `expectedUpdatedAt`, aggiorna `updatedAt` dalla risposta.\r\n */\r\n\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { FlowBuilderApi } from '../api/flow-builder-api';\r\nimport { FlowCatalogStore, FlowDictionaryStore } from '../core/flow-dictionary.store';\r\nimport { FlowDocumentStore } from '../core/flow-document.store';\r\nimport { FlowEditorSession } from '../core/flow-editor-session';\r\nimport { FlowLayoutService } from '../core/flow-layout.service';\r\nimport { FlowValidationStore } from '../core/flow-validation.store';\r\nimport { START_NODE_NAME, outletsOf } from '../core/element-outlets';\r\nimport { variantPresetOf } from '../core/element-variants';\r\nimport { uniqueFlowName } from '../core/flow-name.util';\r\nimport { FlowOutline, FlowSaveResult } from '../model/api.model';\r\nimport { FlowApiError } from '../model/error.model';\r\nimport { FlowAnyNode, FlowDefinition, FlowElementType } from '../model/flow.model';\r\nimport { DebugPanelComponent } from './debug/debug-panel.component';\r\nimport { ElementDialogComponent } from './inspector/element-dialog.component';\r\nimport { ElementInspectorComponent } from './inspector/element-inspector.component';\r\nimport { ElementPaletteComponent, FlowPalettePick } from './palette/element-palette.component';\r\nimport { ProblemsPanelComponent } from './problems/problems-panel.component';\r\nimport { ResourcePanelComponent } from './resources/resource-panel.component';\r\nimport { VersionPanelComponent } from './versions/version-panel.component';\r\nimport { FLOW_NODE_HEIGHT, FlowCanvasComponent, flowNodeWidth } from './canvas/flow-canvas.component';\r\nimport { SelectValueDirective } from './shared/select-value.directive';\r\n\r\ntype SidePanel = 'inspector' | 'resources' | 'versions' | 'debug';\r\n\r\ninterface Notice {\r\n kind: 'info' | 'error';\r\n message: string;\r\n}\r\n\r\n@Component({\r\n selector: 'fb-flow-builder',\r\n standalone: true,\r\n imports: [DebugPanelComponent,\r\n ElementDialogComponent,\r\n ElementInspectorComponent,\r\n ElementPaletteComponent,\r\n FlowCanvasComponent,\r\n ProblemsPanelComponent,\r\n ResourcePanelComponent,\r\n VersionPanelComponent, SelectValueDirective],\r\n // Gli store sono per-istanza: due builder editano due documenti indipendenti.\r\n providers: [\r\n FlowDocumentStore,\r\n FlowDictionaryStore,\r\n FlowCatalogStore,\r\n FlowValidationStore,\r\n FlowEditorSession,\r\n FlowLayoutService,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './flow-builder.component.html',\r\n styleUrl: './flow-builder.component.css',\r\n})\r\nexport class FlowBuilderComponent {\r\n private readonly api = inject(FlowBuilderApi);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n protected readonly store = inject(FlowDocumentStore);\r\n protected readonly dictionaries = inject(FlowDictionaryStore);\r\n protected readonly session = inject(FlowEditorSession);\r\n protected readonly validation = inject(FlowValidationStore);\r\n private readonly layout = inject(FlowLayoutService);\r\n\r\n /** Il flow da aprire. Assente → si parte da un flow nuovo. */\r\n readonly flowName = input<string | null>(null);\r\n /** La versione da aprire; assente → l'attiva se c'e', altrimenti l'ultima (§6.1). */\r\n readonly version = input<number | null>(null);\r\n /** Registrato sulla versione e mostrato nell'elenco (§6.2). */\r\n readonly author = input<string | undefined>(undefined);\r\n /** `processType` iniziale di un flow nuovo. */\r\n readonly defaultProcessType = input<string>('Screen');\r\n\r\n /**\r\n * Dove si configura l'elemento selezionato.\r\n *\r\n * `dialog` (predefinito) apre il form in una finestra sopra il canvas, come il flow builder\r\n * di Salesforce: i form degli elementi sono grandi e in una colonna da 340px si scorreva\r\n * troppo. `panel` tiene il form nel pannello laterale, che e' piu' comodo quando si\r\n * modificano molti elementi di fila perche' non c'e' niente da aprire e chiudere.\r\n */\r\n readonly inspectorMode = input<'dialog' | 'panel'>('dialog');\r\n\r\n readonly saved = output<FlowSaveResult>();\r\n readonly activated = output<FlowSaveResult>();\r\n readonly closeRequested = output<void>();\r\n\r\n readonly selectedName = signal<string | null>(START_NODE_NAME);\r\n readonly activePanel = signal<SidePanel>('inspector');\r\n /** La dialog del dettaglio e' aperta. Vale solo con `inspectorMode = 'dialog'`. */\r\n readonly isDialogOpen = signal(false);\r\n readonly showProblems = signal(true);\r\n readonly notice = signal<Notice | null>(null);\r\n readonly outline = signal<FlowOutline | null>(null);\r\n readonly isLoading = signal(false);\r\n\r\n /** Il documento e' cambiato: usato per riscadenzare validazione e outline. */\r\n private lastDocument?: FlowDefinition;\r\n private outlineTimer?: ReturnType<typeof setTimeout>;\r\n\r\n readonly isDialogMode = computed(() => this.inspectorMode() === 'dialog');\r\n\r\n /**\r\n * Il pannello effettivamente mostrato a lato. Con la dialog il tab «Elemento» non esiste:\r\n * avere lo stesso form in due posti confonde su quale dei due sia quello vero.\r\n */\r\n readonly sidePanel = computed<SidePanel>(() => {\r\n const panel = this.activePanel();\r\n return this.isDialogMode() && panel === 'inspector' ? 'resources' : panel;\r\n });\r\n\r\n readonly document = computed(() => this.store.document());\r\n readonly isDirty = computed(() => this.store.isDirty());\r\n readonly canUndo = computed(() => this.store.canUndo());\r\n readonly canRedo = computed(() => this.store.canRedo());\r\n readonly primaryCommand = computed(() => this.session.primaryCommand());\r\n readonly isEditable = computed(() => this.session.isEditable());\r\n readonly conflict = computed(() => this.session.conflict());\r\n readonly errorCount = computed(() => this.validation.errorCount());\r\n readonly warningCount = computed(() => this.validation.warningCount());\r\n readonly canActivate = computed(() => this.session.canActivate());\r\n readonly isBusy = computed(() => this.session.isBusy() || this.isLoading());\r\n\r\n readonly statusLabel = computed(() => {\r\n const summary = this.session.currentVersionSummary();\r\n if (!summary) {\r\n return 'Nuovo';\r\n }\r\n switch (summary.status) {\r\n case 'Draft':\r\n return 'Bozza';\r\n case 'InvalidDraft':\r\n return 'Bozza con errori';\r\n case 'UnderReview':\r\n return 'In approvazione';\r\n case 'Active':\r\n return 'Attiva';\r\n case 'Obsolete':\r\n return 'Superata';\r\n default:\r\n return summary.status ?? '';\r\n }\r\n });\r\n\r\n constructor() {\r\n /**\r\n * I dizionari si caricano una volta e si tengono in cache, **per `processType`**: le\r\n * globali dipendono dal tipo di flow — `$Record` non esiste in uno screen flow — e\r\n * cambiare tipo cambia quali sono proponibili (§4.1, §6.4). Lo store memoizza per tipo,\r\n * quindi tornare a un tipo già visto non produce una richiesta.\r\n */\r\n effect(() => {\r\n void this.dictionaries.load(this.store.document().processType);\r\n });\r\n\r\n effect(() => {\r\n this.session.setAuthor(this.author());\r\n });\r\n\r\n // Apertura: reagisce ai parametri di ingresso.\r\n effect(() => {\r\n const flowName = this.flowName();\r\n const version = this.version();\r\n void this.openOrCreate(flowName, version);\r\n });\r\n\r\n /**\r\n * §11 — a ogni modifica: validazione su pausa di digitazione, e outline rilanciato per\r\n * riflettere archi e raggiungibilita' autorevoli. L'outline e' debounced insieme alla\r\n * validazione: il canvas nel frattempo usa il calcolo locale, così il disegno non\r\n * dipende dalla latenza.\r\n */\r\n effect(() => {\r\n const document = this.store.document();\r\n if (document === this.lastDocument) {\r\n return;\r\n }\r\n this.lastDocument = document;\r\n this.validation.schedule(document);\r\n this.scheduleOutline(document);\r\n });\r\n\r\n this.destroyRef.onDestroy(() => {\r\n if (this.outlineTimer) {\r\n clearTimeout(this.outlineTimer);\r\n }\r\n });\r\n }\r\n\r\n private async openOrCreate(flowName: string | null, version: number | null): Promise<void> {\r\n this.isLoading.set(true);\r\n this.notice.set(null);\r\n // Si sta cambiando documento: una dialog aperta guarderebbe un elemento di un altro flow.\r\n this.isDialogOpen.set(false);\r\n try {\r\n if (flowName) {\r\n await this.session.open(flowName, version ?? undefined);\r\n } else {\r\n // Un flow appena creato ha errori — manca il primo node — ed e' normale (§11).\r\n this.session.startNew('', '', this.defaultProcessType());\r\n }\r\n this.selectedName.set(START_NODE_NAME);\r\n } catch (error) {\r\n this.showError(error);\r\n } finally {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n private scheduleOutline(definition: FlowDefinition): void {\r\n if (this.outlineTimer) {\r\n clearTimeout(this.outlineTimer);\r\n }\r\n this.outlineTimer = setTimeout(() => {\r\n this.outlineTimer = undefined;\r\n void this.api\r\n .getOutline(definition)\r\n .then((outline) => this.outline.set(outline))\r\n // L'outline e' un arricchimento: senza, il canvas usa il calcolo locale.\r\n .catch(() => this.outline.set(null));\r\n }, 500);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Intestazione del documento\r\n // -------------------------------------------------------------------------\r\n\r\n setLabel(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.label = value || undefined;\r\n });\r\n }\r\n\r\n setFullName(value: string): void {\r\n // `fullName` nel documento non rinomina il flow: la rinomina passa da `flowName` nella\r\n // richiesta di salvataggio (§2, §6.2). Qui si scrive il documento; al salvataggio si\r\n // manda anche `flowName`, ed e' quello a vincere.\r\n this.store.updateHeader((definition) => {\r\n definition.fullName = value || undefined;\r\n });\r\n }\r\n\r\n setDescription(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.description = value || undefined;\r\n });\r\n }\r\n\r\n setInterviewLabel(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.interviewLabel = value || undefined;\r\n });\r\n }\r\n\r\n setProcessType(value: string): void {\r\n this.store.updateHeader((definition) => {\r\n definition.processType = value;\r\n });\r\n }\r\n\r\n readonly processTypes = computed(() => this.dictionaries.processTypes());\r\n\r\n /** `AutoLaunched` + screen e' un errore di validazione: si segnala subito (§13.6). */\r\n readonly hasScreensInAutoLaunched = computed(\r\n () =>\r\n this.store.document().processType === 'AutoLaunched' &&\r\n (this.store.document().screens?.length ?? 0) > 0,\r\n );\r\n\r\n /** Un flow `Screen` senza screen e' `SCREEN_FLOW_WITHOUT_SCREENS`. */\r\n readonly hasNoScreensInScreenFlow = computed(\r\n () =>\r\n this.store.document().processType === 'Screen' && (this.store.document().screens?.length ?? 0) === 0,\r\n );\r\n\r\n /**\r\n * Un flow `Orchestration` senza stage di orchestrazione e' un **avviso**\r\n * (`ORCHESTRATION_WITHOUT_STAGES`): il tipo dichiara un'orchestrazione che non c'e' (§3.1).\r\n */\r\n readonly isOrchestrationWithoutStages = computed(() => {\r\n const document = this.store.document();\r\n return document.processType === 'Orchestration' && (document.orchestratedStages?.length ?? 0) === 0;\r\n });\r\n\r\n // -------------------------------------------------------------------------\r\n // Canvas\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Click singolo sul canvas: seleziona. Con la dialog il form **non** si apre qui: un click\r\n * capita anche solo per spostare un node, e una finestra che si apre a ogni click sarebbe\r\n * insopportabile. Nel pannello laterale, invece, mostrare subito il form non costa nulla.\r\n */\r\n onSelectionChange(name: string | null): void {\r\n this.selectedName.set(name);\r\n if (name && !this.isDialogMode()) {\r\n this.activePanel.set('inspector');\r\n }\r\n }\r\n\r\n /** Doppio click o bottone «✎» sul node: qui il dettaglio si apre. */\r\n onNodeOpened(name: string): void {\r\n this.openElement(name);\r\n }\r\n\r\n /** Porta l'utente sull'elemento **e** ne apre il form: e' l'ancora dei problemi (§7). */\r\n focusElement(name: string): void {\r\n this.openElement(name);\r\n }\r\n\r\n /** Apre il dettaglio dell'elemento, nella dialog o nel pannello secondo la modalita'. */\r\n openElement(name: string): void {\r\n this.selectedName.set(name);\r\n if (this.isDialogMode()) {\r\n this.isDialogOpen.set(true);\r\n return;\r\n }\r\n this.activePanel.set('inspector');\r\n }\r\n\r\n /** Il comando della top bar: apre il dettaglio di cio' che e' selezionato. */\r\n openSelectedElement(): void {\r\n const name = this.selectedName();\r\n if (name) {\r\n this.openElement(name);\r\n }\r\n }\r\n\r\n closeDialog(): void {\r\n this.isDialogOpen.set(false);\r\n }\r\n\r\n /**\r\n * Evidenzia l'elemento sul canvas senza cambiare pannello.\r\n * Serve durante la prova: l'esecuzione segnala su quale elemento e' ferma, ma sostituire\r\n * il pannello con l'inspector farebbe sparire il form da compilare a metà interview.\r\n */\r\n highlightElement(name: string): void {\r\n this.selectedName.set(name);\r\n }\r\n\r\n /** Rilascio dalla palette: il punto di rilascio diventa `locationX`/`locationY` (§11). */\r\n onElementDropped(event: { type: FlowElementType; variant?: string; x: number; y: number }): void {\r\n this.createElement(event.type, event.variant, event.x, event.y);\r\n }\r\n\r\n /** Click sulla palette: l'elemento si posiziona in una zona libera. */\r\n onElementPicked(pick: FlowPalettePick): void {\r\n const nodes = this.store.nodes();\r\n const lowest = nodes.reduce((max, reference) => Math.max(max, reference.node.locationY ?? 0), 60);\r\n this.createElement(pick.type, pick.variant, 60, lowest + 120);\r\n }\r\n\r\n private createElement(type: FlowElementType, variant: string | undefined, x: number, y: number): void {\r\n const collection = this.dictionaries.collectionOf(type);\r\n if (!collection) {\r\n this.notice.set({ kind: 'error', message: `Tipo di elemento non riconosciuto: ${type}.` });\r\n return;\r\n }\r\n /**\r\n * Su un tipo a varianti la label e' quella della variante: un node chiamato «Ordina o\r\n * filtra» non dice cosa fa, e da lì viene anche il nome tecnico. Se la palette non ha\r\n * passato nessuna variante — dizionario non disponibile — si prende la prima dichiarata,\r\n * così l'elemento nasce comunque completo (§5.5).\r\n */\r\n const variants = this.dictionaries.variantsOf(type);\r\n const chosenVariant = variant ?? variants[0]?.value;\r\n const label = chosenVariant\r\n ? this.dictionaries.variantLabelOf(type, chosenVariant) || this.dictionaries.labelOf(type)\r\n : this.dictionaries.labelOf(type);\r\n // Il nome si genera dalla label e si verifica contro node **e** risorse (§3.3, §11).\r\n const name = uniqueFlowName(label, this.store.usedNames());\r\n const node: FlowAnyNode = {\r\n name,\r\n label,\r\n locationX: Math.round(x),\r\n locationY: Math.round(y),\r\n ...variantPresetOf(type, chosenVariant),\r\n };\r\n // Default che rendono l'elemento sensato appena creato, senza inventare configurazione.\r\n if (type === 'RecordLookup' || type === 'RecordCreate') {\r\n node['storeOutputAutomatically'] = true;\r\n }\r\n if (type === 'Decision') {\r\n node['rules'] = [\r\n { name: 'Regola', label: 'Regola 1', conditionLogic: 'and', conditions: [{ operator: 'EqualTo' }] },\r\n ];\r\n }\r\n if (type === 'CustomError') {\r\n node['customErrorMessages'] = [{ errorMessage: '' }];\r\n }\r\n if (type === 'Wait') {\r\n node['waitEvents'] = [{ name: 'Evento', label: 'Evento 1' }];\r\n }\r\n if (type === 'OrchestratedStage') {\r\n // Lo step nasce senza `actionType`: e' l'utente a scegliere se e' in background,\r\n // interattivo o di approvazione, e il form lo segnala finche' manca (§5.13).\r\n node['stageSteps'] = [\r\n { name: uniqueFlowName('Step', [...this.store.usedNames(), name]), label: 'Step 1' },\r\n ];\r\n }\r\n this.store.addNode(collection, node);\r\n // Un elemento appena creato e' vuoto: il posto giusto in cui finire e' il suo form.\r\n this.openElement(name);\r\n }\r\n\r\n onRemoveNode(name: string): void {\r\n // Rimuove anche i connector che lo referenziavano: un target orfano bloccherebbe\r\n // l'attivazione con CONNECTOR_TARGET_UNKNOWN.\r\n this.store.removeNode(name);\r\n if (this.selectedName() === name) {\r\n this.selectedName.set(START_NODE_NAME);\r\n // L'elemento non c'e' piu': una dialog aperta sul vuoto non ha senso.\r\n this.isDialogOpen.set(false);\r\n }\r\n }\r\n\r\n onDuplicateNode(name: string): void {\r\n const newName = uniqueFlowName(`${name}_copia`, this.store.usedNames());\r\n this.store.duplicateNode(name, newName);\r\n this.selectedName.set(newName);\r\n }\r\n\r\n /** Riordina il grafo e **scrive** le coordinate nel documento (§3.5). */\r\n autoLayout(): void {\r\n // La larghezza dipende dal numero di rami, perche' le uscite stanno in fila sul bordo\r\n // inferiore: passare a dagre una larghezza fissa lascerebbe i node larghi sovrapposti.\r\n const nodes = [\r\n {\r\n name: START_NODE_NAME,\r\n width: flowNodeWidth(outletsOf('Start', this.store.start() as FlowAnyNode).length),\r\n height: FLOW_NODE_HEIGHT,\r\n },\r\n ...this.store.nodes().map((reference) => ({\r\n name: reference.name,\r\n width: flowNodeWidth(outletsOf(reference.type, reference.node).length),\r\n height: FLOW_NODE_HEIGHT,\r\n })),\r\n ];\r\n const result = this.layout.layout(nodes, this.store.edges(), { direction: 'TB' });\r\n if (!result.positions.size) {\r\n return;\r\n }\r\n let first = true;\r\n for (const [name, position] of result.positions) {\r\n this.store.moveNode(name, position.x, position.y, { silent: !first });\r\n first = false;\r\n }\r\n }\r\n\r\n undo(): void {\r\n this.store.undo();\r\n }\r\n\r\n redo(): void {\r\n this.store.redo();\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Salvataggio e ciclo di vita\r\n // -------------------------------------------------------------------------\r\n\r\n async save(): Promise<void> {\r\n const definition = this.store.document();\r\n if (!definition.fullName) {\r\n this.notice.set({ kind: 'error', message: 'Dai un nome tecnico al flow prima di salvare.' });\r\n return;\r\n }\r\n try {\r\n const result = await this.session.save({ flowName: definition.fullName });\r\n this.saved.emit(result);\r\n // Il salvataggio riesce anche con errori: l'esito sano si legge in `validation` (§6.2).\r\n const errors = result.validation?.errorCount ?? 0;\r\n this.notice.set({\r\n kind: 'info',\r\n message: errors\r\n ? `Salvato come versione ${result.version}, con ${errors} ${errors === 1 ? 'errore' : 'errori'} da correggere.`\r\n : `Salvato come versione ${result.version}.`,\r\n });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n async createNewVersion(): Promise<void> {\r\n try {\r\n const result = await this.session.createNewVersion();\r\n this.notice.set({ kind: 'info', message: `Creata la versione ${result.version}.` });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n async activate(): Promise<void> {\r\n try {\r\n const result = await this.session.activate();\r\n this.activated.emit(result);\r\n this.notice.set({ kind: 'info', message: `Versione ${result.version} attivata.` });\r\n } catch (error) {\r\n // Con `ValidationFailed` il payload porta l'elenco: si apre il pannello (§11).\r\n if (FlowApiError.is(error) && error.category === 'ValidationFailed') {\r\n this.showProblems.set(true);\r\n }\r\n this.showError(error);\r\n }\r\n }\r\n\r\n /** §9.3 — prima opzione davanti a un conflitto. */\r\n async reloadAfterConflict(): Promise<void> {\r\n try {\r\n await this.session.reloadAfterConflict();\r\n this.notice.set({ kind: 'info', message: 'Ricaricata la versione salvata da altri.' });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n /** §9.3 — seconda opzione: conserva le modifiche locali in una nuova versione. */\r\n async saveAsNewVersionAfterConflict(): Promise<void> {\r\n try {\r\n const result = await this.session.saveAsNewVersionAfterConflict();\r\n this.notice.set({\r\n kind: 'info',\r\n message: `Le tue modifiche sono nella nuova versione ${result.version}.`,\r\n });\r\n } catch (error) {\r\n this.showError(error);\r\n }\r\n }\r\n\r\n dismissConflict(): void {\r\n this.session.dismissConflict();\r\n }\r\n\r\n /** Esporta il documento come JSON indentato, per un salvataggio fuori dal backend. */\r\n exportJson(): string {\r\n return JSON.stringify(this.store.document(), null, 2);\r\n }\r\n\r\n /**\r\n * Importa un documento. Passa da `POST /flows/parse`, che lo normalizza o lo rifiuta con\r\n * `InvalidDefinition`: e' l'unico modo di sapere se il file e' leggibile prima di caricarlo.\r\n */\r\n async importJson(raw: string): Promise<void> {\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(raw);\r\n } catch {\r\n this.notice.set({ kind: 'error', message: 'Il file non e’ JSON valido.' });\r\n return;\r\n }\r\n try {\r\n const definition = await this.api.parseFlow(parsed);\r\n this.store.load(definition);\r\n this.notice.set({ kind: 'info', message: 'Documento importato.' });\r\n } catch (error) {\r\n if (FlowApiError.is(error) && error.category === 'MissingService') {\r\n // Senza la primitiva si carica il JSON così com'e': la validazione dira' cosa non torna.\r\n this.store.load(parsed as FlowDefinition);\r\n this.notice.set({\r\n kind: 'info',\r\n message: 'Documento importato senza normalizzazione: il backend non espone la primitiva.',\r\n });\r\n return;\r\n }\r\n this.showError(error);\r\n }\r\n }\r\n\r\n onFileSelected(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const file = input.files?.[0];\r\n if (!file) {\r\n return;\r\n }\r\n void file.text().then((raw) => this.importJson(raw));\r\n input.value = '';\r\n }\r\n\r\n async openVersion(version: number): Promise<void> {\r\n const flowName = this.session.flowName();\r\n if (!flowName) {\r\n return;\r\n }\r\n this.isLoading.set(true);\r\n this.isDialogOpen.set(false);\r\n try {\r\n await this.session.open(flowName, version);\r\n this.selectedName.set(START_NODE_NAME);\r\n } catch (error) {\r\n this.showError(error);\r\n } finally {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /** Valida subito, senza attendere la pausa di digitazione. */\r\n async validateNow(): Promise<void> {\r\n await this.validation.run(this.store.document());\r\n this.showProblems.set(true);\r\n }\r\n\r\n setPanel(panel: SidePanel): void {\r\n this.activePanel.set(panel);\r\n }\r\n\r\n toggleProblems(): void {\r\n this.showProblems.update((value) => !value);\r\n }\r\n\r\n showNotice(notice: Notice): void {\r\n this.notice.set(notice);\r\n }\r\n\r\n dismissNotice(): void {\r\n this.notice.set(null);\r\n }\r\n\r\n private showError(error: unknown): void {\r\n if (FlowApiError.is(error)) {\r\n this.notice.set({ kind: 'error', message: error.message });\r\n return;\r\n }\r\n this.notice.set({\r\n kind: 'error',\r\n message: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n}\r\n","<div class=\"fb-builder\" [attr.data-fb-theme]=\"null\">\r\n <header class=\"fb-top\">\r\n <div class=\"fb-top__identity\">\r\n <input\r\n class=\"fb-top__label\"\r\n [value]=\"document().label || ''\"\r\n placeholder=\"Nome del flow\"\r\n aria-label=\"Nome del flow\"\r\n [disabled]=\"!isEditable()\"\r\n (input)=\"setLabel($any($event.target).value)\"\r\n />\r\n <div class=\"fb-top__meta\">\r\n <input\r\n class=\"fb-top__name\"\r\n [value]=\"document().fullName || ''\"\r\n placeholder=\"NomeTecnico\"\r\n aria-label=\"Nome tecnico del flow\"\r\n [disabled]=\"!isEditable()\"\r\n (input)=\"setFullName($any($event.target).value)\"\r\n />\r\n <select\r\n class=\"fb-top__process\"\r\n [fbValue]=\"document().processType || ''\"\r\n aria-label=\"Tipo di flow\"\r\n [disabled]=\"!isEditable()\"\r\n (change)=\"setProcessType($any($event.target).value)\"\r\n >\r\n @for (type of processTypes(); track type.value) {\r\n <option [value]=\"type.value\">{{ type.label }}</option>\r\n }\r\n </select>\r\n <span class=\"fb-top__status\">{{ statusLabel() }}</span>\r\n @if (session.version() !== null) {\r\n <span class=\"fb-top__version\">v{{ session.version() }}</span>\r\n }\r\n @if (isDirty()) {\r\n <span class=\"fb-top__dirty\" title=\"Ci sono modifiche non salvate\">modificato</span>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"fb-top__actions\">\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"!canUndo()\" aria-label=\"Annulla\" (click)=\"undo()\">↶</button>\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"!canRedo()\" aria-label=\"Ripeti\" (click)=\"redo()\">↷</button>\r\n <button type=\"button\" class=\"fb-btn\" title=\"Ricalcola le posizioni\" (click)=\"autoLayout()\">Riordina</button>\r\n @if (isDialogMode()) {\r\n <!-- Il doppio click sul node fa la stessa cosa, ma non si vede: questo comando sì. -->\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"!selectedName()\"\r\n title=\"Apri il dettaglio dell’elemento selezionato\"\r\n (click)=\"openSelectedElement()\"\r\n >\r\n Dettaglio\r\n </button>\r\n }\r\n <button type=\"button\" class=\"fb-btn\" [disabled]=\"isBusy()\" (click)=\"validateNow()\">Valida</button>\r\n\r\n @switch (primaryCommand()) {\r\n @case ('newVersion') {\r\n <!-- Su una versione non modificabile il comando primario e' \"Nuova versione\" (§8.1). -->\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"createNewVersion()\">\r\n Nuova versione\r\n </button>\r\n }\r\n @case ('create') {\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"save()\">\r\n Crea\r\n </button>\r\n }\r\n @default {\r\n <button type=\"button\" class=\"fb-btn fb-btn--primary\" [disabled]=\"isBusy()\" (click)=\"save()\">\r\n Salva\r\n </button>\r\n }\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"fb-btn\"\r\n [disabled]=\"isBusy() || !canActivate()\"\r\n [title]=\"\r\n canActivate()\r\n ? 'Attiva questa versione'\r\n : 'L’attivazione esige zero errori: correggili nel pannello dei problemi'\r\n \"\r\n (click)=\"activate()\"\r\n >\r\n Attiva\r\n </button>\r\n </div>\r\n </header>\r\n\r\n @if (conflict()) {\r\n <!-- §9.3: qualcun altro ha salvato. Due strade, entrambe offerte. -->\r\n <div class=\"fb-banner fb-banner--warn\" role=\"alert\">\r\n <span>\r\n {{ conflict()?.message }}\r\n @if (conflict()?.conflictingAuthor) {\r\n Ha salvato {{ conflict()?.conflictingAuthor }}.\r\n }\r\n </span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--icon\" (click)=\"reloadAfterConflict()\">Ricarica</button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--icon\" (click)=\"saveAsNewVersionAfterConflict()\">\r\n Salva come nuova versione\r\n </button>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" (click)=\"dismissConflict()\">×</button>\r\n </div>\r\n }\r\n\r\n @if (notice()) {\r\n <div\r\n class=\"fb-banner\"\r\n [class.fb-banner--error]=\"notice()?.kind === 'error'\"\r\n role=\"status\"\r\n >\r\n <span>{{ notice()?.message }}</span>\r\n <button type=\"button\" class=\"fb-btn fb-btn--ghost fb-btn--icon\" aria-label=\"Chiudi\" (click)=\"dismissNotice()\">\r\n ×\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (hasScreensInAutoLaunched()) {\r\n <div class=\"fb-banner fb-banner--error\">\r\n Un flow AutoLaunched che contiene screen e’ un errore di validazione: non c’e’ nessuno a cui mostrarli.\r\n </div>\r\n }\r\n @if (isOrchestrationWithoutStages()) {\r\n <div class=\"fb-banner fb-banner--warn\">\r\n Un flow Orchestration senza stage di orchestrazione viene segnalato dalla validazione\r\n (ORCHESTRATION_WITHOUT_STAGES).\r\n </div>\r\n }\r\n @if (hasNoScreensInScreenFlow()) {\r\n <div class=\"fb-banner fb-banner--warn\">\r\n Un flow di tipo Screen senza nessuno screen viene segnalato dalla validazione.\r\n </div>\r\n }\r\n @if (!isEditable()) {\r\n <div class=\"fb-banner\">\r\n Questa versione e’ in sola lettura: per modificarla creane una nuova.\r\n </div>\r\n }\r\n\r\n <div class=\"fb-main\">\r\n <aside class=\"fb-main__palette\">\r\n <fb-element-palette [processType]=\"document().processType\" (elementPicked)=\"onElementPicked($event)\" />\r\n </aside>\r\n\r\n <div class=\"fb-main__center\">\r\n <fb-flow-canvas\r\n class=\"fb-main__canvas\"\r\n [selectedName]=\"selectedName()\"\r\n [outline]=\"outline()\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n (nodeOpened)=\"onNodeOpened($event)\"\r\n (nodeRemoveRequested)=\"onRemoveNode($event)\"\r\n (nodeDuplicateRequested)=\"onDuplicateNode($event)\"\r\n (elementDropped)=\"onElementDropped($event)\"\r\n />\r\n\r\n @if (showProblems()) {\r\n <fb-problems-panel\r\n class=\"fb-main__problems\"\r\n (elementFocused)=\"focusElement($event)\"\r\n (closed)=\"toggleProblems()\"\r\n />\r\n } @else {\r\n <button type=\"button\" class=\"fb-main__problems-toggle\" (click)=\"toggleProblems()\">\r\n Problemi\r\n @if (errorCount()) {\r\n <span class=\"fb-main__count fb-main__count--error\">{{ errorCount() }}</span>\r\n }\r\n @if (warningCount()) {\r\n <span class=\"fb-main__count fb-main__count--warn\">{{ warningCount() }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <aside class=\"fb-main__side\">\r\n <nav class=\"fb-side__tabs\" aria-label=\"Pannelli\">\r\n @if (!isDialogMode()) {\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'inspector'\"\r\n (click)=\"setPanel('inspector')\"\r\n >\r\n Elemento\r\n </button>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'resources'\"\r\n (click)=\"setPanel('resources')\"\r\n >\r\n Risorse\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'versions'\"\r\n (click)=\"setPanel('versions')\"\r\n >\r\n Versioni\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fb-side__tab\"\r\n [class.fb-side__tab--active]=\"sidePanel() === 'debug'\"\r\n (click)=\"setPanel('debug')\"\r\n >\r\n Prova\r\n </button>\r\n </nav>\r\n\r\n <div class=\"fb-side__content\">\r\n @switch (sidePanel()) {\r\n @case ('inspector') {\r\n <fb-element-inspector\r\n [selectedName]=\"selectedName()\"\r\n (removeRequested)=\"onRemoveNode($event)\"\r\n (duplicateRequested)=\"onDuplicateNode($event)\"\r\n (closed)=\"setPanel('resources')\"\r\n />\r\n }\r\n @case ('resources') {\r\n <fb-resource-panel (closed)=\"setPanel('inspector')\" />\r\n }\r\n @case ('versions') {\r\n <fb-version-panel\r\n (versionOpened)=\"openVersion($event)\"\r\n (notice)=\"showNotice($event)\"\r\n (closed)=\"setPanel('inspector')\"\r\n />\r\n }\r\n @case ('debug') {\r\n <!-- Evidenzia sul canvas senza rubare il pannello: l'interview e’ in corso. -->\r\n <fb-debug-panel (elementFocused)=\"highlightElement($event)\" (closed)=\"setPanel('inspector')\" />\r\n }\r\n }\r\n </div>\r\n\r\n <footer class=\"fb-side__footer\">\r\n <label class=\"fb-btn fb-btn--icon\">\r\n Importa JSON\r\n <input type=\"file\" accept=\"application/json,.json\" hidden (change)=\"onFileSelected($event)\" />\r\n </label>\r\n </footer>\r\n </aside>\r\n </div>\r\n\r\n @if (isDialogMode() && isDialogOpen() && selectedName()) {\r\n <!-- La dialog sta dentro il builder, non nel body: la libreria e’ innestabile. -->\r\n <fb-element-dialog\r\n [selectedName]=\"selectedName()\"\r\n (closed)=\"closeDialog()\"\r\n (removeRequested)=\"onRemoveNode($event)\"\r\n (duplicateRequested)=\"onDuplicateNode($event)\"\r\n />\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["removeConditionInPlace","moveConditionInPlace"],"mappings":"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"}