diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index 03ffd1685..c37e9a123 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -44,7 +44,7 @@ class BackupController extends ClientApiController } /** - * Returns all of the backups for a given server instance in a paginated + * Returns all the backups for a given server instance in a paginated * result set. * * @throws \Illuminate\Auth\Access\AuthorizationException @@ -60,6 +60,9 @@ class BackupController extends ClientApiController return $this->fractal->collection($server->backups()->paginate($limit)) ->transformWith($this->getTransformer(BackupTransformer::class)) + ->addMeta([ + 'used_backup_count' => $this->initiateBackupService->getNonFailedBackups($server)->count(), + ]) ->toArray(); } diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index f51279f69..7d9f47ba1 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -9,6 +9,7 @@ use Pterodactyl\Models\Backup; use Pterodactyl\Models\Server; use Illuminate\Database\ConnectionInterface; use Pterodactyl\Extensions\Backups\BackupManager; +use Illuminate\Database\Eloquent\Relations\HasMany; use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Repositories\Wings\DaemonBackupRepository; use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException; @@ -134,10 +135,7 @@ class InitiateBackupService // Check if the server has reached or exceeded its backup limit. // completed_at == null will cover any ongoing backups, while is_successful == true will cover any completed backups. - $successful = $server->backups()->where(function ($query) { - $query->whereNull('completed_at') - ->orWhere('is_successful', true); - }); + $successful = $this->getNonFailedBackups($server); if (!$server->backup_limit || $successful->count() >= $server->backup_limit) { // Do not allow the user to continue if this server is already at its limit and can't override. if (!$override || $server->backup_limit <= 0) { @@ -174,4 +172,12 @@ class InitiateBackupService return $backup; }); } + + public function getNonFailedBackups(Server $server): HasMany + { + return $server->backups()->where(function ($query) { + $query->whereNull('completed_at') + ->orWhere('is_successful', true); + }); + } } diff --git a/resources/scripts/api/swr/getServerBackups.ts b/resources/scripts/api/swr/getServerBackups.ts index 85a8c1886..004a6e43a 100644 --- a/resources/scripts/api/swr/getServerBackups.ts +++ b/resources/scripts/api/swr/getServerBackups.ts @@ -12,16 +12,19 @@ interface ctx { export const Context = createContext({ page: 1, setPage: () => 1 }); +type BackupResponse = PaginatedResult & { usedBackupCount: number }; + export default () => { const { page } = useContext(Context); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); - return useSWR>([ 'server:backups', uuid, page ], async () => { + return useSWR([ 'server:backups', uuid, page ], async () => { const { data } = await http.get(`/api/client/servers/${uuid}/backups`, { params: { page } }); return ({ items: (data.data || []).map(rawDataToServerBackup), pagination: getPaginationSet(data.meta.pagination), + usedBackupCount: data.meta.used_backup_count, }); }); }; diff --git a/resources/scripts/components/server/backups/BackupContainer.tsx b/resources/scripts/components/server/backups/BackupContainer.tsx index 97dba20f8..69c116e11 100644 --- a/resources/scripts/components/server/backups/BackupContainer.tsx +++ b/resources/scripts/components/server/backups/BackupContainer.tsx @@ -65,12 +65,12 @@ const BackupContainer = () => { }
- {(backupLimit > 0 && backups.pagination.total > 0) && + {(backupLimit > 0 && backups.usedBackupCount > 0) &&

- {backups.pagination.total} of {backupLimit} backups have been created for this server. + {backups.usedBackupCount} of {backupLimit} backups have been created for this server.

} - {backupLimit > 0 && backupLimit !== backups.pagination.total && + {backupLimit > 0 && backupLimit > backups.usedBackupCount && }
diff --git a/resources/scripts/components/server/backups/BackupContextMenu.tsx b/resources/scripts/components/server/backups/BackupContextMenu.tsx index 48a3a29c7..158dd1be1 100644 --- a/resources/scripts/components/server/backups/BackupContextMenu.tsx +++ b/resources/scripts/components/server/backups/BackupContextMenu.tsx @@ -51,6 +51,7 @@ export default ({ backup }: Props) => { .then(() => mutate(data => ({ ...data!, items: data!.items.filter(b => b.uuid !== backup.uuid), + usedBackupCount: data!.usedBackupCount - 1, }), false)) .catch(error => { console.error(error); diff --git a/resources/scripts/components/server/backups/CreateBackupButton.tsx b/resources/scripts/components/server/backups/CreateBackupButton.tsx index 5f02f22d0..2605a8321 100644 --- a/resources/scripts/components/server/backups/CreateBackupButton.tsx +++ b/resources/scripts/components/server/backups/CreateBackupButton.tsx @@ -81,7 +81,7 @@ export default () => { clearFlashes('backups:create'); createServerBackup(uuid, values) .then(backup => { - mutate(data => ({ ...data!, items: data!.items.concat(backup) }), false); + mutate(data => ({ ...data!, items: data!.items.concat(backup), usedBackupCount: data!.usedBackupCount + 1 }), false); setVisible(false); }) .catch(error => {