widget leantime refactor
This commit is contained in:
parent
b4099d507e
commit
90bde85c5c
@ -23,10 +23,90 @@ interface TwentyTask {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Twenty CRM workspace member ID by email
|
||||||
|
*/
|
||||||
|
async function getTwentyCrmUserId(email: string): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
if (!process.env.TWENTY_CRM_API_URL || !process.env.TWENTY_CRM_API_KEY) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiUrl = process.env.TWENTY_CRM_API_URL.endsWith('/graphql')
|
||||||
|
? process.env.TWENTY_CRM_API_URL
|
||||||
|
: `${process.env.TWENTY_CRM_API_URL}/graphql`;
|
||||||
|
|
||||||
|
// Query to find workspace member by email
|
||||||
|
const query = `
|
||||||
|
query GetWorkspaceMemberByEmail {
|
||||||
|
workspaceMembers {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
user {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const response = await fetch(apiUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${process.env.TWENTY_CRM_API_KEY}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ query }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
logger.error('[TWENTY_CRM_TASKS] Failed to fetch workspace members', {
|
||||||
|
status: response.status,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.errors) {
|
||||||
|
logger.error('[TWENTY_CRM_TASKS] GraphQL errors fetching workspace members', {
|
||||||
|
errors: data.errors,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find workspace member with matching email
|
||||||
|
const members = data.data?.workspaceMembers?.edges || [];
|
||||||
|
const member = members.find((edge: any) =>
|
||||||
|
edge.node?.user?.email?.toLowerCase() === email.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (member) {
|
||||||
|
logger.debug('[TWENTY_CRM_TASKS] Found workspace member', {
|
||||||
|
memberId: member.node.id,
|
||||||
|
emailHash: Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12),
|
||||||
|
});
|
||||||
|
return member.node.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn('[TWENTY_CRM_TASKS] Workspace member not found', {
|
||||||
|
emailHash: Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12),
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[TWENTY_CRM_TASKS] Error fetching workspace member', {
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch tasks from Twenty CRM using GraphQL API
|
* Fetch tasks from Twenty CRM using GraphQL API
|
||||||
*/
|
*/
|
||||||
async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||||
try {
|
try {
|
||||||
if (!process.env.TWENTY_CRM_API_URL) {
|
if (!process.env.TWENTY_CRM_API_URL) {
|
||||||
logger.error('[TWENTY_CRM_TASKS] TWENTY_CRM_API_URL is not set in environment variables');
|
logger.error('[TWENTY_CRM_TASKS] TWENTY_CRM_API_URL is not set in environment variables');
|
||||||
@ -216,18 +296,40 @@ async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
|||||||
title: t.title,
|
title: t.title,
|
||||||
status: t.status,
|
status: t.status,
|
||||||
dueAt: t.dueAt,
|
dueAt: t.dueAt,
|
||||||
|
assigneeId: t.assigneeId,
|
||||||
hasDueDate: !!t.dueAt,
|
hasDueDate: !!t.dueAt,
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter client-side for overdue tasks (dueAt < today) and not completed (status !== 'Done')
|
// Filter by assignee if userId is provided
|
||||||
|
let filteredByAssignee = allTasks;
|
||||||
|
if (userId) {
|
||||||
|
filteredByAssignee = allTasks.filter((task: TwentyTask) => {
|
||||||
|
const isAssignedToUser = task.assigneeId === userId;
|
||||||
|
if (!isAssignedToUser) {
|
||||||
|
logger.debug('[TWENTY_CRM_TASKS] Filtering out task not assigned to user', {
|
||||||
|
id: task.id,
|
||||||
|
assigneeId: task.assigneeId,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return isAssignedToUser;
|
||||||
|
});
|
||||||
|
logger.error('[TWENTY_CRM_TASKS] Tasks after assignee filter', {
|
||||||
|
before: allTasks.length,
|
||||||
|
after: filteredByAssignee.length,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter client-side for overdue tasks (dueAt <= today) and not completed (status !== 'Done')
|
||||||
// Use local date for comparison to avoid timezone issues
|
// Use local date for comparison to avoid timezone issues
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const todayYear = now.getFullYear();
|
const todayYear = now.getFullYear();
|
||||||
const todayMonth = now.getMonth();
|
const todayMonth = now.getMonth();
|
||||||
const todayDay = now.getDate();
|
const todayDay = now.getDate();
|
||||||
|
|
||||||
const tasks: TwentyTask[] = allTasks
|
const tasks: TwentyTask[] = filteredByAssignee
|
||||||
.filter((task: TwentyTask) => {
|
.filter((task: TwentyTask) => {
|
||||||
// Filter: only overdue tasks (dueAt < today) and not completed
|
// Filter: only overdue tasks (dueAt < today) and not completed
|
||||||
if (task.status === 'Done') {
|
if (task.status === 'Done') {
|
||||||
@ -311,7 +413,22 @@ export async function GET(request: NextRequest) {
|
|||||||
forceRefresh,
|
forceRefresh,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tasks = await fetchTwentyTasks();
|
// Get Twenty CRM user ID from email
|
||||||
|
const twentyCrmUserId = await getTwentyCrmUserId(session.user.email);
|
||||||
|
|
||||||
|
if (!twentyCrmUserId) {
|
||||||
|
logger.warn('[TWENTY_CRM_TASKS] User not found in Twenty CRM, returning empty tasks', {
|
||||||
|
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||||
|
});
|
||||||
|
return NextResponse.json([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug('[TWENTY_CRM_TASKS] Found Twenty CRM user ID', {
|
||||||
|
userId: twentyCrmUserId,
|
||||||
|
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||||
|
});
|
||||||
|
|
||||||
|
const tasks = await fetchTwentyTasks(twentyCrmUserId);
|
||||||
|
|
||||||
// Transform to match Leantime task format for consistency
|
// Transform to match Leantime task format for consistency
|
||||||
const transformedTasks = tasks.map((task) => ({
|
const transformedTasks = tasks.map((task) => ({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user