Skip to content

Commit 62cb21e

Browse files
Lexical generator (#116)
Original PR #97 Generates HTML (for email embedding cf. daymail) from lexical rich-content. This should support all nodes implemented and render the html as displayed in the frontend rich text editor. Of course, emails have a lack of features and the rendered result won't be exactly the same as original web presentation (eg. the font won't be the same as we cannot safely import a font, etc) This branch is based on `feat/asso/edit` --- Fonctionnalités manquantes : - [x] Gestion des CheckList (style, ajout d'élément pour remplacer le `::before` css) - [x] Tweak des listes imbriquées (remplacement d'un selecteur css pour masquer le `marker`) - [x] Suppression des marges des paragraphes pour rendre comme sur le front - [x] Suppression des marges des listes - [x] Conserver le centrage par défaut des headers des tableaux - [x] Trouver une façon d'afficher correctement les images quand trop grandes (enlever les pptés width/height pour les mettre dans le style ?) - [x] Fix la validation du type 'image' - [x] Modifier le texte des tests pour qu'il soit dans le format validé par l'api Outils manquants : - [x] Documentation - [x] Tests unitaires --------- Co-authored-by: AlbanSdl <alban.delavoreille@free.fr>
1 parent 234921a commit 62cb21e

32 files changed

Lines changed: 1099 additions & 53 deletions

.github/workflows/ci.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@ jobs:
5050
- run: pnpm prisma generate
5151
- run: pnpm build
5252

53+
docs:
54+
runs-on: self-hosted
55+
strategy:
56+
matrix:
57+
node-version: [22]
58+
pnpm-version: [10]
59+
steps:
60+
- uses: actions/checkout@v5
61+
- name: Install pnpm
62+
uses: pnpm/action-setup@v4
63+
with:
64+
version: ${{ matrix.pnpm-version }}
65+
- name: Use Node.js
66+
uses: actions/setup-node@v6
67+
with:
68+
package-manager-cache: false
69+
node-version: ${{ matrix.node-version }}
70+
cache: 'pnpm'
71+
- name: Use Python
72+
uses: actions/setup-python@v6
73+
with:
74+
python-version: '3.14'
75+
- run: pnpm build:docs:configure
76+
- run: pnpm build:docs
77+
5378
test:
5479
runs-on: self-hosted
5580
strategy:

docs/conf.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# -- Project information -----------------------------------------------------
1919

2020
project = 'EtuUTT'
21-
copyright = '2024, UTT Net Group'
21+
copyright = '2026, UTT Net Group'
2222
author = 'UTT Net Group'
2323

2424

@@ -52,7 +52,14 @@
5252
# The theme to use for HTML and HTML Help pages. See the documentation for
5353
# a list of builtin themes.
5454
#
55-
html_theme = 'sphinx_rtd_theme'
55+
html_theme = 'shibuya'
56+
html_theme_options = {
57+
"accent_color": "blue",
58+
"github_url": "https://github.com/ungdev/etu-utt-api",
59+
"announcement": "<center>Le site étu est toujours en cours de développement : la documentation est en cours d'écriture et peux être incomplète/incorrecte.</center>",
60+
}
61+
html_favicon = "logo.svg"
62+
html_logo = "logo.svg"
5663

5764
# Add any paths that contain custom static files (such as style sheets) here,
5865
# relative to this directory. They are copied after the builtin static files,
@@ -64,4 +71,5 @@
6471
'.md': 'markdown',
6572
}
6673

67-
myst_enable_extensions = ["attrs_inline"]
74+
myst_enable_extensions = ["attrs_inline"]
75+
myst_heading_anchors = 4

docs/doc_developers/api/index.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Documentation développeurs - API
1+
# API
22

33
Cette documentation s'adresse aux développeurs de l'API de EtuUTT. Elle traite des aspects techniques la concernant :
44
outils utilisés, outils développés, choix faits, ...
@@ -10,6 +10,12 @@ setup.md
1010
nestjs.md
1111
conventions.md
1212
test.md
13+
documentation.md
14+
errors.md
15+
permissions.md
16+
lexical.md
1317
ues.md
1418
timetables.md
19+
scripts.md
20+
mails.md
1521
```

docs/doc_developers/api/lexical.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Texte formatable
2+
3+
```{danger}
4+
*Le texte formatable est un **sujet de travail actuel**. Son implémentation est susceptible de changer.* \
5+
Par ailleurs, il est possible que cette fonctionnalité soit séparée dans un package nodejs indépendant.
6+
```
7+
8+
A certains endroits du site étu, les utilisateurs pourront formatter du texte. Nous avons décidé de nous baser sur une bibliothèque, [lexical](https://lexical.dev) ([github](https://github.com/facebook/lexical)). Bien que l'utilisateur puisse envoyer du contenu formatté sur à peu près n'importe quel champ texte de l'api (à condition de respecter la limite de caractères), il n'y a que quelques champs qui supportent réellement le texte formatté.
9+
10+
```{warning}
11+
Les champs qui ne supportent pas le texte formatté acceptent **pour le moment** des inputs formattés. Cependant, ces champs ne seront pas traités comme telles par les applications front-end (comme le front du site étu). Cela peut donner lieu à un affichage considéré comme buggé si la feature est mal utilisée par certaines implémentations front-end !
12+
```
13+
14+
## Abbréviations dans ce document
15+
16+
Nous utiliserons dans ce documents les abbréviations/anglicismes suivantes :
17+
18+
- RTE: Rich Text Editor, l'éditeur de texte dans lequel l'utilisateur peut formater du texte
19+
- Renderer: côté serveur, la fonction qui transforme du contenu lexical en html
20+
- Document Object Model (DOM): la structure d'un document, généralement HTML. On l'utilisera ici pour parler de tout ce qui est relatif à l'affichage du texte formatable.
21+
22+
## Les bundles
23+
24+
Un bundle est la définition de l'ensemble des contenus supportés par une zone de texte formatable. Il contient des [nodes](#node) et, pour le front, des [plugins](#plugin) et des [composants de toolbar](#composant-de-toolbar).
25+
La définition d'un bundle permet de configurer plusieurs RTE ou Renderers de manière identique.
26+
27+
Détaillons maintenant les différents éléments contenu dans un bundle :
28+
29+
### Node
30+
31+
Une node est une partie du texte ou un élément visuel que l'utilisateur peut ajouter à son texte. Il peut s'agir par exemple d'images, d'émojis customs, ou de texte avec un fond coloré.
32+
Pour créer de nouvelles capacités/de nouveaux éléments dans le texte formatté, la première étape est de créer une `class` qui hérite de `ElementNode`, `TextNode` ou `DecoratorNode`. Pour voir les méthodes à implémenter, regardez [la doc de lexical](https://lexical.dev/docs/concepts/nodes#creating-custom-nodes). Comme indiqué plus bas dans la doc, on peut utiliser [`$config` et ne pas implémenter les 3 fonctions statiques](https://lexical.dev/docs/concepts/nodes#extending-elementnode-with-config).
33+
34+
```{tip}
35+
Seule les `DecoratorNode` pourront être rendues avec une ReactNode côté front (cf. `DecoratorNode#decorate`). Si tu n'as pas envie d'écrire des opérations DOM, cela peut être une bonne solution 😉
36+
```
37+
38+
Lorsqu'on applique des classes à des éléments, il faut faire bien attention à prendre celles du thème de l'éditeur, `editor.theme[className]`. Sinon, on pourrait oublier de les implémenter de l'autre côté (serveur/client) et le rendu serait alors différent !
39+
40+
Si on souhaite remplacer une node déjà définie, on peut enregistrer des [remplacements](https://lexical.dev/docs/concepts/node-replacement). Cela nous évite de devoir copier-coller tout notre code, et à chaque fois qu'une node remplacée sera créée, elle sera transformée en notre nouvelle node à l'aide de la fonction qu'on aura définie !
41+
42+
### Plugin
43+
44+
Les plugins n'existent que côté front-end. Ce sont eux qui vont ajouter de la logique, on va pouvoir:
45+
46+
- écouter des [évènements](https://lexical.dev/docs/concepts/commands), à l'aide de `editor.registerCommand()`
47+
- enregistrer des [transformers](https://lexical.dev/docs/concepts/transforms) avec `editor.registerNodeTransform()`
48+
- en react, utiliser `useEffect`
49+
- rendre un élément supplémentaire, un overlay par exemple
50+
51+
```{admonition} TLDR
52+
:class: tip
53+
Un transformer, c'est du code qui va te permettre de transformer du contenu dans le RTE au fur et à mesure qu'il est ajouté. Par exemple, tu peux transformer automatiquement `:joy:` en l'émoji correspondant, 😂.
54+
```
55+
56+
### Composant de toolbar
57+
58+
Ce qui permettra à l'utilisateur d'intéragir avec nos nodes depuis une interface.
59+
60+
A l'heure actuelle, ces composants n'existent pas encore en tant que tel et font partie du composant `ToolbarPlugin`. Leur future séparation permettra d'ajouter facilement des composants (boutons, etc) custom dans cette toolbar.
61+
62+
## Côté serveur
63+
64+
Bien que le serveur n'ait pas à gérer l'édition en temps réel, il doit pouvoir effectuer quelques opérations sur le contenu généré par l'utilisateur. Cela inclut la validation du contenu lexical et l'export en HTML (pour pouvoir l'utiliser dans des emails par exemple).
65+
66+
```{admonition} Structure Lexical
67+
La structure envoyée entre l'API et le client est un JSON (créé avec `LexicalNode#exportJSON`). Il contient les nodes imbriquées les unes dans les autres.
68+
```
69+
70+
### La validation
71+
72+
La validation vérifie que le contenu fourni par l'utilisateur a bien une structure comprise par le serveur. Cela vérifie :
73+
74+
- que c'est bien du JSON
75+
- que l'éditeur lexical le comprend
76+
- qu'il n'y a pas de node absente du bundle
77+
- qu'il n'y a pas de propriétés inconnues sur les nodes
78+
79+
```{attention}
80+
Les propriétés des nodes doivent apparaitre dans le même sens lors de l'exportJSON côté front et côté serveur.
81+
```
82+
83+
### Le rendu
84+
85+
Le rendu permet au serveur de transformer du contenu lexical en html. Il faut faire attention à deux points ici :
86+
87+
- les méthodes `DecoratorNode#decorate` doivent être enlevées et le contenu de la node doit être traduit en instructions DOM dans `DecoratorNode#createDOM`
88+
- les styles appliqués sur le front doivent être réappliqués sur le DOM produit sur l'API. Cela peut nécessiter des modifications structurelles dans l'HTML généré. En cas de besoin, il est possible d'ajouter des conditions spécifiques dans `NodeStyleInjector.ts`

docs/doc_developers/api/nestjs.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export class DummyModule {}
228228
```
229229

230230
```{tip}
231-
L'API de EtuUTT utilise des guards personnalisés, ils sont listés [ici](#outils-specifiques-de-etuutt).
231+
L'API de EtuUTT utilise des guards personnalisés, ils sont listés [ici](#outils-spécifiques-du-site-étu).
232232
```
233233

234234
### Les interceptors [_(docs)_](https://docs.nestjs.com/interceptors)
@@ -292,7 +292,7 @@ Voici une illustration qui permet de récapituler les différentes étapes dans
292292

293293
### La gestion des erreurs
294294

295-
Nous avons implémenté des messages d'erreurs customisés, voir la page sur [la gestion des erreurs]().
295+
Nous avons implémenté des messages d'erreurs customisés, voir la page sur [la gestion des erreurs](errors.md).
296296

297297
### L'authentification nécessaire par défaut
298298

docs/doc_developers/api/setup.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,10 @@ Les tests sont tous lancés. Au bout de quelques secondes / minutes, tous les te
171171

172172
Pour cela, vous devez avoir Python3 installé.
173173

174-
Il faut commencer par installer les dépendances :
175-
176174
```bash
177-
# Pour les commandes pip, il est possible d'utiliser python -m pip (ou python3 -m pip) à la place de pip.
178-
cd docs
179-
pip install --upgrade pip setuptools sphinx readthedocs-sphinx-ext
180-
pip install -r docs/requirements.txt
181-
python -m sphinx -T -b html -d _build/doctrees -D language=fr . build/html
175+
# Pour la première commande, il faut la faire uniquement la première fois, elle va installer les dépendances python
176+
pnpm build:docs:configure
177+
pnpm build:docs
182178
```
183179

184180
Le résultat du build se situe alors dans `docs/build/html`. Le fichier racine est `index.html`. Le résultat de la

docs/doc_developers/front/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Documentation développeurs - Site web
1+
# Site web
22

33
Cette documentation s'adresse aux développeurs du site web de EtuUTT. Elle traite des aspects techniques le concernant :
44
outils utilisés, outils développés, choix faits, ...

docs/doc_developers/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Documentation développeurs
1+
# Développeurs
22

33
Cette documentation s'adresse aux développeurs de EtuUTT. Elle traite des aspects techniques de l'API, de l'application
44
mobile et du site web : outils utilisés, outils développés, choix faits, ...

docs/doc_developers/mobile_app/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Documentation EtuUTT - Application mobile
1+
# Application mobile
22

33
Cette documentation s'adresse aux développeurs de l'appli MyUTT. Elle traite des aspects techniques la concernant :
44
outils utilisés, outils développés, choix faits, ...

docs/logo.svg

Lines changed: 5 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)