+ {syncResult && (
+
+ {syncResult.repoName} synced:{" "}
+ {syncResult.created} created, {syncResult.updated} updated,{" "}
+ {syncResult.open} open, {syncResult.closed} closed
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
),
- title: EMPTY_STATE_DATA.title,
- description: EMPTY_STATE_DATA.description,
- actionHref: "/git-projects/connect",
- actionLabel: "Connect repository",
+ title: "No repositories tracked yet",
+ description:
+ "Connect a Forgejo instance and add repositories to start tracking issues.",
+ actionHref: "/git-projects/connections",
+ actionLabel: "Set up connection",
}}
/>
);
-}
+}
\ No newline at end of file
diff --git a/frontend/src/app/git-projects/repositories/page.tsx b/frontend/src/app/git-projects/repositories/page.tsx
index 9a0f9d9..f5baac7 100644
--- a/frontend/src/app/git-projects/repositories/page.tsx
+++ b/frontend/src/app/git-projects/repositories/page.tsx
@@ -10,6 +10,8 @@ import { ForgejoRepositoriesTable } from "@/components/git/ForgejoRepositoriesTa
import {
getForgejoRepositories,
deleteForgejoRepository,
+ syncRepository,
+ validateRepository,
type ForgejoRepository,
} from "@/lib/api-forgejo";
@@ -54,6 +56,47 @@ export default function ForgejoRepositoriesPage() {
}
};
+ const handleSync = async (repository: ForgejoRepository) => {
+ try {
+ const result = await syncRepository(repository.id);
+ alert(
+ `Sync completed!\n\n` +
+ `Created: ${result.created}\n` +
+ `Updated: ${result.updated}\n` +
+ `Open: ${result.open}\n` +
+ `Closed: ${result.closed}\n` +
+ `Total: ${result.total}`
+ );
+ // Refetch to update last_sync_at
+ const data = await getForgejoRepositories();
+ setRepositories(data);
+ return result;
+ } catch (err) {
+ alert(err instanceof Error ? err.message : "Failed to sync repository");
+ throw err;
+ }
+ };
+
+ const handleValidateRepository = async (repository: ForgejoRepository) => {
+ try {
+ const result = await validateRepository(repository.id);
+ if (result.ok) {
+ alert(
+ `Repository is valid!\n\n` +
+ `Repository exists: ${result.repo_exists ? "Yes" : "No"}`
+ );
+ } else {
+ alert(
+ `Repository validation failed: ${result.error_message || "Unknown error"}`
+ );
+ }
+ return result;
+ } catch (err) {
+ alert(err instanceof Error ? err.message : "Failed to validate repository");
+ throw err;
+ }
+ };
+
return (
)}
diff --git a/frontend/src/components/git/ForgejoConnectionsTable.tsx b/frontend/src/components/git/ForgejoConnectionsTable.tsx
index bee4cf5..427332e 100644
--- a/frontend/src/components/git/ForgejoConnectionsTable.tsx
+++ b/frontend/src/components/git/ForgejoConnectionsTable.tsx
@@ -11,6 +11,7 @@ import {
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
+import { Loader2, CheckCircle2 } from "lucide-react";
import { DataTable } from "@/components/tables/DataTable";
import DropdownSelect from "@/components/ui/dropdown-select";
import { Input } from "@/components/ui/input";
@@ -23,6 +24,7 @@ interface ConnectionsTableProps {
isLoading: boolean;
onEdit?: (connection: ForgejoConnection) => void;
onDelete?: (connection: ForgejoConnection) => void;
+ onValidate?: (connection: ForgejoConnection) => void;
}
export function ForgejoConnectionsTable({
@@ -30,10 +32,13 @@ export function ForgejoConnectionsTable({
isLoading,
onEdit,
onDelete,
+ onValidate,
}: ConnectionsTableProps) {
+ // onEdit available for future use
+ const _ = onEdit;
const table = useReactTable({
data: connections,
- columns: columns,
+ columns: columns(onValidate),
getCoreRowModel: getCoreRowModel(),
});
@@ -70,7 +75,9 @@ export function ForgejoConnectionsTable({
);
}
-const columns: ColumnDef