kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 121 lines 3.0 kB view raw
1import { eq } from "drizzle-orm"; 2import db from "../../../database"; 3import { labelTable, taskTable } from "../../../database/schema"; 4import { findExternalLink } from "../services/link-manager"; 5import { 6 findAllIntegrationsByRepo, 7 updateTaskStatus, 8} from "../services/task-service"; 9import { 10 extractIssuePriority, 11 extractIssueStatus, 12} from "../utils/extract-priority"; 13 14type IssueLabeledPayload = { 15 action: string; 16 issue: { 17 number: number; 18 labels?: Array<string | { name?: string }>; 19 }; 20 label?: { 21 name: string; 22 color: string; 23 }; 24 repository: { 25 owner: { login: string }; 26 name: string; 27 }; 28}; 29 30export async function handleIssueLabeled(payload: IssueLabeledPayload) { 31 const { issue, repository, label: addedLabel } = payload; 32 33 const integrations = await findAllIntegrationsByRepo( 34 repository.owner.login, 35 repository.name, 36 ); 37 38 for (const integration of integrations) { 39 const existingLink = await findExternalLink( 40 integration.id, 41 "issue", 42 issue.number.toString(), 43 ); 44 45 if (!existingLink) { 46 continue; 47 } 48 49 const priority = extractIssuePriority(issue.labels); 50 const status = extractIssueStatus(issue.labels); 51 52 if (priority) { 53 await db 54 .update(taskTable) 55 .set({ priority }) 56 .where(eq(taskTable.id, existingLink.taskId)); 57 } 58 59 if (status) { 60 await updateTaskStatus(existingLink.taskId, status); 61 } 62 63 if (!addedLabel) { 64 return; 65 } 66 67 const isSystemLabel = 68 addedLabel.name.startsWith("priority:") || 69 addedLabel.name.startsWith("status:"); 70 71 if (isSystemLabel) { 72 return; 73 } 74 75 if (payload.action === "labeled") { 76 const task = await db.query.taskTable.findFirst({ 77 where: eq(taskTable.id, existingLink.taskId), 78 with: { 79 project: true, 80 }, 81 }); 82 83 if (task?.project?.workspaceId) { 84 const existingLabel = await db.query.labelTable.findFirst({ 85 where: (table, { and, eq }) => 86 and( 87 eq(table.workspaceId, task.project.workspaceId), 88 eq(table.name, addedLabel.name), 89 eq(table.taskId, task.id), 90 ), 91 }); 92 93 if (!existingLabel) { 94 const color = addedLabel.color ? `#${addedLabel.color}` : "#6B7280"; 95 await db.insert(labelTable).values({ 96 name: addedLabel.name, 97 color, 98 taskId: task.id, 99 workspaceId: task.project.workspaceId, 100 }); 101 } 102 } 103 } 104 105 if (payload.action === "unlabeled") { 106 const labelsToDelete = await db.query.labelTable.findMany({ 107 where: (table, { and, eq }) => 108 and( 109 eq(table.taskId, existingLink.taskId), 110 eq(table.name, addedLabel.name), 111 ), 112 }); 113 114 for (const label of labelsToDelete) { 115 await db.delete(labelTable).where(eq(labelTable.id, label.id)); 116 } 117 } 118 119 return; 120 } 121}