max / goingson
1 file changed,
+48 insertions,
-11 deletions
| @@ -24,17 +24,24 @@ | |||
| 24 | 24 | if (selectedIds.size === 0) return; | |
| 25 | 25 | ||
| 26 | 26 | const count = selectedIds.size; | |
| 27 | - | try { | |
| 28 | - | const promises = Array.from(selectedIds).map(apiCall); | |
| 29 | - | await Promise.all(promises); | |
| 27 | + | const promises = Array.from(selectedIds).map(apiCall); | |
| 28 | + | const results = await Promise.allSettled(promises); | |
| 29 | + | const succeeded = results.filter(r => r.status === 'fulfilled').length; | |
| 30 | + | const failed = results.filter(r => r.status === 'rejected').length; | |
| 31 | + | ||
| 32 | + | if (failed === 0) { | |
| 30 | 33 | GoingsOn.ui.showToast(successMessage.replace('{count}', count)); | |
| 31 | - | selectedIds.clear(); | |
| 32 | - | if (closeModalAfter) GoingsOn.ui.closeModal(); | |
| 33 | - | reloadFn(); | |
| 34 | - | updateBulkActionsBar(); | |
| 35 | - | } catch (err) { | |
| 36 | - | GoingsOn.ui.showToast(`${errorMessage}: ${GoingsOn.utils.getErrorMessage(err)}`, 'error'); | |
| 34 | + | } else if (succeeded === 0) { | |
| 35 | + | const firstErr = results.find(r => r.status === 'rejected'); | |
| 36 | + | GoingsOn.ui.showToast(`${errorMessage}: ${GoingsOn.utils.getErrorMessage(firstErr.reason)}`, 'error'); | |
| 37 | + | } else { | |
| 38 | + | GoingsOn.ui.showToast(`${succeeded} succeeded, ${failed} failed`, 'warning'); | |
| 37 | 39 | } | |
| 40 | + | ||
| 41 | + | selectedIds.clear(); | |
| 42 | + | if (closeModalAfter) GoingsOn.ui.closeModal(); | |
| 43 | + | reloadFn(); | |
| 44 | + | updateBulkActionsBar(); | |
| 38 | 45 | } | |
| 39 | 46 | ||
| 40 | 47 | /** | |
| @@ -177,7 +184,22 @@ | |||
| 177 | 184 | const selectedTaskIds = GoingsOn.tasks?.getSelected?.() || new Set(); | |
| 178 | 185 | await executeBulkAction({ | |
| 179 | 186 | selectedIds: selectedTaskIds, | |
| 180 | - | apiCall: id => GoingsOn.api.tasks.update(id, { projectId }), | |
| 187 | + | apiCall: async (id) => { | |
| 188 | + | const task = await GoingsOn.api.tasks.get(id); | |
| 189 | + | if (!task) return; | |
| 190 | + | return GoingsOn.api.tasks.update(id, { | |
| 191 | + | description: task.description, | |
| 192 | + | priority: task.priority, | |
| 193 | + | status: task.status, | |
| 194 | + | projectId: projectId, | |
| 195 | + | due: task.due, | |
| 196 | + | tags: task.tags, | |
| 197 | + | recurrence: task.recurrence, | |
| 198 | + | estimatedMinutes: task.estimatedMinutes, | |
| 199 | + | contactId: task.contactId, | |
| 200 | + | milestoneId: task.milestoneId, | |
| 201 | + | }); | |
| 202 | + | }, | |
| 181 | 203 | successMessage: 'Updated project for {count} tasks', | |
| 182 | 204 | errorMessage: 'Failed to update some tasks', | |
| 183 | 205 | reloadFn: () => GoingsOn.tasks.load(), | |
| @@ -189,7 +211,22 @@ | |||
| 189 | 211 | const selectedTaskIds = GoingsOn.tasks?.getSelected?.() || new Set(); | |
| 190 | 212 | await executeBulkAction({ | |
| 191 | 213 | selectedIds: selectedTaskIds, | |
| 192 | - | apiCall: id => GoingsOn.api.tasks.update(id, { priority }), | |
| 214 | + | apiCall: async (id) => { | |
| 215 | + | const task = await GoingsOn.api.tasks.get(id); | |
| 216 | + | if (!task) return; | |
| 217 | + | return GoingsOn.api.tasks.update(id, { | |
| 218 | + | description: task.description, | |
| 219 | + | priority: priority, | |
| 220 | + | status: task.status, | |
| 221 | + | projectId: task.projectId, | |
| 222 | + | due: task.due, | |
| 223 | + | tags: task.tags, | |
| 224 | + | recurrence: task.recurrence, | |
| 225 | + | estimatedMinutes: task.estimatedMinutes, | |
| 226 | + | contactId: task.contactId, | |
| 227 | + | milestoneId: task.milestoneId, | |
| 228 | + | }); | |
| 229 | + | }, | |
| 193 | 230 | successMessage: 'Updated priority for {count} tasks', | |
| 194 | 231 | errorMessage: 'Failed to update some tasks', | |
| 195 | 232 | reloadFn: () => GoingsOn.tasks.load(), |