|
1 | 1 | 'use client' |
2 | 2 |
|
3 | 3 | import { useCallback } from 'react' |
4 | | -import { parseEnvironmentName } from '@/lib/projects' |
5 | | -import type { Project } from '@/app/o/[organizationId]/p/hooks/use-projects' |
6 | | -import { |
7 | | - useDeleteWorkspace, |
8 | | - usePinnedWorkspaceIds, |
9 | | - useToggleWorkspacePin, |
10 | | - useUpdateWorkspace, |
11 | | - useWorkspacesQuery, |
12 | | -} from '@/hooks/queries/workspace' |
| 4 | +import { isProjectPinned } from '@/app/o/[organizationId]/components/organization-sidebar/components/projects-section/use-project-order' |
| 5 | +import { defaultEnvironment, type Project } from '@/app/o/[organizationId]/p/hooks/use-projects' |
| 6 | +import { useArchiveProject, useRenameProject } from '@/hooks/queries/projects' |
| 7 | +import { usePinnedWorkspaceIds, useToggleWorkspacePin } from '@/hooks/queries/workspace' |
13 | 8 |
|
14 | 9 | /** |
15 | | - * Rename, pin and delete for a project, applied to every workspace of its lineage: a rename |
16 | | - * keeps each environment's own suffix ("Staging", "Sandbox"), a delete removes forks before |
17 | | - * their parent, and the pin lives on the root. Mock projects have no workspace, so every |
18 | | - * action is a no-op for them. |
| 10 | + * Rename, pin and delete for a project. Rename and delete act on the project itself; delete |
| 11 | + * archives it with every environment. Pins live on workspaces, so pinning pins the project's |
| 12 | + * default environment and unpinning clears every environment's pin. |
19 | 13 | */ |
20 | 14 | export function useProjectActions() { |
21 | | - const { data: workspaces } = useWorkspacesQuery() |
22 | 15 | const { data: pinnedIds } = usePinnedWorkspaceIds() |
23 | 16 | const { mutate: togglePin } = useToggleWorkspacePin() |
24 | | - const { mutateAsync: updateWorkspace, isPending: isRenaming } = useUpdateWorkspace() |
25 | | - const { mutateAsync: deleteWorkspace, isPending: isDeleting } = useDeleteWorkspace() |
| 17 | + const { mutateAsync: renameProject, isPending: isRenaming } = useRenameProject() |
| 18 | + const { mutateAsync: archiveProject, isPending: isDeleting } = useArchiveProject() |
26 | 19 |
|
27 | 20 | const isPinned = useCallback( |
28 | | - (project: Project) => Boolean(pinnedIds?.has(project.rootId)), |
| 21 | + (project: Project) => isProjectPinned(project, pinnedIds), |
29 | 22 | [pinnedIds] |
30 | 23 | ) |
31 | 24 |
|
32 | 25 | const setPinned = useCallback( |
33 | 26 | (project: Project, pinned: boolean) => { |
34 | | - togglePin({ workspaceId: project.rootId, pinned }) |
| 27 | + if (pinned) { |
| 28 | + togglePin({ workspaceId: defaultEnvironment(project).workspaceId, pinned }) |
| 29 | + return |
| 30 | + } |
| 31 | + for (const environment of project.environments) { |
| 32 | + if (pinnedIds?.has(environment.workspaceId)) |
| 33 | + togglePin({ workspaceId: environment.workspaceId, pinned }) |
| 34 | + } |
35 | 35 | }, |
36 | | - [togglePin] |
| 36 | + [togglePin, pinnedIds] |
37 | 37 | ) |
38 | 38 |
|
39 | 39 | const rename = useCallback( |
40 | 40 | async (project: Project, name: string) => { |
41 | | - const base = name.trim() |
42 | | - if (!base || base === project.name) return |
43 | | - for (const environment of project.environments) { |
44 | | - const workspace = workspaces?.find((candidate) => candidate.id === environment.workspaceId) |
45 | | - if (!workspace) continue |
46 | | - const { environment: suffix } = parseEnvironmentName(workspace.name) |
47 | | - await updateWorkspace({ |
48 | | - workspaceId: workspace.id, |
49 | | - name: suffix ? `${base} ${suffix}` : base, |
50 | | - }) |
51 | | - } |
| 41 | + const trimmed = name.trim() |
| 42 | + if (!trimmed || trimmed === project.name) return |
| 43 | + await renameProject({ projectId: project.id, name: trimmed }) |
52 | 44 | }, |
53 | | - [updateWorkspace, workspaces] |
| 45 | + [renameProject] |
54 | 46 | ) |
55 | 47 |
|
56 | 48 | const remove = useCallback( |
57 | 49 | async (project: Project) => { |
58 | | - /** Forks first: the root is the last workspace to go, so a failure leaves a valid lineage. */ |
59 | | - for (const environment of [...project.environments].reverse()) { |
60 | | - await deleteWorkspace({ workspaceId: environment.workspaceId }) |
61 | | - } |
| 50 | + await archiveProject({ projectId: project.id }) |
62 | 51 | }, |
63 | | - [deleteWorkspace] |
| 52 | + [archiveProject] |
64 | 53 | ) |
65 | 54 |
|
66 | 55 | return { isPinned, setPinned, rename, remove, isRenaming, isDeleting } |
|
0 commit comments