Skip to main content

Macchine a stati

Con l'aggiornamento di oggi, trovate la documentazione per le Macchine a stati, che permettono di gestire le transizioni e la business logic delle Entità da un punto centralizzato.

Oltre ai casi d'uso di base, viene presentata l'integrazione fra le macchine a stati e i Form, Yup e i Controller per gestire in modo integrato la modificabilità dei singoli campi e le fasi di lavorazione di un'entità. Gli esempi nascono da quello che stiamo vedendo nei progetti attivi attualmente: validazioni che cambiano in base allo stato dell'entità, come la pubblicazione di una domanda o la variazione di una fattura.

Nel pratico, sarà possibile definire una macchina a stati per esprimere la logica di un'azione, ovvero una condizione booleana

const InvoiceMachine = EntityMachine.for<IInvoiceType>()
.withAction('edit.accounting', invoice => invoice.protocolNumber != null)

Per poi inserire nell'Entità il decoratore @SchemaAction() per ogni proprietà che deve essere collegata a una specifica azione di modifica.

class Invoice {
@SchemaAction(InvoiceMachine, 'edit.accounting')
accountingAmount!: number;
}

In questo modo, la modifica del campo accountingAmount sarà vincolata alla macchina a stati.

Lato frontend, il collegamento avviene grazie al context del nuovo componente <FormikAugmented>, che va a sostituire <Formik>: aggiungendo una proprietà al context di validazione di Yup, ovvero machineActions, i campi di Input saranno abilitati e/o disabilitati proprio in base alle azioni disponibili per l'entità selezionata.

<FormikAugmented
validationContext={{
machineActions: InvoiceMachine.actionsFor(props.invoice)
}}

Potete trovare la documentazione completa dalla machina a stati, a partire dalla sua definizione fino al collegamento con i form e i controller, nella pagina della Macchina a stati 👍🏼

Dettagli di implementazione#

A livello tecnico questo legame è implementato con il nuovo metodo di Yup needsAction, che viene aggiunto automaticamente dal Generatore dei DTO.

accountingAmount: yup.number().required().needsAction('edit.accounting')

A questo punto viene utilizzato l'hook useFormikFieldValidation() all'interno del FormFieldItem per effettuare l'introspezione sullo schema e conoscere l'azione richiesta, lo stato required, ecc. del campo.

Ricerca sulla documentazione#

Dato che mancava la ricerca sulla documentazione, è stata aggiunta (con Algolia) e ho rifinito alcune parti del sito che erano rimaste incomplete.

Avvio

E' stata pubblicata la prima versione del sito e della documentazione, la repository è in sviluppo su GitHub.

Come linea guida d'obiettivo manteniamo la conversione del codice utilizzato sulle repository interne, al fine di creare un framework riutilizzabile di componenti, sia React che NestJS, quindi adatti al Frontend e al Backend.

La pubblicazione dei package avviene sui GitHub Packages, quindi sarà necessario configurare npm nei nuovi progetti per utilizzarlo.

Per lo sviluppo, utilizziamo pnpm per l'installazione dei pacchetti e la gestione della monorepo.

Dovremo aggiungere anche questi passaggi nella documentazione qui presente.