From a8d9eccf9cd5b2766f11a712643290c49735820c Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 6 Dec 2020 12:01:42 -0800 Subject: [PATCH] Support pagination of server backups, closes #2787 --- .../Api/Client/Servers/BackupController.php | 3 +- resources/scripts/api/swr/getServerBackups.ts | 11 +++- .../components/dashboard/ApiKeyModal.tsx | 2 +- .../server/backups/BackupContainer.tsx | 55 +++++++++++++------ .../server/backups/ChecksumModal.tsx | 2 +- .../server/databases/DatabaseRow.tsx | 2 +- 6 files changed, 53 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index cc8ba0917..23daf1bc6 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -60,7 +60,8 @@ class BackupController extends ClientApiController */ public function index(GetBackupsRequest $request, Server $server) { - return $this->fractal->collection($server->backups()->paginate(20)) + $limit = min($request->query('per_page') ?? 20, 50); + return $this->fractal->collection($server->backups()->paginate($limit)) ->transformWith($this->getTransformer(BackupTransformer::class)) ->toArray(); } diff --git a/resources/scripts/api/swr/getServerBackups.ts b/resources/scripts/api/swr/getServerBackups.ts index 0c38cd278..85a8c1886 100644 --- a/resources/scripts/api/swr/getServerBackups.ts +++ b/resources/scripts/api/swr/getServerBackups.ts @@ -3,8 +3,17 @@ import http, { getPaginationSet, PaginatedResult } from '@/api/http'; import { ServerBackup } from '@/api/server/types'; import { rawDataToServerBackup } from '@/api/transformers'; import { ServerContext } from '@/state/server'; +import { createContext, useContext } from 'react'; -export default (page?: number | string) => { +interface ctx { + page: number; + setPage: (value: number | ((s: number) => number)) => void; +} + +export const Context = createContext({ page: 1, setPage: () => 1 }); + +export default () => { + const { page } = useContext(Context); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); return useSWR>([ 'server:backups', uuid, page ], async () => { diff --git a/resources/scripts/components/dashboard/ApiKeyModal.tsx b/resources/scripts/components/dashboard/ApiKeyModal.tsx index e73274309..ba6568b84 100644 --- a/resources/scripts/components/dashboard/ApiKeyModal.tsx +++ b/resources/scripts/components/dashboard/ApiKeyModal.tsx @@ -13,7 +13,7 @@ const ApiKeyModal = ({ apiKey }: Props) => { return ( <> -

Your API Key

+

Your API Key

The API key you have requested is shown below. Please store this in a safe location, it will not be shown again. diff --git a/resources/scripts/components/server/backups/BackupContainer.tsx b/resources/scripts/components/server/backups/BackupContainer.tsx index 493c059a5..99f1e6326 100644 --- a/resources/scripts/components/server/backups/BackupContainer.tsx +++ b/resources/scripts/components/server/backups/BackupContainer.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import Spinner from '@/components/elements/Spinner'; import useFlash from '@/plugins/useFlash'; import Can from '@/components/elements/Can'; @@ -6,11 +6,13 @@ import CreateBackupButton from '@/components/server/backups/CreateBackupButton'; import FlashMessageRender from '@/components/FlashMessageRender'; import BackupRow from '@/components/server/backups/BackupRow'; import tw from 'twin.macro'; -import getServerBackups from '@/api/swr/getServerBackups'; +import getServerBackups, { Context as ServerBackupContext } from '@/api/swr/getServerBackups'; import { ServerContext } from '@/state/server'; import ServerContentBlock from '@/components/elements/ServerContentBlock'; +import Pagination from '@/components/elements/Pagination'; -export default () => { +const BackupContainer = () => { + const { page, setPage } = useContext(ServerBackupContext); const { clearFlashes, clearAndAddHttpError } = useFlash(); const { data: backups, error, isValidating } = getServerBackups(); @@ -33,19 +35,29 @@ export default () => { return ( - {!backups.items.length ? -

- There are no backups stored for this server. -

- : -
- {backups.items.map((backup, index) => 0 ? tw`mt-2` : undefined} - />)} -
- } + + {({ items }) => ( + !items.length ? + // Don't show any error messages if the server has no backups and the user cannot + // create additional ones for the server. + !backupLimit ? + null + : +

+ {page > 1 ? + 'Looks like we\'ve run out of backups to show you, try going back a page.' + : + 'It looks like there are no backups currently stored for this server.' + } +

+ : + items.map((backup, index) => 0 ? tw`mt-2` : undefined} + />) + )} +
{backupLimit === 0 &&

Backups cannot be created for this server. @@ -59,10 +71,19 @@ export default () => {

} {backupLimit > 0 && backupLimit !== backups.items.length && - + } ); }; + +export default () => { + const [ page, setPage ] = useState(1); + return ( + + + + ); +}; diff --git a/resources/scripts/components/server/backups/ChecksumModal.tsx b/resources/scripts/components/server/backups/ChecksumModal.tsx index 57e6ba8b5..a0a318d67 100644 --- a/resources/scripts/components/server/backups/ChecksumModal.tsx +++ b/resources/scripts/components/server/backups/ChecksumModal.tsx @@ -4,7 +4,7 @@ import tw from 'twin.macro'; const ChecksumModal = ({ checksum, ...props }: RequiredModalProps & { checksum: string }) => ( -

Verify file checksum

+

Verify file checksum

The checksum of this file is:

diff --git a/resources/scripts/components/server/databases/DatabaseRow.tsx b/resources/scripts/components/server/databases/DatabaseRow.tsx index 952a7b746..caf4a702e 100644 --- a/resources/scripts/components/server/databases/DatabaseRow.tsx +++ b/resources/scripts/components/server/databases/DatabaseRow.tsx @@ -111,7 +111,7 @@ export default ({ database, className }: Props) => { setConnectionVisible(false)}> -

Database connection details

+

Database connection details