Files
kandev/apps/web/components/task/task-session-sidebar-dialogs.tsx
2026-09-06 15:19:25 +01:00

243 lines
7.3 KiB
TypeScript

"use client";
import { TaskRenameDialog } from "./task-rename-dialog";
import { TaskArchiveConfirmDialog } from "./task-archive-confirm-dialog";
import { TaskDeleteConfirmDialog } from "./task-delete-confirm-dialog";
import { TaskDetachTargetConfirmDialog } from "./task-detach-confirm-dialog";
import { NewSubtaskDialog } from "./new-subtask-dialog";
import { TaskExternalLinkDialog } from "./task-external-link-dialog";
import { TaskGitHubIssueDialog } from "./task-github-issue-dialog";
import { TaskGitHubPRDialog } from "./task-github-pr-dialog";
import { TaskMRLinkDialog } from "@/components/gitlab/task-mr-link-dialog";
import { SidebarTaskEditDialog, type SidebarTaskEditTarget } from "./task-session-sidebar-edit";
import type { StepDef } from "./task-switcher-context-menu";
import type { Repository } from "@/lib/types/http";
import type {
SidebarExternalLinkTarget,
SidebarLinkTarget,
} from "./task-session-sidebar-link-actions";
type Target = { id: string; title: string; executorType?: string | null } | null;
type DetachTarget = {
id: string;
title: string;
workspaceMode?: "inherit_parent" | "new_workspace" | "shared_group";
} | null;
type LinkTarget = SidebarLinkTarget | null;
export type SidebarDialogsActions = {
renamingTask: Target;
setRenamingTask: (next: Target) => void;
handleRenameSubmit: (newTitle: string) => Promise<void> | void;
creatingSubtask: Target;
setCreatingSubtask: (next: Target) => void;
handleCreateSubtask: (taskId: string, taskTitle: string) => void;
archivingTask: Target;
setArchivingTask: (next: Target) => void;
archivingTaskId: string | null;
isArchiving: boolean;
handleArchiveConfirm: (opts: { cascade: boolean }) => Promise<void> | void;
deletingTask: Target;
setDeletingTask: (next: Target) => void;
isDeleting: boolean;
handleDeleteConfirm: (opts: {
cascade: boolean;
discardWorktreeChanges: boolean;
}) => Promise<void> | void;
detachingTask: DetachTarget;
setDetachingTask: (next: DetachTarget) => void;
detachingTaskId: string | null;
handleDetachConfirm: () => Promise<void> | void;
linkingPullRequestTask: LinkTarget;
setLinkingPullRequestTask: (next: LinkTarget) => void;
linkingIssueTask: LinkTarget;
setLinkingIssueTask: (next: LinkTarget) => void;
linkingMergeRequestTask: LinkTarget;
setLinkingMergeRequestTask: (next: LinkTarget) => void;
linkingExternalIssueTask: SidebarExternalLinkTarget | null;
setLinkingExternalIssueTask: (next: SidebarExternalLinkTarget | null) => void;
editingTask: SidebarTaskEditTarget | null;
setEditingTask: (next: SidebarTaskEditTarget | null) => void;
};
function SidebarSubtaskDialog({
target,
onTargetChange,
}: {
target: Target;
onTargetChange: (next: Target) => void;
}) {
return (
<NewSubtaskDialog
open={target !== null}
onOpenChange={(open) => {
if (!open) onTargetChange(null);
}}
parentTaskId={target?.id ?? ""}
parentTaskTitle={target?.title ?? ""}
/>
);
}
export function SidebarDialogs({
actions,
repositories,
workspaceId,
stepsByWorkflowId,
}: {
actions: SidebarDialogsActions;
repositories: Repository[];
workspaceId: string | null;
stepsByWorkflowId: Record<string, StepDef[]>;
}) {
const {
renamingTask,
setRenamingTask,
handleRenameSubmit,
creatingSubtask,
setCreatingSubtask,
archivingTask,
setArchivingTask,
archivingTaskId,
isArchiving,
handleArchiveConfirm,
deletingTask,
setDeletingTask,
isDeleting,
handleDeleteConfirm,
detachingTask,
setDetachingTask,
detachingTaskId,
handleDetachConfirm,
editingTask,
setEditingTask,
} = actions;
return (
<>
<TaskRenameDialog
open={renamingTask !== null}
onOpenChange={(open) => {
if (!open) setRenamingTask(null);
}}
currentTitle={renamingTask?.title ?? ""}
onSubmit={handleRenameSubmit}
/>
<SidebarSubtaskDialog target={creatingSubtask} onTargetChange={setCreatingSubtask} />
<TaskArchiveConfirmDialog
open={archivingTask !== null}
onOpenChange={(open) => {
if (!open) setArchivingTask(null);
}}
taskTitle={archivingTask?.title ?? ""}
taskId={archivingTask?.id}
executorType={archivingTask?.executorType}
isArchiving={isArchiving && archivingTask?.id === archivingTaskId}
onConfirm={handleArchiveConfirm}
/>
<TaskDeleteConfirmDialog
open={deletingTask !== null}
onOpenChange={(open) => {
if (!open) setDeletingTask(null);
}}
taskTitle={deletingTask?.title ?? ""}
taskId={deletingTask?.id}
executorType={deletingTask?.executorType}
isDeleting={isDeleting}
onConfirm={handleDeleteConfirm}
/>
<TaskDetachTargetConfirmDialog
target={detachingTask}
detachingTaskId={detachingTaskId}
onDismiss={() => setDetachingTask(null)}
onConfirm={handleDetachConfirm}
/>
<SidebarTaskEditDialog
target={editingTask}
onTargetChange={setEditingTask}
workspaceId={workspaceId}
stepsByWorkflowId={stepsByWorkflowId}
/>
<SidebarLinkDialogs actions={actions} repositories={repositories} workspaceId={workspaceId} />
</>
);
}
export function SidebarLinkDialogs({
actions,
repositories,
workspaceId,
}: {
actions: Pick<
SidebarDialogsActions,
| "linkingPullRequestTask"
| "setLinkingPullRequestTask"
| "linkingIssueTask"
| "setLinkingIssueTask"
| "linkingMergeRequestTask"
| "setLinkingMergeRequestTask"
| "linkingExternalIssueTask"
| "setLinkingExternalIssueTask"
>;
repositories: Repository[];
workspaceId: string | null;
}) {
const {
linkingPullRequestTask,
setLinkingPullRequestTask,
linkingIssueTask,
setLinkingIssueTask,
linkingMergeRequestTask,
setLinkingMergeRequestTask,
linkingExternalIssueTask,
setLinkingExternalIssueTask,
} = actions;
return (
<>
{linkingPullRequestTask && (
<TaskGitHubPRDialog
workspaceId={workspaceId}
open={true}
onOpenChange={(open) => {
if (!open) setLinkingPullRequestTask(null);
}}
task={linkingPullRequestTask}
repositories={repositories}
/>
)}
{linkingIssueTask && (
<TaskGitHubIssueDialog
open={true}
onOpenChange={(open) => {
if (!open) setLinkingIssueTask(null);
}}
task={linkingIssueTask}
repositories={repositories}
/>
)}
{linkingMergeRequestTask && workspaceId && (
<TaskMRLinkDialog
open={true}
onOpenChange={(open) => {
if (!open) setLinkingMergeRequestTask(null);
}}
taskId={linkingMergeRequestTask.id}
workspaceId={workspaceId}
taskRepositories={linkingMergeRequestTask.repositories ?? []}
repositories={repositories}
/>
)}
{linkingExternalIssueTask && workspaceId && (
<TaskExternalLinkDialog
open={true}
onOpenChange={(open) => {
if (!open) setLinkingExternalIssueTask(null);
}}
provider={linkingExternalIssueTask.provider}
task={linkingExternalIssueTask.task}
workspaceId={workspaceId}
/>
)}
</>
);
}