diff --git a/app.jsx b/app.jsx index 3cdcf45..fb81282 100644 --- a/app.jsx +++ b/app.jsx @@ -134,6 +134,17 @@ function App() { } catch(e) {} }; + const completeTask = async (taskId) => { + try { + await api.updateTask(taskId, { status: 'closed' }); + await api.addAudit({ actor: meId, action: 'task_completed', summary: 'Marked task as completed', target: taskId }); + setOpenTaskId(null); + } catch(e) { + console.error(e); + alert("Failed to complete task: " + e.message); + } + }; + const dismissHU = (id) => setHeadsUp(h => h.filter(x => x.id !== id)); const openTaskFromAnywhere = (id) => { setOpenTaskId(id); setShowLogs(false); }; @@ -191,7 +202,7 @@ function App() { setAdding(null)} onSubmit={addTask} defaultAssignee={adding} me={me} /> {mappedOpenTask && ( - setOpenTaskId(null)} onMove={moveTask} onPriority={setPriority} /> + setOpenTaskId(null)} onMove={moveTask} onPriority={setPriority} onComplete={() => completeTask(mappedOpenTask.id)} /> )} {showLogs && ( setShowLogs(false)} wide> diff --git a/dashy.db b/dashy.db index 5f017eb..729c86f 100644 Binary files a/dashy.db and b/dashy.db differ diff --git a/screens.jsx b/screens.jsx index cb2f530..db26f90 100644 --- a/screens.jsx +++ b/screens.jsx @@ -163,7 +163,7 @@ function HeadsUp({ items, onDismiss, onOpenTask }) { function OverviewScreen({ tasks, onOpen, onAddFor, density, onMoveTask }) { const byUser = Object.fromEntries(USERS.map(u => [u.id, []])); - tasks.forEach(t => { if (byUser[t.assignee]) byUser[t.assignee].push(t); }); + tasks.forEach(t => { if (byUser[t.assignee] && t.status !== 'closed') byUser[t.assignee].push(t); }); const [draggingTask, setDraggingTask] = React.useState(null); const [dragOverCol, setDragOverCol] = React.useState(null); return ( @@ -244,13 +244,14 @@ function UserScreen({ user, tasks, onOpen, onAddFor, density }) { const mine = tasks.filter(t => t.assignee === user.id); const open = mine.filter(t => t.status === 'open'); const flagged = mine.filter(t => t.status === 'unsuccessful' || t.status === 'billing'); + const closed = mine.filter(t => t.status === 'closed'); return (

{user.name}

-

{user.role} · {mine.length} tasks

+

{user.role} · {open.length + flagged.length} open tasks

+ + {closed.length > 0 && ( +
+
+ {closed.map(t => )} +
+
+ )}
); } @@ -398,7 +407,7 @@ function Modal({ children, onClose, title, eyebrow, wide = false }) { ); } -function TaskDetail({ task, allAudit = [], onClose, onMove, onPriority }) { +function TaskDetail({ task, allAudit = [], onClose, onMove, onPriority, onComplete }) { if (!task) return null; const assignee = findUser(task.assignee); const author = findUser(task.addedBy); @@ -415,7 +424,7 @@ function TaskDetail({ task, allAudit = [], onClose, onMove, onPriority }) { Auto-marked Unsuccessful. Two missed bookings detected by the scheduler. Decide on next step or revert.
- +
)} @@ -478,6 +487,10 @@ function TaskDetail({ task, allAudit = [], onClose, onMove, onPriority }) {