feat(projects): duplicateProject accepts name/description/visibility overrides

The profile Duplicate dialog passes the chosen name, description and
visibility to POST /projects/{id}/duplicate. Options are optional — an
empty call still clones with the source name + " (copy)".
This commit is contained in:
David Montero Crespo 2026-07-16 04:51:24 +02:00
parent 6eba0d4850
commit 0d7dad16dd
1 changed files with 19 additions and 3 deletions

View File

@ -103,10 +103,26 @@ export async function deleteProject(id: string): Promise<void> {
await api.delete(`/projects/${id}`); await api.delete(`/projects/${id}`);
} }
/** Optional overrides for a duplicate — the Duplicate dialog supplies name /
* description / visibility; omit any field to inherit the source. */
export interface DuplicateOptions {
name?: string;
description?: string;
is_public?: boolean;
visibility?: ProjectVisibility;
}
/** Clone a project (row + files) into the caller's account. Owners can /** Clone a project (row + files) into the caller's account. Owners can
* duplicate any of their projects; public projects can be duplicated by * duplicate any of their projects; public projects can be duplicated by
* anyone. Returns the freshly created copy. */ * anyone. With no options the copy takes the source name + " (copy)" and
export async function duplicateProject(id: string): Promise<ProjectResponse> { * its visibility. Returns the freshly created copy. */
const { data: result } = await api.post<ProjectResponse>(`/projects/${id}/duplicate`); export async function duplicateProject(
id: string,
options?: DuplicateOptions,
): Promise<ProjectResponse> {
const { data: result } = await api.post<ProjectResponse>(
`/projects/${id}/duplicate`,
options ?? {},
);
return result; return result;
} }