first commit

This commit is contained in:
2025-09-27 18:13:02 -04:00
commit 6e1b5407b7
253 changed files with 289900 additions and 0 deletions
@@ -0,0 +1,31 @@
<ul class="p-2 space-y-1">
@for (node of nodes(); track node.name) {
<li>
@if (node.type === 'folder') {
@let folder = node;
<div>
<button (click)="toggleFolder(folder)" class="w-full flex items-center text-left p-1.5 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2 transition-transform" [class.rotate-90]="folder.isOpen" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
<span class="font-semibold text-sm">{{ folder.name }}</span>
</button>
@if (folder.isOpen) {
<div class="pl-4">
<app-file-explorer [nodes]="folder.children" [selectedNoteId]="selectedNoteId()" (fileSelected)="onFileSelected($event)"></app-file-explorer>
</div>
}
</div>
} @else {
@let file = node;
<button (click)="onFileSelected(file.id)"
class="w-full text-left p-1.5 rounded text-sm transition-colors"
[class]="file.id === selectedNoteId()
? 'bg-obs-l-accent text-white dark:bg-obs-d-accent'
: 'hover:bg-gray-200 dark:hover:bg-gray-600'">
<span class="pl-6">{{ file.name }}</span>
</button>
}
</li>
}
</ul>
@@ -0,0 +1,78 @@
import { Component, ChangeDetectionStrategy, input, output, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { VaultNode, VaultFile, VaultFolder } from '../../types';
import { VaultService } from '../../services/vault.service';
@Component({
selector: 'app-file-explorer',
template: `
<ul class="space-y-0.5">
@for(node of nodes(); track node.path) {
<li>
@if (isFolder(node)) {
@let folder = node;
<div>
<div
(click)="toggleFolder(folder)"
class="flex items-center cursor-pointer p-2 rounded my-0.5 text-sm hover:bg-obs-l-bg-main dark:hover:bg-obs-d-bg-main"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2 transition-transform text-obs-l-text-muted dark:text-obs-d-text-muted" [class.rotate-90]="folder.isOpen" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2 flex-shrink-0 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"></path></svg>
<span class="font-semibold truncate">{{ folder.name }}</span>
</div>
@if (folder.isOpen) {
<div class="pl-5">
<app-file-explorer
[nodes]="folder.children"
[selectedNoteId]="selectedNoteId()"
(fileSelected)="onFileSelected($event)"
></app-file-explorer>
</div>
}
</div>
} @else {
@let file = node;
<div
(click)="onFileSelected(file.id)"
class="flex items-center cursor-pointer p-2 rounded my-0.5 text-sm ml-5"
[class.bg-obs-l-bg-main]="selectedNoteId() === file.id"
[class.dark:bg-obs-d-bg-main]="selectedNoteId() === file.id"
[class.hover:bg-obs-l-bg-main]="selectedNoteId() !== file.id"
[class.dark:hover:bg-obs-d-bg-main]="selectedNoteId() !== file.id"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2 flex-shrink-0 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="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<span class="truncate">{{ file.name }}</span>
</div>
}
</li>
}
</ul>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule],
})
export class FileExplorerComponent {
nodes = input.required<VaultNode[]>();
selectedNoteId = input<string | null>(null);
fileSelected = output<string>();
private vaultService = inject(VaultService);
onFileSelected(noteId: string) {
if(noteId) {
this.fileSelected.emit(noteId);
}
}
toggleFolder(folder: VaultFolder) {
this.vaultService.toggleFolder(folder.path);
}
isFolder(node: VaultNode): node is VaultFolder {
return node.type === 'folder';
}
}