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
+14 -12
View File
@@ -662,13 +662,14 @@ function parseYaml(yamlString) {
// ENDPOINT: PATCH /api/vault/notes/:id - Update note frontmatter
// ============================================================================
export function setupUpdateNoteEndpoint(app, vaultDir) {
console.log('[Setup] Setting up /api/vault/notes/:id endpoint');
app.patch('/api/vault/notes/:id', async (req, res) => {
console.log('[Setup] Setting up regex PATCH /api/vault/notes/* endpoint');
// Use regex route to capture IDs with slashes (folder paths)
app.patch(/^\/api\/vault\/notes\/(.+)$/, async (req, res) => {
try {
const { id } = req.params;
const id = req.params[0];
const { frontmatter } = req.body;
console.log('[/api/vault/notes/:id] PATCH request received:', { id, frontmatter });
console.log('[/api/vault/notes/*] PATCH request received:', { id, frontmatter });
if (!frontmatter || typeof frontmatter !== 'object') {
return res.status(400).json({ error: 'frontmatter is required and must be an object' });
@@ -732,7 +733,7 @@ export function setupUpdateNoteEndpoint(app, vaultDir) {
const fullContent = frontmatterYaml + content;
writeFileSync(filePath, fullContent, 'utf8');
console.log(`[/api/vault/notes/:id] Updated note: ${id}`);
console.log(`[/api/vault/notes/*] Updated note: ${id}`);
res.json({
id,
@@ -741,7 +742,7 @@ export function setupUpdateNoteEndpoint(app, vaultDir) {
});
} catch (error) {
console.error('[/api/vault/notes/:id] Error updating note:', error.message, error.stack);
console.error('[/api/vault/notes/*] Error updating note:', error.message, error.stack);
res.status(500).json({ error: 'Failed to update note', details: error.message });
}
});
@@ -751,12 +752,13 @@ export function setupUpdateNoteEndpoint(app, vaultDir) {
// ENDPOINT: DELETE /api/vault/notes/:id - Delete note (move to trash)
// ============================================================================
export function setupDeleteNoteEndpoint(app, vaultDir) {
console.log('[Setup] Setting up DELETE /api/vault/notes/:id endpoint');
app.delete('/api/vault/notes/:id', async (req, res) => {
console.log('[Setup] Setting up regex DELETE /api/vault/notes/* endpoint');
// Use regex route to capture IDs with slashes (folder paths)
app.delete(/^\/api\/vault\/notes\/(.+)$/, async (req, res) => {
try {
const { id } = req.params;
const id = req.params[0];
console.log('[/api/vault/notes/:id] DELETE request received:', { id });
console.log('[/api/vault/notes/*] DELETE request received:', { id });
// Build file path from ID
const filePath = join(vaultDir, `${id}.md`);
@@ -780,7 +782,7 @@ export function setupDeleteNoteEndpoint(app, vaultDir) {
// Move file to trash
renameSync(filePath, trashPath);
console.log(`[/api/vault/notes/:id] Moved note to trash: ${id} -> ${trashFileName}`);
console.log(`[/api/vault/notes/*] Moved note to trash: ${id} -> ${trashFileName}`);
res.json({
id,
@@ -789,7 +791,7 @@ export function setupDeleteNoteEndpoint(app, vaultDir) {
});
} catch (error) {
console.error('[/api/vault/notes/:id] Error deleting note:', error.message, error.stack);
console.error('[/api/vault/notes/*] Error deleting note:', error.message, error.stack);
res.status(500).json({ error: 'Failed to delete note', details: error.message });
}
});