diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index fe9232e8..3bea4f5e 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -58,7 +58,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 @@ -73,6 +73,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 f51279f6..7d9f47ba 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 85a8c188..004a6e43 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 97dba20f..69c116e1 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 146ab50e..0beec395 100644 --- a/resources/scripts/components/server/backups/BackupContextMenu.tsx +++ b/resources/scripts/components/server/backups/BackupContextMenu.tsx @@ -58,6 +58,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 c26dd728..6fd7c050 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 => {