mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 10:50:38 +09:00
Add sub-issue issue-page flows
This commit is contained in:
parent
365b6d9bd8
commit
977e9f3e9a
6 changed files with 665 additions and 8 deletions
|
|
@ -46,6 +46,7 @@ import {
|
|||
Paperclip,
|
||||
FileText,
|
||||
Loader2,
|
||||
ListTree,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { cn } from "../lib/utils";
|
||||
|
|
@ -297,6 +298,9 @@ export function NewIssueDialog() {
|
|||
|
||||
const effectiveCompanyId = dialogCompanyId ?? selectedCompanyId;
|
||||
const dialogCompany = companies.find((c) => c.id === effectiveCompanyId) ?? selectedCompany;
|
||||
const isSubIssueMode = Boolean(newIssueDefaults.parentId);
|
||||
const parentIssueLabel = newIssueDefaults.parentIdentifier
|
||||
?? (newIssueDefaults.parentId ? newIssueDefaults.parentId.slice(0, 8) : "");
|
||||
|
||||
// Popover states
|
||||
const [statusOpen, setStatusOpen] = useState(false);
|
||||
|
|
@ -510,7 +514,23 @@ export function NewIssueDialog() {
|
|||
executionWorkspaceDefaultProjectId.current = null;
|
||||
|
||||
const draft = loadDraft();
|
||||
if (newIssueDefaults.title) {
|
||||
if (newIssueDefaults.parentId) {
|
||||
const defaultProjectId = newIssueDefaults.projectId ?? "";
|
||||
const defaultProject = orderedProjects.find((project) => project.id === defaultProjectId);
|
||||
setTitle(newIssueDefaults.title ?? "");
|
||||
setDescription(newIssueDefaults.description ?? "");
|
||||
setStatus(newIssueDefaults.status ?? "todo");
|
||||
setPriority(newIssueDefaults.priority ?? "");
|
||||
setProjectId(defaultProjectId);
|
||||
setProjectWorkspaceId(defaultProjectWorkspaceIdForProject(defaultProject));
|
||||
setAssigneeValue(assigneeValueFromSelection(newIssueDefaults));
|
||||
setAssigneeModelOverride("");
|
||||
setAssigneeThinkingEffort("");
|
||||
setAssigneeChrome(false);
|
||||
setExecutionWorkspaceMode(defaultExecutionWorkspaceModeForProject(defaultProject));
|
||||
setSelectedExecutionWorkspaceId("");
|
||||
executionWorkspaceDefaultProjectId.current = defaultProjectId || null;
|
||||
} else if (newIssueDefaults.title) {
|
||||
setTitle(newIssueDefaults.title);
|
||||
setDescription(newIssueDefaults.description ?? "");
|
||||
setStatus(newIssueDefaults.status ?? "todo");
|
||||
|
|
@ -616,6 +636,7 @@ export function NewIssueDialog() {
|
|||
}
|
||||
|
||||
function handleCompanyChange(companyId: string) {
|
||||
if (isSubIssueMode) return;
|
||||
if (companyId === effectiveCompanyId) return;
|
||||
setDialogCompanyId(companyId);
|
||||
setAssigneeValue("");
|
||||
|
|
@ -666,6 +687,8 @@ export function NewIssueDialog() {
|
|||
priority: priority || "medium",
|
||||
...(selectedAssigneeAgentId ? { assigneeAgentId: selectedAssigneeAgentId } : {}),
|
||||
...(selectedAssigneeUserId ? { assigneeUserId: selectedAssigneeUserId } : {}),
|
||||
...(newIssueDefaults.parentId ? { parentId: newIssueDefaults.parentId } : {}),
|
||||
...(newIssueDefaults.goalId ? { goalId: newIssueDefaults.goalId } : {}),
|
||||
...(projectId ? { projectId } : {}),
|
||||
...(projectWorkspaceId ? { projectWorkspaceId } : {}),
|
||||
...(assigneeAdapterOverrides ? { assigneeAdapterOverrides } : {}),
|
||||
|
|
@ -908,6 +931,7 @@ export function NewIssueDialog() {
|
|||
"px-1.5 py-0.5 rounded text-xs font-semibold cursor-pointer hover:opacity-80 transition-opacity",
|
||||
!dialogCompany?.brandColor && "bg-muted",
|
||||
)}
|
||||
disabled={isSubIssueMode}
|
||||
style={
|
||||
dialogCompany?.brandColor
|
||||
? {
|
||||
|
|
@ -955,7 +979,7 @@ export function NewIssueDialog() {
|
|||
</PopoverContent>
|
||||
</Popover>
|
||||
<span className="text-muted-foreground/60">›</span>
|
||||
<span>New issue</span>
|
||||
<span>{isSubIssueMode ? "New sub-issue" : "New issue"}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
|
|
@ -1119,6 +1143,19 @@ export function NewIssueDialog() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{isSubIssueMode ? (
|
||||
<div className="px-4 pb-2 shrink-0">
|
||||
<div className="inline-flex max-w-full items-center gap-1.5 rounded-md border border-border bg-muted/30 px-2.5 py-1 text-xs text-muted-foreground">
|
||||
<ListTree className="h-3.5 w-3.5 shrink-0" />
|
||||
<span className="shrink-0">Sub-issue of</span>
|
||||
<span className="font-medium text-foreground">{parentIssueLabel}</span>
|
||||
{newIssueDefaults.parentTitle ? (
|
||||
<span className="truncate">· {newIssueDefaults.parentTitle}</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{currentProject && currentProjectSupportsExecutionWorkspace && (
|
||||
<div className="px-4 py-3 shrink-0 space-y-2">
|
||||
<div className="space-y-1.5">
|
||||
|
|
@ -1455,7 +1492,7 @@ export function NewIssueDialog() {
|
|||
>
|
||||
<span className="inline-flex items-center justify-center gap-1.5">
|
||||
{createIssue.isPending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : null}
|
||||
<span>{createIssue.isPending ? "Creating..." : "Create Issue"}</span>
|
||||
<span>{createIssue.isPending ? "Creating..." : isSubIssueMode ? "Create Sub-Issue" : "Create Issue"}</span>
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue