fix(tasks): overdue always first; sort by due date, priority as tiebreaker
effectiveDue() and sortTasks() added — same logic on client (tasks.js)
and server (dashboard.js urgentTasks moved from SQL to JS sort).
Applies in list-group, Kanban, and dashboard widget views.
SQLite DATE('now') replaced with new Date() for timezone-safe due_time.
This commit is contained in:
+33
-18
@@ -42,9 +42,12 @@ router.get('/', (req, res) => {
|
||||
SELECT
|
||||
ce.*,
|
||||
u.display_name AS assigned_name,
|
||||
u.avatar_color AS assigned_color
|
||||
u.avatar_color AS assigned_color,
|
||||
ec.name AS cal_name,
|
||||
ec.color AS cal_color
|
||||
FROM calendar_events ce
|
||||
LEFT JOIN users u ON ce.assigned_to = u.id
|
||||
LEFT JOIN users u ON ce.assigned_to = u.id
|
||||
LEFT JOIN external_calendars ec ON ec.id = ce.calendar_ref_id
|
||||
WHERE ce.start_datetime >= ?
|
||||
ORDER BY ce.start_datetime ASC
|
||||
LIMIT 5
|
||||
@@ -54,27 +57,39 @@ router.get('/', (req, res) => {
|
||||
result.upcomingEvents = [];
|
||||
}
|
||||
|
||||
// Offene Aufgaben: alle nicht-erledigten, sortiert nach Priorität und Fälligkeit
|
||||
// Offene Aufgaben: in JS sortiert damit due_time korrekt gegen lokale Zeit geprüft wird
|
||||
try {
|
||||
result.urgentTasks = d.prepare(`
|
||||
SELECT
|
||||
t.*,
|
||||
u.display_name AS assigned_name,
|
||||
u.avatar_color AS assigned_color
|
||||
const allOpen = d.prepare(`
|
||||
SELECT t.*, u.display_name AS assigned_name, u.avatar_color AS assigned_color
|
||||
FROM tasks t
|
||||
LEFT JOIN users u ON t.assigned_to = u.id
|
||||
WHERE t.status != 'done'
|
||||
ORDER BY
|
||||
CASE t.priority
|
||||
WHEN 'urgent' THEN 0
|
||||
WHEN 'high' THEN 1
|
||||
WHEN 'medium' THEN 2
|
||||
WHEN 'low' THEN 3
|
||||
ELSE 4
|
||||
END,
|
||||
t.due_date ASC NULLS LAST
|
||||
LIMIT 5
|
||||
`).all();
|
||||
|
||||
const PRIO = { urgent: 0, high: 1, medium: 2, low: 3, none: 4 };
|
||||
const now = new Date();
|
||||
|
||||
function effectiveDue(task) {
|
||||
if (!task.due_date) return null;
|
||||
return task.due_time
|
||||
? new Date(`${task.due_date}T${task.due_time}`)
|
||||
: new Date(`${task.due_date}T23:59:59`);
|
||||
}
|
||||
|
||||
allOpen.sort((a, b) => {
|
||||
const aDate = effectiveDue(a);
|
||||
const bDate = effectiveDue(b);
|
||||
const aOver = aDate && aDate < now ? 1 : 0;
|
||||
const bOver = bDate && bDate < now ? 1 : 0;
|
||||
if (bOver !== aOver) return bOver - aOver;
|
||||
if (!aDate && !bDate) return (PRIO[a.priority] ?? 4) - (PRIO[b.priority] ?? 4);
|
||||
if (!aDate) return 1;
|
||||
if (!bDate) return -1;
|
||||
if (aDate.getTime() !== bDate.getTime()) return aDate < bDate ? -1 : 1;
|
||||
return (PRIO[a.priority] ?? 4) - (PRIO[b.priority] ?? 4);
|
||||
});
|
||||
|
||||
result.urgentTasks = allOpen.slice(0, 5);
|
||||
} catch (err) {
|
||||
log.error('urgentTasks-Fehler:', err.message);
|
||||
result.urgentTasks = [];
|
||||
|
||||
Reference in New Issue
Block a user