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
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:
1 parent
f91926c208
commit
5a8922011d
20 files changed
+511
-53
No files matched your search
@@ -443,43 +443,6 @@ func (s *Store) docTaskLinks(docID string) map[string]string {
|
||||
return links
|
||||
}
|
||||
|
||||
// ReconcileDocTaskLinks brings tasks linked to blocks in line with the note: a ticked block completes its
|
||||
// task, a deleted block unlinks it (the task itself stays). Returns the IDs of changed tasks.
|
||||
func (s *Store) ReconcileDocTaskLinks(docID string) []string {
|
||||
links := s.docTaskLinks(docID)
|
||||
if len(links) == 0 {
|
||||
return nil
|
||||
}
|
||||
d, _, err := loadCollabDoc(s.db, docID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var changed []string
|
||||
for blockID, taskID := range links {
|
||||
b, ok := d.Blocks[blockID]
|
||||
if !ok || b.Deleted {
|
||||
if _, err := s.db.Exec(`UPDATE thoughts SET converted_type = '', converted_ref_id = '' WHERE id = ?`, taskID); err == nil {
|
||||
changed = append(changed, taskID)
|
||||
}
|
||||
continue
|
||||
}
|
||||
kanban := "todo"
|
||||
if b.Props.Checked {
|
||||
kanban = "done"
|
||||
}
|
||||
res, err := s.db.Exec(
|
||||
`UPDATE thoughts SET is_completed = ?, kanban_status = ? WHERE id = ? AND is_completed != ?`,
|
||||
boolInt(b.Props.Checked), kanban, taskID, boolInt(b.Props.Checked))
|
||||
if err == nil {
|
||||
if n, _ := res.RowsAffected(); n > 0 {
|
||||
changed = append(changed, taskID)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(changed)
|
||||
return changed
|
||||
}
|
||||
|
||||
// GetThoughtByIDUnchecked loads a task without access check, for server-internal notifications.
|
||||
func (s *Store) GetThoughtByIDUnchecked(thoughtID string) (*domain.Thought, error) {
|
||||
return scanThought(s.db.QueryRow(
|
||||
|
||||
Reference in new issue
Block a user