feat(tasks): linked tasks sync title and subtasks with their note in both directions
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 2m32s

Subtasks of a task linked to a note checkbox are tied 1:1 to checkboxes of that note
(subtasks[].blockId), wherever they are moved. ReconcileDocTaskLinks now carries tick, title and
subtasks from the note to the task and adopts new checkboxes directly under the task;
SyncTaskToDoc carries tick, title and subtasks to the note and adds checkboxes for new subtasks.
Deleting is not mirrored. Deepening a task ties its subtasks right away; saves without links keep
the server's links. The sync response reports taskLinks/subtaskLinks; the editor shows an
"Unteraufgabe" badge. v0.36.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-01 12:29:10 +01:00
1 parent f91926c208
commit 5a8922011d
20 files changed
+511 -53

No files matched your search

@@ -1488,6 +1488,24 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
</button>
</div>
)}
{/* Checkbox tied to a subtask of a linked task: tick and text follow the subtask */}
{block.type === 'todo' && !block.taskId && block.subtaskOf && (
<div className="flex items-center gap-1 mt-0.5 select-none">
<button
type="button"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => {
e.stopPropagation();
onOpenTask?.(block.subtaskOf as string);
}}
className="badge-neutral text-[9px] inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded font-medium shrink-0 cursor-pointer hover:opacity-80"
title="Unteraufgabe einer verknüpften Aufgabe – Aufgabe öffnen"
>
<CheckSquare className="w-2.5 h-2.5" />
<span>Unteraufgabe</span>
</button>
</div>
)}
{/* Conflict copy: text that lost against someone else's change */}
{block.conflictOf && (
@@ -1619,7 +1637,9 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
className="absolute right-0 top-full mt-1 bg-panel border border-border shadow-lg rounded-card p-1 z-30 w-52 text-xs"
onClick={(e) => e.stopPropagation()}
>
{!block.taskId ? (
{block.subtaskOf && !block.taskId ? (
<p className="px-2 py-1.5 text-faint">Unteraufgabe einer verknüpften Aufgabe</p>
) : !block.taskId ? (
<button
type="button"
onClick={async () => {