feat(ui): comment insert / close
This commit is contained in:
parent
9300f4b670
commit
a985af3f4a
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ export function ForgejoIssuesTable({
|
|||
}
|
||||
}}
|
||||
onRefresh={onRefresh}
|
||||
canClose={canClose}
|
||||
/>
|
||||
<EditForgejoIssueDialog
|
||||
issue={issueToEdit}
|
||||
|
|
|
|||
Loading…
Reference in New Issue