chore: update Angular cache and TypeScript build info

This commit is contained in:
2025-09-29 23:22:47 -04:00
parent b4a706930b
commit 67407f68f0
85 changed files with 10400 additions and 492 deletions
@@ -0,0 +1,79 @@
<div class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" (click)="onBackdropClick($event)">
<div class="bg-white dark:bg-gray-900 rounded-lg shadow-xl max-w-2xl w-full p-6" (click)="$event.stopPropagation()">
<!-- Header -->
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-semibold text-gray-900 dark:text-gray-100">
{{ isEditMode() ? 'Edit bookmark' : 'Add bookmark' }}
</h2>
<button
(click)="onCancel()"
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
aria-label="Close">
<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="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<!-- Form -->
<div class="space-y-4">
<!-- Path -->
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Path
</label>
<input
type="text"
[value]="path()"
(input)="onPathChange($any($event.target).value)"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="e.g. Tests/Allo note.md"
/>
</div>
<!-- Title -->
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Title
</label>
<input
type="text"
[value]="title()"
(input)="onTitleChange($any($event.target).value)"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Display name (optional)"
/>
</div>
<!-- Bookmark group -->
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Bookmark group
</label>
<select
[value]="selectedGroupCtime() || ''"
(change)="onGroupChange($any($event.target).value)"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Root (no group)</option>
@for (group of groups(); track group.ctime) {
<option [value]="group.ctime">{{ group.title }}</option>
}
</select>
</div>
</div>
<!-- Actions -->
<div class="flex items-center justify-end gap-3 mt-6">
<button
(click)="onCancel()"
class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md transition-colors">
Cancel
</button>
<button
(click)="onSave()"
class="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors">
Save
</button>
</div>
</div>
</div>
@@ -0,0 +1,16 @@
:host {
display: contents;
}
select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
}
:host-context(.dark) select {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%239ca3af' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
}
@@ -0,0 +1,119 @@
/**
* Add Bookmark Modal Component
*/
import {
Component,
ChangeDetectionStrategy,
Input,
Output,
EventEmitter,
signal,
computed,
inject,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { BookmarksService } from '../../core/bookmarks/bookmarks.service';
import type { BookmarkGroup } from '../../core/bookmarks/types';
export interface BookmarkFormData {
path: string;
title: string;
groupCtime: number | null;
}
@Component({
selector: 'app-add-bookmark-modal',
imports: [CommonModule, FormsModule],
templateUrl: './add-bookmark-modal.component.html',
styleUrls: ['./add-bookmark-modal.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddBookmarkModalComponent {
private readonly bookmarksService = inject(BookmarksService);
@Input() notePath: string = '';
@Input() noteTitle: string = '';
@Input() existingBookmark: { ctime: number; title?: string; groupCtime?: number } | null = null;
@Output() close = new EventEmitter<void>();
@Output() save = new EventEmitter<BookmarkFormData>();
readonly path = signal('');
readonly title = signal('');
readonly selectedGroupCtime = signal<number | null>(null);
readonly groups = computed(() => {
const doc = this.bookmarksService.doc();
const result: Array<{ ctime: number; title: string }> = [];
const collectGroups = (items: any[], level = 0) => {
for (const item of items) {
if (item.type === 'group') {
result.push({
ctime: item.ctime,
title: ' '.repeat(level) + (item.title || 'Untitled Group'),
});
if (item.items) {
collectGroups(item.items, level + 1);
}
}
}
};
collectGroups(doc.items);
return result;
});
readonly isEditMode = computed(() => this.existingBookmark !== null);
ngOnInit(): void {
this.path.set(this.notePath);
this.title.set(this.noteTitle);
if (this.existingBookmark) {
this.title.set(this.existingBookmark.title || this.noteTitle);
this.selectedGroupCtime.set(this.existingBookmark.groupCtime || null);
}
}
onPathChange(value: string): void {
this.path.set(value);
}
onTitleChange(value: string): void {
this.title.set(value);
}
onGroupChange(value: string): void {
const ctime = value ? parseInt(value, 10) : null;
this.selectedGroupCtime.set(ctime);
}
onSave(): void {
const pathValue = this.path().trim();
const titleValue = this.title().trim();
if (!pathValue) {
alert('Path is required');
return;
}
this.save.emit({
path: pathValue,
title: titleValue || pathValue,
groupCtime: this.selectedGroupCtime(),
});
}
onCancel(): void {
this.close.emit();
}
onBackdropClick(event: MouseEvent): void {
if (event.target === event.currentTarget) {
this.close.emit();
}
}
}