L’application mobile utilise un automate à état fini pour son fonctionnement.
L’automate est décrit dans le fichier mobile.ts.
À l’exécution, on aura une pile (stack) qui retiendra tous les choix successifs, et toutes les valeurs des différents formulaires rencontrés.
La définition de l’automate est un object javascript.
Chaque clé de cet objet représente un écran.
L’écran initial doit avoir pour clé «init».
Chaque état est ensuite décrit par un object javascript. La clé type
donne le type d’écran.
Le présent chapitre liste les différents états et leurs différentes options.
La classe State est la classe de base. Les options qu’auront tous les autres états :
Le type de l’état. Le fichier index.ts va se baser sur cette valeur pour instancier la bonne classe.
Le nom de l’écran. Sera affiché en haut.
La classe StateChoice représente un écran qui proposera plusieurs choix, sous forme de boutons.
L’option choices
est un tableau d’objets de la forme :
{
label: 'Le libellé du choix',
value: 'La valeur associée', // c'est la valeur qui sera mise dans la stack
goto: 'stateX', // vers quel state aller quand on fait ce choix
name: 'xxx' // Optionnel. voir plus loin
}
Le champ name
est optionnel. Il permet de changer le nom du champ qui sera stocké dans la stack (par défaut c’est le nom de l’état courant).
La classe StateForm représente un formulaire.
Vers quel état aller quand le formulaire est validé.
Un tableau de définition de champs.
Ce code étant encore amené à beaucoup bouger, la documentation de ce qu’est un field
est volontairement incomplète. On ne retrouve ici que les attributs de base, communs à tous les types de champs.
Le type du champ (varchar
, text
, integer
, select
, …).
Le nom technique du champs. Ce nom sera la clé utilisée pour la sauvegarde des données.
Le libellé du champs.
Si le champ est obligatoire ou non (booléen).
Valeur par défaut du champ.
Longueur max de la valeur.
Permet d’ajouter des annotations à coté d’un champs, pour guider l’usage.
Plusieurs formes possibles :
{
label: 'Ceci est une note...'
}
On peut aussi se baser sur des choix précédemment fait (et donc dans la stack) pour personnaliser les notes à partir d’une liste remontée du backend.
Par exemple, le backend a une liste de tags, pour chaque tag une note optionnelle à afficher. On va donc charger une liste de tags depuis le backend, chercher le tag qui est actuellement appliqué au produit, et afficher la note correspondante.
interface {
load: string, // Le nom de la source backend à utiliser (exemple : les pcat)
basedOnValueOf: string, // nom de champs qu'on va chercher dans la stack. On utilisera la valeur de ce champs pour filtrer
key: string, // le champs clé dans la source de donnée, dans lequel il vaut chercher la valeur de la stack (ex: rowid)
field: string, // le nom du champs de la source de donnée qui contient les notes à afficher (ex: notes)
}
Un formulaire peut être en mode «édition» pour modifier des données existantes. La définition sera alors du type suivant :
interface StateFormDefinition extends StateDefinitionBase {
type: 'form'
goto: string
edit?: StateFormEditDefinition
fields: FormField[]
}
interface StateFormEditDefinition {
stackKey: string
getDataKey: string
}
stackKey
est le nom de la clé primaire se trouvant dans la stack.
getDataKey
est le nom de la source de donnée à utiliser.
Chaque champs du formulaire devra avoir une clé edit
pour décrire comment
charger la valeur courante à partir de la stack:
interface FormFieldEditInfo {
getDataFromSourceKey: string
convertData?: (v: any) => string
}
getDataFromSourceKey
indique le nom du champs dans la source de donnée.
convertData
est une méthode qui va transformer les données de la source,
pour les faire correspondre aux champs du formulaire.
La classe StatePick proposera de sélectionner une valeur dans une ou plusieurs liste(s) (en utilisant des widgets de type «autocomplete»).
La clé qui sera utilisée pour charger la liste depuis le backend.
On peut donc sélectionner une ligne avec un ou plusieurs champs successifs. Exemple : d’abord la marque, puis la référence. La liste des références sera filtrée en fonction de la marque préalablement choisie.
La définition d’un field :
interface PickField {
name: string, // le nom du champs tel qu'il sera stocké dans la stack
label: string, // le libellé du champs
applyFilter?: 'lowerCase' | 'upperCase' | 'localeLowerCase' | 'localeUpperCase' // un filtre à appliquer aux valeurs pour les homogénéiser.
}
Nom du champs dans la source de donnée qui contient la valeur à stocker dans la stack (la clé primaire).
L’état où aller après avoir sélectionné une valeur.
Si fourni, un bouton «créer nouveau» sera affiché. La valeur est le state dans lequel aller.
creationLabel permet de personnaliser le libellé du bouton.
La classe StateSelect est un état qui affichera un select
.
interface Option {
value: string,
label: string
}
La classe StateShow représente une page va afficher un objet remonté du backend. Par exemple une fiche produit.
Le type d’objet (clé pour la source backend). Par exemple product
.
Nom de la clé à chercher dans la stock, pour avoir l’id à chercher niveau backend.
Par exemple product
si dans ma stack j’ai un champ product
dont la valeur est l’id produit.
Les champs à afficher. Voir le code pour la doc (le code bouge encore, ce sera à documenter plus tard).
Affiche un bouton «ok» qui ira sur le state correspondant.
Affiche un bouton «ajouter» qui ira sur le state correspondant.
addLabel permet de personnaliser le libellé du bouton.
La classe StateVirtual est un état virtuel qui avance automatiquement.
La classe StateCompute est un état virtuel qui permet d’effectuer des modifications sur les valeurs en stack.
Par exemple d’injecter les valeurs de la stack dans un template, et de de s’en serveur pour générer une description.
Cette classe n’est pas documentée pour l’instant, car non utilisée et sujette à changements.
La classe StateSave permet de faire un récapitulatif des données dans la stack, et de proposer de les enregistrer.
Documentation à faire.
Pour débuguer, on peut accéder à la machine dans la console JS du navigateur via window.pickupMobileMachine
.
La stack est dans window.pickupMobileMachine.stack
. On peut en avoir une version «lisible à l’oeil humain» via window.pickupMobileMachine.stack.dumpForHuman()
.
On peut également débuguer le cache des données remontées du backend via window.pickupMobileDebugDataCache()
.
Il y a une fonction qui essaie de trouver les problèmes de définition de l’automate (status manquants, template manquant, etc…) : window.pickupMobileMachine.findProblems().then(console.log)
.