diff --git a/docs/images/add-repo-target-org.png b/docs/images/add-repo-target-org.png new file mode 100644 index 0000000..e980255 Binary files /dev/null and b/docs/images/add-repo-target-org.png differ diff --git a/src/components/repositories/AddRepositoryDialog.tsx b/src/components/repositories/AddRepositoryDialog.tsx index 5676db0..c0ac0fe 100644 --- a/src/components/repositories/AddRepositoryDialog.tsx +++ b/src/components/repositories/AddRepositoryDialog.tsx @@ -18,10 +18,12 @@ interface AddRepositoryDialogProps { repo, owner, force, + destinationOrg, }: { repo: string; owner: string; force?: boolean; + destinationOrg?: string; }) => Promise; } @@ -32,6 +34,7 @@ export default function AddRepositoryDialog({ }: AddRepositoryDialogProps) { const [repo, setRepo] = useState(""); const [owner, setOwner] = useState(""); + const [destinationOrg, setDestinationOrg] = useState(""); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(""); @@ -40,6 +43,7 @@ export default function AddRepositoryDialog({ setError(""); setRepo(""); setOwner(""); + setDestinationOrg(""); } }, [isDialogOpen]); @@ -54,11 +58,16 @@ export default function AddRepositoryDialog({ try { setIsLoading(true); - await onAddRepository({ repo, owner }); + await onAddRepository({ + repo, + owner, + destinationOrg: destinationOrg.trim() || undefined, + }); setError(""); setRepo(""); setOwner(""); + setDestinationOrg(""); setIsDialogOpen(false); } catch (err: any) { setError(err?.message || "Failed to add repository."); @@ -124,6 +133,27 @@ export default function AddRepositoryDialog({ /> +
+ + setDestinationOrg(e.target.value)} + className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" + placeholder="Gitea org or user (uses default strategy if empty)" + autoComplete="off" + /> +
+ {error &&

{error}

} diff --git a/src/components/repositories/Repository.tsx b/src/components/repositories/Repository.tsx index f10e2c7..1e09b6a 100644 --- a/src/components/repositories/Repository.tsx +++ b/src/components/repositories/Repository.tsx @@ -698,10 +698,12 @@ export default function Repository() { repo, owner, force = false, + destinationOrg, }: { repo: string; owner: string; force?: boolean; + destinationOrg?: string; }) => { if (!user || !user.id) { return; @@ -736,6 +738,7 @@ export default function Repository() { repo: trimmedRepo, owner: trimmedOwner, force, + ...(destinationOrg ? { destinationOrg } : {}), }; const response = await apiRequest( diff --git a/src/pages/api/sync/repository.ts b/src/pages/api/sync/repository.ts index 1192405..0cc7f10 100644 --- a/src/pages/api/sync/repository.ts +++ b/src/pages/api/sync/repository.ts @@ -20,7 +20,7 @@ export const POST: APIRoute = async ({ request, locals }) => { const userId = authResult.userId; const body: AddRepositoriesApiRequest = await request.json(); - const { owner, repo, force = false } = body; + const { owner, repo, force = false, destinationOrg } = body; if (!owner || !repo) { return new Response( @@ -122,7 +122,7 @@ export const POST: APIRoute = async ({ request, locals }) => { lastMirrored: existingRepo?.lastMirrored ?? null, errorMessage: existingRepo?.errorMessage ?? null, mirroredLocation: existingRepo?.mirroredLocation ?? "", - destinationOrg: existingRepo?.destinationOrg ?? null, + destinationOrg: destinationOrg?.trim() || existingRepo?.destinationOrg || null, updatedAt: repoData.updated_at ? new Date(repoData.updated_at) : new Date(), diff --git a/src/types/Repository.ts b/src/types/Repository.ts index fd9a712..30cc169 100644 --- a/src/types/Repository.ts +++ b/src/types/Repository.ts @@ -83,6 +83,7 @@ export interface AddRepositoriesApiRequest { repo: string; owner: string; force?: boolean; + destinationOrg?: string; } export interface AddRepositoriesApiResponse {