diff --git a/assets/css/github-preview.css b/assets/css/github-preview.css
new file mode 100644
index 0000000..1bdc089
--- /dev/null
+++ b/assets/css/github-preview.css
@@ -0,0 +1,454 @@
+/* CSS pour la prévisualisation du journal - Style GitHub authentique */
+
+.markdown-preview {
+ /* Variables spécifiques GitHub */
+ --github-text-color: #1f2328;
+ --github-text-light: #656d76;
+ --github-bg-color: #ffffff;
+ --github-border-color: #d0d7de;
+ --github-border-muted: #d8dee4;
+ --github-accent-emphasis: #0969da;
+ --github-accent-fg: #0969da;
+ --github-neutral-muted: #afb8c1;
+ --github-canvas-subtle: #f6f8fa;
+ --github-danger-fg: #cf222e;
+ --github-success-fg: #1a7f37;
+ --github-attention-fg: #9a6700;
+ --github-severe-fg: #bc4c00;
+ --github-done-fg: #8250df;
+
+ /* Override pour thème sombre */
+ color: var(--github-text-color);
+ background: var(--github-bg-color);
+ border: 1px solid var(--github-border-color);
+ border-radius: 6px;
+
+ /* GitHub typography */
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
+ font-size: 16px;
+ line-height: 1.5;
+ word-wrap: break-word;
+
+ /* Layout comme GitHub */
+ max-width: none;
+ width: 100%;
+ padding: 48px;
+ margin: 0;
+ box-sizing: border-box;
+}
+
+/* Mode sombre GitHub */
+body.dark-theme .markdown-preview {
+ --github-text-color: #e6edf3;
+ --github-text-light: #7d8590;
+ --github-bg-color: #0d1117;
+ --github-border-color: #30363d;
+ --github-border-muted: #21262d;
+ --github-accent-emphasis: #1f6feb;
+ --github-accent-fg: #58a6ff;
+ --github-neutral-muted: #6e7681;
+ --github-canvas-subtle: #161b22;
+ --github-danger-fg: #f85149;
+ --github-success-fg: #3fb950;
+ --github-attention-fg: #d29922;
+ --github-severe-fg: #db6d28;
+ --github-done-fg: #a5a3ff;
+
+ background: var(--github-bg-color);
+ color: var(--github-text-color);
+ border-color: var(--github-border-color);
+}
+
+/* Titres style GitHub */
+.markdown-preview h1,
+.markdown-preview h2,
+.markdown-preview h3,
+.markdown-preview h4,
+.markdown-preview h5,
+.markdown-preview h6 {
+ margin-top: 24px;
+ margin-bottom: 16px;
+ font-weight: 600;
+ line-height: 1.25;
+ color: var(--github-text-color);
+}
+
+.markdown-preview h1 {
+ font-size: 2em;
+ border-bottom: 1px solid var(--github-border-muted);
+ padding-bottom: 0.3em;
+ margin-top: 0;
+}
+
+.markdown-preview h2 {
+ font-size: 1.5em;
+ border-bottom: 1px solid var(--github-border-muted);
+ padding-bottom: 0.3em;
+}
+
+.markdown-preview h3 {
+ font-size: 1.25em;
+}
+
+.markdown-preview h4 {
+ font-size: 1em;
+}
+
+.markdown-preview h5 {
+ font-size: 0.875em;
+}
+
+.markdown-preview h6 {
+ font-size: 0.85em;
+ color: var(--github-text-light);
+}
+
+/* Paragraphes */
+.markdown-preview p {
+ margin-top: 0;
+ margin-bottom: 16px;
+}
+
+/* Listes style GitHub */
+.markdown-preview ul,
+.markdown-preview ol {
+ margin-top: 0;
+ margin-bottom: 16px;
+ padding-left: 2em;
+}
+
+.markdown-preview li {
+ word-wrap: break-all;
+ margin-bottom: 0;
+}
+
+.markdown-preview li > p {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-preview li + li {
+ margin-top: 0.25em;
+}
+
+/* Listes de tâches */
+.markdown-preview .task-list-item {
+ list-style-type: none;
+}
+
+.markdown-preview .task-list-item input[type="checkbox"] {
+ margin: 0 0.2em 0.25em -1.4em;
+ vertical-align: middle;
+}
+
+/* Citations */
+.markdown-preview blockquote {
+ margin: 0 0 16px 0;
+ padding: 0 1em;
+ color: var(--github-text-light);
+ border-left: 0.25em solid var(--github-border-color);
+}
+
+.markdown-preview blockquote > :first-child {
+ margin-top: 0;
+}
+
+.markdown-preview blockquote > :last-child {
+ margin-bottom: 0;
+}
+
+/* Code inline */
+.markdown-preview code {
+ padding: 0.2em 0.4em;
+ margin: 0;
+ font-size: 85%;
+ white-space: break-spaces;
+ background-color: var(--github-neutral-muted);
+ border-radius: 6px;
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
+}
+
+body.dark-theme .markdown-preview code {
+ background-color: rgba(110, 118, 129, 0.4);
+}
+
+/* Blocs de code */
+.markdown-preview pre {
+ padding: 16px;
+ margin-bottom: 16px;
+ background-color: var(--github-canvas-subtle);
+ border-radius: 6px;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.45;
+ word-wrap: normal;
+}
+
+body.dark-theme .markdown-preview pre {
+ background-color: var(--github-canvas-subtle);
+}
+
+.markdown-preview pre code {
+ display: inline;
+ max-width: auto;
+ padding: 0;
+ margin: 0;
+ overflow: visible;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0;
+ white-space: pre;
+ word-break: normal;
+ word-spacing: normal;
+ tab-size: 4;
+}
+
+/* Tables style GitHub */
+.markdown-preview table {
+ border-spacing: 0;
+ border-collapse: collapse;
+ display: table;
+ width: 100%;
+ overflow: auto;
+ margin-top: 0;
+ margin-bottom: 16px;
+ border: 1px solid var(--github-border-color);
+}
+
+.markdown-preview table th {
+ font-weight: 600;
+ background-color: var(--github-canvas-subtle);
+ border: 1px solid var(--github-border-color);
+ padding: 6px 13px;
+ text-align: left;
+ vertical-align: top;
+}
+
+body.dark-theme .markdown-preview table th {
+ background-color: var(--github-canvas-subtle);
+}
+
+.markdown-preview table td {
+ border: 1px solid var(--github-border-color);
+ padding: 6px 13px;
+ text-align: left;
+ vertical-align: top;
+}
+
+.markdown-preview table tr {
+ background-color: var(--github-bg-color);
+ border-top: 1px solid var(--github-border-color);
+}
+
+.markdown-preview table tr:nth-child(even) {
+ background-color: var(--github-canvas-subtle);
+}
+
+body.dark-theme .markdown-preview table tr:nth-child(even) {
+ background-color: var(--github-canvas-subtle);
+}
+
+.markdown-preview table thead tr {
+ background-color: var(--github-canvas-subtle);
+}
+
+body.dark-theme .markdown-preview table thead tr {
+ background-color: var(--github-canvas-subtle);
+}
+
+/* Liens style GitHub */
+.markdown-preview a {
+ color: var(--github-accent-fg);
+ text-decoration: none;
+}
+
+.markdown-preview a:hover {
+ text-decoration: underline;
+}
+
+.markdown-preview a:visited {
+ color: var(--github-done-fg);
+}
+
+/* Images */
+.markdown-preview img {
+ max-width: 100%;
+ box-sizing: content-box;
+ background-color: var(--github-bg-color);
+}
+
+.markdown-preview img[align=right] {
+ padding-left: 20px;
+}
+
+.markdown-preview img[align=left] {
+ padding-right: 20px;
+}
+
+/* Séparateurs horizontaux */
+.markdown-preview hr {
+ height: 0.25em;
+ padding: 0;
+ margin: 24px 0;
+ background-color: var(--github-border-color);
+ border: 0;
+ border-radius: 6px;
+}
+
+/* Emphasis */
+.markdown-preview strong {
+ font-weight: 600;
+}
+
+.markdown-preview em {
+ font-style: italic;
+}
+
+/* Strikethrough */
+.markdown-preview del {
+ text-decoration: line-through;
+}
+
+/* Keyboard keys */
+.markdown-preview kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font-size: 11px;
+ line-height: 10px;
+ color: var(--github-text-light);
+ vertical-align: middle;
+ background-color: var(--github-canvas-subtle);
+ border: solid 1px var(--github-neutral-muted);
+ border-bottom-color: var(--github-neutral-muted);
+ border-radius: 6px;
+ box-shadow: inset 0 -1px 0 var(--github-neutral-muted);
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
+}
+
+/* Support pour les alertes GitHub (Notes, Tips, etc.) */
+.markdown-preview .markdown-alert {
+ padding: 0.5rem 1em;
+ margin-bottom: 16px;
+ color: inherit;
+ border-left: 0.25em solid var(--github-border-color);
+ background-color: var(--github-canvas-subtle);
+ border-radius: 0 6px 6px 0;
+}
+
+.markdown-preview .markdown-alert > :first-child {
+ margin-top: 0;
+}
+
+.markdown-preview .markdown-alert > :last-child {
+ margin-bottom: 0;
+}
+
+.markdown-preview .markdown-alert .markdown-alert-title {
+ display: flex;
+ font-weight: 500;
+ align-items: center;
+ line-height: 1;
+}
+
+.markdown-preview .markdown-alert.markdown-alert-note {
+ border-left-color: var(--github-accent-emphasis);
+}
+
+.markdown-preview .markdown-alert.markdown-alert-tip {
+ border-left-color: var(--github-success-fg);
+}
+
+.markdown-preview .markdown-alert.markdown-alert-important {
+ border-left-color: var(--github-done-fg);
+}
+
+.markdown-preview .markdown-alert.markdown-alert-warning {
+ border-left-color: var(--github-attention-fg);
+}
+
+.markdown-preview .markdown-alert.markdown-alert-caution {
+ border-left-color: var(--github-danger-fg);
+}
+
+/* Support pour Mermaid avec style GitHub */
+.markdown-preview .mermaid {
+ text-align: center;
+ margin: 16px 0;
+ background: transparent;
+}
+
+.markdown-preview .mermaid svg {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Support pour les footnotes */
+.markdown-preview .footnotes {
+ font-size: 0.875em;
+ color: var(--github-text-light);
+ border-top: 1px solid var(--github-border-color);
+ margin-top: 24px;
+ padding-top: 24px;
+}
+
+.markdown-preview .footnotes ol {
+ padding-left: 16px;
+}
+
+.markdown-preview .footnotes li {
+ margin: 0.25rem 0;
+}
+
+/* Amélioration de l'espacement pour les éléments imbriqués */
+.markdown-preview li p {
+ margin-bottom: 0;
+ margin-top: 0;
+}
+
+.markdown-preview li blockquote {
+ margin: 8px 0;
+}
+
+.markdown-preview li ul,
+.markdown-preview li ol {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-preview ul ul,
+.markdown-preview ul ol,
+.markdown-preview ol ol,
+.markdown-preview ol ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* Scrollbars GitHub-like (webkit only) */
+.markdown-preview::-webkit-scrollbar {
+ width: 16px;
+ height: 16px;
+}
+
+.markdown-preview::-webkit-scrollbar-corner,
+.markdown-preview::-webkit-scrollbar-track {
+ background-color: transparent;
+}
+
+.markdown-preview::-webkit-scrollbar-thumb {
+ background-color: var(--github-neutral-muted);
+ border-radius: 8px;
+ border: 4px solid transparent;
+ background-clip: content-box;
+}
+
+.markdown-preview::-webkit-scrollbar-thumb:hover {
+ background-color: var(--github-text-light);
+}
+
+/* Responsive pour mobile */
+@media (max-width: 768px) {
+ .markdown-preview {
+ padding: 24px 16px;
+ }
+}
\ No newline at end of file
diff --git a/assets/js/app.js b/assets/js/app.js
index 8b0bbe7..b14cf0c 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -125,32 +125,42 @@ class ConceptionAssistant {
this.showNotification('Retour en haut', 'success');
}
- saveState() {
+ saveState(immediate = false) {
+ // Si immediate est true, sauvegarder immédiatement sans debounce
+ if (immediate) {
+ this.performSaveState();
+ return;
+ }
+
// Éviter de sauvegarder trop souvent (debounce)
if (this.saveStateTimer) {
clearTimeout(this.saveStateTimer);
}
this.saveStateTimer = setTimeout(() => {
- const currentContent = this.editor.innerText;
-
- // Ne pas sauvegarder si le contenu n'a pas changé
- if (this.undoStack.length > 0 && this.undoStack[this.undoStack.length - 1] === currentContent) {
- return;
- }
-
- this.undoStack.push(currentContent);
-
- // Limiter la pile d'annulation à 50 éléments
- if (this.undoStack.length > 50) {
- this.undoStack.shift();
- }
-
- // Vider la pile de refaire car on a fait une nouvelle action
- this.redoStack = [];
+ this.performSaveState();
}, 1000); // Sauvegarder après 1 seconde d'inactivité
}
+ performSaveState() {
+ const currentContent = this.editor.innerText;
+
+ // Ne pas sauvegarder si le contenu n'a pas changé
+ if (this.undoStack.length > 0 && this.undoStack[this.undoStack.length - 1] === currentContent) {
+ return;
+ }
+
+ this.undoStack.push(currentContent);
+
+ // Limiter la pile d'annulation à 50 éléments
+ if (this.undoStack.length > 50) {
+ this.undoStack.shift();
+ }
+
+ // Vider la pile de refaire car on a fait une nouvelle action
+ this.redoStack = [];
+ }
+
undo() {
if (this.undoStack.length > 1) {
const currentContent = this.undoStack.pop();
@@ -262,6 +272,14 @@ class ConceptionAssistant {
this.currentJournalId = id;
this.editor.innerText = journal.markdownContent;
this.generateTOC();
+
+ // Réinitialiser l'historique pour le nouveau journal
+ this.undoStack = [journal.markdownContent];
+ this.redoStack = [];
+
+ // S'assurer que l'éditeur est en mode édition
+ this.ensureEditMode();
+
this.showNotification('Journal chargé', 'success');
}
} catch (error) {
@@ -336,6 +354,14 @@ class ConceptionAssistant {
this.editor.innerText = '';
this.generateTOC();
this.clearFeedback();
+
+ // Réinitialiser l'historique pour le nouveau journal
+ this.undoStack = [''];
+ this.redoStack = [];
+
+ // S'assurer que l'éditeur est en mode édition
+ this.ensureEditMode();
+
this.showNotification('Nouveau journal créé', 'success');
}
@@ -441,64 +467,134 @@ class ConceptionAssistant {
}
scrollToHeading(title) {
- const content = this.editor.innerText;
- const lines = content.split('\n');
+ try {
+ // Méthode plus simple et robuste : chercher le texte directement dans l'éditeur
+ const content = this.editor.innerText;
+ const lines = content.split('\n');
- // Chercher la ligne qui correspond au titre
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i].trim();
- if (line.startsWith('#') && line.replace(/^#+\s*/, '') === title) {
- try {
- // Approche plus simple : utiliser un élément temporaire avec une position spécifique
- const tempElement = document.createElement('div');
- tempElement.style.position = 'absolute';
- tempElement.style.visibility = 'hidden';
- tempElement.style.height = '1px';
-
- // Calculer la position approximative en fonction de la ligne
- const editorRect = this.editor.getBoundingClientRect();
- const computedStyle = window.getComputedStyle(this.editor);
- const lineHeight = parseInt(computedStyle.lineHeight) || 20;
-
- // Insérer l'élément temporaire dans l'éditeur
- this.editor.appendChild(tempElement);
-
- // Calculer la position de scroll basée sur le numéro de ligne
- const targetPosition = i * lineHeight;
-
- // Scroller vers la position calculée
- this.editor.scrollTo({
- top: targetPosition,
- behavior: 'smooth'
- });
-
- // Si l'éditeur n'a pas de scroll, utiliser le parent
- if (this.editor.scrollHeight <= this.editor.clientHeight) {
- const scrollContainer = this.editor.parentElement || document.documentElement;
- const editorTop = this.editor.offsetTop;
-
- scrollContainer.scrollTo({
- top: editorTop + targetPosition - 100, // -100 pour un padding
- behavior: 'smooth'
- });
- }
-
- // Nettoyer l'élément temporaire
- setTimeout(() => {
- if (tempElement.parentNode) {
- tempElement.parentNode.removeChild(tempElement);
- }
- }, 100);
-
- this.showNotification('Navigation vers la section', 'success');
- return;
- } catch (error) {
- console.log('Erreur de scroll:', error);
+ // Trouver l'index de la ligne correspondant au titre
+ let targetLineIndex = -1;
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i].trim();
+ if (line.startsWith('#') && line.replace(/^#+\s*/, '') === title) {
+ targetLineIndex = i;
+ break;
}
}
- }
- this.showNotification('Section non trouvée', 'warning');
+ if (targetLineIndex === -1) {
+ this.showNotification('Section non trouvée', 'warning');
+ return;
+ }
+
+ // Calculer la position approximative de la ligne
+ const editorStyles = window.getComputedStyle(this.editor);
+ const lineHeight = parseFloat(editorStyles.lineHeight) || 20;
+ const paddingTop = parseFloat(editorStyles.paddingTop) || 0;
+
+ // Calculer la position de scroll basée sur le numéro de ligne
+ const targetScrollPosition = (targetLineIndex * lineHeight) + paddingTop;
+
+ // Déterminer si l'éditeur ou la fenêtre doit être scrollée
+ const editorRect = this.editor.getBoundingClientRect();
+ const editorHasScroll = this.editor.scrollHeight > this.editor.clientHeight;
+
+ if (editorHasScroll) {
+ // Scroller dans l'éditeur
+ this.editor.scrollTo({
+ top: Math.max(0, targetScrollPosition - 60),
+ behavior: 'smooth'
+ });
+ } else {
+ // Scroller la page entière
+ const editorTop = this.editor.offsetTop;
+ const windowScrollTarget = editorTop + targetScrollPosition - 100;
+
+ window.scrollTo({
+ top: Math.max(0, windowScrollTarget),
+ behavior: 'smooth'
+ });
+ }
+
+ // Optionnel : mettre en surbrillance temporairement le titre
+ this.highlightHeading(title);
+
+ this.showNotification(`Navigation vers: ${title}`, 'success');
+
+ } catch (error) {
+ console.error('Erreur de scroll:', error);
+ this.showNotification('Erreur lors de la navigation', 'error');
+ }
+ }
+
+ highlightHeading(title) {
+ // Fonction pour mettre en surbrillance temporairement le titre trouvé
+ try {
+ const content = this.editor.innerText;
+ const lines = content.split('\n');
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i].trim();
+ if (line.startsWith('#') && line.replace(/^#+\s*/, '') === title) {
+ // Créer un range pour sélectionner la ligne
+ const selection = window.getSelection();
+ const range = document.createRange();
+
+ // Trouver le nœud texte et la position
+ const walker = document.createTreeWalker(
+ this.editor,
+ NodeFilter.SHOW_TEXT,
+ null,
+ false
+ );
+
+ let currentLine = 0;
+ let textNode = walker.nextNode();
+
+ while (textNode && currentLine < i) {
+ const nodeText = textNode.textContent;
+ const newLines = (nodeText.match(/\n/g) || []).length;
+ currentLine += newLines;
+
+ if (currentLine < i) {
+ textNode = walker.nextNode();
+ }
+ }
+
+ if (textNode) {
+ // Trouver le début de la ligne dans ce nœud
+ const nodeText = textNode.textContent;
+ const linesInNode = nodeText.split('\n');
+ const targetLineInNode = i - (currentLine - linesInNode.length + 1);
+
+ if (targetLineInNode >= 0 && targetLineInNode < linesInNode.length) {
+ let startPos = 0;
+ for (let j = 0; j < targetLineInNode; j++) {
+ startPos += linesInNode[j].length + 1;
+ }
+
+ const endPos = startPos + linesInNode[targetLineInNode].length;
+
+ range.setStart(textNode, startPos);
+ range.setEnd(textNode, endPos);
+
+ // Sélectionner temporairement
+ selection.removeAllRanges();
+ selection.addRange(range);
+
+ // Retirer la sélection après un court délai
+ setTimeout(() => {
+ selection.removeAllRanges();
+ }, 1000);
+ }
+ }
+ break;
+ }
+ }
+ } catch (error) {
+ // Ignorer les erreurs de surbrillance, ce n'est pas critique
+ console.log('Erreur surbrillance:', error);
+ }
}
exportMarkdown() {
@@ -529,9 +625,18 @@ class ConceptionAssistant {
const reader = new FileReader();
reader.onload = (e) => {
- this.editor.innerText = e.target.result;
+ const importedContent = e.target.result;
+ this.editor.innerText = importedContent;
this.generateTOC();
this.currentJournalId = null; // Nouveau journal
+
+ // Réinitialiser l'historique pour le fichier importé
+ this.undoStack = [importedContent];
+ this.redoStack = [];
+
+ // S'assurer que l'éditeur est en mode édition
+ this.ensureEditMode();
+
this.showNotification('Fichier Markdown importé', 'success');
};
reader.readAsText(file);
@@ -633,6 +738,9 @@ class ConceptionAssistant {
break;
case 'liberty':
+ // Sauvegarder l'état avant les modifications de l'IA
+ this.saveState(true);
+
const count = document.getElementById('liberty-repeat-count')?.value || 3;
// Mode liberté utilise toujours le document complet
result = await this.callAI('/api/ai/liberty-mode', { content: fullContent, iterations: count, focus: 'conception' });
@@ -641,7 +749,8 @@ class ConceptionAssistant {
if (result.finalContent) {
this.editor.innerText = result.finalContent;
this.generateTOC();
- this.saveState();
+ // Sauvegarder l'état après les modifications de l'IA
+ this.saveState(true);
}
let libertyHTML = `Mode Liberté Intelligent (${result.iterations} itérations)
`;
@@ -775,6 +884,9 @@ class ConceptionAssistant {
if (!this.lastRephraseData) return;
try {
+ // Sauvegarder l'état avant la reformulation pour permettre l'undo
+ this.saveState(true);
+
// Remplacer le texte dans l'éditeur
const range = this.lastRephraseData.selection.getRangeAt(0);
range.deleteContents();
@@ -784,6 +896,9 @@ class ConceptionAssistant {
window.getSelection().removeAllRanges();
this.generateTOC();
+ // Sauvegarder l'état après la reformulation
+ this.saveState(true);
+
// Afficher un message de succès
this.showNotification('Reformulation appliquée avec succès', 'success');
this.clearFeedback();
@@ -806,6 +921,31 @@ class ConceptionAssistant {
`;
}
+ ensureEditMode() {
+ // Si on est en mode preview, forcer le retour en mode édition
+ if (this.isPreviewMode) {
+ const previewBtn = document.getElementById('preview-toggle');
+
+ // Revenir en mode édition sans utiliser originalContent car on veut le nouveau contenu
+ this.editor.contentEditable = true;
+ this.editor.style.background = '';
+ this.editor.style.border = '';
+ this.editor.style.borderRadius = '';
+
+ // Changer le bouton
+ if (previewBtn) {
+ previewBtn.innerHTML = 'Visualiser';
+ previewBtn.classList.remove('secondary');
+ previewBtn.classList.add('primary');
+ }
+
+ this.isPreviewMode = false;
+ }
+
+ // S'assurer que l'éditeur est toujours éditable
+ this.editor.contentEditable = true;
+ }
+
showNotification(message, type = 'success') {
const notification = document.createElement('div');
notification.className = `notification ${type}`;
@@ -1059,6 +1199,13 @@ function initializeTemplateForm() {
app.generateTOC();
app.currentJournalId = null; // Nouveau journal
+ // Réinitialiser l'historique pour le nouveau template
+ app.undoStack = [result.data.content];
+ app.redoStack = [];
+
+ // S'assurer que l'éditeur est en mode édition
+ app.ensureEditMode();
+
app.showNotification(`Template ${domain}/${level} chargé avec succès`, 'success');
closeAllPanels();
} else {
diff --git a/views/page.js b/views/page.js
index a53ddf6..5cd8bb4 100644
--- a/views/page.js
+++ b/views/page.js
@@ -11,6 +11,7 @@ function getHead(){