"use client"; import { createElement } from "react"; import { useTranslation } from "react-i18next"; import { IconBrandGitlab, IconBrandSentry, IconCircleDot, IconGitPullRequest, IconLink, IconTicket, } from "@tabler/icons-react"; import { ContextMenuItem, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, } from "@kandev/ui/context-menu"; import { resolvePluginIcon } from "@/lib/plugins/icons"; import type { PluginIcon } from "@/lib/plugins/types"; import { useTaskPluginLinkActions } from "./task-session-sidebar-link-actions"; import type { TaskSwitcherItem } from "./task-switcher-types"; export type TaskLinkHandlers = { onLinkPullRequest?: (taskId: string, taskTitle?: string) => void; onLinkIssue?: (taskId: string, taskTitle?: string) => void; onLinkMergeRequest?: (taskId: string, taskTitle?: string) => void; onLinkJiraTicket?: (taskId: string, taskTitle?: string) => void; onLinkLinearIssue?: (taskId: string, taskTitle?: string) => void; onLinkSentryIssue?: (taskId: string, taskTitle?: string) => void; }; export function createTaskLinkSelectAction( task: Pick, handler: ((taskId: string, taskTitle?: string) => void) | undefined, closeMenu: () => void, ) { if (!handler) return undefined; return () => { closeMenu(); handler(task.id, task.title); }; } export function selectTaskLinkActions( task: Pick, closeMenu: () => void, handlers: TaskLinkHandlers, ) { return { onLinkPullRequest: createTaskLinkSelectAction(task, handlers.onLinkPullRequest, closeMenu), onLinkIssue: createTaskLinkSelectAction(task, handlers.onLinkIssue, closeMenu), onLinkMergeRequest: createTaskLinkSelectAction(task, handlers.onLinkMergeRequest, closeMenu), onLinkJiraTicket: createTaskLinkSelectAction(task, handlers.onLinkJiraTicket, closeMenu), onLinkLinearIssue: createTaskLinkSelectAction(task, handlers.onLinkLinearIssue, closeMenu), onLinkSentryIssue: createTaskLinkSelectAction(task, handlers.onLinkSentryIssue, closeMenu), }; } export function TaskPluginLinkMenu({ task, disabled, closeMenu, linkActions, }: { task: TaskSwitcherItem; disabled?: boolean; closeMenu: () => void; linkActions: ReturnType; }) { const pluginLinkActions = useTaskPluginLinkActions(task.id, task.repositoryLinks ?? []); return ( ({ ...action, onSelect: () => { closeMenu(); queueMicrotask(action.onSelect); }, }))} {...linkActions} /> ); } function TaskLinkMenu({ disabled, onLinkPullRequest, onLinkIssue, onLinkMergeRequest, onLinkJiraTicket, onLinkLinearIssue, onLinkSentryIssue, pluginLinkActions = [], }: { disabled?: boolean; onLinkPullRequest?: () => void; onLinkIssue?: () => void; onLinkMergeRequest?: () => void; onLinkJiraTicket?: () => void; onLinkLinearIssue?: () => void; onLinkSentryIssue?: () => void; pluginLinkActions?: { id: string; label: string; icon?: PluginIcon; onSelect: () => void }[]; }) { const { t } = useTranslation(); if ( !onLinkPullRequest && !onLinkIssue && !onLinkMergeRequest && !onLinkJiraTicket && !onLinkLinearIssue && !onLinkSentryIssue && pluginLinkActions.length === 0 ) { return null; } return ( {t("task:link")} {onLinkPullRequest ? ( {t("task:githubPullRequest")} ) : null} {onLinkIssue ? ( {t("task:githubIssue")} ) : null} {onLinkMergeRequest ? ( {t("task:gitlabMergeRequest")} ) : null} {onLinkJiraTicket ? ( {t("task:jiraTicket")} ) : null} {onLinkLinearIssue ? ( {t("task:linearIssue")} ) : null} {onLinkSentryIssue ? ( {t("task:sentryIssue")} ) : null} {pluginLinkActions.map((action) => ( {createElement(resolvePluginIcon(action.icon), { className: "mr-2 h-4 w-4" })} {action.label} ))} ); }