Widget Devoir Finition

This commit is contained in:
alma 2026-01-24 16:10:31 +01:00
parent 6af464eb70
commit 099c3b61bd
2 changed files with 1 additions and 158 deletions

View File

@ -113,8 +113,6 @@ async function getDoneStatusValues(userId: number): Promise<Set<string>> {
});
if (!data.result || typeof data.result !== 'object' || Array.isArray(data.result)) {
console.log('[LEANTIME_TASKS] ⚠️ Invalid response format from getAllStatusLabelsByUserId, using fallback');
console.log('[LEANTIME_TASKS] Response type:', typeof data.result, 'isArray:', Array.isArray(data.result));
logger.warn('[LEANTIME_TASKS] Invalid response format from getAllStatusLabelsByUserId, using fallback');
// Fallback to default values if API fails
return new Set(['0', '3', '5']);
@ -124,12 +122,6 @@ async function getDoneStatusValues(userId: number): Promise<Set<string>> {
// - Keys are project IDs (strings like "4", "5", "6", "457")
// - Values are objects where keys are status numbers (strings like "0", "1", "2", "3", "4", "5", "-1")
// - Each status object has: name, statusType, class, kanbanCol, sortKey
console.log('[LEANTIME_TASKS] 📋 getAllStatusLabelsByUserId response structure:', {
resultType: typeof data.result,
isObject: typeof data.result === 'object',
projectIds: Object.keys(data.result),
});
// Iterate through all projects
Object.keys(data.result).forEach((projectId: string) => {
@ -148,17 +140,12 @@ async function getDoneStatusValues(userId: number): Promise<Set<string>> {
if (statusType === 'DONE' || statusName === 'done' || statusName.includes('done')) {
// The statusKey IS the status number (e.g., "0", "3", "5", "-1")
doneStatusValues.add(statusKey);
console.log(`[LEANTIME_TASKS] ✅ Found done status: ${statusKey} in project ${projectId} (name: "${statusInfo.name}", statusType: "${statusType}")`);
}
}
});
}
});
console.log('[LEANTIME_TASKS] ✅ Identified done status values:', {
doneStatusValues: Array.from(doneStatusValues),
projectsCount: Object.keys(data.result).length,
});
logger.debug('[LEANTIME_TASKS] Identified done status values', {
doneStatusValues: Array.from(doneStatusValues),
projectsCount: Object.keys(data.result).length,
@ -181,14 +168,11 @@ async function getDoneStatusValues(userId: number): Promise<Set<string>> {
}
export async function GET(request: NextRequest) {
console.log('[LEANTIME_TASKS] 🔵 API CALLED - Starting request');
try {
const session = await getServerSession(authOptions);
if (!session?.user?.email) {
console.log('[LEANTIME_TASKS] ❌ Unauthorized - no session');
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
console.log('[LEANTIME_TASKS] ✅ Session found, user:', session.user.email);
// Check for force refresh parameter
const url = new URL(request.url);
@ -206,7 +190,6 @@ export async function GET(request: NextRequest) {
// Get done status values dynamically from Leantime status labels
const doneStatusValues = await getDoneStatusValues(userId);
console.log('[LEANTIME_TASKS] ✅ Done status values for filtering:', Array.from(doneStatusValues));
logger.debug('[LEANTIME_TASKS] Done status values identified', {
doneStatusValues: Array.from(doneStatusValues),
});
@ -291,12 +274,6 @@ export async function GET(request: NextRequest) {
throw new Error('Invalid response format from Leantime');
}
console.log('[LEANTIME_TASKS] 🔍 RAW DATA FROM LEANTIME - Total tasks:', data.result.length);
// Log RAW data from Leantime to see exact status values (using console.log so it shows in production)
data.result.forEach((task: any) => {
console.log(`[LEANTIME_TASKS] Task ID: ${task.id}, Headline: ${task.headline}, Status: ${task.status} (type: ${typeof task.status}), EditorId: ${task.editorId}`);
});
// Log detailed status information before filtering
const statusBreakdownBefore = data.result.reduce((acc: any, task: any) => {
const status = task.status;
@ -342,9 +319,6 @@ export async function GET(request: NextRequest) {
// Only show tasks where the user is the editor
const isUserEditor = taskEditorId === currentUserId;
if (!isUserEditor) {
console.log(`[LEANTIME_TASKS] ⚠️ Task filtered - user is not editor: ID=${task.id}, EditorId=${taskEditorId}, UserId=${currentUserId}`);
}
return isUserEditor;
})

View File

@ -131,26 +131,15 @@ export function Duties() {
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,
headline: t.headline,
status: t.status,
statusType: typeof t.status,
})));
// Mark tasks with source
leantimeTasks = leantimeData.map((t: Task) => ({ ...t, source: 'leantime' as const }));
}
} else {
console.warn('Failed to fetch Leantime tasks:', leantimeResponse);
}
// Process Twenty CRM tasks
@ -161,79 +150,11 @@ export function Duties() {
// Mark tasks with source
twentyCrmTasks = twentyCrmData.map((t: Task) => ({ ...t, source: 'twenty-crm' as const }));
}
} else {
console.warn('Failed to fetch Twenty CRM tasks:', twentyCrmResponse);
}
// Combine tasks from both sources
const allTasks = [...leantimeTasks, ...twentyCrmTasks];
// Log detailed status information
const leantimeStatusDetails = leantimeTasks.map((t: Task) => {
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();
// Use dynamic done statuses instead of hardcoded values
const isDone = currentDoneStatuses.has(String(rawStatus)) || currentDoneStatuses.has(statusStr);
return {
id: t.id,
headline: t.headline,
status: rawStatus,
statusType: typeof rawStatus,
statusNum,
statusStr,
isDone,
};
});
// Group by status for better visibility
const statusGroups = leantimeStatusDetails.reduce((acc: any, t) => {
const key = String(t.status);
if (!acc[key]) {
acc[key] = { status: t.status, count: 0, tasks: [] };
}
acc[key].count++;
if (acc[key].tasks.length < 3) {
acc[key].tasks.push({ id: t.id, headline: t.headline });
}
return acc;
}, {});
const doneTasks = leantimeStatusDetails.filter(t => t.isDone);
// Always log status breakdown for debugging
const statusGroupsArray = Object.keys(statusGroups).map(key => ({
status: key,
count: statusGroups[key].count,
sample: statusGroups[key].tasks,
}));
console.log('[Devoirs Widget] 📊 Status Breakdown:', {
totalTasks: leantimeTasks.length,
statusGroups: statusGroupsArray,
doneTasksCount: doneTasks.length,
allStatuses: leantimeStatusDetails.map(t => `${t.id}:${t.status}(${t.statusType})`),
});
if (doneTasks.length > 0) {
console.error('[Devoirs Widget] ❌❌❌ FOUND DONE TASKS - THEY SHOULD BE FILTERED ❌❌❌', {
total: leantimeTasks.length,
doneCount: doneTasks.length,
doneTasks: doneTasks.map(t => ({
id: t.id,
headline: t.headline,
status: t.status,
statusType: t.statusType,
statusNum: t.statusNum,
statusStr: t.statusStr,
})),
});
}
console.log('[Devoirs Widget] Combined tasks:', {
leantime: leantimeTasks.length,
twentyCrm: twentyCrmTasks.length,
total: allTasks.length,
});
if (allTasks.length === 0) {
setTasks([]);
@ -256,12 +177,6 @@ export function Duties() {
// 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,
source: task.source,
});
return false;
}
// For Twenty CRM or legacy format, keep old check as fallback
@ -269,11 +184,6 @@ export function Duties() {
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;
}
}
@ -302,17 +212,6 @@ export function Duties() {
return isOverdueOrDueToday;
});
// Log filtered results
console.log('[Devoirs Widget] Filtering results:', {
before: allTasks.length,
after: filteredTasks.length,
filteredOut: allTasks.length - filteredTasks.length,
filteredTasksStatuses: filteredTasks.map((t: Task) => ({
id: t.id,
headline: t.headline,
status: (t as any).status,
})),
});
// Sort by dateToFinish (oldest first)
const sortedTasks = filteredTasks
@ -338,14 +237,6 @@ export function Duties() {
return 0;
});
console.log('Sorted tasks:', sortedTasks.map(t => ({
id: t.id,
date: t.dateToFinish,
status: t.status,
type: t.type || 'main',
source: (t as any).source || 'leantime'
})));
// Calculate current task count
const currentTaskCount = sortedTasks.length;
@ -401,12 +292,6 @@ export function Duties() {
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;
@ -416,11 +301,6 @@ export function Duties() {
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';
if (isDone) {
console.warn('[Devoirs Widget] ⚠️ Filtering out done task before notification:', {
id: task.id,
headline: task.headline,
status: rawStatus,
});
return false;
}
return true;
@ -434,25 +314,14 @@ export function Duties() {
url: (task as any).url || null,
}));
console.log('[Devoirs Widget] 📋 Dispatching tasks update', {
tasksCount: tasksForNotification.length,
tasks: tasksForNotification.map(t => ({
id: t.id,
title: t.headline,
dateToFinish: t.dateToFinish,
source: t.source,
})),
});
try {
window.dispatchEvent(new CustomEvent('tasks-updated', {
detail: {
tasks: tasksForNotification,
}
}));
console.log('[Devoirs Widget] ✅ Event dispatched successfully');
} catch (error) {
console.error('[Devoirs Widget] Error dispatching event', error);
console.error('[Devoirs Widget] Error dispatching event', error);
}
} catch (error) {
console.error('Error fetching tasks:', error);