Configurer des vues
Vue d'ensemble
La configuration des vues dâun OAV repose sur :
- des fichiers YAML décrivant chaque vue ;
- des fichiers de transitions définissant la navigation entre les vues ;
- une commande views:gen générant le code client et serveur de chacune des vues.
Définition des vues
Emplacement
Les fichiers de dĂ©finition des vues doivent ĂȘtre créés dans le dossier config/views.
Structure
Chaque vue est associée à un fichier de configuration YAML qui contient les propriétés suivantes :
- viewId : identifiant unique de la vue ;
- pathname : chemin de la vue dans lâURL ;
- directory : nom du dossier dans lequel générer le code de la vue ;
- graphql : définition des queries et mutations GraphQL utilisées par la vue.
Exemple complet d'un fichier de configuration
start:
viewId: start
pathname: /start
directory: start
graphql:
queries:
- type: Customer
fields:
firstName: String
lastName: String
resolver: getCustomer
mutations:
- type: Customer
inputs:
firstName: String
lastName: String
resolver: createCustomerDéfinition des queries GraphQL
La clĂ© queries de lâobjet graphql dĂ©finit les queries GraphQL utilisĂ©es par la vue.
graphql:
queries:
- type: Customer # Type de la réponse de la query
fields: # Propriétés à retourner : nom + type
firstName: String
lastName: String
resolver: getCustomer # Nom de la fonction resolver cÎté serveur- type : nom du type de la réponse GraphQL ;
- fields : liste des champs attendus en réponse ;
- resolver : nom de la fonction qui résout la query cÎté serveur.
Définition des mutations GraphQL
La clĂ© mutations de lâobjet graphql dĂ©finit les mutations GraphQL utilisĂ©es par la vue.
mutations:
- type: Customer # Type de la réponse de la mutation
resolver: createCustomer # Fonction permettant d'exécuter la mutation
inputs: # Arguments de la mutation : nom + type
firstName: String
lastName: String- type : nom du type de la réponse GraphQL ;
- resolver : nom de la fonction qui résout la mutation cÎté serveur ;
- inputs : paramĂštres attendus par le resolver.
Définition des transitions
Emplacement
Les fichiers de dĂ©finition des transitions doivent ĂȘtre créés dans le dossier config/views/transitions.
Structure dâun fichier de transition
Chaque vue est associée à un fichier de transition.
Le fichier de transition exporte un objet qui contient au moins lâune des propriĂ©tĂ©s suivantes :
- next : définit les vues « suivantes » possibles lors d'une action next
- prev : définit les vues « précédentes » possibles lors d'une action prev
next et prev sont de type objet avec :
- transitions : propriété obligatoire qui définit chaque transition possible
- hooks : propriété optionnelle qui définit les hooks de transition before et after
Propriété transitions
transitions est une liste ordonnée définissant les vues accessibles depuis la vue courante lors d'une action next ou prev.
Chaque élément de la liste est un objet qui contient :
- viewId : identifiant de la vue cible ;
- handler : fonction qui contient la logique d'évaluation de la transition. Elle doit retourner impérativement true ou false.
Pour déterminer la vue suivante (ou précédente) :
- Le fichier de transitions de la vue courante est lu.
- Les handlers dĂ©finis dans next.transitions (ou prev.transitions) sont Ă©valuĂ©s dans lâordre.
- La premiÚre fonction qui retourne true détermine la vue cible via son viewId.
Propriété hooks (optionnelle)
hooks est un objet regroupant des fonctions pouvant ĂȘtre appelĂ©es :
- avant lâĂ©valuation des conditions (before) ;
- aprĂšs lâĂ©valuation des conditions (after).
Ces hooks permettent par exemple :
- de charger une seule fois des données utilisées dans plusieurs conditions ;
- dâexĂ©cuter des opĂ©rations de nettoyage aprĂšs la rĂ©solution de la transition.
Exemple d'un fichier de transition
const prev__DONNEES_CONTRAT = () => {
return true;
};
export default {
prev: {
transitions: [
{ viewId: 'DONNEES_CONTRAT', handler: prev__DONNEES_CONTRAT }
]
}
};Dans cet exemple :
- une seule transition précédente est définie ;
- elle cible la vue DONNEES_CONTRAT ;
- la transition est toujours autorisée car le handler retourne toujours true.
Génération du code des vues et des transitions
La commande views:gen lit les fichiers YAML présents dans le dossier config/views pour :
- vérifier que chaque vue possÚde un fichier de transition associé ;
- vérifier que chaque transition est valide ;
- générer le fichier views/views.mjs, utilisé en interne pour la navigation entre les vues ;
- générer le code client et serveur de chaque vue.
npm run views:genFichiers générés d'une vue
Considérons le fichier de configuration suivant pour une vue home :
home:
viewId: home
pathname: /
directory: home
graphql:
queries:
- type: Customer
fields:
firstName: String
lastName: String
resolver: getCustomer
mutations:
- type: Customer
inputs:
firstName: String
lastName: String
resolver: createCustomerAprĂšs exĂ©cution de la commande npm run views:gen lâarborescence gĂ©nĂ©rĂ©e est la suivante :
views/home/
ââ client/
â ââ graphql/
â â ââ mutations/
â â â ââ CreateCustomerMutation.js
â â ââ queries/
â â ââ GetCustomerQuery.js
â ââ hooks/
â â ââ useCreateCustomerMutation.js
â â ââ useGetCustomerQuery.js
â ââ Home.inte.test.jsx
â ââ Home.jsx
ââ server/
ââ graphql/
ââ resolver/
â ââ createCustomer.mjs
â ââ createCustomer.test.js
â ââ getCustomer.mjs
â ââ getCustomer.test.js
â ââ index.mjs
ââ type/
ââ MutationType.mjs
ââ QueryType.mjs
ââ queryTypeResolvers.mjsUne vue est donc composĂ©e d'une partie serveur et client.
Partie serveur
Deux dossiers principaux sont générés pour la partie serveur :
- graphql/resolver : contient deux fichiers squelettes pour chaque resolver déclaré dans le fichier de configuration :
- un fichier pour la fonction resolver ;
- un fichier de test associé.
- graphql/type : contient la déclaration des types GraphQL de la vue.
Signature dâun resolver
Une fonction resolver possĂšde la signature suivante :
async (args, context) => ExpectedType;avec :
- args : objet contenant les arguments de la query ou les inputs de la mutation ;
- context : objet possédant une propriété process, qui contient notamment :
- projectId : identifiant du projet en cours ;
- viewId : identifiant de la vue courante.
Exemple de resolver pour la query getCustomer
export const getCustomer = async (_args, context) => {
const { projectId, viewId } = context.process;
// Resolve query fields
let firstName;
let lastName;
// Send back query fields
return {
firstName,
lastName
};
};
export default getCustomer;Exemple de resolver pour la mutation createCustomer
export const createCustomer = async (args, context) => {
const { projectId, viewId } = context.process;
const { firstName, lastName } = args;
try {
// Resolve mutation
// Send OK to inform that everything went smoothly
return { ok: true, error: null };
} catch (error) {
// Send KO to inform that an error occurred
return { ok: false, error: error.message };
}
};
export default createCustomer;Partie client
Pour la partie client de chaque vue, les éléments suivants sont générés :
- un fichier squelette pour le composant principal de la vue ;
- un fichier squelette de test pour ce composant ;
- un dossier graphql qui contient la définition client de chaque query et mutation GraphQL ;
- un dossier hooks qui contient un hook React pour chaque query et mutation déclarée.
Hooks générés
- Pour une query, le hook suit la convention use<ResolverName>Query. Exemple : useGetCustomerQuery ;
- Pour une mutation, le hook suit la convention use<ResolverName>Mutation. Exemple : useCreateCustomerMutation.