Files
kandev/apps/web/components/task/task-switcher-action-items.tsx
T
José Almeida b56bca5a4d feat: move subtask action to task context menu (#1920)
* feat: move subtask action to task context menu

* fix: resolve subtask defaults from selected parent

* fix: handle repository-less subtask parents
2026-07-24 15:50:30 +01:00

111 lines
2.6 KiB
TypeScript

"use client";
import { IconArchive, IconLoader, IconSubtask, IconTrash, IconUnlink } from "@tabler/icons-react";
import { ContextMenuItem, ContextMenuSeparator } from "@kandev/ui/context-menu";
export function TaskArchiveItem({
taskId,
actingIds,
actingOnSelection,
disabled,
onArchiveTask,
onBulkArchive,
}: {
taskId: string;
actingIds: string[];
actingOnSelection: boolean;
disabled?: boolean;
onArchiveTask?: (taskId: string) => void;
onBulkArchive?: (taskIds: string[]) => void;
}) {
if (actingOnSelection && onBulkArchive) {
const count = actingIds.length;
return (
<ContextMenuItem disabled={disabled} onSelect={() => onBulkArchive(actingIds)}>
<IconArchive className="mr-2 h-4 w-4" />
{count > 1 ? `Archive ${count} tasks` : "Archive"}
</ContextMenuItem>
);
}
if (!onArchiveTask) return null;
return (
<ContextMenuItem disabled={disabled} onSelect={() => onArchiveTask(taskId)}>
<IconArchive className="mr-2 h-4 w-4" />
Archive
</ContextMenuItem>
);
}
export function TaskCreateSubtaskItem({
task,
disabled,
onCreateSubtask,
}: {
task: { id: string; title: string };
disabled?: boolean;
onCreateSubtask?: (taskId: string, taskTitle: string) => void;
}) {
if (!onCreateSubtask) return null;
return (
<ContextMenuItem
data-testid="task-context-create-subtask"
disabled={disabled}
onSelect={() => onCreateSubtask(task.id, task.title)}
>
<IconSubtask className="mr-2 h-4 w-4" />
Create Subtask
</ContextMenuItem>
);
}
export function TaskDetachItem({
task,
disabled,
onDetachTask,
}: {
task: { id: string; parentTaskId?: string | null };
disabled?: boolean;
onDetachTask?: (taskId: string) => void;
}) {
if (!task.parentTaskId || !onDetachTask) return null;
return (
<ContextMenuItem
data-testid="task-context-detach"
disabled={disabled}
onSelect={() => onDetachTask(task.id)}
>
<IconUnlink className="mr-2 h-4 w-4" />
Detach from parent
</ContextMenuItem>
);
}
export function TaskDeleteItem({
taskId,
isDeleting,
onDeleteTask,
}: {
taskId: string;
isDeleting?: boolean;
onDeleteTask?: (taskId: string) => void;
}) {
if (!onDeleteTask) return null;
return (
<>
<ContextMenuSeparator />
<ContextMenuItem
variant="destructive"
disabled={isDeleting}
onSelect={() => onDeleteTask(taskId)}
>
{isDeleting ? (
<IconLoader className="mr-2 h-4 w-4 animate-spin" />
) : (
<IconTrash className="mr-2 h-4 w-4" />
)}
Delete
</ContextMenuItem>
</>
);
}