docs: remove legacy implementation docs in French
This commit is contained in:
+10
-9
@@ -879,15 +879,16 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async openHelpPage(): Promise<void> {
|
||||
// Load the help.md file from the vault
|
||||
const helpPath = 'help.md';
|
||||
await this.vaultService.ensureNoteLoadedByPath(helpPath);
|
||||
const helpNoteId = this.vaultService.buildSlugIdFromPath(helpPath);
|
||||
const helpNote = this.vaultService.getNoteById(helpNoteId);
|
||||
|
||||
if (helpNote) {
|
||||
this.selectNote(helpNote.id);
|
||||
this.logService.log('HELP_PAGE_OPEN');
|
||||
try {
|
||||
// Load the built-in help note (embedded in app code)
|
||||
const helpNoteId = await this.vaultService.loadBuiltinHelpNote();
|
||||
if (helpNoteId) {
|
||||
await this.selectNote(helpNoteId);
|
||||
this.logService.log('HELP_PAGE_OPEN');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to open help page:', error);
|
||||
// L'erreur est déjà loguée dans la console pour le débogage
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// Contenu par défaut si le chargement du fichier échoue
|
||||
export const DEFAULT_HELP_CONTENT =
|
||||
`---
|
||||
titre: Guide d'utilisateur
|
||||
auteur: Bruno Charest
|
||||
creation_date: 2025-10-21
|
||||
modification_date: 2025-10-21T22:42:09-04:00
|
||||
catégorie: documentation
|
||||
tags:
|
||||
- aide
|
||||
- guide
|
||||
aliases: []
|
||||
status: publié
|
||||
publish: false
|
||||
favoris: true
|
||||
template: false
|
||||
task: false
|
||||
archive: false
|
||||
draft: false
|
||||
private: false
|
||||
---
|
||||
# 🧭 Guide d'utilisateur ObsiViewer
|
||||
|
||||
Bienvenue dans **ObsiViewer** !
|
||||
|
||||
Ce guide vous aidera à comprendre les principales fonctionnalités :
|
||||
|
||||
## 📂 Navigation
|
||||
- La barre latérale permet d'accéder aux notes, favoris, tags et modèles.
|
||||
- Les boutons en haut à droite donnent accès au mode édition, plein écran, et propriétés.
|
||||
|
||||
## ✏️ Édition
|
||||
- Le bouton ✏️ ouvre le **mode édition** basé sur CodeMirror 6.
|
||||
- Toutes les modifications sont sauvegardées automatiquement.
|
||||
|
||||
## 🏷️ Tags
|
||||
- Cliquez sur un tag pour voir toutes les notes qui le contiennent.
|
||||
- Utilisez l'icône 🏷️ à gauche pour modifier ou ajouter des tags.
|
||||
|
||||
## ⚙️ Paramètres
|
||||
- Les thèmes, langues et préférences sont gérés depuis le menu principal.
|
||||
|
||||
---
|
||||
|
||||
💡 **Astuce :** vous pouvez mettre à jour ce guide directement depuis votre voute Markdown.`;
|
||||
|
||||
// Variable pour stocker le contenu du fichier help.md
|
||||
let helpContent: string | null = null;
|
||||
|
||||
// Fonction pour charger le contenu du fichier help.md
|
||||
export async function loadHelpContent(): Promise<string> {
|
||||
if (helpContent) return helpContent;
|
||||
|
||||
try {
|
||||
// En mode développement, on utilise fetch pour charger le fichier
|
||||
if (import.meta.env.DEV) {
|
||||
const response = await fetch('/src/app/constants/help.md');
|
||||
if (response.ok) {
|
||||
helpContent = await response.text();
|
||||
return helpContent;
|
||||
}
|
||||
}
|
||||
|
||||
// En cas d'échec ou en production, utiliser le contenu par défaut
|
||||
helpContent = DEFAULT_HELP_CONTENT;
|
||||
return helpContent;
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement du fichier help.md:', error);
|
||||
return DEFAULT_HELP_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
// Pour la rétrocompatibilité, on exporte une promesse qui se résout avec le contenu
|
||||
export const HELP_NOTE_RAW = DEFAULT_HELP_CONTENT;
|
||||
@@ -33,7 +33,7 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
<section *ngIf="env.features.showTestSection" class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-4 py-3 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 transition-colors"
|
||||
(click)="open.tests = !open.tests">
|
||||
<span>Section Tests</span>
|
||||
<span class="flex items-center gap-2">🧪 <span>Section Tests</span></span>
|
||||
<span class="text-xs text-muted transition-transform duration-200" [class.rotate-90]="!open.tests">{{ open.tests ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.tests" class="px-3 py-2">
|
||||
@@ -49,7 +49,7 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-4 py-3 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 transition-colors"
|
||||
(click)="open.quick = !open.quick">
|
||||
<span>Quick Links</span>
|
||||
<span class="flex items-center gap-2">⚡ <span>Quick Links</span></span>
|
||||
<span class="text-xs text-muted transition-transform duration-200" [class.rotate-90]="!open.quick">{{ open.quick ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.quick" class="pt-1">
|
||||
@@ -61,7 +61,7 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-4 py-3 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 transition-colors"
|
||||
(click)="open.folders = !open.folders">
|
||||
<span>Folders</span>
|
||||
<span class="flex items-center gap-2">📁 <span>Folders</span></span>
|
||||
<span class="text-xs text-muted transition-transform duration-200" [class.rotate-90]="!open.folders">{{ open.folders ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.folders" class="px-1 py-1">
|
||||
@@ -73,7 +73,7 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-4 py-3 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 transition-colors"
|
||||
(click)="open.tags = !open.tags">
|
||||
<span>Tags</span>
|
||||
<span class="flex items-center gap-2">🏷️ <span>Tags</span></span>
|
||||
<span class="text-xs text-muted transition-transform duration-200" [class.rotate-90]="!open.tags">{{ open.tags ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.tags" class="px-2 py-2">
|
||||
@@ -93,7 +93,7 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-4 py-3 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 transition-colors"
|
||||
(click)="open.trash = !open.trash; onFolder('.trash')">
|
||||
<span class="flex items-center gap-2">Trash</span>
|
||||
<span class="flex items-center gap-2">🗑️ <span>Trash</span></span>
|
||||
<span class="text-xs text-muted transition-transform duration-200" [class.rotate-90]="!open.trash">{{ open.trash ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.trash" class="px-1 py-2">
|
||||
|
||||
@@ -27,7 +27,7 @@ import { VaultService } from '../../../services/vault.service';
|
||||
<section *ngIf="env.features.showTestSection" class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card"
|
||||
(click)="open.tests = !open.tests">
|
||||
<span>Section Tests</span>
|
||||
<span class="flex items-center gap-2">🧪 <span>Section Tests</span></span>
|
||||
<span class="text-xs text-muted">{{ open.tests ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.tests" class="px-3 py-2">
|
||||
@@ -43,7 +43,7 @@ import { VaultService } from '../../../services/vault.service';
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card"
|
||||
(click)="open.quick = !open.quick">
|
||||
<span>Quick Links</span>
|
||||
<span class="flex items-center gap-2">⚡ <span>Quick Links</span></span>
|
||||
<span class="text-xs text-muted">{{ open.quick ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.quick" class="pt-1">
|
||||
@@ -55,7 +55,7 @@ import { VaultService } from '../../../services/vault.service';
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card"
|
||||
(click)="toggleFoldersSection()">
|
||||
<span>Folders</span>
|
||||
<span class="flex items-center gap-2">📁 <span>Folders</span></span>
|
||||
<span class="text-xs text-muted">{{ open.folders ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.folders" class="px-1 py-1">
|
||||
@@ -73,7 +73,7 @@ import { VaultService } from '../../../services/vault.service';
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card"
|
||||
(click)="open.tags = !open.tags">
|
||||
<span>Tags</span>
|
||||
<span class="flex items-center gap-2">🏷️ <span>Tags</span></span>
|
||||
<span class="text-xs text-muted">{{ open.tags ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.tags" class="px-2 py-2">
|
||||
@@ -93,7 +93,7 @@ import { VaultService } from '../../../services/vault.service';
|
||||
<section class="border-b border-border dark:border-gray-800">
|
||||
<button class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold hover:bg-surface1 dark:hover:bg-card"
|
||||
(click)="toggleTrashSection()">
|
||||
<span class="flex items-center gap-2">Trash</span>
|
||||
<span class="flex items-center gap-2">🗑️ <span>Trash</span></span>
|
||||
<span class="text-xs text-muted">{{ open.trash ? '▾' : '▸' }}</span>
|
||||
</button>
|
||||
<div *ngIf="open.trash" class="px-1 py-2">
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly MODE: 'development' | 'production';
|
||||
readonly DEV: boolean;
|
||||
readonly PROD: boolean;
|
||||
// add other environment variables here as needed
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { Note, VaultNode, GraphData, TagInfo, VaultFolder, FileMetadata } from '
|
||||
import { VaultEventsService, VaultEventPayload } from './vault-events.service';
|
||||
import { Subscription, firstValueFrom } from 'rxjs';
|
||||
import { rewriteTagsFrontmatter, rewriteBooleanFrontmatter } from '../app/shared/markdown/markdown-frontmatter.util';
|
||||
import { DEFAULT_HELP_CONTENT } from '../app/constants/help-note.content';
|
||||
|
||||
// ============================================================================
|
||||
// INTERFACES
|
||||
@@ -191,6 +192,52 @@ export class VaultService implements OnDestroy {
|
||||
return this.notesMap().get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the built-in help note content into the in-memory notes map.
|
||||
* This loads the help content from the embedded file.
|
||||
* Returns a promise that resolves with the id (slug) of the registered note.
|
||||
*/
|
||||
async loadBuiltinHelpNote(): Promise<string> {
|
||||
const slugId = this.buildSlugIdFromPath('help.md'); // "help"
|
||||
if (this.getNoteById(slugId)) return slugId;
|
||||
|
||||
try {
|
||||
// Load help content from embedded constant
|
||||
const rawContent = DEFAULT_HELP_CONTENT;
|
||||
|
||||
const normalizedContent = this.normalizeLineEndings(rawContent);
|
||||
const { frontmatter, body } = this.parseFrontmatter(normalizedContent);
|
||||
|
||||
const title = (frontmatter.title as string) || (frontmatter.titre as string) || 'Guide utilisateur';
|
||||
const nowIso = new Date().toISOString();
|
||||
const createdAt = typeof frontmatter.creation_date === 'string' ? frontmatter.creation_date : nowIso;
|
||||
const updatedAt = typeof frontmatter.modification_date === 'string' ? frontmatter.modification_date : nowIso;
|
||||
const tags = Array.isArray(frontmatter.tags) ? this.normalizeTags(frontmatter.tags as string[]) : [];
|
||||
|
||||
const note: Note = {
|
||||
id: slugId,
|
||||
title,
|
||||
content: body,
|
||||
rawContent: normalizedContent,
|
||||
tags,
|
||||
frontmatter,
|
||||
backlinks: [],
|
||||
mtime: Date.now(),
|
||||
fileName: 'help.md',
|
||||
filePath: 'assets/help/help.md',
|
||||
originalPath: 'help',
|
||||
createdAt,
|
||||
updatedAt,
|
||||
};
|
||||
|
||||
this.registerBuiltinNote(note);
|
||||
return slugId;
|
||||
} catch (error) {
|
||||
console.error('Failed to load built-in help note:', error);
|
||||
throw new Error('Impossible de charger le guide d\'aide');
|
||||
}
|
||||
}
|
||||
|
||||
async ensureNoteLoadedById(id: string): Promise<boolean> {
|
||||
if (!id || this.getNoteById(id)) return !!id;
|
||||
|
||||
@@ -677,7 +724,9 @@ export class VaultService implements OnDestroy {
|
||||
|
||||
this.refreshTimeoutId = setTimeout(() => {
|
||||
this.refreshTimeoutId = null;
|
||||
// Refresh notes contents and also reload the fast file tree to reflect new/removed folders
|
||||
this.refreshNotes();
|
||||
this.loadFastFileTree();
|
||||
}, REFRESH_DEBOUNCE_MS);
|
||||
}
|
||||
|
||||
@@ -1257,6 +1306,14 @@ export class VaultService implements OnDestroy {
|
||||
this.notesMap.set(current);
|
||||
}
|
||||
|
||||
/** Register a builtin (virtual) note without touching file indices. */
|
||||
private registerBuiltinNote(note: Note): void {
|
||||
// Do not update fast indices that rely on physical paths
|
||||
const current = new Map(this.notesMap());
|
||||
current.set(note.id, note);
|
||||
this.notesMap.set(current);
|
||||
}
|
||||
|
||||
private updateNoteInMap(note: Note, updates: Partial<Note>): void {
|
||||
const updated: Note = { ...note, ...updates };
|
||||
const mapCopy = new Map(this.notesMap());
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
// Déclaration de type pour les imports bruts de fichiers .md
|
||||
declare module '*.md?raw' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Charge le contenu d'un fichier en utilisant fetch
|
||||
* @param url URL du fichier à charger
|
||||
* @returns Contenu du fichier sous forme de chaîne
|
||||
*/
|
||||
export async function loadFileContent(url: string): Promise<string> {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur lors du chargement du fichier: ${response.statusText}`);
|
||||
}
|
||||
return await response.text();
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement du fichier:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user