Skip to content

feat(conversation): #IMPULS-6140 affiche la modale de message d'absence via le menu déroulant - #1097

Merged
damienromito merged 1 commit into
feat-IMPULS-6109-absence-messagefrom
feat-IMPULS-6140-menu-open-modal
Aug 4, 2026
Merged

feat(conversation): #IMPULS-6140 affiche la modale de message d'absence via le menu déroulant#1097
damienromito merged 1 commit into
feat-IMPULS-6109-absence-messagefrom
feat-IMPULS-6140-menu-open-modal

Conversation

@damienromito

@damienromito damienromito commented Aug 4, 2026

Copy link
Copy Markdown
Member

Description

Ajoute le point d'entrée réel de la modale de paramétrage du message d'absence (IMPULS-6138/6139) : un item « Message d'absence » dans le menu déroulant du header (AppActionHeader), visible uniquement pour les profils ENSEIGNANT et PERSEDUCNAT.

Introduit PortalModal, un wrapper de Modal qui rend via createPortal dans le nœud #portal plutôt que dans l'arbre React où il est monté. Cela permet de déclencher la modale depuis un point isolé (l'item de menu) avec un état isOpen local à l'instance, sans remonter un état partagé vers un ancêtre commun.

Retire l'ouverture automatique temporaire de la modale ajoutée pour les tests QA d'IMPULS-6139 (isAbsenceModalOpenForQA dans routes/root/index.tsx), qui était explicitement marquée comme à supprimer avant ce commit.

Fixes

IMPULS-6140

Type of change

  • Chore (PATCH)
  • Doc (PATCH)
  • Bug fix (PATCH)
  • New feature (MINOR)

Which packages changed?

  • conversation

Tests

  1. cd conversation/frontend && pnpm test — nouveaux tests dans AppActionHeader.test.tsx : visibilité de l'item selon le profil (ENSEIGNANT/PERSEDUCNAT vs ELEVE/PERSRELELEVE/SUPERADMIN) et ouverture de la modale par portail au clic.
  2. Manuel (pnpm dev:mock) : se connecter avec un profil enseignant, ouvrir le menu du header, cliquer sur « Message d'absence » → la modale de paramétrage s'ouvre. Avec un profil élève, l'item n'apparaît pas dans le menu.

Reminder

  • Security flaws

  • Performance impacts (think bulk !)

  • Unit tests were replayed

  • Unit tests were added and/or changed

  • I have updated the reminder for the version including my modifications

  • All done ! 😃

@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds the real UI entry point for configuring the “message d’absence” in the Conversation app by exposing it as a header dropdown action (restricted to ENSEIGNANT and PERSEDUCNAT). To support opening the modal from this isolated trigger without lifting state, it introduces a PortalModal wrapper that renders Modal content into the app’s #portal node, and removes the previous temporary QA auto-open behavior.

Changes:

  • Add a new “Message d’absence” dropdown item in AppActionHeader, conditionally visible by user profile, which opens the absence modal.
  • Introduce PortalModal (React portal wrapper) and switch AbsenceModal to render through it.
  • Remove the temporary QA auto-open absence modal code from the root route.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
conversation/frontend/src/routes/root/index.tsx Removes temporary QA-only auto-open for the absence modal.
conversation/frontend/src/features/app/Action/AppActionHeader.tsx Adds a profile-gated dropdown entry that opens AbsenceModal from the header menu.
conversation/frontend/src/features/app/Action/AppActionHeader.test.tsx Adds tests for menu-item visibility and opening the absence modal.
conversation/frontend/src/features/absence/AbsenceModal.tsx Switches the absence modal rendering to use PortalModal.
conversation/frontend/src/components/PortalModal.tsx Adds a portal-based modal wrapper that mounts into #portal (fallback to body).
conversation/frontend/src/components/index.ts Re-exports PortalModal from the components barrel.
conversation/backend/src/main/resources/i18n/fr.json Adds the i18n label for the new absence menu item.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to +58
it('opens the absence modal by portal when the menu item is clicked', async () => {
mocks.useEdificeClient.mockReturnValue({ user: { type: 'ENSEIGNANT' } });

const { user } = render(<AppActionHeader />);
await user.click(screen.getByTestId('dropdown').querySelector('button')!);
await user.click(screen.getByText('conversation.absence.menu.label'));

expect(document.getElementById('modalAbsence')).toBeInTheDocument();
});

@jcbe-ode jcbe-ode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PortalModal a mettre dans l'EFF ?
On a dû écrire ce code 10x au moins déjà...

@@ -1,4 +1,5 @@
import { Modal } from '@edifice.io/react';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L'import est toujours nécéssaire ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pour le <Modal.Header>

@damienromito

Copy link
Copy Markdown
Member Author

PortalModal a mettre dans l'EFF ? On a dû écrire ce code 10x au moins déjà...
On l'a utilisé uniquement dans actualites mais je peux le faire
@pascalsaussier-edifice t'en dit quoi ?

@damienromito
damienromito merged commit d79ee26 into feat-IMPULS-6109-absence-message Aug 4, 2026
2 checks passed
@damienromito
damienromito deleted the feat-IMPULS-6140-menu-open-modal branch August 4, 2026 14:24
damienromito added a commit that referenced this pull request Aug 4, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>
jenkinsEdificePublic pushed a commit that referenced this pull request Aug 6, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>
jcbe-ode pushed a commit that referenced this pull request Aug 6, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Aug 6, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Aug 6, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Aug 10, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Aug 10, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
pb-jo pushed a commit that referenced this pull request Aug 10, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
pb-jo pushed a commit that referenced this pull request Aug 14, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
vbillard91 pushed a commit that referenced this pull request Aug 26, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Sep 1, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
jenkinsEdificePublic pushed a commit that referenced this pull request Sep 1, 2026
* docs(conversation): #IMPULS-6109 ajout de la Feature Spec FS-IMPULS-6109

* docs(conversation):#IMPULS-6158 cadrage technique

add gherkin on US4

* docs(conversation):#IMPULS-6135 docs api

modif cadrage bandeau

* adjust cadrage tech

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence (#1093)

* add i18n mock

* feat(conversation): #IMPULS-6138 ajoute la modale de paramétrage du message d'absence

Modale + hook (react-hook-form) pour paramétrer/activer/modifier un
message d'absence : DatePicker avec minDate réactif sur la date de fin
et décalage automatique à début + 1 jour quand elle devient invalide,
champs désactivés quand le message est désactivé, texte requis
uniquement si activé.

Écart assumé par rapport à la FS (US-1) : pas de message d'erreur
inline, le bouton "Enregistrer" est simplement désactivé tant que le
formulaire n'est pas valide — jugé plus simple pour le code et
l'expérience. Jira IMPULS-6130, FS et cadrage mis à jour en
conséquence.

Autres changements :
- CSS dédié au composant (AbsenceModal.css), opacité ciblée sur
  l'éditeur uniquement.
- Clés i18n propres au module, préfixées `conversation.` (plus de
  common_t).
- data-testid sur les boutons, format module-composant-élément-nom.
- Tests hook (validation/UTC/toasts) et composant (rendu/câblage)
  séparés.
- Doc de bonnes pratiques frontend issue du pairing
  (conversation/specs/IMPULS-6109/BONNES-PRATIQUES-FRONTEND.md).

Contient un câblage QA temporaire dans routes/root/index.tsx
(ouverture automatique de la modale au lancement) en attendant le
vrai point d'entrée porté par IMPULS-6140.

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1096)

* feat(conversation): #IMPULS-6139 ajoute le service API et les hooks TanStack Query du message d'absence (#1095)

- absenceService (GET/PUT /conversation/absence) + absenceQueryKeys/useAbsenceSettings/useSaveAbsenceSettings avec setQueryData optimiste au succès
- AbsenceModalContainer + useAbsenceModalContainer pour brancher AbsenceModal sur l'API, sans dépendre du store openedModal
- déplace AbsenceModal/AbsenceModalContainer/hooks dans features/absence/ (regroupement par feature)
- mocks MSW (mocks/datas/absences.ts + handlers/absence-handlers.ts) pour dev:mock et les tests
- documente les retours de pairing dans BONNES-PRATIQUES-FRONTEND.md

* add skeleton + refacto

* bonne pratique skeleton

* Feat impuls 6109 back (#1094)

* IMPULS-6136

* IMPULS-6141

* IMPULS-6137

* IMPULS-6137

* IMPULS-6142

* IMPULS-6143 IMPULS-6144

* IMPULS-6144

* IMPULS-6148

* IMPULS-6150

* IMPULS-6150

* maj des claude.md

* PR review

* feat(conversation):#IMPULS-6140-display modal via dropdown (#1097)

* feat(conversation): #IMPULS-6147 transmet le fuseau de l'expéditeur dans la charge utile d'envoi (#1098)

* fix(conversation):#IMPULS-6130-disabled-submit-when-not-dirty

* fix(conversation):#IMPULS-6130-close-modal-on-save

* feat(conversation):#IMPULS-6133-add-absence-banner (#1099)

---------

Co-authored-by: Vincent Billard <vincent.billard@edifice.io>

* fix(conversation): #IMPULS-6109 fix cron expression

* fix(conversation): ne charge les settings d'absence que pour les profils autorisés

AbsenceReminderBanner appelait useAbsenceSettings pour tous les
utilisateurs, alors que seuls ENSEIGNANT et PERSEDUCNAT peuvent avoir
un message d'absence (cf. AppActionHeader). Le check de profil est
centralisé dans useRights (canManageAbsence) et useAbsenceSettings
accepte désormais un flag enabled pour ne déclencher la requête que
pour ces profils.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(conversation): #IMPULS-6109 fix rights on conversation schema
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants