Widget Devoir Finition
This commit is contained in:
parent
485c49523e
commit
b3ce739153
@ -246,7 +246,11 @@ export async function GET(request: NextRequest) {
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
taskCount: filteredCachedTasks.length,
|
||||
});
|
||||
return NextResponse.json(filteredCachedTasks);
|
||||
// Return tasks with done statuses for frontend filtering
|
||||
return NextResponse.json({
|
||||
tasks: filteredCachedTasks,
|
||||
doneStatuses: Array.from(doneStatusValues),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,7 +392,11 @@ export async function GET(request: NextRequest) {
|
||||
// Cache the results
|
||||
await cacheTasksData(session.user.id, tasks);
|
||||
|
||||
return NextResponse.json(tasks);
|
||||
// Return tasks with done statuses for frontend filtering
|
||||
return NextResponse.json({
|
||||
tasks: tasks,
|
||||
doneStatuses: Array.from(doneStatusValues),
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('[LEANTIME_TASKS] Error in tasks route', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
|
||||
@ -50,6 +50,7 @@ export function Duties() {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const { triggerNotification } = useWidgetNotification();
|
||||
const lastTaskCountRef = useRef<number>(-1);
|
||||
const [leantimeDoneStatuses, setLeantimeDoneStatuses] = useState<Set<string>>(new Set(['0', '3', '5'])); // Fallback values
|
||||
|
||||
const getStatusLabel = (status: number): string => {
|
||||
switch (status) {
|
||||
@ -114,9 +115,29 @@ export function Duties() {
|
||||
|
||||
// Process Leantime tasks
|
||||
let leantimeTasks: Task[] = [];
|
||||
let currentDoneStatuses = new Set<string>(['0', '3', '5']); // Fallback values
|
||||
if (leantimeResponse.status === 'fulfilled' && leantimeResponse.value.ok) {
|
||||
const leantimeData = await leantimeResponse.value.json();
|
||||
if (Array.isArray(leantimeData)) {
|
||||
const leantimeResponseData = await leantimeResponse.value.json();
|
||||
|
||||
// Handle both formats: new format with {tasks, doneStatuses} or legacy array format
|
||||
let leantimeData: Task[];
|
||||
if (Array.isArray(leantimeResponseData)) {
|
||||
// Legacy format: direct array
|
||||
leantimeData = leantimeResponseData;
|
||||
} else if (leantimeResponseData.tasks && Array.isArray(leantimeResponseData.tasks)) {
|
||||
// New format: object with tasks and doneStatuses
|
||||
leantimeData = leantimeResponseData.tasks;
|
||||
if (leantimeResponseData.doneStatuses && Array.isArray(leantimeResponseData.doneStatuses)) {
|
||||
currentDoneStatuses = new Set(leantimeResponseData.doneStatuses);
|
||||
setLeantimeDoneStatuses(currentDoneStatuses);
|
||||
console.log('[Devoirs Widget] ✅ Using dynamic done statuses from API:', leantimeResponseData.doneStatuses);
|
||||
}
|
||||
} else {
|
||||
console.warn('[Devoirs Widget] ⚠️ Invalid Leantime response format:', leantimeResponseData);
|
||||
leantimeData = [];
|
||||
}
|
||||
|
||||
if (leantimeData.length > 0) {
|
||||
// Log ALL tasks with their statuses to see what we receive
|
||||
console.log('[Devoirs Widget] 📥 RAW Leantime tasks from API:', leantimeData.map((t: any) => ({
|
||||
id: t.id,
|
||||
@ -125,22 +146,6 @@ export function Duties() {
|
||||
statusType: typeof t.status,
|
||||
})));
|
||||
leantimeTasks = leantimeData;
|
||||
// Log tasks with status 0, 3, or 5 (done) to debug
|
||||
const doneTasks = leantimeData.filter((t: Task) => {
|
||||
const taskStatus = (t as any).status; // Use any to handle potential string/number mismatch
|
||||
if (taskStatus === null || taskStatus === undefined) return false;
|
||||
const statusNum = typeof taskStatus === 'string' ? parseInt(taskStatus, 10) : taskStatus;
|
||||
const statusStr = typeof taskStatus === 'string' ? taskStatus.toLowerCase() : String(taskStatus).toLowerCase();
|
||||
return statusNum === 0 || statusNum === 3 || statusNum === 5 || statusStr === '0' || statusStr === '3' || statusStr === '5' || statusStr === 'done';
|
||||
});
|
||||
if (doneTasks.length > 0) {
|
||||
console.warn('[Devoirs Widget] ⚠️ Received done tasks from Leantime API:', doneTasks.map((t: Task) => ({
|
||||
id: t.id,
|
||||
headline: t.headline,
|
||||
status: t.status,
|
||||
statusType: typeof t.status,
|
||||
})));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn('Failed to fetch Leantime tasks:', leantimeResponse);
|
||||
@ -165,7 +170,8 @@ export function Duties() {
|
||||
const rawStatus = (t as any).status;
|
||||
const statusNum = typeof rawStatus === 'string' ? parseInt(rawStatus, 10) : rawStatus;
|
||||
const statusStr = typeof rawStatus === 'string' ? rawStatus.toLowerCase().trim() : String(rawStatus).toLowerCase().trim();
|
||||
const isDone = statusNum === 0 || statusNum === 3 || statusNum === 5 || statusStr === '0' || statusStr === '3' || statusStr === '5' || statusStr === 'done';
|
||||
// Use dynamic done statuses instead of hardcoded values
|
||||
const isDone = currentDoneStatuses.has(String(rawStatus)) || currentDoneStatuses.has(statusStr);
|
||||
return {
|
||||
id: t.id,
|
||||
headline: t.headline,
|
||||
@ -240,30 +246,43 @@ export function Duties() {
|
||||
const todayDay = now.getDate();
|
||||
|
||||
const filteredTasks = allTasks.filter((task: Task) => {
|
||||
// Exclude tasks with status Done
|
||||
// In Leantime: status 3 = DONE (see api/leantime/status-labels/route.ts), also check status 5
|
||||
// FILTRE 1: Exclude tasks with status Done (using dynamic done statuses)
|
||||
const rawStatus = (task as any).status; // Use any to handle potential string/number mismatch
|
||||
if (rawStatus === null || rawStatus === undefined) {
|
||||
// If status is null/undefined, keep the task (let other filters handle it)
|
||||
} else {
|
||||
const taskStatus = typeof rawStatus === 'string' ? parseInt(rawStatus, 10) : rawStatus;
|
||||
const statusStr = typeof rawStatus === 'string' ? rawStatus.toLowerCase() : String(rawStatus).toLowerCase();
|
||||
if (taskStatus === 0 || taskStatus === 3 || taskStatus === 5 || statusStr === '0' || statusStr === '3' || statusStr === '5' || statusStr === 'done') {
|
||||
if (rawStatus !== null && rawStatus !== undefined) {
|
||||
const statusStr = String(rawStatus);
|
||||
// Check if this task's status is in the done statuses set (for Leantime tasks)
|
||||
// For Twenty CRM tasks, we still check the old way since they don't use dynamic statuses
|
||||
if (task.source === 'leantime' && currentDoneStatuses.has(statusStr)) {
|
||||
console.log('[Devoirs Widget] Filtering out done task:', {
|
||||
id: task.id,
|
||||
headline: task.headline,
|
||||
status: rawStatus,
|
||||
taskStatus,
|
||||
source: task.source,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// For Twenty CRM or legacy format, keep old check as fallback
|
||||
if (task.source !== 'leantime') {
|
||||
const taskStatus = typeof rawStatus === 'string' ? parseInt(rawStatus, 10) : rawStatus;
|
||||
const statusStrLower = typeof rawStatus === 'string' ? rawStatus.toLowerCase() : String(rawStatus).toLowerCase();
|
||||
if (taskStatus === 0 || taskStatus === 3 || taskStatus === 5 || statusStrLower === '0' || statusStrLower === '3' || statusStrLower === '5' || statusStrLower === 'done') {
|
||||
console.log('[Devoirs Widget] Filtering out done task (Twenty CRM):', {
|
||||
id: task.id,
|
||||
headline: task.headline,
|
||||
status: rawStatus,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const dueDate = getValidDate(task);
|
||||
if (!dueDate) {
|
||||
return false; // Exclude tasks without a due date
|
||||
}
|
||||
|
||||
// FILTRE 2: Exclude tasks without a due date
|
||||
const dueDate = getValidDate(task);
|
||||
if (!dueDate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FILTRE 3: Keep tasks with due date <= today (overdue or due today, not future)
|
||||
// Use local date comparison to avoid timezone issues
|
||||
// Leantime dates with 'Z' are actually local time, not UTC - remove Z before parsing
|
||||
const dateStrForParsing = dueDate.endsWith('Z') ? dueDate.slice(0, -1) : dueDate;
|
||||
@ -375,6 +394,21 @@ export function Duties() {
|
||||
if (rawStatus === null || rawStatus === undefined) {
|
||||
return true; // Keep tasks without status
|
||||
}
|
||||
// Use dynamic done statuses for Leantime tasks
|
||||
if (task.source === 'leantime') {
|
||||
const statusStr = String(rawStatus);
|
||||
if (currentDoneStatuses.has(statusStr)) {
|
||||
console.warn('[Devoirs Widget] ⚠️ Filtering out done task before notification:', {
|
||||
id: task.id,
|
||||
headline: task.headline,
|
||||
status: rawStatus,
|
||||
source: task.source,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// For Twenty CRM tasks, use old check as fallback
|
||||
const taskStatus = typeof rawStatus === 'string' ? parseInt(rawStatus, 10) : rawStatus;
|
||||
const statusStr = typeof rawStatus === 'string' ? rawStatus.toLowerCase().trim() : String(rawStatus).toLowerCase().trim();
|
||||
const isDone = taskStatus === 0 || taskStatus === 3 || taskStatus === 5 || statusStr === '0' || statusStr === '3' || statusStr === '5' || statusStr === 'done';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user