189 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!-- ObsiViewer - Application optimisée pour mobile et desktop -->
 | 
						|
<main class="relative flex min-h-screen flex-col bg-obs-l-bg-main text-obs-l-text-main dark:bg-obs-d-bg-main dark:text-obs-d-text-main lg:flex-row lg:h-screen lg:overflow-hidden">
 | 
						|
    <!-- Navigation latérale desktop -->
 | 
						|
    <nav class="hidden w-14 flex-col items-center gap-4 border-r border-obs-l-border bg-obs-l-bg-main py-4 dark:border-obs-d-border dark:bg-obs-d-bg-main lg:flex">
 | 
						|
      <button
 | 
						|
        (click)="setView('files')"
 | 
						|
        class="rounded-lg p-2 transition hover:bg-obs-l-bg-secondary dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.bg-obs-l-bg-secondary]="activeView() === 'files'"
 | 
						|
        [class.dark:bg-obs-d-bg-secondary]="activeView() === 'files'"
 | 
						|
        aria-label="Afficher les fichiers"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-obs-l-text-muted dark:text-obs-d-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" /></svg>
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('search')"
 | 
						|
        class="rounded-lg p-2 transition hover:bg-obs-l-bg-secondary dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.bg-obs-l-bg-secondary]="activeView() === 'search'"
 | 
						|
        [class.dark:bg-obs-d-bg-secondary]="activeView() === 'search'"
 | 
						|
        aria-label="Ouvrir la recherche"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-obs-l-text-muted dark:text-obs-d-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('tags')"
 | 
						|
        class="rounded-lg p-2 transition hover:bg-obs-l-bg-secondary dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.bg-obs-l-bg-secondary]="activeView() === 'tags'"
 | 
						|
        [class.dark:bg-obs-d-bg-secondary]="activeView() === 'tags'"
 | 
						|
        aria-label="Afficher les tags"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-obs-l-text-muted dark:text-obs-d-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-5 5a2 2 0 01-2.828 0l-7-7A2 2 0 013 8V3z" /></svg>
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('graph')"
 | 
						|
        class="rounded-lg p-2 transition hover:bg-obs-l-bg-secondary dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.bg-obs-l-bg-secondary]="activeView() === 'graph'"
 | 
						|
        [class.dark:bg-obs-d-bg-secondary]="activeView() === 'graph'"
 | 
						|
        aria-label="Afficher la vue graphe"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-obs-l-text-muted dark:text-obs-d-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" /></svg>
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('calendar')"
 | 
						|
        class="rounded-lg p-2 transition hover:bg-obs-l-bg-secondary dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.bg-obs-l-bg-secondary]="activeView() === 'calendar'"
 | 
						|
        [class.dark:bg-obs-d-bg-secondary]="activeView() === 'calendar'"
 | 
						|
        aria-label="Afficher le calendrier"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-obs-l-text-muted dark:text-obs-d-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2h-1.5a1.5 1.5 0 01-3 0h-5a1.5 1.5 0 01-3 0H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
 | 
						|
      </button>
 | 
						|
    </nav>
 | 
						|
  
 | 
						|
    <nav class="sticky bottom-0 z-30 flex w-full items-center justify-around gap-2 border-t border-obs-l-border bg-obs-l-bg-main/95 px-2 py-2 backdrop-blur-xs dark:border-obs-d-border dark:bg-obs-d-bg-main/95 lg:hidden">
 | 
						|
      <button
 | 
						|
        (click)="setView('files'); toggleSidebarTo(true)"
 | 
						|
        class="flex flex-1 flex-col items-center gap-1 rounded-lg px-3 py-2 text-xs font-semibold text-obs-l-text-muted transition hover:bg-obs-l-bg-secondary dark:text-obs-d-text-muted dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.text-obs-l-text-main]="activeView() === 'files'"
 | 
						|
        [class.dark:text-obs-d-text-main]="activeView() === 'files'"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" /></svg>
 | 
						|
        Fichiers
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('search'); toggleSidebarTo(true)"
 | 
						|
        class="flex flex-1 flex-col items-center gap-1 rounded-lg px-3 py-2 text-xs font-semibold text-obs-l-text-muted transition hover:bg-obs-l-bg-secondary dark:text-obs-d-text-muted dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.text-obs-l-text-main]="activeView() === 'search'"
 | 
						|
        [class.dark:text-obs-d-text-main]="activeView() === 'search'"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
 | 
						|
        Recherche
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('tags'); toggleSidebarTo(true)"
 | 
						|
        class="flex flex-1 flex-col items-center gap-1 rounded-lg px-3 py-2 text-xs font-semibold text-obs-l-text-muted transition hover:bg-obs-l-bg-secondary dark:text-obs-d-text-muted dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.text-obs-l-text-main]="activeView() === 'tags'"
 | 
						|
        [class.dark:text-obs-d-text-main]="activeView() === 'tags'"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-5 5a2 2 0 01-2.828 0l-7-7A2 2 0 013 8V3z" /></svg>
 | 
						|
        Tags
 | 
						|
      </button>
 | 
						|
      <button
 | 
						|
        (click)="setView('calendar'); toggleSidebarTo(true)"
 | 
						|
        class="flex flex-1 flex-col items-center gap-1 rounded-lg px-3 py-2 text-xs font-semibold text-obs-l-text-muted transition hover:bg-obs-l-bg-secondary dark:text-obs-d-text-muted dark:hover:bg-obs-d-bg-secondary"
 | 
						|
        [class.text-obs-l-text-main]="activeView() === 'calendar'"
 | 
						|
        [class.dark:text-obs-d-text-main]="activeView() === 'calendar'"
 | 
						|
        [attr.aria-pressed]="activeView() === 'calendar'"
 | 
						|
      >
 | 
						|
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2h-1.5a1.5 1.5 0 01-3 0h-5a1.5 1.5 0 01-3 0H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
 | 
						|
        Agenda
 | 
						|
      </button>
 | 
						|
    </nav>
 | 
						|
  
 | 
						|
    @if (isDesktop() || isSidebarOpen()) {
 | 
						|
    <aside
 | 
						|
      class="fixed inset-y-0 left-0 z-40 flex h-screen w-[min(320px,85vw)] -translate-x-full transform flex-col border-r border-obs-l-border bg-obs-l-bg-secondary shadow-xl transition-transform duration-200 ease-in-out dark:border-obs-d-border dark:bg-obs-d-bg-secondary lg:static lg:h-auto lg:w-auto lg:translate-x-0 lg:shadow-none"
 | 
						|
      [class.translate-x-0]="isSidebarOpen() || isDesktop()"
 | 
						|
      [class.pointer-events-none]="!isSidebarOpen() && !isDesktop()"
 | 
						|
      [style.width.px]="isDesktop() ? (isSidebarOpen() ? leftSidebarWidth() : 0) : null"
 | 
						|
      [style.minWidth.px]="isDesktop() ? (isSidebarOpen() ? leftSidebarWidth() : 0) : null"
 | 
						|
      [style.maxWidth.px]="isDesktop() ? (isSidebarOpen() ? leftSidebarWidth() : 0) : null"
 | 
						|
      role="navigation"
 | 
						|
      aria-label="Arborescence de la voûte"
 | 
						|
    >
 | 
						|
      <div class="flex h-full flex-col overflow-hidden"
 | 
						|
        [style.width.px]="isDesktop() ? (isSidebarOpen() ? leftSidebarWidth() : 0) : null"
 | 
						|
      >
 | 
						|
        <div class="space-y-4 border-b border-obs-l-border bg-obs-l-bg-secondary/60 px-4 py-4 dark:border-obs-d-border dark:bg-obs-d-bg-secondary/60">
 | 
						|
          <div class="flex items-start justify-between gap-3">
 | 
						|
            <div class="flex items-center gap-3">
 | 
						|
              <div class="flex h-10 w-10 items-center justify-center rounded-2xl border border-obs-l-border/60 bg-obs-l-bg-main/70 text-obs-l-text-muted shadow-sm dark:border-obs-d-border/60 dark:bg-obs-d-bg-main/60 dark:text-obs-d-text-muted">
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM5.5 21a6.5 6.5 0 0113 0" /></svg>
 | 
						|
              </div>
 | 
						|
              <div>
 | 
						|
                <span class="text-sm font-semibold tracking-wide text-obs-l-text-main dark:text-obs-d-text-main">{{ vaultName() }}</span>
 | 
						|
                <div class="mt-1 flex items-center gap-2 text-xs uppercase text-obs-l-text-muted dark:text-obs-d-text-muted">
 | 
						|
                  <span class="inline-flex items-center gap-1 rounded-full bg-obs-l-bg-main/70 px-2 py-0.5 text-[0.65rem] font-semibold tracking-widest text-obs-l-text-main/80 dark:bg-obs-d-bg-main/60 dark:text-obs-d-text-main/80">{{ activeView() | titlecase }}</span>
 | 
						|
                  <span class="hidden text-[0.65rem] tracking-widest text-obs-l-text-muted/80 dark:text-obs-d-text-muted/70 sm:inline">Vue active</span>
 | 
						|
                </div>
 | 
						|
              </div>
 | 
						|
            </div>
 | 
						|
  
 | 
						|
            @if (!isDesktop()) {
 | 
						|
              <button
 | 
						|
                class="rounded-xl border border-transparent bg-obs-l-bg-main/70 p-2 text-obs-l-text-muted transition hover:border-obs-l-border/50 hover:bg-obs-l-bg-main/90 dark:bg-obs-d-bg-main/60 dark:text-obs-d-text-muted dark:hover:border-obs-d-border/60 dark:hover:bg-obs-d-bg-main/70"
 | 
						|
                (click)="closeSidebar()"
 | 
						|
                aria-label="Fermer le panneau latéral"
 | 
						|
              >
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>
 | 
						|
              </button>
 | 
						|
            }
 | 
						|
          </div>
 | 
						|
  
 | 
						|
          <div class="rounded-2xl border border-obs-l-border/60 bg-obs-l-bg-main/75 px-3 py-3 shadow-inner dark:border-obs-d-border/60 dark:bg-obs-d-bg-main/60">
 | 
						|
            <div class="grid grid-cols-2 gap-2 sm:grid-cols-4">
 | 
						|
              <button
 | 
						|
                (click)="setView('files')"
 | 
						|
                class="group flex flex-col items-center gap-1 rounded-xl border border-transparent px-2.5 py-2 text-xs font-medium text-obs-l-text-muted transition duration-150 hover:border-obs-l-border/50 hover:bg-obs-l-bg-main/60 hover:text-obs-l-text-main dark:text-obs-d-text-muted dark:hover:border-obs-d-border/50 dark:hover:bg-obs-d-bg-main/60 dark:hover:text-obs-d-text-main"
 | 
						|
                [ngClass]="{ 'bg-obs-l-bg-main/80 text-obs-l-text-main shadow-sm dark:bg-obs-d-bg-main/70 dark:text-obs-d-text-main': activeView() === 'files' }"
 | 
						|
                aria-label="Afficher les fichiers"
 | 
						|
              >
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" /></svg>
 | 
						|
                <span>Fichiers</span>
 | 
						|
              </button>
 | 
						|
              <button
 | 
						|
                (click)="setView('search')"
 | 
						|
                class="group flex flex-col items-center gap-1 rounded-xl border border-transparent px-2.5 py-2 text-xs font-medium text-obs-l-text-muted transition duration-150 hover:border-obs-l-border/50 hover:bg-obs-l-bg-main/60 hover:text-obs-l-text-main dark:text-obs-d-text-muted dark:hover:border-obs-d-border/50 dark:hover:bg-obs-d-bg-main/60 dark:hover:text-obs-d-text-main"
 | 
						|
                [ngClass]="{ 'bg-obs-l-bg-main/80 text-obs-l-text-main shadow-sm dark:bg-obs-d-bg-main/70 dark:text-obs-d-text-main': activeView() === 'search' }"
 | 
						|
                aria-label="Ouvrir la recherche"
 | 
						|
              >
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
 | 
						|
                <span>Recherche</span>
 | 
						|
              </button>
 | 
						|
              <button
 | 
						|
                (click)="setView('tags')"
 | 
						|
                class="group flex flex-col items-center gap-1 rounded-xl border border-transparent px-2.5 py-2 text-xs font-medium text-obs-l-text-muted transition duration-150 hover:border-obs-l-border/50 hover:bg-obs-l-bg-main/60 hover:text-obs-l-text-main dark:text-obs-d-text-muted dark:hover:border-obs-d-border/50 dark:hover:bg-obs-d-bg-main/60 dark:hover:text-obs-d-text-main"
 | 
						|
                [ngClass]="{ 'bg-obs-l-bg-main/80 text-obs-l-text-main shadow-sm dark:bg-obs-d-bg-main/70 dark:text-obs-d-text-main': activeView() === 'tags' }"
 | 
						|
                aria-label="Afficher les tags"
 | 
						|
              >
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-5 5a2 2 0 01-2.828 0l-7-7A2 2 0 013 8V3z" /></svg>
 | 
						|
                <span>Tags</span>
 | 
						|
              </button>
 | 
						|
              <button
 | 
						|
                (click)="setView('calendar')"
 | 
						|
                class="group flex flex-col items-center gap-1 rounded-xl border border-transparent px-2.5 py-2 text-xs font-medium text-obs-l-text-muted transition duration-150 hover:border-obs-l-border/50 hover:bg-obs-l-bg-main/60 hover:text-obs-l-text-main dark:text-obs-d-text-muted dark:hover:border-obs-d-border/50 dark:hover:bg-obs-d-bg-main/60 dark:hover:text-obs-d-text-main"
 | 
						|
                [ngClass]="{ 'bg-obs-l-bg-main/80 text-obs-l-text-main shadow-sm dark:bg-obs-d-bg-main/70 dark:text-obs-d-text-main': activeView() === 'calendar' }"
 | 
						|
                [attr.aria-pressed]="activeView() === 'calendar'"
 | 
						|
                aria-label="Afficher l'agenda"
 | 
						|
              >
 | 
						|
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2h-1.5a1.5 1.5 0 01-3 0h-5a1.5 1.5 0 01-3 0H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
 | 
						|
                <span>Agenda</span>
 | 
						|
              </button>
 | 
						|
            </div>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
        <div class="flex-1 overflow-y-auto">
 | 
						|
          @switch (activeView()) {
 | 
						|
            @case ('files') {
 | 
						|
              <app-file-explorer
 | 
						|
                [nodes]="filteredFileTree()"
 | 
						|
                [selectedNoteId]="selectedNoteId()"
 | 
						|
                (fileSelected)="selectNote($event)"
 | 
						|
              ></app-file-explorer>
 | 
						|
            }
 | 
						|
            @case ('tags') {
 | 
						|
              <app-tags-view [tags]="filteredTags()" (tagSelected)="handleTagClick($event)"></app-tags-view>
 | 
						|
            }
 | 
						|
            @case ('graph') {
 | 
						|
              <div class="h-full p-2"><app-graph-view [graphData]="graphData()" (nodeSelected)="selectNote($event)"></app-graph-view></div>
 | 
						|
            }
 |