feat: reorder frontmatter keys and add publish/private quick links

This commit is contained in:
2025-10-19 22:19:35 -04:00
parent 0f7610bed1
commit 168fcaf049
9 changed files with 144 additions and 42 deletions
@@ -202,15 +202,6 @@ interface MetadataEntry {
</svg>
{{ getAuthorFromFrontmatter() ?? note().author ?? 'Auteur inconnu' }}
</span>
@if (hasState('publish')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('publish') ? 'text-green-500' : 'text-gray-400'" title="{{ state('publish') ? 'Publié sur le web' : 'Non publié' }}" role="img" aria-label="{{ state('publish') ? 'Publié sur le web' : 'Non publié' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<path d="M2 12h20" />
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
</svg>
</span>
}
@if (hasState('favoris')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('favoris') ? 'text-rose-500' : 'text-gray-400'" title="{{ state('favoris') ? 'Ajouté aux favoris' : 'Non favori' }}" role="img" aria-label="{{ state('favoris') ? 'Ajouté aux favoris' : 'Non favori' }}">
@if (state('favoris')) {
@@ -224,21 +215,13 @@ interface MetadataEntry {
}
</span>
}
@if (hasState('archive')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('archive') ? 'text-amber-600' : 'text-gray-400'" title="{{ state('archive') ? 'Document archivé' : 'Document non archivé' }}" role="img" aria-label="{{ state('archive') ? 'Document archivé' : 'Document non archivé' }}">
@if (state('archive')) {
@if (hasState('publish')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('publish') ? 'text-green-500' : 'text-gray-400'" title="{{ state('publish') ? 'Publié sur le web' : 'Non publié' }}" role="img" aria-label="{{ state('publish') ? 'Publié sur le web' : 'Non publié' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22,12 18,12 18,8"/>
<path d="M18,2H6a2,2,0,0,0-2,2V22a2,2,0,0,0,2,2H18a2,2,0,0,0,2-2V8Z"/>
<line x1="10" y1="12" x2="14" y2="12"/>
<circle cx="12" cy="12" r="10" />
<path d="M2 12h20" />
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 8v13a2 2 0 01-2 2H5a2 2 0 01-2-2V8"/>
<path d="M3 4h18l-2-2H5l-2 2z"/>
<line x1="10" y1="12" x2="14" y2="12"/>
</svg>
}
</span>
}
@if (hasState('draft')) {
@@ -256,6 +239,35 @@ interface MetadataEntry {
}
</span>
}
@if (hasState('template')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('template') ? 'text-amber-500' : 'text-gray-400'" title="{{ state('template') ? 'Modèle' : 'Non modèle' }}" role="img" aria-label="{{ state('template') ? 'Modèle' : 'Non modèle' }}">
@if (state('template')) {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="14" rx="2" />
<path d="M7 8h10" />
<path d="M7 12h6" />
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="5" width="18" height="12" rx="2" />
</svg>
}
</span>
}
@if (hasState('task')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('task') ? 'text-indigo-500' : 'text-gray-400'" title="{{ state('task') ? 'Tâche' : 'Pas une tâche' }}" role="img" aria-label="{{ state('task') ? 'Tâche' : 'Pas une tâche' }}">
@if (state('task')) {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="16" rx="2" />
<path d="M8 12l2 2 4-4" />
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="16" rx="2" />
</svg>
}
</span>
}
@if (hasState('private')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('private') ? 'text-purple-500' : 'text-gray-400'" title="{{ state('private') ? 'Privé' : 'Public' }}" role="img" aria-label="{{ state('private') ? 'Privé' : 'Public' }}">
@if (state('private')) {
@@ -271,6 +283,23 @@ interface MetadataEntry {
}
</span>
}
@if (hasState('archive')) {
<span class="inline-flex items-center gap-1 transition-colors" [ngClass]="state('archive') ? 'text-amber-600' : 'text-gray-400'" title="{{ state('archive') ? 'Document archivé' : 'Document non archivé' }}" role="img" aria-label="{{ state('archive') ? 'Document archivé' : 'Document non archivé' }}">
@if (state('archive')) {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22,12 18,12 18,8"/>
<path d="M18,2H6a2,2,0,0,0-2,2V22a2,2,0,0,0,2,2H18a2,2,0,0,0,2-2V8Z"/>
<line x1="10" y1="12" x2="14" y2="12"/>
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 8v13a2 2 0 01-2 2H5a2 2 0 01-2-2V8"/>
<path d="M3 4h18l-2-2H5l-2 2z"/>
<line x1="10" y1="12" x2="14" y2="12"/>
</svg>
}
</span>
}
</div>
<div [innerHTML]="sanitizedHtmlContent()"></div>
@@ -1148,7 +1177,7 @@ export class NoteViewerComponent implements OnDestroy {
this.copyFeedbackTimers.set(block, timeout);
}
hasState(key: 'publish' | 'favoris' | 'archive' | 'draft' | 'private'): boolean {
hasState(key: 'publish' | 'favoris' | 'archive' | 'draft' | 'private' | 'template' | 'task'): boolean {
try {
const fm = (this.note()?.frontmatter ?? {}) as any;
const raw = (fm as any)[key];
@@ -1158,7 +1187,7 @@ export class NoteViewerComponent implements OnDestroy {
}
}
state(key: 'publish' | 'favoris' | 'archive' | 'draft' | 'private'): boolean {
state(key: 'publish' | 'favoris' | 'archive' | 'draft' | 'private' | 'template' | 'task'): boolean {
try {
const fm = (this.note()?.frontmatter ?? {}) as any;
const raw = (fm as any)[key];