notes better

This commit is contained in:
2026-03-23 12:56:56 -05:00
parent 23e3ddd667
commit 609163f933
+28 -10
View File
@@ -81,7 +81,7 @@ export const NotepadView: Component<{
}); });
createEffect(() => { createEffect(() => {
const note = activeNote(); const note = taskLinkOwnerNote();
if (!note) return; if (!note) return;
const linkageSignature = `${note.id}|${note.key || note.title}|${(note.tasks || []).join(",")}|${note.updated}`; const linkageSignature = `${note.id}|${note.key || note.title}|${(note.tasks || []).join(",")}|${note.updated}`;
void linkageSignature; void linkageSignature;
@@ -94,6 +94,22 @@ export const NotepadView: Component<{
return store.notes.find(n => n.id === id) || null; return store.notes.find(n => n.id === id) || null;
}); });
const getImmediateParentNote = (note: Note | null): Note | null => {
if (!note) return null;
const parentTag = note.tags?.find(t => t.startsWith("child-of-"));
if (!parentTag) return null;
const parentId = parentTag.replace("child-of-", "");
return store.notes.find(n => n.id === parentId) || null;
};
const taskLinkOwnerNote = createMemo(() => {
const note = activeNote();
if (!note) return null;
return getImmediateParentNote(note) || note;
});
const isChildNote = createMemo(() => !!getImmediateParentNote(activeNote()));
const handleUpdateNote = async (id: string, data: Partial<Note>) => { const handleUpdateNote = async (id: string, data: Partial<Note>) => {
await updateNote(id, data); await updateNote(id, data);
}; };
@@ -141,7 +157,7 @@ export const NotepadView: Component<{
}; };
const handleLinkTask = async (taskId: string) => { const handleLinkTask = async (taskId: string) => {
const note = activeNote(); const note = taskLinkOwnerNote();
if (!note) return; if (!note) return;
const task = store.tasks.find(existing => existing.id === taskId); const task = store.tasks.find(existing => existing.id === taskId);
const noteTag = buildNoteTag(note.key || note.title); const noteTag = buildNoteTag(note.key || note.title);
@@ -155,7 +171,8 @@ export const NotepadView: Component<{
}; };
const handleUnlinkTask = async (taskId: string) => { const handleUnlinkTask = async (taskId: string) => {
const note = activeNote(); if (isChildNote()) return;
const note = taskLinkOwnerNote();
if (!note) return; if (!note) return;
const task = store.tasks.find(existing => existing.id === taskId); const task = store.tasks.find(existing => existing.id === taskId);
const noteTag = buildNoteTag(note.key || note.title).toLowerCase(); const noteTag = buildNoteTag(note.key || note.title).toLowerCase();
@@ -168,7 +185,7 @@ export const NotepadView: Component<{
// Linked tasks calculation // Linked tasks calculation
const linkedTasks = createMemo(() => { const linkedTasks = createMemo(() => {
const note = activeNote(); const note = taskLinkOwnerNote();
if (!note) return []; if (!note) return [];
const noteTagName = buildNoteTag(note.key || note.title).toLowerCase(); const noteTagName = buildNoteTag(note.key || note.title).toLowerCase();
return store.tasks.filter(t => { return store.tasks.filter(t => {
@@ -181,7 +198,7 @@ export const NotepadView: Component<{
}); });
const unlinkedTasks = createMemo(() => { const unlinkedTasks = createMemo(() => {
const note = activeNote(); const note = taskLinkOwnerNote();
if (!note) return []; if (!note) return [];
const q = linkSearchQuery().toLowerCase(); const q = linkSearchQuery().toLowerCase();
@@ -271,6 +288,10 @@ export const NotepadView: Component<{
}; };
const openQuickEntry = () => { const openQuickEntry = () => {
const ownerNote = taskLinkOwnerNote();
if (ownerNote) {
(window as any)._activeNoteId = ownerNote.id;
}
window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 'k' })); window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 'k' }));
}; };
@@ -390,9 +411,6 @@ export const NotepadView: Component<{
return s.startsWith('<div data-type="file-viewer-wrapper"') || return s.startsWith('<div data-type="file-viewer-wrapper"') ||
(s.startsWith('<div data-type="file-attachment"') && s.includes('data-filename') && s.toLowerCase().includes('.pdf')); (s.startsWith('<div data-type="file-attachment"') && s.includes('data-filename') && s.toLowerCase().includes('.pdf'));
}); });
const isChildNote = createMemo(() => {
return (note()?.tags || []).some(t => t.startsWith("child-of-"));
});
return ( return (
<> <>
@@ -744,14 +762,14 @@ export const NotepadView: Component<{
<div class="text-center text-xs text-muted-foreground p-6 bg-muted/10 border border-dashed border-border/50 rounded-xl flex flex-col items-center gap-2"> <div class="text-center text-xs text-muted-foreground p-6 bg-muted/10 border border-dashed border-border/50 rounded-xl flex flex-col items-center gap-2">
<LinkIcon size={24} class="opacity-20" /> <LinkIcon size={24} class="opacity-20" />
<p>No tasks linked yet.</p> <p>No tasks linked yet.</p>
<p class="text-[0.6rem] opacity-70 max-w-[200px]">Link an existing task, create a new one, or add the tag #{note().title} to a task.</p> <p class="text-[0.6rem] opacity-70 max-w-[200px]">Link an existing task, create a new one, or add the tag #{taskLinkOwnerNote()?.title || note().title} to a task.</p>
</div> </div>
}> }>
{(task) => ( {(task) => (
<div class="relative group"> <div class="relative group">
<TaskCard task={task} /> <TaskCard task={task} />
{/* If explicitly linked, allow unlinking. If linked by tag, they should remove the tag from the task, which we can't easily do here unless we implement it. */} {/* If explicitly linked, allow unlinking. If linked by tag, they should remove the tag from the task, which we can't easily do here unless we implement it. */}
<Show when={note().tasks && note().tasks.includes(task.id)}> <Show when={!isChildNote() && taskLinkOwnerNote()?.tasks?.includes(task.id)}>
<button <button
class="absolute -top-2 -right-2 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity shadow-sm hover:scale-110" class="absolute -top-2 -right-2 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity shadow-sm hover:scale-110"
onClick={(e) => { onClick={(e) => {