feat(ui): comment insert / close

This commit is contained in:
null 2026-05-21 23:45:59 -05:00
parent 9300f4b670
commit a985af3f4a
2 changed files with 33 additions and 3 deletions

View File

@ -2,7 +2,7 @@
import { useEffect, useMemo, useState } from "react";
import { ExternalLink, Loader2, MessageSquarePlus, Pencil } from "lucide-react";
import { ExternalLink, Loader2, MessageSquarePlus, Pencil, XCircle } from "lucide-react";
import {
Dialog,
@ -20,8 +20,9 @@ import {
type ForgejoIssue,
type ForgejoIssueDetail,
} from "@/lib/api-forgejo";
import { PostForgejoCommentDialog } from "@/components/git/PostForgejoCommentDialog";
import { CloseForgejoIssueDialog } from "@/components/git/CloseForgejoIssueDialog";
import { EditForgejoIssueDialog } from "@/components/git/EditForgejoIssueDialog";
import { PostForgejoCommentDialog } from "@/components/git/PostForgejoCommentDialog";
type ForgejoIssueDetailDialogProps = {
issue: ForgejoIssue | null;
@ -29,6 +30,7 @@ type ForgejoIssueDetailDialogProps = {
open: boolean;
onOpenChange: (open: boolean) => void;
onRefresh?: () => void;
canClose?: boolean;
};
const formatDateTime = (value: string | null | undefined): string => {
@ -58,6 +60,7 @@ export function ForgejoIssueDetailDialog({
open,
onOpenChange,
onRefresh,
canClose = false,
}: ForgejoIssueDetailDialogProps) {
const [detail, setDetail] = useState<ForgejoIssueDetail | null>(null);
const [isLoading, setIsLoading] = useState(false);
@ -66,6 +69,7 @@ export function ForgejoIssueDetailDialog({
const [isCommentDialogOpen, setIsCommentDialogOpen] = useState(false);
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
const [isCloseIssueDialogOpen, setIsCloseIssueDialogOpen] = useState(false);
const loadDetail = (id: string) => {
let cancelled = false;
@ -113,6 +117,12 @@ export function ForgejoIssueDetailDialog({
const body = detail?.body ?? issue.body ?? issue.body_preview ?? "";
const stateVariant = active.state === "open" ? "success" : "default";
const handleCloseIssueSuccess = () => {
if (detail) setDetail({ ...detail, state: "closed" });
if (issue) loadDetail(issue.id);
onRefresh?.();
};
const handleCommentSuccess = () => {
if (issue) loadDetail(issue.id);
onRefresh?.();
@ -179,6 +189,17 @@ export function ForgejoIssueDetailDialog({
<MessageSquarePlus className="h-3.5 w-3.5" />
Comment
</Button>
{canClose && active.state === "open" ? (
<Button
variant="outline"
size="sm"
className="h-9 gap-2 rounded-xl border-[color:rgba(248,113,113,0.45)] px-3 text-xs font-semibold text-[color:var(--danger)] hover:bg-[color:rgba(248,113,113,0.08)]"
onClick={() => setIsCloseIssueDialogOpen(true)}
>
<XCircle className="h-3.5 w-3.5" />
Close Issue
</Button>
) : null}
<a
href={active.html_url}
target="_blank"
@ -357,12 +378,20 @@ export function ForgejoIssueDetailDialog({
<div className="flex justify-end">
<Button variant="outline" onClick={() => onOpenChange(false)}>
Close
Dismiss
</Button>
</div>
</DialogContent>
</Dialog>
<CloseForgejoIssueDialog
issue={issue}
repositoryName={repositoryName}
open={isCloseIssueDialogOpen}
onOpenChange={setIsCloseIssueDialogOpen}
onCloseSuccess={handleCloseIssueSuccess}
/>
<PostForgejoCommentDialog
issue={issue}
repositoryName={repositoryName}

View File

@ -421,6 +421,7 @@ export function ForgejoIssuesTable({
}
}}
onRefresh={onRefresh}
canClose={canClose}
/>
<EditForgejoIssueDialog
issue={issueToEdit}