- @if (messages.length === 0) {
-
- Pose une question sur ta source, ou demande une adaptation pour ta campagne.
- @if (!hasReadySource()) {
-
(Ajoute d'abord une source indexée pour des réponses ancrées.)
- }
-
- }
- @for (m of messages; track m) {
-
-
- @if (m.role === 'assistant') {
-
- }
- {{ m.role === 'user' ? 'Vous' : 'IA' }}
-
- @if (m.role === 'assistant') {
- @if (parsedOf(m); as p) {
- @if (sending && deepProgress && !p.text) {
-
-
- Analyse approfondie du document… {{ deepProgress.current }}/{{ deepProgress.total }}
-
- }
-
{{ p.text }}@if (sending && !p.text && !p.actions.length && !deepProgress) {
- ▌
- }
- @for (a of p.actions; track $index) {
-
-
- }
- @if (sourcesLabel(m); as label) {
-
- 📖 {{ label }}
-
- }
- }
- } @else {
-
{{ m.content }}
- }
-
+
+
+ @if (viewingArchive) {
+
+
+ Archive du {{ archiveLabel(viewingArchive) }} — lecture seule
+
+
+ } @else {
+ @if (referencedArchiveIds.size > 0) {
+
+
+ {{ referencedArchiveIds.size }} archive(s) en référence
+
+ }
+
+
+
}
+
+ @if (archivesOpen && !viewingArchive) {
+
+ @if (archives.length === 0) {
+
Aucune conversation archivée pour l'instant — « Vider » archive le fil courant ici.
+ } @else {
+
+ Cochez une archive pour l'utiliser comme référence dans le chat ;
+ cliquez sur son nom pour la relire.
+
+ }
+ @for (a of archives; track a.archivedAt) {
+
+
+
+
+ }
+
+ }
+
+ @if (viewingArchive) {
+
+ @for (m of viewingArchive.messages; track $index) {
+
+
+ @if (m.role === 'assistant') {
+
+ }
+ {{ m.role === 'user' ? 'Vous' : 'IA' }}
+
+ @if (m.role === 'assistant') {
+
+ } @else {
+
{{ m.content }}
+ }
+
+ }
+ } @else {
+ @if (messages.length === 0) {
+
+ Pose une question sur ta source, ou demande une adaptation pour ta campagne.
+ @if (!hasReadySource()) {
+
(Ajoute d'abord une source indexée pour des réponses ancrées.)
+ }
+
+ }
+ @for (m of messages; track m) {
+
+
+ @if (m.role === 'assistant') {
+
+ }
+ {{ m.role === 'user' ? 'Vous' : 'IA' }}
+
+ @if (m.role === 'assistant') {
+ @if (parsedOf(m); as p) {
+ @if (sending && deepProgress && !p.text) {
+
+
+ Analyse approfondie du document… {{ deepProgress.current }}/{{ deepProgress.total }}
+
+ }
+ @if (p.text) {
+
+ } @else if (sending && !p.actions.length && !deepProgress) {
+
▌
+ }
+ @for (a of p.actions; track $index) {
+
+
+ }
+ @if (sourcesLabel(m); as label) {
+
+ 📖 {{ label }}
+
+ }
+ }
+ } @else {
+
{{ m.content }}
+ }
+
+ }
+ }
+
+ @if (!viewingArchive) {
+ }
diff --git a/web/src/app/campaigns/notebook/notebook-detail/notebook-detail.component.scss b/web/src/app/campaigns/notebook/notebook-detail/notebook-detail.component.scss
index 1328361..e1d240b 100644
--- a/web/src/app/campaigns/notebook/notebook-detail/notebook-detail.component.scss
+++ b/web/src/app/campaigns/notebook/notebook-detail/notebook-detail.component.scss
@@ -81,8 +81,84 @@
/* Chat */
.nbd-chat {
display: flex; flex-direction: column; min-height: 0;
+ // min-width: 0 indispensable : enfant de grille (colonne 1fr), sinon sa largeur
+ // MINIMALE devient celle de la plus longue ligne insécable d'un message
+ // (tableau markdown, longue URL…) et le chat pousse toute la page hors écran.
+ min-width: 0;
border: 1px solid rgba(255,255,255,0.08); border-radius: 10px;
}
+
+// Barre d'actions du chat : archives + vider (ou bandeau « archive en lecture seule »).
+.nbd-chat-head {
+ display: flex; align-items: center; gap: 0.4rem;
+ padding: 0.45rem 0.6rem; border-bottom: 1px solid rgba(255,255,255,0.08);
+
+ .nbd-chat-head-spacer { flex: 1; }
+
+ .nbd-archive-banner {
+ flex: 1;
+ display: inline-flex; align-items: center; gap: 0.35rem;
+ font-size: 0.8rem; color: #e0c074; font-style: italic;
+ }
+
+ // Badge « N archive(s) en référence » : rappelle que le contexte du chat
+ // inclut d'anciennes conversations, même panneau fermé.
+ .nbd-ref-badge {
+ display: inline-flex; align-items: center; gap: 0.3rem;
+ padding: 0.2rem 0.5rem; border-radius: 999px; font-size: 0.74rem;
+ background: rgba(168,130,255,0.12); border: 1px solid rgba(168,130,255,0.4);
+ color: #c4a8ff;
+ }
+
+ .nbd-chat-btn {
+ display: inline-flex; align-items: center; gap: 0.3rem;
+ padding: 0.28rem 0.55rem; border-radius: 6px; font-size: 0.78rem;
+ border: 1px solid rgba(255,255,255,0.12); background: rgba(255,255,255,0.04);
+ color: inherit; cursor: pointer;
+ &:hover:not(:disabled) { background: rgba(255,255,255,0.09); }
+ &.active { border-color: #667eea; }
+ &:disabled { opacity: 0.45; cursor: default; }
+
+ &--danger {
+ color: #e88; border-color: rgba(224,90,90,0.35);
+ &:hover:not(:disabled) { background: rgba(224,90,90,0.12); }
+ }
+ }
+}
+
+// Panneau des conversations archivées.
+.nbd-archives {
+ display: flex; flex-direction: column; gap: 0.3rem;
+ padding: 0.5rem 0.6rem; border-bottom: 1px solid rgba(255,255,255,0.08);
+
+ .nbd-archives-help {
+ margin: 0 0 0.2rem;
+ font-size: 0.74rem;
+ color: var(--color-text-muted, #9aa0aa);
+ }
+
+ .nbd-archive-row {
+ display: flex; align-items: center; gap: 0.45rem;
+
+ // Archive cochée en référence : léger liseré violet pour la repérer.
+ &.referenced .nbd-archive-item { border-color: rgba(168,130,255,0.5); }
+ }
+
+ .nbd-archive-check {
+ accent-color: #c4a8ff;
+ cursor: pointer;
+ flex-shrink: 0;
+ }
+
+ .nbd-archive-item {
+ flex: 1;
+ display: inline-flex; align-items: center; gap: 0.4rem;
+ padding: 0.35rem 0.55rem; border-radius: 6px; font-size: 0.82rem;
+ border: 1px solid rgba(255,255,255,0.08); background: rgba(255,255,255,0.03);
+ color: inherit; cursor: pointer; text-align: left;
+ &:hover { background: rgba(255,255,255,0.08); }
+ }
+}
.nbd-messages { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.85rem; }
.nbd-empty { color: var(--color-text-muted, #9aa0aa); font-style: italic; }
@@ -93,7 +169,90 @@
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em;
color: var(--color-text-muted, #9aa0aa); margin-bottom: 0.2rem;
}
- .nbd-msg-content { white-space: pre-wrap; line-height: 1.5; }
+ // overflow-wrap: anywhere : autorise la coupure DANS une séquence insécable
+ // (ligne de tableau markdown, URL) plutôt que de déborder du conteneur.
+ .nbd-msg-content { white-space: pre-wrap; line-height: 1.5; overflow-wrap: anywhere; }
+
+ // Rendu markdown des messages assistant (même esthétique que ai-chat-drawer).
+ // white-space normal : marked génère des