feat: multi-person assignment for tasks and calendar events

- DB migration v32: task_assignments and event_assignments join tables
  with CASCADE delete; existing assigned_to data migrated automatically
- Tasks API: accepts assigned_to as array, returns assigned_users[]
  with json_group_array; filter uses EXISTS on task_assignments
- Calendar API: same pattern via event_assignments; serializeEvent
  includes assigned_users array
- Recurring task completion copies all assignments to the new instance
- Frontend: shared UserMultiSelect component with avatar stack display
  (renderAvatarStack, renderUserMultiSelect, getSelectedUserIds,
  bindUserMultiSelect); tasks.js and calendar.js use it in modals
  and card/agenda views
- CSS: user-multi-select.css with avatar-stack and user-ms classes
- 14 new tests covering CRUD, JSON aggregation, EXISTS filter,
  and CASCADE behavior for both task and event assignments

Closes #125
This commit is contained in:
Ulas Kalayci
2026-05-06 10:04:41 +02:00
parent f0503f3df1
commit 2a48fb7af0
12 changed files with 648 additions and 146 deletions
+4
View File
@@ -1293,5 +1293,9 @@
"dropzoneTitle": "Datei hier ablegen oder klicken",
"dropzoneHint": "Ziehe eine Datei in diesen Bereich oder nutze die Dateiauswahl.",
"selectedFileLabel": "Ausgewählt: {{name}}"
},
"userMultiSelect": {
"nobody": "- Niemand -",
"moreUsers": "weitere"
}
}