diff --git a/backend/app/api/forgejo_issues.py b/backend/app/api/forgejo_issues.py
index cce7d5b..bd592b9 100644
--- a/backend/app/api/forgejo_issues.py
+++ b/backend/app/api/forgejo_issues.py
@@ -43,7 +43,10 @@ async def list_issues(
) -> ForgejoIssueListResponse:
"""List cached issues with optional filters."""
# Build query with filters
- statement = select(ForgejoIssue).where(ForgejoIssue.organization_id == ctx.organization.id)
+ statement = select(ForgejoIssue).where(
+ ForgejoIssue.organization_id == ctx.organization.id,
+ ForgejoIssue.is_pull_request.is_(False),
+ )
if repository_id:
try:
@@ -75,7 +78,10 @@ async def list_issues(
)
# Count total
- total_statement = select(func.count()).select_from(ForgejoIssue).where(ForgejoIssue.organization_id == ctx.organization.id)
+ total_statement = select(func.count()).select_from(ForgejoIssue).where(
+ ForgejoIssue.organization_id == ctx.organization.id,
+ ForgejoIssue.is_pull_request.is_(False),
+ )
if repository_id:
try:
repo_uuid = UUID(repository_id)
diff --git a/frontend/src/app/git-projects/issues/page.tsx b/frontend/src/app/git-projects/issues/page.tsx
index 63afd15..881e9d3 100644
--- a/frontend/src/app/git-projects/issues/page.tsx
+++ b/frontend/src/app/git-projects/issues/page.tsx
@@ -260,6 +260,7 @@ export default function GitIssuesPage() {
diff --git a/frontend/src/components/git/ForgejoIssuesTable.tsx b/frontend/src/components/git/ForgejoIssuesTable.tsx
index 5b33a68..96c2357 100644
--- a/frontend/src/components/git/ForgejoIssuesTable.tsx
+++ b/frontend/src/components/git/ForgejoIssuesTable.tsx
@@ -1,19 +1,18 @@
"use client";
-import { useCallback, useMemo, useState } from "react";
+import { useMemo } from "react";
import {
type ColumnDef,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
-import { CircleDot, ExternalLink, XCircle } from "lucide-react";
+import { CircleDot, ExternalLink } from "lucide-react";
-import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { DataTable } from "@/components/tables/DataTable";
-import { CloseForgejoIssueDialog } from "@/components/git/CloseForgejoIssueDialog";
import type { ForgejoIssue, ForgejoIssueLabel } from "@/lib/api-forgejo";
+import type { ForgejoRepository } from "@/lib/api-forgejo";
/** Normalize a Forgejo label color to a valid 6-char hex string or null. */
function normalizeLabelColor(raw: string | null | undefined): string | null {
@@ -54,29 +53,42 @@ function LabelChip({ label }: { label: ForgejoIssueLabel }) {
export type ForgejoIssuesTableProps = {
issues: ForgejoIssue[];
+ repositories: ForgejoRepository[];
isLoading?: boolean;
onRefresh: () => void;
};
export function ForgejoIssuesTable({
issues,
+ repositories,
isLoading = false,
- onRefresh,
+ onRefresh: _onRefresh,
}: ForgejoIssuesTableProps) {
- const [closeIssueDialogOpen, setCloseIssueDialogOpen] = useState(false);
- const [issueToClose, setIssueToClose] = useState(null);
-
- const handleCloseClick = useCallback((issue: ForgejoIssue) => {
- setIssueToClose(issue);
- setCloseIssueDialogOpen(true);
- }, []);
-
- const handleCloseSuccess = () => {
- onRefresh();
- };
+ const repositoryNameById = useMemo(() => {
+ const map = new Map();
+ for (const repository of repositories) {
+ map.set(
+ repository.id,
+ repository.display_name || `${repository.owner}/${repository.repo}`,
+ );
+ }
+ return map;
+ }, [repositories]);
const columns: ColumnDef[] = useMemo(
() => [
+ {
+ id: "repository",
+ header: "Repository",
+ cell: ({ row }) => {
+ const fallback = row.original.repository_id;
+ return (
+
+ {repositoryNameById.get(row.original.repository_id) ?? fallback}
+
+ );
+ },
+ },
{
accessorKey: "forgejo_issue_number",
header: "#",
@@ -104,20 +116,6 @@ export function ForgejoIssuesTable({
),
},
- {
- accessorKey: "body_preview",
- header: "Description",
- cell: ({ row }) => {
- const body = row.original.body_preview;
- if (!body) return null;
- const truncated = body.length > 120 ? body.slice(0, 120) + "…" : body;
- return (
-
- {truncated}
-
- );
- },
- },
{
accessorKey: "state",
header: "State",
@@ -153,13 +151,24 @@ export function ForgejoIssuesTable({
},
},
{
- accessorKey: "author",
- header: "Author",
- cell: ({ row }) => (
-
- {row.original.author || "Unknown"}
-
- ),
+ id: "assignee",
+ header: "Assignee",
+ cell: ({ row }) => {
+ const assignee = row.original.assignees?.[0];
+ const login =
+ assignee &&
+ typeof assignee === "object" &&
+ "login" in assignee &&
+ typeof assignee.login === "string"
+ ? assignee.login
+ : null;
+
+ return (
+
+ {login || "Unassigned"}
+
+ );
+ },
},
{
accessorKey: "forgejo_updated_at",
@@ -180,27 +189,8 @@ export function ForgejoIssuesTable({
}
},
},
- {
- id: "actions",
- header: "Actions",
- cell: ({ row }) => {
- const issue = row.original;
- if (issue.state !== "open" || issue.is_pull_request) return null;
- return (
-
- );
- },
- },
],
- [handleCloseClick],
+ [repositoryNameById],
);
const table = useReactTable({
data: issues,
@@ -215,7 +205,7 @@ export function ForgejoIssuesTable({
table={table}
isLoading={isLoading}
loadingLabel="Loading Git Project issues…"
- tableClassName="min-w-[960px] w-full text-left text-sm"
+ tableClassName="min-w-[980px] w-full text-left text-sm"
emptyState={{
icon: ,
title: "No Git Project issues found",
@@ -224,12 +214,6 @@ export function ForgejoIssuesTable({
}}
/>
-
>
);
}