feat: improve note path handling and add delete confirmation modal

- Updated API endpoints to handle note paths with slashes using regex routes
- Added warning modal component for note deletion confirmation
- Fixed URL encoding of note paths to preserve spaces and special characters
- Improved fullscreen note handling to use URL state and custom events
- Enhanced internal link copying to use proper URL format
- Removed test/sample note files from vault directory
This commit is contained in:
2025-10-25 16:27:42 -04:00
parent 96745e9997
commit b873577e93
11 changed files with 420 additions and 54 deletions
+53 -2
View File
@@ -7,12 +7,13 @@ import { TagFilterStore } from '../../core/stores/tag-filter.store';
import { NotesListStateService, SortBy, ViewMode } from '../../services/notes-list-state.service';
import { NoteCreationService } from '../../services/note-creation.service';
import { NoteContextMenuComponent } from '../../../components/note-context-menu/note-context-menu.component';
import { WarningPanelComponent } from '../../components/warning-panel/warning-panel.component';
import { NoteContextMenuService } from '../../services/note-context-menu.service';
@Component({
selector: 'app-notes-list',
standalone: true,
imports: [CommonModule, ScrollableOverlayDirective, NoteContextMenuComponent],
imports: [CommonModule, ScrollableOverlayDirective, NoteContextMenuComponent, WarningPanelComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="h-full flex flex-col">
@@ -173,6 +174,17 @@ import { NoteContextMenuService } from '../../services/note-context-menu.service
(color)="onContextMenuColor($event)"
(closed)="contextMenuService.close()">
</app-note-context-menu>
<!-- Delete Warning Modal -->
<app-warning-panel
[visible]="deleteWarningOpen()"
[title]="'Delete this note?'"
[message]="'The note will be moved to the trash folder and can be restored later.'"
[confirmText]="'Delete'"
[cancelText]="'Cancel'"
[confirmColor]="'danger'"
(delete)="confirmDelete()"
(cancel)="closeDeleteWarning()"></app-warning-panel>
`,
styles: [`
:host {
@@ -367,6 +379,45 @@ export class NotesListComponent {
private noteCreationService = inject(NoteCreationService);
readonly contextMenuService = inject(NoteContextMenuService);
// Delete warning modal state
deleteWarningOpen = signal<boolean>(false);
private deleteTarget: Note | null = null;
openDeleteWarning(note: Note) {
console.log('[NotesList] Opening delete warning for note:', note.title);
// Close context menu so it does not overlay/capture clicks above the modal
this.contextMenuService.close();
this.deleteTarget = note;
this.deleteWarningOpen.set(true);
}
closeDeleteWarning() {
console.log('[NotesList] Closing delete warning');
this.deleteWarningOpen.set(false);
this.deleteTarget = null;
}
async confirmDelete() {
console.log('[NotesList] Confirm delete called for:', this.deleteTarget?.title);
const note = this.deleteTarget;
if (!note) {
console.warn('[NotesList] No delete target found');
this.closeDeleteWarning();
return;
}
try {
console.log('[NotesList] Calling deleteNoteConfirmed...');
await this.contextMenuService.deleteNoteConfirmed(note);
// Only close on success
console.log('[NotesList] Delete successful, closing modal');
this.closeDeleteWarning();
this.contextMenuService.close();
} catch (error) {
console.error('Confirm delete error:', error);
// Keep modal open on error so user can try again or cancel
}
}
private q = signal('');
activeTag = signal<string | null>(null);
sortMenuOpen = signal<boolean>(false);
@@ -595,7 +646,7 @@ export class NotesListComponent {
await this.contextMenuService.toggleReadOnly(note);
break;
case 'delete':
await this.contextMenuService.deleteNote(note);
this.openDeleteWarning(note);
break;
}
}