Notes linking confirmed

This commit is contained in:
2026-03-19 18:48:10 -05:00
parent b246f2da78
commit 4eb7650916
+26 -9
View File
@@ -1,5 +1,5 @@
import { type Component, createSignal, createMemo, createEffect, onCleanup, For, Show } from "solid-js";
import { store, renameTagDefinition, updateNote, removeNote, restoreNote, setActiveNoteId, cleanupNoteAttachments, getFavoriteTag, fetchNoteById, updateStoreWithNote } from "@/store";
import { store, renameTagDefinition, updateNote, updateTask, removeNote, restoreNote, setActiveNoteId, cleanupNoteAttachments, getFavoriteTag, fetchNoteById, updateStoreWithNote } from "@/store";
import { pb } from "@/lib/pocketbase";
import { type Note } from "@/store";
import { Plus, X, Lock, Unlock, Trash2, ChevronDown, Link as LinkIcon, MoreHorizontal, Type, FileText, Search, Star, ChevronRight } from "lucide-solid";
@@ -14,7 +14,7 @@ import { NotesSidebar } from "@/components/NotesSidebar";
import { toast } from "solid-sonner";
import { TextBubbleMenu } from "@/components/TextBubbleMenu";
import { TableBubbleMenu } from "@/components/TableBubbleMenu";
import { normalizeNoteKey } from "@/lib/tags";
import { buildNoteTag, normalizeNoteKey } from "@/lib/tags";
export const NotepadView: Component<{
selectedNoteId: string | null;
@@ -106,12 +106,15 @@ export const NotepadView: Component<{
};
const handleRenameNote = async (id: string, oldTitle: string, newTitle: string) => {
const currentNote = store.notes.find(note => note.id === id);
const oldKey = currentNote?.key || normalizeNoteKey(oldTitle);
const newKey = normalizeNoteKey(newTitle);
// 1. Update the note title
await handleUpdateNote(id, { title: newTitle });
await handleUpdateNote(id, { title: newTitle, key: newKey });
// 2. Rename the TagDefinition (preserves color) and propagate to all tagged tasks
// Use '#' prefix for note tags
await renameTagDefinition(`#${oldTitle}`, `#${newTitle}`);
await renameTagDefinition(buildNoteTag(oldKey), buildNoteTag(newKey));
};
const handleDeleteNote = async (id: string) => {
@@ -134,8 +137,13 @@ export const NotepadView: Component<{
const handleLinkTask = async (taskId: string) => {
const note = activeNote();
if (!note) return;
const task = store.tasks.find(existing => existing.id === taskId);
const noteTag = buildNoteTag(note.key || note.title);
const newTasks = [...(note.tasks || []), taskId];
await handleUpdateNote(note.id, { tasks: newTasks });
if (task && !task.tags.some(tag => tag.toLowerCase() === noteTag.toLowerCase())) {
await updateTask(taskId, { tags: [...task.tags, noteTag] });
}
setIsLinking(false);
setLinkSearchQuery("");
};
@@ -143,20 +151,25 @@ export const NotepadView: Component<{
const handleUnlinkTask = async (taskId: string) => {
const note = activeNote();
if (!note) return;
const task = store.tasks.find(existing => existing.id === taskId);
const noteTag = buildNoteTag(note.key || note.title).toLowerCase();
const newTasks = (note.tasks || []).filter(id => id !== taskId);
await handleUpdateNote(note.id, { tasks: newTasks });
if (task && task.tags.some(tag => tag.toLowerCase() === noteTag)) {
await updateTask(taskId, { tags: task.tags.filter(tag => tag.toLowerCase() !== noteTag) });
}
};
// Linked tasks calculation
const linkedTasks = createMemo(() => {
const note = activeNote();
if (!note) return [];
const noteTagName = `#${note.title}`;
const noteTagName = buildNoteTag(note.key || note.title).toLowerCase();
return store.tasks.filter(t => {
// Explicit relation
if (note.tasks && note.tasks.includes(t.id)) return true;
// Tag relation (case-insensitive title match with # prefix)
if (t.tags && t.tags.some(tag => tag.toLowerCase() === noteTagName.toLowerCase())) return true;
if (t.noteRefs && t.noteRefs.some(ref => ref.key === note.key || ref.noteId === note.id)) return true;
if (t.tags && t.tags.some(tag => tag.toLowerCase() === noteTagName)) return true;
return false;
});
});
@@ -184,7 +197,11 @@ export const NotepadView: Component<{
if (!hasPinnedBucket) return false;
}
if (note.tasks && note.tasks.includes(t.id)) return false; // Already linked
const isAlreadyLinked =
(note.tasks && note.tasks.includes(t.id)) ||
t.noteRefs?.some(ref => ref.key === note.key || ref.noteId === note.id) ||
t.tags?.some(tag => tag.toLowerCase() === buildNoteTag(note.key || note.title).toLowerCase());
if (isAlreadyLinked) return false;
if (!q) return false; // Don't show all by default
return t.title.toLowerCase().includes(q);
}).slice(0, 10);