-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
388 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import {Meta} from "@storybook/blocks"; | ||
|
||
<Meta title="Les bases/Gestion des messages" /> | ||
|
||
# Gestion des messages | ||
|
||
Les messages dans une application Focus sont gérés par le **`messageStore`**. | ||
|
||
Par défaut, tout message envoyé dans ce store sera transféré au **`MessageCenter`** (posé par le `Layout` du module `@focus4/layout`, qui les affichera dans | ||
une [`Snackbar`](/docs/composants-focus4∕toolbox-snackbar--docs), en bas de l'application, en les dépilant un par un. | ||
|
||
4 types de messages sont préconfigurés : | ||
|
||
- Succès (en vert) | ||
- Erreur (en rouge) | ||
- Avertissement (en jaune) | ||
- Information (en noir/blanc, selon le thème). | ||
|
||
D'autres types de messages arbitraires peuvent être enregistrés, mais ils ne seront pas captés par le `MessageCenter` s'il n'est pas reconfiguré pour. | ||
|
||
## Enregistrer un message | ||
|
||
Le `messageStore` expose une méthode `messageStore.addMessage(type, message)` pour ajouter un message, et une surcharge par type de message | ||
préconfiguré (`addSuccessMessage`, `addErrorMessage`...) | ||
|
||
De plus, la méthode `messageStore.addMessages(messages)` est disponible, ou `messages` est un objet JS dont les clés sont les types de messages et les | ||
valeurs les messages (unitaire ou en liste). Les types de messages récoltés dans cet objet peuvent être configurés via `messageStore.messageTypes`, par | ||
défaut limité aux 4 types préconfigurés `error`, `warning`, `info` et `success`. 4 variantes sur le nom de la clé sont supportées : par exemple pour un type | ||
`error`, on cherchera dans les propriétés `error`, `errors`, `globalError` et `globalErrors`. | ||
|
||
Par défaut, tous les formulaires (du module `@focus4/stores`) envoient des messages de succès lorsqu'une sauvegarde est réalisée avec succès, et toute | ||
[requête](/docs/les-bases-gestion-des-requêtes--docs) en erreur envoie des messages d'erreurs contenant leurs détails. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import {Meta} from "@storybook/blocks"; | ||
|
||
<Meta title="Les bases/Gestion des requêtes" /> | ||
|
||
# Gestion des requêtes | ||
|
||
## `coreFetch` | ||
|
||
Focus propose un wrapper à [`window.fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) appelé **`coreFetch`**, qui a pour vocation de simplifier son usage dans les cas courants et de traiter automatiquement les erreurs. | ||
|
||
Son API est la suivante : | ||
|
||
**`coreFetch(method, url, {body?, query?}, options?)`** | ||
|
||
- **`method`** permet de renseigner le verbe HTTP (GET, POST, PUT, DELETE...) de la requête. | ||
- **`url`** permet de renseigner l'URL que l'on veut appeler. | ||
- **`{body?, query?}`** permettent de renseigner le contenu du _body_ de la requête (pour un POST ou un PUT), ainsi que les _query params_ qui devront être | ||
ajoutés à l'URL. La méthode s'occupera d'inclure les _query params_ à l'URL et gère donc leur caractère optionnel. | ||
- **`options`** est le paramètre d'options de `window.fetch`. Cet objet d'options est prérempli par `coreFetch` pour y inclure ce qu'on a déjà défini (la | ||
méthode et le body en particulier), mais il est surchargeable via ce paramètre. | ||
|
||
Si `coreFetch` reçoit une erreur et que le corps de la réponse est un JSON, alors cette réponse sera envoyée au [`messageStore`](/docs/les-bases-gestion-des-messages--docs) en appelant sa méthode | ||
`addMessages`. Pour assurer une intégration native avec la gestion de messages Focus, les APIs appelées devront renvoyer des réponses de la forme. | ||
`{error: "Message d'erreur"}` ou `{errors: ["Message 1", "Message 2"]}`. | ||
|
||
## `RequestStore` | ||
|
||
Le `RequestStore` est un store dédié au suivi des requêtes en cours dans l'application. | ||
|
||
### Suivi automatique des requêtes | ||
|
||
Par défaut, toute requête faite avec `coreFetch` est automatiquement suivie dans ce store. Les requêtes en cours peuvent se récupérer dans | ||
`requestStore.pending` et la propriété `requestStore.loading` permet de savoir s'il y au moins une requête encore en cours. Cette propriété peut être | ||
utilisée directement pour poser un "spinner" global sur votre application à moindre frais. | ||
|
||
### Suivi personnalisé de services | ||
|
||
Le `requestStore` dispose également d'une API pour suivre le statut de vos propres services (n'importe quelle fonction retournant une `Promise`) via | ||
`requestStore.track` : | ||
|
||
```ts | ||
const id = useId(); // ou v4() du package "uuid" si vous n'est pas dans un composant | ||
|
||
/* ---- */ | ||
|
||
const user = await requestStore.track(id, () => getUser(id)); // Enregistre le service sur cet ID et l'appelle | ||
|
||
/* ---- */ | ||
|
||
requestStore.isLoading(id); // La requête est-elle en cours ? | ||
``` | ||
|
||
**Plusieurs services peuvent être enregistré sur le même ID de suivi**, ce qui permet de récupérer facilement un état de chargement sur plusieurs services à la | ||
fois. | ||
|
||
Ce suivi est automatiquement intégré à `useLoad` et `useFormActions`, qui génèrent un ID de suivi pour leurs services et peuvent y associer d'autres IDs. |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import {Meta} from "@storybook/blocks"; | ||
|
||
<Meta title="Les bases/Libellés et icônes" /> | ||
|
||
# Libellés et icônes | ||
|
||
Focus utilise [`i18next`](https://www.i18next.com/) pour gérer les libellés et les icônes utilisés à travers ses différents composants. Vous êtes largement encouragés à l'utiliser pour vos | ||
propres libellés également. | ||
|
||
En ce qui concerne Focus, chaque module expose son propre objet de traductions (réexporté dans le méta-package `focus4` en un seul objet), à utiliser dans | ||
l'initialisation d'`i18next`. | ||
|
||
Par exemple : | ||
|
||
```ts | ||
import {translation as focus} from "focus4"; | ||
import i18next from "i18next"; | ||
|
||
i18next.init({lng: "fr", resources: {fr: {translation: {focus}}}}); | ||
``` | ||
|
||
Focus ne dispose (pour l'instant...) que de traductions en français (n'hésitez pas à faire une PR avec au moins la version anglaise... 😉) | ||
|
||
## Surcharge de libellés | ||
|
||
Chaque traduction utilisée dans un composant est récupérée sous la forme `${i18nPrefix}.module.component.label`, ou `i18nPrefix` est une prop du | ||
composant qui vaut `"focus"` par défaut. Le fichier de traduction de Focus contient donc `focus.module.component.label`, et vous pouvez redéfinir cette | ||
traduction en renseignant `custom.module.component.label` dans l'initialisation d'i18n et `custom` comme valeur d'`i18nPrefix`. | ||
|
||
Pour s'assurer de garder toutes les autres traductions par défaut, vous pouvez la définir de cette façon : | ||
|
||
```ts | ||
i18next.init({ | ||
lng: "fr", | ||
resources: { | ||
fr: { | ||
translation: { | ||
focus, | ||
custom: { | ||
...focus, | ||
module: {...focus.module, component: {...focus.module.component, label: "Ma valeur custom"}} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
|
||
// Ou bien utiliser `merge` de `lodash` : | ||
custom = merge(focus, {module: {component: {label: "Ma valeur custom"}}}); | ||
``` | ||
|
||
Vous pouvez bien sûr utiliser cette stratégie pour surcharger un libellé de `focus` pour qu'elle s'applique dans toute l'application. | ||
|
||
## Icônes | ||
|
||
Les icônes sont également définies dans les traductions de Focus. Elle sont toutes dans l'objet `icons` qui est à la racine de l'objet `focus` (ou la valeur | ||
de `i18nPrefix`). Par exemple `focus.icons.list.add` correspond à l'icône du bouton "Voir plus" des listes, tandis que le libellé est dans | ||
`focus.list.show.more`. | ||
|
||
Une icône se définit avec un **nom** et une **classe CSS**, qui permet de retrouver la police d'icônes associée, et se pose avec le composant [`FontIcon`](/docs/composants-focus4∕toolbox-fonticon--docs). La classe | ||
CSS est faculative car il existe une classe par défaut, définie dans `config.defaultIconClassName` (et vaut `"material-icons"`). | ||
|
||
La clé i18n devra donc pointer vers un objet `{name, className?}` (avec `className` facultatif). Tout ce qui a été présenté pour la surcharge de libellé | ||
s'applique naturellement aussi pour les icônes. | ||
|
||
_Remarque : la classe CSS de l'icône peut également être un template du nom de l'icône, par exemple `icon-{name}` pour avoir une classe `"icon-home"` | ||
pour `"home"`, ce qui est utile si la police d'icône ne fonctionne pas directement avec le nom de l'icône et qu'il faut une classe CSS dédiée par icône._ |
Oops, something went wrong.