|
12 | 12 | import { BillingPlanGroup, type Models } from '@appwrite.io/console'; |
13 | 13 | import { sdk } from '$lib/stores/sdk'; |
14 | 14 | import { addNotification } from '$lib/stores/notifications'; |
| 15 | + import { invalidate } from '$app/navigation'; |
| 16 | + import { Dependencies } from '$lib/constants'; |
15 | 17 |
|
16 | 18 | const { |
17 | 19 | projects = [], |
|
30 | 32 | let hasConfirmedSelection = $state(false); |
31 | 33 |
|
32 | 34 | let isDeletingProjects = $state(false); |
| 35 | + let deletedProjectIds = $state<Set<string>>(new Set()); |
33 | 36 | let selectedProjectsToDelete = $state<Array<string>>([]); |
34 | 37 | const baseFreePlan = getBasePlanFromGroup(BillingPlanGroup.Starter); |
35 | 38 |
|
|
43 | 46 | // When preparing to downgrade to Free, enforce Free plan limit locally (2) |
44 | 47 | const allowedProjectsToKeep = $derived(freePlanLimits.projects); |
45 | 48 |
|
| 49 | + const filteredProjects = $derived( |
| 50 | + projects.filter((project) => !deletedProjectIds.has(project.$id)) |
| 51 | + ); |
| 52 | +
|
46 | 53 | const currentUsage = $derived({ |
47 | | - projects: projects?.length || 0, |
| 54 | + projects: filteredProjects?.length || 0, |
48 | 55 | members: members?.length || 0, |
49 | 56 | storage: storageUsage || 0 |
50 | 57 | }); |
|
86 | 93 | } |
87 | 94 |
|
88 | 95 | if (selectedProjectsToDelete?.length) { |
89 | | - const projectsDeletionPromise = selectedProjectsToDelete.map((projectId) => { |
90 | | - return sdk.forConsole.projects.delete({ projectId }); |
91 | | - }); |
| 96 | + const projectsDeletionPromises = selectedProjectsToDelete.map((projectId) => ({ |
| 97 | + projectId, |
| 98 | + promise: sdk.forConsole.projects.delete({ projectId }) |
| 99 | + })); |
92 | 100 |
|
93 | 101 | try { |
94 | | - await Promise.all(projectsDeletionPromise); |
95 | | - addNotification({ |
96 | | - type: 'success', |
97 | | - message: 'Selected projects were deleted' |
| 102 | + const results = await Promise.allSettled( |
| 103 | + projectsDeletionPromises.map((p) => p.promise) |
| 104 | + ); |
| 105 | +
|
| 106 | + const failed: string[] = []; |
| 107 | + const successfullyDeleted: string[] = []; |
| 108 | +
|
| 109 | + results.forEach((result, index) => { |
| 110 | + const projectId = projectsDeletionPromises[index].projectId; |
| 111 | + if (result.status === 'fulfilled') { |
| 112 | + successfullyDeleted.push(projectId); |
| 113 | + } else { |
| 114 | + failed.push(projectId); |
| 115 | + } |
98 | 116 | }); |
99 | | - showSelectProject = false; |
100 | | - showSelectionReminder = false; |
| 117 | +
|
| 118 | + if (successfullyDeleted.length > 0) { |
| 119 | + deletedProjectIds = new Set([...deletedProjectIds, ...successfullyDeleted]); |
| 120 | + await invalidate(Dependencies.ORGANIZATION); |
| 121 | +
|
| 122 | + addNotification({ |
| 123 | + type: 'success', |
| 124 | + message: `${successfullyDeleted.length} project${successfullyDeleted.length !== 1 ? 's' : ''} deleted successfully` |
| 125 | + }); |
| 126 | + } |
| 127 | +
|
| 128 | + if (failed.length > 0) { |
| 129 | + error = `Failed to delete ${failed.length} project${failed.length !== 1 ? 's' : ''}`; |
| 130 | + } else { |
| 131 | + showSelectProject = false; |
| 132 | + selectedProjectsToDelete = []; |
| 133 | + hasConfirmedSelection = false; |
| 134 | + showSelectionReminder = false; |
| 135 | + } |
101 | 136 | } catch (exception) { |
102 | 137 | error = exception.message; |
103 | 138 | } finally { |
|
0 commit comments