widget leantime refactor
This commit is contained in:
parent
9416cca90a
commit
334bfd04e3
@ -120,57 +120,82 @@ async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Log raw response for debugging
|
||||
logger.debug('[TWENTY_CRM_TASKS] Raw GraphQL response', {
|
||||
hasData: !!data.data,
|
||||
dataKeys: data.data ? Object.keys(data.data) : [],
|
||||
tasksEdgesCount: data.data?.tasks?.edges?.length || 0,
|
||||
sampleResponse: JSON.stringify(data.data).substring(0, 500),
|
||||
});
|
||||
|
||||
// Try different possible response structures
|
||||
// Twenty CRM may use different field names depending on version
|
||||
let activitiesData = null;
|
||||
if (data.data?.tasks?.edges) {
|
||||
activitiesData = data.data.tasks.edges;
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found tasks.edges', { count: activitiesData.length });
|
||||
} else if (data.data?.activities?.edges) {
|
||||
activitiesData = data.data.activities.edges;
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found activities.edges', { count: activitiesData.length });
|
||||
} else if (data.data?.findManyTasks?.edges) {
|
||||
activitiesData = data.data.findManyTasks.edges;
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found findManyTasks.edges', { count: activitiesData.length });
|
||||
} else if (data.data?.findManyActivities?.edges) {
|
||||
activitiesData = data.data.findManyActivities.edges;
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found findManyActivities.edges', { count: activitiesData.length });
|
||||
} else if (Array.isArray(data.data?.tasks)) {
|
||||
// Direct array response
|
||||
activitiesData = data.data.tasks.map((node: any) => ({ node }));
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found tasks as array', { count: activitiesData.length });
|
||||
} else if (Array.isArray(data.data?.activities)) {
|
||||
// Direct array response
|
||||
activitiesData = data.data.activities.map((node: any) => ({ node }));
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found activities as array', { count: activitiesData.length });
|
||||
} else if (Array.isArray(data.data)) {
|
||||
// Root level array
|
||||
activitiesData = data.data.map((node: any) => ({ node }));
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found data as array', { count: activitiesData.length });
|
||||
}
|
||||
|
||||
if (!activitiesData) {
|
||||
logger.warn('[TWENTY_CRM_TASKS] Unexpected response format from Twenty CRM', {
|
||||
dataKeys: Object.keys(data.data || {}),
|
||||
fullData: JSON.stringify(data.data).substring(0, 1000),
|
||||
fullData: JSON.stringify(data.data).substring(0, 2000),
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Activities data extracted', {
|
||||
count: activitiesData.length,
|
||||
sample: activitiesData.length > 0 ? {
|
||||
firstTask: {
|
||||
id: activitiesData[0]?.node?.id || activitiesData[0]?.id,
|
||||
title: activitiesData[0]?.node?.title || activitiesData[0]?.title,
|
||||
status: activitiesData[0]?.node?.status || activitiesData[0]?.status,
|
||||
dueAt: activitiesData[0]?.node?.dueAt || activitiesData[0]?.dueAt,
|
||||
}
|
||||
} : null,
|
||||
});
|
||||
|
||||
// Transform Twenty CRM tasks to match our Task interface
|
||||
// Filter client-side for overdue tasks (dueAt < today) and not completed (status !== 'Done')
|
||||
const tasks: TwentyTask[] = activitiesData
|
||||
.map((edge: any) => {
|
||||
const node = edge.node || edge; // Handle both edge.node and direct node
|
||||
|
||||
const allTasks: TwentyTask[] = activitiesData.map((edge: any) => {
|
||||
const node = edge.node || edge; // Handle both edge.node and direct node
|
||||
|
||||
// Extract text from bodyV2 (RichTextV2 type)
|
||||
let bodyText = null;
|
||||
if (node.bodyV2) {
|
||||
// bodyV2 has blocknote and markdown subfields
|
||||
bodyText = node.bodyV2.markdown || node.bodyV2.blocknote || null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: node.id,
|
||||
title: node.title || 'Untitled Task',
|
||||
bodyV2: node.bodyV2 || null,
|
||||
dueAt: node.dueAt || null,
|
||||
status: node.status || null,
|
||||
type: node.type || 'Task',
|
||||
assigneeId: node.assigneeId || null,
|
||||
|
||||
return {
|
||||
id: node.id,
|
||||
title: node.title || 'Untitled Task',
|
||||
bodyV2: node.bodyV2 || null,
|
||||
dueAt: node.dueAt || null,
|
||||
status: node.status || null,
|
||||
type: node.type || 'Task',
|
||||
assigneeId: node.assigneeId || null,
|
||||
assignee: node.assignee ? {
|
||||
id: node.assignee.id,
|
||||
name: node.assignee.name ? {
|
||||
@ -178,26 +203,53 @@ async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
||||
lastName: node.assignee.name.lastName || null,
|
||||
} : null,
|
||||
} : null,
|
||||
// Store extracted body text for easier access
|
||||
_bodyText: bodyText,
|
||||
};
|
||||
})
|
||||
// Store extracted body text for easier access
|
||||
_bodyText: bodyText,
|
||||
};
|
||||
});
|
||||
|
||||
// Log all tasks before filtering for debugging
|
||||
logger.debug('[TWENTY_CRM_TASKS] All tasks before filtering', {
|
||||
count: allTasks.length,
|
||||
tasks: allTasks.map(t => ({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
status: t.status,
|
||||
dueAt: t.dueAt,
|
||||
hasDueDate: !!t.dueAt,
|
||||
})),
|
||||
});
|
||||
|
||||
// Filter client-side for overdue tasks (dueAt < today) and not completed (status !== 'Done')
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const tasks: TwentyTask[] = allTasks
|
||||
.filter((task: TwentyTask) => {
|
||||
// Filter: only overdue tasks (dueAt < today) and not completed
|
||||
if (task.status === 'Done') {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Filtering out Done task', { id: task.id, status: task.status });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!task.dueAt) {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Filtering out task without due date', { id: task.id });
|
||||
return false; // Exclude tasks without due date
|
||||
}
|
||||
|
||||
const taskDueDate = new Date(task.dueAt);
|
||||
taskDueDate.setHours(0, 0, 0, 0);
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
return taskDueDate < today; // Only overdue tasks
|
||||
const isOverdue = taskDueDate < today;
|
||||
logger.debug('[TWENTY_CRM_TASKS] Task date check', {
|
||||
id: task.id,
|
||||
dueAt: task.dueAt,
|
||||
taskDueDate: taskDueDate.toISOString(),
|
||||
today: today.toISOString(),
|
||||
isOverdue,
|
||||
});
|
||||
|
||||
return isOverdue; // Only overdue tasks
|
||||
})
|
||||
.sort((a: TwentyTask, b: TwentyTask) => {
|
||||
// Sort by dueAt (oldest first)
|
||||
@ -207,6 +259,16 @@ async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
||||
return dateA - dateB;
|
||||
});
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Tasks after filtering', {
|
||||
count: tasks.length,
|
||||
tasks: tasks.map(t => ({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
status: t.status,
|
||||
dueAt: t.dueAt,
|
||||
})),
|
||||
});
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Successfully fetched tasks from Twenty CRM', {
|
||||
count: tasks.length,
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user