Comprendre le dossier views
Le dossier views contient les views générées par @fasstech/oip-views-generator à partir des fichiers de configuration des views déclarées dans le dossier viewsConfig. Un fichier de configuration correspond à une view.
Commande pour générer les views :
$> yarn build:viewsLes views sont chargées par l'app React en fonction du routing via le fichier views/client.js par le component app/Router.jsx. Voir app/index.js.
Structure générale
Après génération des views via la commande yarn build:views, le dossier views contient un dossier par view et un dossier _common.
views/
├── _common/
│ ├── client/
│ └── server/
├── myViewOne/
│ ├── client/
│ │ ├── components/
│ │ ├── graphql/
│ │ ├── hooks/
│ │ └── MyViewOne.jsx
│ ├── server/
│ │ └── graphql/
│ │ ├── resolver/
│ │ └── type/
│ └── transitions/
└── myViewTwo/
├── client/
│ ├── components/
│ ├── graphql/
│ ├── hooks/
│ └── MyViewTwo.jsx
├── server/
│ └── graphql/
│ ├── resolver/
│ └── type/
└── transitions/Chaque view contient un dossier client pour la logique front, un dossier server pour la logique back et un dossier transitions pour la logique de transition d'une vue à l'autre.
_common contient également les dossiers client et server.
Structure du dossier _common
_common contient les composants communs utilisés par les différentes views dans le dossier client/components.
_common/
├── client/
│ ├── components/
│ │ ├── MyCommonComponent.jsx
│ │ └── MyOtherCommonComponent.jsx
│ └── hooks/
│ ├── useCommitMutation.js
│ ├── useFetching.js
│ └── useFetchQuery.js
└── server/
└── graphql/
└── enum/
├── MyEnumType.mjs
└── MagicEnumType.mjsExemple d'import d'un composant commun depuis un composant d'une view :
import MyCommonComponent from '@@viewCommonComponents/MyCommonComponent.jsx';Les fichiers contenus dans client/hooks/ sont générés et ne doivent pas être modifiés.
Déclarer et placer les enum types graphql dans _common/server/graphql/enum/. Un enum type graphql doit correspondre à un enum d'une propriété d'une entité.
Exemple de déclaration d'un enum type graphql pour la propriété civility de l'entité Customer :
import { gql } from 'apollo-server-express';
const CivilityEnum = {
typeDefs: gql`
enum CivilityEnum {
MONSIEUR,
MADAME
}
`
};
export default CivilityEnum;Par convention, le fichier sera nommé CivilityEnumType.mjs.
Structure du dossier client d'une view
À la racine du dossier client d'une view se trouve le composant maître de la view. Ici, le composant MyView.jsx. Le composant maître est chargé en fonction du routing dans app/Router.jsx.
Par défaut, le composant maître est wrappé par withProcess(MyView) pour recevoir en properties context pour consommer le context et processHandler pour gérer les transitions. Voir le fichier app/withProcess.jsx.
myView/
└── client/
├── components/
│ ├── MyViewForm.jsx
│ └── MyViewDialog.jsx
├── graphql/
│ ├── mutations/
│ │ ├── __generated__/
│ │ │ └── CreateItemMutation.graphql.js
│ │ └── CreateItemMutation.js
│ └── queries/
│ ├── __generated__/
│ │ └── GetItemQuery.graphql.js
│ └── GetItemQuery.js
├── hooks/
│ ├── useCreateItemMutation.js
│ └── useGetItemQuery.js
└── MyView.jsxDans le dossier client/components/ sont déclarés les différents composants utilisé par la view.
Les fichiers des mutations et queries qui se trouvent dans le dossier client/graphql/ sont générés en fonction du fichier de configuration de la view courante et ne doivent pas être modifié.
Un hook react est généré dans le dossier client/hooks/ pour chacunes des mutations ou queries. Ces hooks ne doivent pas être modifiés. Ces hooks peuvent être appelés dans n'importe quel composant interne à la view pour exécuter les mutations ou queries souhaitées.
Structure du dossier server d'une view
Le dossier server d'une view contient la logique back de la view.
myView/
└── server/
└── graphql/
├── resolver/
│ ├── createItem.mjs
│ ├── getItem.mjs
| └── index.mjs
└── type/
├── MutationType.mjs
├── QueryType.mjs
└── queryTypeResolvers.mjsLes types graphql contenus dans le dossier graphql/type/ sont générés en fonction du fichier de configuration de la view courante et ne doivent pas être modifiés.
Pour chacunes des mutations et queries déclarées dans le fichier de configuration de la view, la base d'un resolver est généré dans graphql/resolver/. Il est alors à la charge du développeur d'ajouter la logique souhaitée dans ces resolvers. Et notamment d'importer Entities et les getters et setters souhaités exposés par l'oip-core pour accéder à la donnée ou l'altérer.
Exemple d'un resolver getProject qui récupère le projet courant :
import { Entities } from '@fasstech/oip-core';
import {
getProjectId,
getProjectExternalId,
getProjectName
} from '@fasstech/oip-core/entities';
export const getProject = async (args, context) => {
// récupération de projectId depuis le context graphql
const { projectId } = context.process;
// récupération de l'entité projet par id
const project = await Entities('Project').get({ id: projectId });
// récupération de la valeur des champs via les getters
return {
id: getProjectId(project),
externalId: getProjectExternalId(project),
name: getProjectName(project)
};
};
export default getProject;L'identifiant du projet courant relatif au process courant est résolu et accessible depuis le context graphql du resolver.
La section graphql du fichier de configuration de la view relative à ce resolver pour cet exemple serait :
...
graphql:
queries:
- type: Project
fields:
id: String
externalId: String
name: String
resolver: getProjectStructure du dossier transitions d'une view
Les fichiers contenus dans le dossier transitions d'une view sont générés en fonction du fichier de configuration de la view courante. Ils sont utilisés par l'app pour la logique de transition.
myView/
└── transitions/
├── _default_.mjs
├── index.mjs
└── next.mjsIl n'est normalement pas nécessaire de modifier ces fichiers. Mais il peut arriver que ces fichiers se génèrent avec des erreurs et que les transitions de la view relative ne fonctionnent pas de la manière attendue.
Dans ce cas, charge au développeur de vérifier ces fichiers et notamment les identifiants des views retournés en fonction de l'action et d'appliquer des corrections si besoin.
Le fichier _default_.mjs définit la logique de transition pour la vue par défaut. La vue par défaut contient dans ses actions la valeur _DEFAULT_ dans le fichier de configuration. Un projet OAV ne possède qu'une vue _DEFAULT_.
# fichier de configuration viewsConfig/01_home.yml
home:
...
actions:
- NEXT
- _DEFAULT_ # cette vue sera la vue par défaut de l'oav_default_.mjs implémente la méthode initialize du transitionRouter exposé par l'oip-core.
// fichier views/home/transitions/_default_.mjs
import { transitionRouter as router } from '@fasstech/oip-core/process';
import { viewIds } from '../../ids.mjs';
// prend en paramètre une callback qui retourne l'id de la vue par défaut, ici HOME
router.initialize(async ({ sessionId }) => {
return { viewId: viewIds.HOME };
});
export default router;Pour chaque autre action définie dans le fichier de configuration d'une vue, un fichier de transition est généré et implémente la méthode declare du transitionRouter exposé par l'oip-core. Par exemple, le fichier next.mjs gère la transition pour l'action NEXT déclarée dans le fichier de configuration ci-dessus.
// fichier views/home/transitions/next.mjs
import { transitionRouter as router } from '@fasstech/oip-core/process';
import { actionIds, viewIds } from '../../ids.mjs';
// le 1er paramètre correspond à l'id de la vue courante, ici HOME
// le 2d paramètre correspond à l'id de l'action courante, ici HOME_NEXT
// le 3ème paramètre correspond à la callback qui retourne l'id de la vue attendue après la transition, ici START
router.declare(viewIds.HOME, actionIds.HOME_NEXT, async ({ sessionId, process }) => {
return { viewId: viewIds.START };
});
export default router;