From 9e5689b06f5c134e23e2ecd7a33585d2e834aa8a Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Wed, 9 Jul 2025 11:59:57 -0400 Subject: [PATCH] feature/IO-3291-Tasks-Notifications: Checkpoint --- .../task-center/task-center.component.jsx | 94 ++++++++++++------- .../task-center/task-center.container.jsx | 16 ++-- .../task-center/task-center.styles.scss | 45 ++++++++- 3 files changed, 107 insertions(+), 48 deletions(-) diff --git a/client/src/components/task-center/task-center.component.jsx b/client/src/components/task-center/task-center.component.jsx index da4ebaf52..16303d6c2 100644 --- a/client/src/components/task-center/task-center.component.jsx +++ b/client/src/components/task-center/task-center.component.jsx @@ -12,59 +12,83 @@ const TaskCenterComponent = forwardRef(({ visible, tasks, loading, onTaskClick, const { t } = useTranslation(); const virtuosoRef = useRef(null); - const sections = useMemo(() => { + const groupedItems = useMemo(() => { const now = day(); const today = now.startOf("day"); - const overdue = tasks.filter((task) => task.due_date && day(task.due_date).isBefore(today)); - const dueToday = tasks.filter((task) => task.due_date && day(task.due_date).isSame(today, "day")); - const upcoming = tasks.filter((task) => task.due_date && day(task.due_date).isAfter(today)); - const noDueDate = tasks.filter((task) => !task.due_date); + const overdue = tasks.filter((t) => t.due_date && day(t.due_date).isBefore(today)); + const dueToday = tasks.filter((t) => t.due_date && day(t.due_date).isSame(today, "day")); + const upcoming = tasks.filter((t) => t.due_date && day(t.due_date).isAfter(today)); + const noDueDate = tasks.filter((t) => !t.due_date); + + const makeGroup = (label, data) => + data.length ? [{ type: "header", label }, ...data.map((task) => ({ type: "task", task }))] : []; return [ - { title: t("tasks.labels.overdue"), data: overdue }, - { title: t("tasks.labels.due_today"), data: dueToday }, - { title: t("tasks.labels.upcoming"), data: upcoming }, - { title: t("tasks.labels.no_due_date"), data: noDueDate } - ].filter((section) => section.data.length > 0); + ...makeGroup(t("tasks.labels.overdue"), overdue), + ...makeGroup(t("tasks.labels.due_today"), dueToday), + ...makeGroup(t("tasks.labels.upcoming"), upcoming), + ...makeGroup(t("tasks.labels.no_due_date"), noDueDate) + ]; }, [tasks, t]); const renderTask = (index, task) => { - const handleClick = () => { - onTaskClick(task.id); + const handleClick = () => onTaskClick(task.id); + + const getPriorityColor = (priority) => { + switch (priority) { + case 1: + return "red"; + case 2: + return "orange"; + case 3: + return "green"; + default: + return null; + } }; + const priorityColor = getPriorityColor(task.priority); + return (
- +
- - <span className="ro-number"> - {t("notifications.labels.ro-number", { - ro_number: task.job?.ro_number || t("general.labels.na") - })} - </span> - <Text type="secondary" className="relative-time" title={DateTimeFormat(task.created_at)}> - {day(task.created_at).fromNow()} - </Text> - {task.title} + +
+
+ {t("notifications.labels.ro-number", { + ro_number: task.job?.ro_number || t("general.labels.na") + })} +
+ {task.due_date && ( + + {day(task.due_date).fromNow()} + + )} +
); }; - const renderSection = (section, sectionIndex) => ( -
- - {section.title} - - {section.data.map((task, index) => renderTask(`${sectionIndex}-${index}`, task))} -
- ); + const renderItem = (index, item) => { + if (item.type === "header") { + return ( +
+ + {item.label} + +
+ ); + } + + return renderTask(index, item.task); + }; return (
@@ -72,13 +96,14 @@ const TaskCenterComponent = forwardRef(({ visible, tasks, loading, onTaskClick,

{t("tasks.labels.my_tasks_center")}

{loading && }
+ renderSection(section, index)} + data={groupedItems} + itemContent={renderItem} /> + {tasks.length < totalTasks && (