diff --git a/README.md b/README.md index f0e61d3..c01b0b1 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,38 @@ ObsiViewer est une application web **Angular 20** moderne et performante qui per - **Keyboard shortcuts** : Raccourcis clavier (Alt+R, Alt+D) - **Animations fluides** : 60fps avec optimisations performance +--- + +## 🧭 Migration UI — Tags (nouveau gestionnaire) + +Depuis cette version, la gestion des tags a été refondue pour une UX claire et performante. + +- **Lecture**: un bouton icône Tag situé à gauche des chips ouvre/ferme l'éditeur. Cliquer un chip applique un filtre sur `NotesList`. +- **Édition**: l'éditeur est un overlay moderne avec dé-dupe forte, suggestions et raccourcis (Enter/Tab/Backspace). Aucune fermeture par clic extérieur ou touche ESC. + +### Intégration +- Composant lecture/commande: `src/app/shared/tags/tag-manager/tag-manager.component.ts` +- Overlay édition: `src/app/shared/tags/tag-editor-overlay/` +- Store de filtre: `src/app/core/stores/tag-filter.store.ts` +- Utilitaires: `src/app/shared/tags/tag-utils.ts` + +### API composants +- `TagManagerComponent` + - `@Input() tags: string[]` + - `@Input() noteId: string` + - `@Output() tagSelected(tag: string)` (lecture) + - `@Output() editingChanged(isEditing: boolean)` + - `@Output() saved(tags: string[])` (après Enregistrer) + +### Comportements clés +- L’édition ne se déclenche QUE via l’icône Tag. +- En lecture, cliquer un chip: met à jour `TagFilterStore` et filtre la liste des notes. Un badge “Filtre: #tag” apparaît avec action “Effacer le filtre”. +- Sauvegarde des tags via `VaultService.updateNoteTags(noteId, tags)` qui réécrit proprement le frontmatter `tags:`. + +### Tests +- `tag-utils.spec.ts` couvre `normalizeTag` et `uniqueTags`. +- `tag-manager.component.spec.ts` vérifie l’émission de `tagSelected`. + ### ✏️ Dessins Excalidraw - **Éditeur intégré** : Ouvrez et modifiez des fichiers `.excalidraw` directement dans l'app - **Création rapide** : Bouton "Nouveau dessin" dans l'en-tête (icône +) diff --git a/src/app/core/stores/tag-filter.store.ts b/src/app/core/stores/tag-filter.store.ts new file mode 100644 index 0000000..68e87b8 --- /dev/null +++ b/src/app/core/stores/tag-filter.store.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; + +@Injectable({ providedIn: 'root' }) +export class TagFilterStore { + private _tag = new BehaviorSubject(null); + readonly selectedTag$: Observable = this._tag.asObservable(); + + set(tag: string | null): void { + this._tag.next(tag); + } + + get(): string | null { + return this._tag.getValue(); + } +} diff --git a/src/app/features/list/notes-list.component.ts b/src/app/features/list/notes-list.component.ts index 06c5df6..349dd80 100644 --- a/src/app/features/list/notes-list.component.ts +++ b/src/app/features/list/notes-list.component.ts @@ -1,8 +1,9 @@ -import { Component, EventEmitter, Output, computed, signal, effect } from '@angular/core'; +import { Component, EventEmitter, Output, computed, signal, effect, inject } from '@angular/core'; import { input } from '@angular/core'; import { CommonModule } from '@angular/common'; import type { Note } from '../../../types'; import { ScrollableOverlayDirective } from '../../shared/overlay-scrollbar/scrollable-overlay.directive'; +import { TagFilterStore } from '../../core/stores/tag-filter.store'; @Component({ selector: 'app-notes-list', @@ -10,7 +11,16 @@ import { ScrollableOverlayDirective } from '../../shared/overlay-scrollbar/scrol imports: [CommonModule, ScrollableOverlayDirective], template: `
-
+
+
+ + + Filtre: #{{ t }} + + +
(); @Output() queryChange = new EventEmitter(); + private store = inject(TagFilterStore); private q = signal(''); + activeTag = signal(null); private syncQuery = effect(() => { this.q.set(this.query() || ''); }); + private syncTagFromStore = effect(() => { + // Prefer explicit input; otherwise, take store value + const inputTag = this.tagFilter(); + if (inputTag !== null && inputTag !== undefined) { + this.activeTag.set(inputTag || null); + return; + } + this.activeTag.set(this.store.get()); + }); filtered = computed(() => { const q = (this.q() || '').toLowerCase().trim(); const folder = (this.folderFilter() || '').toLowerCase().replace(/^\/+|\/+$/g, ''); - const tag = (this.tagFilter() || '').toLowerCase(); + const tag = (this.activeTag() || '').toLowerCase(); const quickLink = this.quickLinkFilter(); let list = this.notes(); @@ -113,4 +134,12 @@ export class NotesListComponent { this.q.set(v); this.queryChange.emit(v); } + + clearTagFilter(): void { + // Clear both local input state and store + this.activeTag.set(null); + if (this.tagFilter() == null) { + this.store.set(null); + } + } } diff --git a/src/app/features/note/components/note-header/note-header.component.html b/src/app/features/note/components/note-header/note-header.component.html index d59fcdb..ea4967c 100644 --- a/src/app/features/note/components/note-header/note-header.component.html +++ b/src/app/features/note/components/note-header/note-header.component.html @@ -19,9 +19,9 @@
- + (saved)="tagsChange.emit($event)" + > diff --git a/src/app/features/note/components/note-header/note-header.component.ts b/src/app/features/note/components/note-header/note-header.component.ts index 8a06e68..b48c94d 100644 --- a/src/app/features/note/components/note-header/note-header.component.ts +++ b/src/app/features/note/components/note-header/note-header.component.ts @@ -2,12 +2,12 @@ import { AfterViewInit, Component, ElementRef, Input, OnDestroy, Output, EventEm import { CommonModule } from '@angular/common'; import { debounceTime, Subject } from 'rxjs'; import { splitPathKeepFilename } from '../../../../shared/utils/path'; -import { TagsEditorComponent } from '../../../../shared/tags-editor/tags-editor.component'; +import { TagManagerComponent } from '../../../../shared/tags/tag-manager/tag-manager.component'; @Component({ selector: 'app-note-header', standalone: true, - imports: [CommonModule, TagsEditorComponent], + imports: [CommonModule, TagManagerComponent], templateUrl: './note-header.component.html', styleUrls: ['./note-header.component.scss'] }) diff --git a/src/app/layout/app-shell-nimbus/app-shell-nimbus.component.ts b/src/app/layout/app-shell-nimbus/app-shell-nimbus.component.ts index 45ab09d..e05191d 100644 --- a/src/app/layout/app-shell-nimbus/app-shell-nimbus.component.ts +++ b/src/app/layout/app-shell-nimbus/app-shell-nimbus.component.ts @@ -32,7 +32,7 @@ import { MarkdownPlaygroundComponent } from '../../features/tests/markdown-playg [noteHtmlContent]="renderedNoteContent" [allNotes]="vault.allNotes()" (noteLinkClicked)="noteSelected.emit($event)" - (tagClicked)="tagClicked.emit($event)" + (tagClicked)="onTagSelected($event)" (wikiLinkActivated)="wikiLinkActivated.emit($event)" [fullScreenActive]="noteFullScreen" (fullScreenRequested)="toggleNoteFullScreen()" @@ -127,7 +127,7 @@ import { MarkdownPlaygroundComponent } from '../../features/tests/markdown-playg [noteHtmlContent]="renderedNoteContent" [allNotes]="vault.allNotes()" (noteLinkClicked)="noteSelected.emit($event)" - (tagClicked)="tagClicked.emit($event)" + (tagClicked)="onTagSelected($event)" (wikiLinkActivated)="wikiLinkActivated.emit($event)" [fullScreenActive]="noteFullScreen" (fullScreenRequested)="toggleNoteFullScreen()" @@ -165,7 +165,7 @@ import { MarkdownPlaygroundComponent } from '../../features/tests/markdown-playg
- +
@@ -398,10 +398,20 @@ export class AppShellNimbusLayoutComponent { } onTagSelected(tagName: string) { - const norm = (tagName || '').replace(/^#/, '').trim(); + const norm = (tagName || '').replace(/^#/, '').trim().toLowerCase(); if (!norm) return; this.tagFilter = norm; this.folderFilter = null; // clear folder when focusing tag + // Clear other filters and search to focus on tag results + this.quickLinkFilter = null; + this.listQuery = ''; + // Ensure the list is visible: exit fullscreen if active + if (this.noteFullScreen) { + this.noteFullScreen = false; + document.body.classList.remove('note-fullscreen-active'); + } + // Bubble up for global handlers (keeps parity with right sidebar tags) + this.tagClicked.emit(norm); if (!this.responsive.isDesktop()) { this.mobileNav.setActiveTab('list'); } diff --git a/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.css b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.css new file mode 100644 index 0000000..c56faa1 --- /dev/null +++ b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.css @@ -0,0 +1,2 @@ +/* Overlay styling relies on Tailwind utilities in the template. Keep minimal spacing fixes here if needed. */ +:host { display: contents; } diff --git a/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.html b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.html new file mode 100644 index 0000000..7f643fa --- /dev/null +++ b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.html @@ -0,0 +1,50 @@ +
+
+
+
+
+ +

Éditer les tags

+ ({{ count() }}) +
+ +
+ +
+
+ @for (t of working(); track t) { + + {{ t }} + + + } + +
+ +
+
+ @if (suggestions().length === 0) { +
Aucune suggestion
+ } @else { +
    + @for (s of suggestions(); track s) { +
  • + +
  • + } +
+ } +
+
+ +
+ + +
+
+
+
diff --git a/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts new file mode 100644 index 0000000..9de88f7 --- /dev/null +++ b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts @@ -0,0 +1,114 @@ +import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, inject, signal, computed } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { uniqueTags, normalizeTag } from '../tag-utils'; +import { VaultService } from '../../../../services/vault.service'; +import { ToastService } from '../../toast/toast.service'; + +@Component({ + selector: 'app-tag-editor-overlay', + standalone: true, + imports: [CommonModule], + templateUrl: './tag-editor-overlay.component.html', + styleUrls: ['./tag-editor-overlay.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TagEditorOverlayComponent { + private vault = inject(VaultService); + private toast = inject(ToastService); + + @Input() value: string[] = []; + @Input() allTags: string[] = []; + @Input() noteId = ''; + + @Output() saved = new EventEmitter(); + @Output() close = new EventEmitter(); + + inputValue = signal(''); + saving = signal(false); + working = signal([]); + count = computed(() => this.working().length); + + ngOnInit() { + this.working.set(uniqueTags(this.value || [])); + } + + private allKnownTags = computed(() => { + const provided = this.allTags || []; + if (provided.length > 0) return provided; + try { + return this.vault.tags().map(t => t.name); + } catch { + return []; + } + }); + + suggestions = computed(() => { + const q = this.inputValue().trim().toLowerCase(); + const source = this.allKnownTags(); + const pool = q ? source.filter(t => t.toLowerCase().includes(q)) : source; + const exist = new Set(this.working().map(t => t.toLowerCase())); + return pool.filter(t => !exist.has(t.toLowerCase())).slice(0, 50); + }); + + onKeydown(ev: KeyboardEvent) { + if (ev.key === 'Enter') { + ev.preventDefault(); + this.addFromInput(); + } else if (ev.key === 'Tab') { + const s = this.suggestions(); + if (s.length) { + ev.preventDefault(); + this.addTag(s[0]); + } + } else if (ev.key === 'Backspace' && !this.inputValue()) { + ev.preventDefault(); + const cur = this.working(); + if (cur.length) this.removeTag(cur[cur.length - 1]); + } + } + + addFromInput() { + const raw = this.inputValue().trim(); + if (!raw) return; + this.addTag(raw); + } + + addTag(raw: string) { + const t = normalizeTag(raw); + if (!t) return; + if (this.working().some(x => x.toLowerCase() === t.toLowerCase())) return; + this.working.update(arr => [...arr, t]); + this.inputValue.set(''); + } + + pickSuggestion(s: string) { + this.addTag(s); + } + + removeTag(tag: string) { + this.working.update(arr => arr.filter(t => t.toLowerCase() !== tag.toLowerCase())); + } + + async save() { + const tags = uniqueTags(this.working()); + if (!this.noteId) { + this.saved.emit(tags); + this.close.emit(); + return; + } + this.saving.set(true); + try { + const ok = await this.vault.updateNoteTags(this.noteId, tags); + if (ok) { + this.toast.success('✅ Tags mis à jour'); + this.saved.emit(tags); + } else { + this.toast.error('❌ Échec de la mise à jour des tags'); + } + } catch { + this.toast.error('❌ Échec de la mise à jour des tags'); + } finally { + this.saving.set(false); + } + } +} diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.css b/src/app/shared/tags/tag-manager/tag-manager.component.css new file mode 100644 index 0000000..920ea98 --- /dev/null +++ b/src/app/shared/tags/tag-manager/tag-manager.component.css @@ -0,0 +1 @@ +/* Styles are provided via Tailwind utility classes directly in templates. */ diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.html b/src/app/shared/tags/tag-manager/tag-manager.component.html new file mode 100644 index 0000000..de1bca4 --- /dev/null +++ b/src/app/shared/tags/tag-manager/tag-manager.component.html @@ -0,0 +1,31 @@ +
+ + +
+ +
+
+ + diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.spec.ts b/src/app/shared/tags/tag-manager/tag-manager.component.spec.ts new file mode 100644 index 0000000..78a15e3 --- /dev/null +++ b/src/app/shared/tags/tag-manager/tag-manager.component.spec.ts @@ -0,0 +1,37 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TagManagerComponent } from './tag-manager.component'; + +describe('TagManagerComponent', () => { + let component: TagManagerComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TagManagerComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(TagManagerComponent); + component = fixture.componentInstance; + component.tags = ['tag1', 'tag2']; + fixture.detectChanges(); + }); + + it('emits tagSelected when chip clicked in read mode', () => { + const spy = jasmine.createSpy('tagSelected'); + component.tagSelected.subscribe(spy); + + component.onChipClick('tag1'); + + expect(spy).toHaveBeenCalledWith('tag1'); + }); + + it('does not emit when editing', () => { + const spy = jasmine.createSpy('tagSelected'); + component.tagSelected.subscribe(spy); + component.toggleEditor(); + + component.onChipClick('tag1'); + + expect(spy).not.toHaveBeenCalled(); + }); +}); diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.ts b/src/app/shared/tags/tag-manager/tag-manager.component.ts new file mode 100644 index 0000000..ddcf996 --- /dev/null +++ b/src/app/shared/tags/tag-manager/tag-manager.component.ts @@ -0,0 +1,59 @@ +import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, inject, signal, computed } from '@angular/core'; +import { CommonModule, NgFor, NgIf } from '@angular/common'; +import { TagEditorOverlayComponent } from '../tag-editor-overlay/tag-editor-overlay.component'; +import { TagFilterStore } from '../../../core/stores/tag-filter.store'; +import { uniqueTags } from '../tag-utils'; + +@Component({ + selector: 'app-tag-manager', + standalone: true, + imports: [CommonModule, NgFor, NgIf, TagEditorOverlayComponent], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './tag-manager.component.html', + styleUrls: ['./tag-manager.component.css'] +}) +export class TagManagerComponent { + private store = inject(TagFilterStore); + + private readonly tagsSignal = signal([]); + @Input() set tags(value: string[] | null | undefined) { + this.tagsSignal.set(value ? [...value] : []); + } + get tags(): string[] { + return this.tagsSignal(); + } + @Input() allTags: string[] | null = null; // optional preloaded + @Input() noteId = ''; + + @Output() tagSelected = new EventEmitter(); + @Output() editingChanged = new EventEmitter(); + @Output() saved = new EventEmitter(); + + isEditing = signal(false); + readonly normalizedTags = computed(() => uniqueTags(this.tagsSignal())); + + toggleEditor(): void { + const next = !this.isEditing(); + this.isEditing.set(next); + this.editingChanged.emit(next); + } + + onChipClick(tag: string): void { + if (this.isEditing()) return; // read-mode only + this.store.set(tag); + this.tagSelected.emit(tag); + } + + onClose(): void { + if (!this.isEditing()) return; + this.isEditing.set(false); + this.editingChanged.emit(false); + } + + onSaved(next: string[]): void { + this.saved.emit(next); + this.tagsSignal.set(next); + this.isEditing.set(false); + this.editingChanged.emit(false); + } +} diff --git a/src/app/shared/tags/tag-utils.spec.ts b/src/app/shared/tags/tag-utils.spec.ts new file mode 100644 index 0000000..51aeb4c --- /dev/null +++ b/src/app/shared/tags/tag-utils.spec.ts @@ -0,0 +1,13 @@ +import { uniqueTags, normalizeTag } from './tag-utils'; + +describe('tag-utils', () => { + it('normalizeTag trims, replaces spaces with underscore, strips invalids, lowercases', () => { + expect(normalizeTag(' Hello World ')).toBe('hello_world'); + expect(normalizeTag('A/B C')).toBe('ab_c'); + expect(normalizeTag('Déjà Vu!')).toBe('dj_vu'); + }); + + it('uniqueTags removes duplicates case-insensitive and empties', () => { + expect(uniqueTags(['Tag', 'tag', ' other ', 'OTHER', '', ' '])).toEqual(['tag', 'other']); + }); +}); diff --git a/src/app/shared/tags/tag-utils.ts b/src/app/shared/tags/tag-utils.ts new file mode 100644 index 0000000..e69b125 --- /dev/null +++ b/src/app/shared/tags/tag-utils.ts @@ -0,0 +1,19 @@ +export const normalizeTag = (s: string) => + (s ?? '') + .trim() + .replace(/\s+/g, '_') + .replace(/[^\w-]/g, '') + .toLowerCase(); + +export const uniqueTags = (arr: string[]) => { + const seen = new Set(); + const out: string[] = []; + for (const raw of arr ?? []) { + const t = normalizeTag(String(raw ?? '')); + if (t && !seen.has(t)) { + seen.add(t); + out.push(t); + } + } + return out; +}; diff --git a/src/app/shared/ui/badge-count.component.ts b/src/app/shared/ui/badge-count.component.ts index c8aadfe..f7b5dd4 100644 --- a/src/app/shared/ui/badge-count.component.ts +++ b/src/app/shared/ui/badge-count.component.ts @@ -17,17 +17,19 @@ import { CommonModule } from '@angular/common'; }) export class BadgeCountComponent { @Input() count = 0; - @Input() color: 'slate'|'rose'|'amber'|'indigo'|'emerald'|'stone'|'zinc' = 'slate'; + @Input() color: 'slate'|'rose'|'amber'|'indigo'|'emerald'|'stone'|'zinc'|'green'|'purple' = 'slate'; get bgClass() { return { 'bg-slate-600': this.color === 'slate', 'bg-rose-600': this.color === 'rose', - 'bg-amber-600': this.color === 'amber', + 'bg-sky-400': this.color === 'amber', 'bg-indigo-600': this.color === 'indigo', 'bg-emerald-600': this.color === 'emerald', 'bg-stone-600': this.color === 'stone', 'bg-zinc-700': this.color === 'zinc', + 'bg-green-500': this.color === 'green', + 'bg-purple-500': this.color === 'purple', }; } } diff --git a/vault/.trash/old-folder/old-note-2.md b/vault/.trash/old-folder/old-note-2.md index 0c750be..a5b0737 100644 --- a/vault/.trash/old-folder/old-note-2.md +++ b/vault/.trash/old-folder/old-note-2.md @@ -4,7 +4,10 @@ auteur: Bruno Charest creation_date: 2025-10-19T11:13:12-04:00 modification_date: 2025-10-19T12:09:46-04:00 catégorie: "" -tags: [] +tags: + - configuration + - bruno + - markdown aliases: [] status: en-cours publish: false diff --git a/vault/.trash/old-folder/old-note-2.md.bak b/vault/.trash/old-folder/old-note-2.md.bak index b097945..ad0662c 100644 --- a/vault/.trash/old-folder/old-note-2.md.bak +++ b/vault/.trash/old-folder/old-note-2.md.bak @@ -1,3 +1,23 @@ +--- +titre: old-note-2 +auteur: Bruno Charest +creation_date: 2025-10-19T11:13:12-04:00 +modification_date: 2025-10-19T12:09:46-04:00 +catégorie: "" +aliases: [] +status: en-cours +publish: false +favoris: false +template: false +task: false +archive: false +draft: false +private: false +tags: + - configuration + - bruno + - markdown +--- # Old Note 2 This note is in a subfolder of trash. diff --git a/vault/Nouveau-markdown.md b/vault/Nouveau-markdown.md index 0beaa78..4859c11 100644 --- a/vault/Nouveau-markdown.md +++ b/vault/Nouveau-markdown.md @@ -3,9 +3,13 @@ titre: Nouveau-markdown auteur: Bruno Charest creation_date: 2025-10-19T21:42:53-04:00 modification_date: 2025-10-19T21:43:06-04:00 -catégorie: "" -tags: [] -aliases: [] +catégorie: markdown +tags: + - test + - Bruno + - markdown +aliases: + - nouveau status: en-cours publish: true favoris: true @@ -15,3 +19,25 @@ archive: true draft: true private: true --- +# Nouveau-markdown + +#tag1 #tag2 #tag3 + +## sous-titre + +## sous-titre 2 + +## sous-titre 3 + +## sous-titre 4 + +## sous-titre 5 + +## sous-titre 6 + +## sous-titre 7 + +## sous-titre 8 + + + diff --git a/vault/Nouveau-markdown.md.bak b/vault/Nouveau-markdown.md.bak index e69de29..8339f19 100644 --- a/vault/Nouveau-markdown.md.bak +++ b/vault/Nouveau-markdown.md.bak @@ -0,0 +1,28 @@ +--- +titre: Nouveau-markdown +auteur: Bruno Charest +creation_date: 2025-10-19T21:42:53-04:00 +modification_date: 2025-10-19T21:43:06-04:00 +catégorie: markdown +tags: + - test + - Bruno + - markdown +aliases: + - nouveau +status: en-cours +publish: true +favoris: true +template: true +task: true +archive: true +draft: true +private: true +--- + +# Nouveau-markdown + +#tag1 #tag2 #tag3 + +## sous-titre + diff --git a/vault/folder-3/test-new-file.md b/vault/folder-3/test-new-file.md index 9ebc72f..cff6ef6 100644 --- a/vault/folder-3/test-new-file.md +++ b/vault/folder-3/test-new-file.md @@ -4,7 +4,9 @@ auteur: Bruno Charest creation_date: 2025-10-19T12:15:21-04:00 modification_date: 2025-10-19T12:15:21-04:00 catégorie: "" -tags: [] +tags: + - home + - accueil aliases: [] status: en-cours publish: false diff --git a/vault/folder-3/test-new-file.md.bak b/vault/folder-3/test-new-file.md.bak index e69de29..2aacb1a 100644 --- a/vault/folder-3/test-new-file.md.bak +++ b/vault/folder-3/test-new-file.md.bak @@ -0,0 +1,19 @@ +--- +titre: test-new-file +auteur: Bruno Charest +creation_date: 2025-10-19T12:15:21-04:00 +modification_date: 2025-10-19T12:15:21-04:00 +catégorie: "" +aliases: [] +status: en-cours +publish: false +favoris: false +template: false +task: false +archive: false +draft: false +private: false +tags: + - home + - accueil +--- diff --git a/vault/folder1/test2.md b/vault/folder1/test2.md index 7e354b2..24852e2 100644 --- a/vault/folder1/test2.md +++ b/vault/folder1/test2.md @@ -4,7 +4,10 @@ auteur: Bruno Charest creation_date: 2025-10-02T16:10:42-04:00 modification_date: 2025-10-19T12:09:47-04:00 catégorie: "" -tags: [] +tags: + - accueil + - markdown + - bruno aliases: [] status: en-cours publish: false diff --git a/vault/folder1/test2.md.bak b/vault/folder1/test2.md.bak index 1eb5d2f..8795ca9 100644 --- a/vault/folder1/test2.md.bak +++ b/vault/folder1/test2.md.bak @@ -1,4 +1,22 @@ --- +titre: test2 +auteur: Bruno Charest +creation_date: 2025-10-02T16:10:42-04:00 +modification_date: 2025-10-19T12:09:47-04:00 +catégorie: "" +aliases: [] +status: en-cours +publish: false +favoris: true +template: false +task: false +archive: false +draft: false +private: false tag: testTag +tags: + - accueil + - markdown + - bruno --- Ceci est la page 1 \ No newline at end of file diff --git a/vault/test.md b/vault/test.md index 438cb1d..ffa042f 100644 --- a/vault/test.md +++ b/vault/test.md @@ -5,9 +5,11 @@ creation_date: 2025-09-25T07:45:20-04:00 modification_date: 2025-10-19T12:09:47-04:00 catégorie: "" tags: - - tag_metadata_1 - - tag_metadata_2 - - tag_metadata_test + - tag1 + - tag2 + - test + - test2 + - home aliases: [] status: en-cours publish: false diff --git a/vault/test.md.bak b/vault/test.md.bak index 21a5e88..0531a77 100644 --- a/vault/test.md.bak +++ b/vault/test.md.bak @@ -1,9 +1,19 @@ --- +titre: test +auteur: Bruno Charest +creation_date: 2025-09-25T07:45:20-04:00 +modification_date: 2025-10-19T12:09:47-04:00 +catégorie: "" +aliases: [] +status: en-cours +publish: false +favoris: false +template: false +task: false +archive: false +draft: false +private: false title: Page de test Markdown -tags: - - tag_metadata_1 - - tag_metadata_2 - - tag_metadata_test created: 2025-09-25T21:20:45-04:00 modified: 2025-09-25T21:20:45-04:00 category: test @@ -14,6 +24,12 @@ number: 12345 todo: false url: https://google.com image: https://images.unsplash.com/photo-1675789652575-0a5d2425b6c2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80 +tags: + - tag1 + - tag2 + - test + - test2 + - home --- #tag1 #tag2 #test #test2 diff --git a/vault/totoTata.md b/vault/totoTata.md new file mode 100644 index 0000000..0bac539 --- /dev/null +++ b/vault/totoTata.md @@ -0,0 +1,17 @@ +--- +titre: totoTata +auteur: Bruno Charest +creation_date: 2025-10-20T10:11:39-04:00 +modification_date: 2025-10-20T10:11:39-04:00 +catégorie: "" +tags: [] +aliases: [] +status: en-cours +publish: false +favoris: true +template: false +task: true +archive: false +draft: false +private: false +--- diff --git a/vault/totoTata.md.bak b/vault/totoTata.md.bak new file mode 100644 index 0000000..e69de29