docs: remove legacy implementation docs in French

This commit is contained in:
Bruno Charest 2025-10-22 14:56:44 -04:00
parent 698bfef3d8
commit 397f1b4b80
28 changed files with 275 additions and 79 deletions

View File

@ -10,6 +10,12 @@ ObsiViewer est une application web **Angular 20** moderne et performante qui per
- 📱 Accès mobile optimisé à votre base de connaissances
- 🔍 Exploration visuelle des liens entre vos notes
- 📊 Analyse du vault via graphe et statistiques
- 🎨 Thèmes personnalisables
- 📚 Support des notes Excalidraw
- 📝 Support des notes Markdown
- 📝 Mode Lecture et Édition
- 📝 Mode Dark et Light
- 📝 Mode Mobile et Desktop
> 📝 Mode démo par défaut : l'interface fonctionne avec des données générées par `VaultService`. Connectez-la à vos fichiers Markdown réels via le serveur Express pour une utilisation complète.

8
package-lock.json generated
View File

@ -86,7 +86,7 @@
"@tailwindcss/typography": "^0.5.15",
"@types/jasmine": "^5.1.9",
"@types/jest": "^30.0.0",
"@types/node": "^22.14.0",
"@types/node": "^22.18.12",
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"autocannon": "^7.15.0",
@ -6963,9 +6963,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.18.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.8.tgz",
"integrity": "sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==",
"version": "22.18.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz",
"integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==",
"devOptional": true,
"license": "MIT",
"dependencies": {

View File

@ -103,7 +103,7 @@
"@tailwindcss/typography": "^0.5.15",
"@types/jasmine": "^5.1.9",
"@types/jest": "^30.0.0",
"@types/node": "^22.14.0",
"@types/node": "^22.18.12",
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"autocannon": "^7.15.0",

View File

@ -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
}
}

View File

@ -1,4 +1,6 @@
---
// 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
@ -10,7 +12,7 @@ tags:
aliases: []
status: publié
publish: false
favoris: false
favoris: true
template: false
task: false
archive: false
@ -40,4 +42,33 @@ Ce guide vous aidera à comprendre les principales fonctionnalités :
---
💡 **Astuce :** vous pouvez mettre à jour ce guide directement depuis votre voute Markdown.
💡 **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;

View File

@ -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">

View File

@ -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">

12
src/env.d.ts vendored Normal file
View File

@ -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;
}

View File

@ -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());

5
src/types/custom.d.ts vendored Normal file
View File

@ -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;
}

17
src/utils/file-utils.ts Normal file
View File

@ -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;
}
}

View File

@ -5,9 +5,8 @@ creation_date: 2025-10-19T11:13:12-04:00
modification_date: 2025-10-19T12:09:46-04:00
catégorie: ""
tags:
- bruno
- configuration
- test
- tag3
aliases: []
status: en-cours
publish: true

View File

@ -4,10 +4,6 @@ auteur: Bruno Charest
creation_date: 2025-10-19T11:13:12-04:00
modification_date: 2025-10-19T12:09:46-04:00
catégorie: ""
tags:
- configuration
- test
- tag3
aliases: []
status: en-cours
publish: true
@ -17,6 +13,9 @@ task: true
archive: false
draft: false
private: false
tags:
- bruno
- configuration
---
# Archived Note

View File

@ -9,10 +9,13 @@ tags:
- accueil
- configuration
- test
- tag4
- tag3
- tag1
aliases: []
status: en-cours
publish: false
favoris: false
publish: true
favoris: true
template: false
task: false
archive: false
@ -23,9 +26,11 @@ NomDeVoute: IT
Description: Page d'accueil de la voute IT
attachements-path: attachements/
---
Page principal - IT
Page principal - Voute de test
[[Voute_IT.png]]
Ceci est la voute Obsidian de test. Elle permet de tester l'application ObsiViewer.
[[test]]
[[test2]]

View File

@ -1,17 +1,36 @@
---
Titre: Page d'accueil
NomDeVoute: IT
Description: Page d'accueil de la voute IT
titre: HOME
auteur: Bruno Charest
creation_date: 2025-09-26T08:20:57-04:00
modification_date: 2025-10-19T12:09:47-04:00
catégorie: ""
tags:
- home
- accueil
- configuration
- test
- tag4
- tag3
- tag1
aliases: []
status: en-cours
publish: false
favoris: true
template: false
task: false
archive: false
draft: false
private: false
Titre: Page d'accueil
NomDeVoute: IT
Description: Page d'accueil de la voute IT
attachements-path: attachements/
---
Page principal - IT
Page principal - Voute de test
[[Voute_IT.png]]
Ceci est la voute Obsidian de test. Elle permet de tester l'application ObsiViewer.
[[test]]
[[test2]]

View File

@ -9,13 +9,14 @@ tags:
aliases:
- nouveau
status: en-cours
publish: true
publish: false
favoris: true
template: true
task: true
archive: true
draft: true
private: true
toto: tata
---
Allo ceci est un tests
toto

View File

@ -10,12 +10,13 @@ aliases:
- nouveau
status: en-cours
publish: true
favoris: false
favoris: true
template: true
task: true
archive: true
draft: true
private: true
toto: tata
---
Allo ceci est un tests
toto

17
vault/folder-4/test.md Normal file
View File

@ -0,0 +1,17 @@
---
titre: test
auteur: Bruno Charest
creation_date: 2025-10-22T13:07:03-04:00
modification_date: 2025-10-22T13:07:04-04:00
catégorie: ""
tags: []
aliases: []
status: en-cours
publish: false
favoris: false
template: false
task: false
archive: false
draft: false
private: false
---

View File

17
vault/folder-4/test2.md Normal file
View File

@ -0,0 +1,17 @@
---
titre: test2
auteur: Bruno Charest
creation_date: 2025-10-22T13:07:29-04:00
modification_date: 2025-10-22T13:07:29-04:00
catégorie: ""
tags: []
aliases: []
status: en-cours
publish: false
favoris: false
template: false
task: false
archive: false
draft: false
private: false
---

View File

22
vault/folder-5/file-5.md Normal file
View File

@ -0,0 +1,22 @@
---
titre: file-5
auteur: Bruno Charest
creation_date: 2025-10-22T13:26:59-04:00
modification_date: 2025-10-22T13:26:59-04:00
catégorie: ""
tags:
- configuration
- tag2
- bruno
- test2
- tag3
aliases: []
status: en-cours
publish: false
favoris: false
template: false
task: false
archive: false
draft: false
private: false
---

View File

@ -0,0 +1,22 @@
---
titre: file-5
auteur: Bruno Charest
creation_date: 2025-10-22T13:26:59-04:00
modification_date: 2025-10-22T13:26:59-04:00
catégorie: ""
aliases: []
status: en-cours
publish: false
favoris: false
template: false
task: false
archive: false
draft: false
private: false
tags:
- configuration
- tag2
- bruno
- test2
- tag3
---

View File

@ -1,36 +0,0 @@
---
titre: Guide d'utilisateur
auteur: Bruno Charest
creation_date: 2025-10-21
modification_date: 2025-10-21
catégorie: documentation
tags:
- aide
- guide
status: publié
---
# 🧭 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.

View File

@ -35,4 +35,5 @@ export default defineConfig(({ mode }) => ({
ssr: {
noExternal: ['@excalidraw/excalidraw'],
},
}));
})
);