From d323662ad5742e1f556142d5b9c61f8749830a0c Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Sat, 9 Jan 2021 09:58:55 -0700 Subject: [PATCH] admin(ui): implement DatabaseEditContainer.tsx --- .../Databases/DatabaseController.php | 30 +++- .../api/admin/databases/createDatabase.ts | 4 +- .../api/admin/databases/updateDatabase.ts | 12 ++ .../admin/databases/DatabaseEditContainer.tsx | 128 ++++++++++++++++++ 4 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 resources/scripts/api/admin/databases/updateDatabase.ts diff --git a/app/Http/Controllers/Api/Application/Databases/DatabaseController.php b/app/Http/Controllers/Api/Application/Databases/DatabaseController.php index 70656467f..135f31a89 100644 --- a/app/Http/Controllers/Api/Application/Databases/DatabaseController.php +++ b/app/Http/Controllers/Api/Application/Databases/DatabaseController.php @@ -5,6 +5,8 @@ namespace Pterodactyl\Http\Controllers\Api\Application\Databases; use Illuminate\Http\JsonResponse; use Pterodactyl\Models\DatabaseHost; use Spatie\QueryBuilder\QueryBuilder; +use Pterodactyl\Services\Databases\Hosts\HostUpdateService; +use Pterodactyl\Services\Databases\Hosts\HostCreationService; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Transformers\Api\Application\DatabaseHostTransformer; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; @@ -17,11 +19,27 @@ use Pterodactyl\Http\Requests\Api\Application\Databases\DeleteDatabaseRequest; class DatabaseController extends ApplicationApiController { /** - * DatabaseController constructor. + * @var \Pterodactyl\Services\Databases\Hosts\HostCreationService */ - public function __construct() + private $creationService; + + /** + * @var \Pterodactyl\Services\Databases\Hosts\HostUpdateService + */ + private $updateService; + + /** + * DatabaseController constructor. + * + * @param \Pterodactyl\Services\Databases\Hosts\HostCreationService $creationService + * @param \Pterodactyl\Services\Databases\Hosts\HostUpdateService $updateService + */ + public function __construct(HostCreationService $creationService, HostUpdateService $updateService) { parent::__construct(); + + $this->creationService = $creationService; + $this->updateService = $updateService; } /** @@ -73,11 +91,11 @@ class DatabaseController extends ApplicationApiController * @param \Pterodactyl\Http\Requests\Api\Application\Databases\StoreDatabaseRequest $request * * @return \Illuminate\Http\JsonResponse - * @throws \Illuminate\Contracts\Container\BindingResolutionException + * @throws \Throwable */ public function store(StoreDatabaseRequest $request): JsonResponse { - $databaseHost = DatabaseHost::query()->create($request->validated()); + $databaseHost = $this->creationService->handle($request->validated()); return $this->fractal->item($databaseHost) ->transformWith($this->getTransformer(DatabaseHostTransformer::class)) @@ -91,11 +109,11 @@ class DatabaseController extends ApplicationApiController * @param \Pterodactyl\Models\DatabaseHost $databaseHost * * @return array - * @throws \Illuminate\Contracts\Container\BindingResolutionException + * @throws \Throwable */ public function update(UpdateDatabaseRequest $request, DatabaseHost $databaseHost): array { - $databaseHost->update($request->validated()); + $databaseHost = $this->updateService->handle($databaseHost->id, $request->validated()); return $this->fractal->item($databaseHost) ->transformWith($this->getTransformer(DatabaseHostTransformer::class)) diff --git a/resources/scripts/api/admin/databases/createDatabase.ts b/resources/scripts/api/admin/databases/createDatabase.ts index 70bb33fd5..a2a273c7f 100644 --- a/resources/scripts/api/admin/databases/createDatabase.ts +++ b/resources/scripts/api/admin/databases/createDatabase.ts @@ -1,10 +1,10 @@ import http from '@/api/http'; import { Database, rawDataToDatabase } from '@/api/admin/databases/getDatabases'; -export default (name: string): Promise => { +export default (name: string, host: string, port: number, username: string, password: string): Promise => { return new Promise((resolve, reject) => { http.post('/api/application/databases', { - name, + name, host, port, username, password, }) .then(({ data }) => resolve(rawDataToDatabase(data))) .catch(reject); diff --git a/resources/scripts/api/admin/databases/updateDatabase.ts b/resources/scripts/api/admin/databases/updateDatabase.ts new file mode 100644 index 000000000..5c9cabba1 --- /dev/null +++ b/resources/scripts/api/admin/databases/updateDatabase.ts @@ -0,0 +1,12 @@ +import http from '@/api/http'; +import { Database, rawDataToDatabase } from '@/api/admin/databases/getDatabases'; + +export default (id: number, name: string, host: string, port: number, username: string, password?: string | undefined): Promise => { + return new Promise((resolve, reject) => { + http.patch(`/api/application/databases/${id}`, { + name, host, port, username, password, + }) + .then(({ data }) => resolve(rawDataToDatabase(data))) + .catch(reject); + }); +}; diff --git a/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx b/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx index 0a290153d..6c44c04b0 100644 --- a/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx +++ b/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx @@ -8,6 +8,13 @@ import AdminContentBlock from '@/components/admin/AdminContentBlock'; import Spinner from '@/components/elements/Spinner'; import FlashMessageRender from '@/components/FlashMessageRender'; import { ApplicationStore } from '@/state'; +import { number, object, string } from 'yup'; +import AdminBox from '@/components/admin/AdminBox'; +import Button from '@/components/elements/Button'; +import Field from '@/components/elements/Field'; +import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; +import { Form, Formik, FormikHelpers } from 'formik'; +import updateDatabase from '@/api/admin/databases/updateDatabase'; interface ctx { database: Database | undefined; @@ -22,6 +29,125 @@ export const Context = createContextStore({ }), }); +interface Values { + name: string; + host: string; + port: number; + username: string; + password: string; +} + +const EditInformationContainer = () => { + const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); + const database = Context.useStoreState(state => state.database); + const setDatabase = Context.useStoreActions(actions => actions.setDatabase); + + if (database === undefined) { + return ( + <> + ); + } + + const submit = ({ name, host, port, username, password }: Values, { setSubmitting }: FormikHelpers) => { + clearFlashes('database'); + + updateDatabase(database.id, name, host, port, username, password || undefined) + .then(() => setDatabase({ ...database, name, host, port, username })) + .catch(error => { + console.error(error); + clearAndAddHttpError({ key: 'database', error }); + }) + .then(() => setSubmitting(false)); + }; + + return ( + + { + ({ isSubmitting, isValid }) => ( + + + + +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ ) + } +
+ ); +}; + const DatabaseEditContainer = () => { const match = useRouteMatch<{ id?: string }>(); @@ -65,6 +191,8 @@ const DatabaseEditContainer = () => { + + ); };