import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { TaskCard } from "../components/TaskCard";
import { deleteTask, updateTask } from "../services/taskService";
import { toast } from "sonner";
import { Fragment, useEffect, useMemo, useRef, useState, } from "react";
import { Inbox } from "lucide-react";
import { DeleteIcon } from "../../components/ui/delete-icon";
import { clamp, DRAG_START_THRESHOLD_PX, getAutoScrollStep, getScrollableAncestorFromPoint, } from "../../lib/pointerDrag";
import { SimpleIconButton } from "../../editor/ui/SimpleIconButton";
import { cn } from "../../lib/utils";
import { useEditContext } from "../../editor/client/editContext";
import { normalizeTaskStatus, getTaskStatusLabel } from "../taskStatus";
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, } from "../../components/ui/context-menu";
import { stripAgentConfigFromResultData } from "../taskAgentConfig";
import { TaskBoardFilterBox } from "../components/TaskBoardFilterBox";
const columns = [
    { status: "Todo" },
    { status: "InProgress" },
    { status: "Waiting" },
    { status: "Review" },
    { status: "Done" },
];
const KANBAN_DRAG_MAX_ROTATION_DEG = 3;
const KANBAN_DRAG_ROTATION_SMOOTHING = 0.34;
const KANBAN_DRAG_DIRECTION_CHANGE_SMOOTHING = 0.92;
const KANBAN_DRAG_MIN_DIRECTION_MOVEMENT_PX = 0.5;
const KANBAN_DRAG_ROTATION_SETTLE_DEG = 0.05;
function getDragRotation(movementX, previousRotation) {
    if (Math.abs(movementX) < KANBAN_DRAG_MIN_DIRECTION_MOVEMENT_PX) {
        return previousRotation;
    }
    const targetRotation = clamp(movementX * 0.35, -KANBAN_DRAG_MAX_ROTATION_DEG, KANBAN_DRAG_MAX_ROTATION_DEG);
    const isSameDirection = targetRotation !== 0 &&
        previousRotation !== 0 &&
        Math.sign(targetRotation) === Math.sign(previousRotation);
    if (isSameDirection &&
        Math.abs(previousRotation) >= Math.abs(targetRotation)) {
        return previousRotation;
    }
    const directionChanged = targetRotation !== 0 &&
        previousRotation !== 0 &&
        Math.sign(targetRotation) !== Math.sign(previousRotation);
    const smoothing = directionChanged
        ? KANBAN_DRAG_DIRECTION_CHANGE_SMOOTHING
        : KANBAN_DRAG_ROTATION_SMOOTHING;
    const nextRotation = clamp(previousRotation + (targetRotation - previousRotation) * smoothing, -KANBAN_DRAG_MAX_ROTATION_DEG, KANBAN_DRAG_MAX_ROTATION_DEG);
    return Math.abs(targetRotation - nextRotation) <=
        KANBAN_DRAG_ROTATION_SETTLE_DEG
        ? targetRotation
        : nextRotation;
}
function getColumnStatusFromPoint(clientX, clientY) {
    const element = document.elementFromPoint(clientX, clientY);
    const status = (element instanceof HTMLElement
        ? element.closest("[data-taskboard-kanban-status]")?.dataset
            .taskboardKanbanStatus
        : undefined);
    if (!status || !columns.some((column) => column.status === status)) {
        return null;
    }
    return status;
}
function shouldSkipCardDrag(target) {
    return (target instanceof HTMLElement &&
        !!target.closest("a, button, input, textarea, select, [role='menuitem'], [data-no-kanban-drag]"));
}
export function KanbanView(props) {
    const { tasks, dependencies, selectedTaskId, onSelectTask, onTasksChanged, projectId, permission, } = props;
    const editContext = useEditContext();
    const [dragOver, setDragOver] = useState(null);
    const [dragState, setDragState] = useState(null);
    const [optimisticTaskMoves, setOptimisticTaskMoves] = useState({});
    const dragStateRef = useRef(null);
    const boardScrollContainerRef = useRef(null);
    const autoScrollFrameRef = useRef(null);
    const optimisticMoveIdRef = useRef(0);
    const latestDragPointRef = useRef(null);
    const suppressNextClickRef = useRef(false);
    const [filter, setFilter] = useState("");
    const [selectedTaskIds, setSelectedTaskIds] = useState(() => selectedTaskId ? new Set([selectedTaskId]) : new Set());
    const [selectionAnchorTaskId, setSelectionAnchorTaskId] = useState(selectedTaskId);
    const canEdit = permission === "Owner" || permission === "Editor";
    const taskById = useMemo(() => {
        const map = new Map();
        for (const t of tasks)
            map.set(t.taskId, t);
        return map;
    }, [tasks]);
    const dependencyTaskIdsByTask = useMemo(() => {
        const map = new Map();
        const toDisplayId = (taskId) => {
            const task = taskById.get(taskId);
            return task?.taskKey || taskId.slice(0, 8).toUpperCase();
        };
        for (const dep of dependencies) {
            const list = map.get(dep.taskId) || [];
            const displayId = toDisplayId(dep.dependsOnTaskId);
            if (!list.includes(displayId))
                list.push(displayId);
            map.set(dep.taskId, list);
        }
        return map;
    }, [dependencies, taskById]);
    const blockedTaskIds = useMemo(() => {
        const blocked = new Set();
        for (const task of tasks) {
            if ((task.executionBlockedByProjectIds?.length ?? 0) > 0) {
                blocked.add(task.taskId);
            }
        }
        for (const dep of dependencies) {
            if (dep.dependencyType !== "BlockedBy")
                continue;
            const blocker = taskById.get(dep.dependsOnTaskId);
            if (!blocker ||
                normalizeTaskStatus(blocker.status, blocker.executionState) !== "Done") {
                blocked.add(dep.taskId);
            }
        }
        return blocked;
    }, [dependencies, taskById, tasks]);
    const filteredTasks = useMemo(() => {
        const query = filter.trim().toLowerCase();
        if (!query)
            return tasks;
        return tasks.filter((task) => {
            return (task.title.toLowerCase().includes(query) ||
                (task.description || "").toLowerCase().includes(query) ||
                (task.taskKey || "").toLowerCase().includes(query) ||
                (task.assigneeDisplayName || "").toLowerCase().includes(query) ||
                (task.assigneeId || "").toLowerCase().includes(query));
        });
    }, [filter, tasks]);
    const orderedFilteredTasks = useMemo(() => {
        return [...filteredTasks].sort((a, b) => {
            if (a.sortOrder !== b.sortOrder)
                return a.sortOrder - b.sortOrder;
            return a.createdAt.localeCompare(b.createdAt);
        });
    }, [filteredTasks]);
    const orderedFilteredTasksWithOptimisticStatus = useMemo(() => {
        if (Object.keys(optimisticTaskMoves).length === 0) {
            return orderedFilteredTasks;
        }
        return orderedFilteredTasks.map((task) => {
            const optimisticMove = optimisticTaskMoves[task.taskId];
            if (!optimisticMove)
                return task;
            return {
                ...task,
                status: optimisticMove.status,
            };
        });
    }, [optimisticTaskMoves, orderedFilteredTasks]);
    const filteredTaskIds = useMemo(() => orderedFilteredTasks.map((task) => task.taskId), [orderedFilteredTasks]);
    useEffect(() => {
        const taskIds = new Set(tasks.map((task) => task.taskId));
        setSelectedTaskIds((previous) => {
            const next = new Set();
            previous.forEach((taskId) => {
                if (taskIds.has(taskId))
                    next.add(taskId);
            });
            if (next.size === 0 && selectedTaskId && taskIds.has(selectedTaskId)) {
                next.add(selectedTaskId);
            }
            return next;
        });
        if (selectionAnchorTaskId && !taskIds.has(selectionAnchorTaskId)) {
            setSelectionAnchorTaskId(selectedTaskId);
        }
    }, [tasks, selectedTaskId, selectionAnchorTaskId]);
    useEffect(() => {
        setOptimisticTaskMoves((previous) => {
            let changed = false;
            const next = { ...previous };
            for (const [taskId, optimisticMove] of Object.entries(previous)) {
                const task = taskById.get(taskId);
                if (!task ||
                    task.status === optimisticMove.status ||
                    task.status !== optimisticMove.previousStatus) {
                    delete next[taskId];
                    changed = true;
                }
            }
            return changed ? next : previous;
        });
    }, [taskById]);
    const selectedCount = selectedTaskIds.size;
    const updateDragState = (nextDragState) => {
        dragStateRef.current = nextDragState;
        setDragState(nextDragState);
    };
    const stopAutoScroll = () => {
        if (autoScrollFrameRef.current !== null) {
            window.cancelAnimationFrame(autoScrollFrameRef.current);
            autoScrollFrameRef.current = null;
        }
        latestDragPointRef.current = null;
    };
    const runAutoScroll = () => {
        autoScrollFrameRef.current = null;
        const dragPoint = latestDragPointRef.current;
        if (!dragPoint || !dragStateRef.current?.isDragging) {
            return;
        }
        const boardScrollContainer = boardScrollContainerRef.current;
        if (boardScrollContainer) {
            const boardRect = boardScrollContainer.getBoundingClientRect();
            const scrollLeftStep = getAutoScrollStep(dragPoint.clientX, boardRect.left, boardRect.right);
            if (scrollLeftStep !== 0) {
                boardScrollContainer.scrollLeft += scrollLeftStep;
            }
        }
        const columnScrollContainer = getScrollableAncestorFromPoint(dragPoint.clientX, dragPoint.clientY, boardScrollContainer);
        if (columnScrollContainer &&
            columnScrollContainer !== boardScrollContainer) {
            const columnRect = columnScrollContainer.getBoundingClientRect();
            const scrollTopStep = getAutoScrollStep(dragPoint.clientY, columnRect.top, columnRect.bottom);
            if (scrollTopStep !== 0) {
                columnScrollContainer.scrollTop += scrollTopStep;
            }
        }
        autoScrollFrameRef.current = window.requestAnimationFrame(runAutoScroll);
    };
    const updateAutoScrollPoint = (clientX, clientY) => {
        latestDragPointRef.current = { clientX, clientY };
        if (autoScrollFrameRef.current === null) {
            autoScrollFrameRef.current = window.requestAnimationFrame(runAutoScroll);
        }
    };
    const endCurrentDrag = () => {
        stopAutoScroll();
        updateDragState(null);
        setDragOver(null);
    };
    useEffect(() => stopAutoScroll, []);
    const suppressNextDragClick = () => {
        suppressNextClickRef.current = true;
        window.setTimeout(() => {
            suppressNextClickRef.current = false;
        }, 0);
    };
    const getDraggedCardStyle = (taskId) => {
        if (!dragState || dragState.taskId !== taskId || !dragState.isDragging) {
            return undefined;
        }
        const translateX = dragState.currentClientX - dragState.startClientX;
        const translateY = dragState.currentClientY - dragState.startClientY;
        return {
            boxShadow: "0 12px 16px 0 rgb(18 18 18 / 10%)",
            height: dragState.rect.height,
            left: dragState.rect.left,
            pointerEvents: "none",
            position: "fixed",
            top: dragState.rect.top,
            transform: `translate3d(${translateX}px, ${translateY}px, 0) rotate(${dragState.rotation}deg) scale(1.015)`,
            transformOrigin: "50% 75%",
            width: dragState.rect.width,
            zIndex: 80,
        };
    };
    const handleTaskPointerDown = (taskId, event) => {
        if (event.button !== 0 || shouldSkipCardDrag(event.target))
            return;
        const rect = event.currentTarget.getBoundingClientRect();
        const taskIdsToMove = selectedTaskIds.has(taskId)
            ? [...selectedTaskIds]
            : [taskId];
        updateDragState({
            taskId,
            taskIds: taskIdsToMove,
            pointerId: event.pointerId,
            startClientX: event.clientX,
            startClientY: event.clientY,
            currentClientX: event.clientX,
            currentClientY: event.clientY,
            rect: {
                left: rect.left,
                top: rect.top,
                width: rect.width,
                height: rect.height,
            },
            isDragging: false,
            rotation: 0,
            targetStatus: null,
        });
    };
    const handleTaskPointerMove = (event) => {
        const currentDragState = dragStateRef.current;
        if (!currentDragState || currentDragState.pointerId !== event.pointerId) {
            return;
        }
        const deltaX = event.clientX - currentDragState.startClientX;
        const deltaY = event.clientY - currentDragState.startClientY;
        const isDragging = currentDragState.isDragging ||
            Math.hypot(deltaX, deltaY) > DRAG_START_THRESHOLD_PX;
        if (!isDragging)
            return;
        event.preventDefault();
        if (!event.currentTarget.hasPointerCapture(event.pointerId)) {
            event.currentTarget.setPointerCapture(event.pointerId);
        }
        const targetStatus = getColumnStatusFromPoint(event.clientX, event.clientY);
        updateAutoScrollPoint(event.clientX, event.clientY);
        const movementX = event.clientX - currentDragState.currentClientX;
        const nextDragState = {
            ...currentDragState,
            currentClientX: event.clientX,
            currentClientY: event.clientY,
            isDragging: true,
            rotation: getDragRotation(movementX, currentDragState.rotation),
            targetStatus,
        };
        updateDragState(nextDragState);
        setDragOver(targetStatus);
    };
    const handleTaskPointerUp = async (event) => {
        const currentDragState = dragStateRef.current;
        if (!currentDragState || currentDragState.pointerId !== event.pointerId) {
            return;
        }
        const targetStatus = getColumnStatusFromPoint(event.clientX, event.clientY);
        if (currentDragState.isDragging) {
            event.preventDefault();
            event.stopPropagation();
            suppressNextDragClick();
        }
        if (event.currentTarget.hasPointerCapture(event.pointerId)) {
            event.currentTarget.releasePointerCapture(event.pointerId);
        }
        if (currentDragState.isDragging && targetStatus) {
            const movePromise = moveTaskIdsToStatus(currentDragState.taskIds, targetStatus);
            endCurrentDrag();
            await movePromise;
            return;
        }
        endCurrentDrag();
    };
    const handleTaskPointerCancel = (event) => {
        const currentDragState = dragStateRef.current;
        if (!currentDragState || currentDragState.pointerId !== event.pointerId) {
            return;
        }
        if (currentDragState.isDragging) {
            suppressNextDragClick();
        }
        endCurrentDrag();
    };
    const moveTaskIdsToStatus = async (taskIds, status) => {
        const uniqueTaskIds = [...new Set(taskIds)];
        if (uniqueTaskIds.length === 0)
            return;
        const moveCandidates = uniqueTaskIds.filter((taskId) => {
            const task = taskById.get(taskId);
            return task && task.status !== status;
        });
        if (moveCandidates.length === 0)
            return;
        const optimisticMoveId = (optimisticMoveIdRef.current += 1);
        setOptimisticTaskMoves((previous) => {
            const next = { ...previous };
            for (const taskId of moveCandidates) {
                const task = taskById.get(taskId);
                if (!task)
                    continue;
                next[taskId] = {
                    status,
                    previousStatus: task.status,
                    moveId: optimisticMoveId,
                };
            }
            return next;
        });
        const clearOptimisticMove = () => {
            setOptimisticTaskMoves((previous) => {
                let changed = false;
                const next = { ...previous };
                for (const taskId of moveCandidates) {
                    if (next[taskId]?.moveId !== optimisticMoveId)
                        continue;
                    delete next[taskId];
                    changed = true;
                }
                return changed ? next : previous;
            });
        };
        const results = await Promise.all(moveCandidates.map((taskId) => updateTask({ taskId, status })));
        const failed = results.filter((result) => result.type !== "success");
        if (failed.length > 0) {
            clearOptimisticMove();
            toast.error(failed[0]?.summary ||
                `Failed to move ${failed.length === moveCandidates.length ? "tasks" : "some tasks"}`);
            return;
        }
        if (moveCandidates.length > 1) {
            toast.success(`Moved ${moveCandidates.length} tasks to ${getTaskStatusLabel(status)}`);
        }
        await onTasksChanged();
    };
    const handleTaskCardClick = (taskId, event) => {
        const isToggleSelect = event.ctrlKey || event.metaKey;
        const isRangeSelect = event.shiftKey;
        const anchor = selectionAnchorTaskId || selectedTaskId || taskId;
        if (isRangeSelect) {
            const anchorIndex = filteredTaskIds.indexOf(anchor);
            const clickedIndex = filteredTaskIds.indexOf(taskId);
            if (anchorIndex === -1 || clickedIndex === -1) {
                setSelectedTaskIds(new Set([taskId]));
            }
            else {
                const [start, end] = anchorIndex <= clickedIndex
                    ? [anchorIndex, clickedIndex]
                    : [clickedIndex, anchorIndex];
                const rangeSelection = new Set(filteredTaskIds.slice(start, end + 1));
                if (isToggleSelect) {
                    setSelectedTaskIds((previous) => {
                        const next = new Set(previous);
                        rangeSelection.forEach((id) => next.add(id));
                        return next;
                    });
                }
                else {
                    setSelectedTaskIds(rangeSelection);
                }
            }
            onSelectTask(taskId);
            return;
        }
        if (isToggleSelect) {
            setSelectedTaskIds((previous) => {
                const next = new Set(previous);
                if (next.has(taskId) && next.size > 1) {
                    next.delete(taskId);
                    return next;
                }
                next.add(taskId);
                return next;
            });
            setSelectionAnchorTaskId(taskId);
            onSelectTask(taskId);
            return;
        }
        setSelectedTaskIds(new Set([taskId]));
        setSelectionAnchorTaskId(taskId);
        onSelectTask(taskId);
    };
    const handleTaskAssigneeChange = async (task, selection) => {
        const result = await updateTask(selection
            ? {
                taskId: task.taskId,
                assigneeType: selection.assigneeType,
                assigneeId: selection.assigneeId,
                ...(selection.assigneeType === "Agent"
                    ? { resultData: stripAgentConfigFromResultData(task.resultData) }
                    : {}),
            }
            : {
                taskId: task.taskId,
                assigneeType: "user",
                assigneeId: "",
            });
        if (result.type !== "success") {
            toast.error(result.summary ||
                (selection
                    ? "Failed to update assignee"
                    : "Failed to clear assignee"));
            return;
        }
        if (!selection) {
            toast.success("Assignee cleared");
        }
        await onTasksChanged();
    };
    const handleDeleteTask = (task) => {
        const runDelete = async () => {
            const result = await deleteTask(task.taskId);
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to delete task");
                return;
            }
            toast.success("Task deleted");
            await onTasksChanged();
        };
        if (editContext?.confirm) {
            editContext.confirm({
                header: "Delete task",
                message: `Are you sure you want to delete "${task.title}"?\n\nThis action cannot be undone.`,
                acceptLabel: "Delete",
                showCancel: true,
                accept: () => {
                    void runDelete();
                },
            });
            return;
        }
        void runDelete();
    };
    const handleDeleteSelectedTasks = () => {
        const taskIds = [...selectedTaskIds];
        if (taskIds.length === 0)
            return;
        const singleTask = taskIds.length === 1 ? taskById.get(taskIds[0]) : undefined;
        const runDelete = async () => {
            const results = await Promise.all(taskIds.map((taskId) => deleteTask(taskId)));
            const failed = results.filter((result) => result.type !== "success");
            if (failed.length > 0) {
                toast.error(failed[0]?.summary ||
                    `Failed to delete ${failed.length === taskIds.length ? "tasks" : "some tasks"}`);
            }
            else if (taskIds.length === 1) {
                toast.success("Task deleted");
            }
            else {
                toast.success(`Deleted ${taskIds.length} tasks`);
            }
            if (taskIds.length - failed.length > 0) {
                setSelectedTaskIds(new Set());
            }
            await onTasksChanged();
        };
        if (editContext?.confirm) {
            editContext.confirm({
                header: taskIds.length === 1 ? "Delete task" : "Delete tasks",
                message: taskIds.length === 1
                    ? `Are you sure you want to delete "${singleTask?.title || "this task"}"?\n\nThis action cannot be undone.`
                    : `Are you sure you want to delete ${taskIds.length} selected tasks?\n\nThis action cannot be undone.`,
                acceptLabel: "Delete",
                showCancel: true,
                accept: () => {
                    void runDelete();
                },
            });
            return;
        }
        void runDelete();
    };
    const handleTaskContextMenu = (taskId) => {
        if (selectedTaskIds.has(taskId))
            return;
        setSelectedTaskIds(new Set([taskId]));
        setSelectionAnchorTaskId(taskId);
        onSelectTask(taskId);
    };
    return (_jsxs("div", { className: "flex min-h-[520px] min-w-0 flex-1 flex-col select-none", children: [_jsx("div", { className: "mb-4", children: _jsx(TaskBoardFilterBox, { value: filter, onChange: setFilter }) }), _jsx("div", { ref: boardScrollContainerRef, className: "flex min-h-[460px] w-full min-w-0 flex-1 gap-4 overflow-x-auto pb-5", children: columns.map((col) => {
                    const colTasks = orderedFilteredTasksWithOptimisticStatus.filter((t) => normalizeTaskStatus(t.status, t.executionState) === col.status);
                    const showTargetDropZone = dragState?.isDragging &&
                        dragOver === col.status &&
                        !colTasks.some((task) => task.taskId === dragState.taskId);
                    return (_jsxs("div", { "data-taskboard-kanban-status": col.status, className: cn("flex w-[300px] shrink-0 flex-col rounded-md bg-[#fafafa] transition-colors md:w-[310px]", "hover:bg-[#fdfdfd]", dragOver === col.status ? "bg-[#fdfdfd]" : ""), children: [_jsx("div", { className: "flex items-center justify-between px-2.5 pt-2.5 pb-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-neutral-grey-50 text-[12px] font-medium", children: getTaskStatusLabel(col.status) }), _jsxs("span", { className: "text-neutral-grey-50 ml-1 text-[12px] font-medium", children: ["(", colTasks.length, ")"] })] }) }), _jsxs("div", { className: "scrollbar-thin scrollbar-thumb-neutral-grey-10 flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2 pt-1", children: [showTargetDropZone && (_jsx("div", { "aria-hidden": "true", className: "border-neutral-grey-15 bg-neutral-grey-5/70 text-neutral-grey-50 flex shrink-0 items-center justify-center rounded-lg border border-dashed text-xs font-medium", "data-testid": `taskboard-kanban-drop-zone-${col.status}`, style: { height: dragState.rect.height }, children: "Drop task" })), colTasks.length === 0 && !showTargetDropZone ? (_jsx("div", { className: "border-border-default flex h-[108px] flex-col items-center justify-center rounded-lg border border-dashed bg-white/60", children: _jsxs("div", { className: "text-neutral-grey-50 flex flex-col items-center gap-1 text-xs font-normal", children: [_jsx(Inbox, { className: "h-4 w-4", strokeWidth: 1, "aria-hidden": "true" }), "No tasks"] }) })) : colTasks.length > 0 ? (colTasks.map((t) => {
                                        const isDraggedCard = dragState?.taskId === t.taskId && dragState.isDragging;
                                        const card = (_jsxs("div", { className: cn("group relative cursor-grab touch-none active:cursor-grabbing", isDraggedCard && "cursor-grabbing"), style: getDraggedCardStyle(t.taskId), onClickCapture: (event) => {
                                                if (!suppressNextClickRef.current)
                                                    return;
                                                event.preventDefault();
                                                event.stopPropagation();
                                            }, onContextMenu: () => handleTaskContextMenu(t.taskId), onPointerDown: (event) => handleTaskPointerDown(t.taskId, event), onPointerMove: handleTaskPointerMove, onPointerUp: handleTaskPointerUp, onPointerCancel: handleTaskPointerCancel, children: [canEdit && (_jsx("span", { className: "absolute -top-2 -right-2 z-10 opacity-0 transition-opacity group-hover:opacity-100", onMouseDown: (e) => {
                                                        e.stopPropagation();
                                                        e.preventDefault();
                                                    }, onPointerDown: (e) => {
                                                        e.stopPropagation();
                                                    }, children: _jsx(SimpleIconButton, { icon: _jsx(DeleteIcon, { size: "md" }), label: "Delete task", className: "text-neutral-grey-50 border bg-white shadow-sm", onClick: (e) => {
                                                            e.stopPropagation();
                                                            handleDeleteTask(t);
                                                        } }) })), _jsx(TaskCard, { task: t, selected: selectedTaskIds.has(t.taskId), onClick: (event) => handleTaskCardClick(t.taskId, event), dependencyTaskIds: dependencyTaskIdsByTask.get(t.taskId) || [], isBlocked: blockedTaskIds.has(t.taskId), projectId: projectId, canEditAssignee: canEdit, onAssigneeChange: (selection) => handleTaskAssigneeChange(t, selection) })] }));
                                        const cardWithMenu = canEdit ? (_jsxs(ContextMenu, { children: [_jsx(ContextMenuTrigger, { asChild: true, children: card }), _jsx(ContextMenuContent, { className: "w-44", children: _jsxs(ContextMenuItem, { onSelect: handleDeleteSelectedTasks, "data-testid": "taskboard-kanban-context-delete-selected", children: [_jsx(DeleteIcon, { size: "md" }), selectedCount > 1
                                                                ? `Delete selected (${selectedCount})`
                                                                : "Delete task"] }) })] })) : (card);
                                        return (_jsxs(Fragment, { children: [isDraggedCard && (_jsx("div", { "aria-hidden": "true", className: "border-neutral-grey-15 bg-neutral-grey-5 rounded-md border border-dashed", style: { height: dragState.rect.height } })), cardWithMenu] }, t.taskId));
                                    })) : null] })] }, col.status));
                }) })] }));
}
//# sourceMappingURL=KanbanView.js.map