"use client"; import { useRef, useState, useTransition } from "react"; import { Dialog, Field, IconButton, Kbd, Switch, Textarea, Tooltip } from "@unlocalhosted/metalui"; import { createIssueAction } from "@/app/actions/issues"; import { ChevronRightIcon, PlusIcon, XIcon } from "@/components/icons"; import { Alert, Button } from "@/components/ui"; import type { NewIssueInput, Status } from "@/lib/issue-meta"; import { AssigneePicker, DueDateField, EstimatePicker, LabelsPicker, PriorityPicker, StatusPicker } from "./properties"; import { useTracker } from "./tracker-context"; export type IssueDefaults = Partial>; /** Title, description and properties for a new issue. Submit with the button or ⌘/Ctrl + Enter. */ export function IssueComposer({ defaults, onCreated, onCancel, offerCreateMore, }: { defaults?: IssueDefaults; onCreated: (number: number, createMore: boolean) => void; onCancel?: () => void; offerCreateMore?: boolean; }) { const { owner, name, canTriage } = useTracker(); const [title, setTitle] = useState(""); const [body, setBody] = useState(""); const [status, setStatus] = useState(defaults?.status ?? "todo"); const [priority, setPriority] = useState(defaults?.priority ?? 0); const [assigneeId, setAssigneeId] = useState(defaults?.assigneeId ?? null); const [labelIds, setLabelIds] = useState(defaults?.labelIds ?? []); const [estimate, setEstimate] = useState(defaults?.estimate ?? null); const [dueDate, setDueDate] = useState(defaults?.dueDate ?? null); const [createMore, setCreateMore] = useState(false); const [error, setError] = useState(); const [pending, startTransition] = useTransition(); const titleRef = useRef(null); function submit() { if (!title.trim() || pending) return; startTransition(async () => { const input: NewIssueInput = { title, body, ...(canTriage ? { status, priority, assigneeId, labelIds, estimate, dueDate } : {}) }; const result = await createIssueAction(owner, name, input); if (result.error || !result.number) { setError(result.error ?? "Couldn't create the issue."); return; } setError(undefined); setTitle(""); setBody(""); onCreated(result.number, createMore); titleRef.current?.focus(); }); } return (
{ e.preventDefault(); submit(); }} onKeyDown={(e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); submit(); } }} >
setTitle(e.target.value)} maxLength={256} placeholder="Issue title" aria-label="Title" className="font-semibold" />