diff --git a/resources/scripts/components/server/UptimeDuration.tsx b/resources/scripts/components/server/UptimeDuration.tsx
new file mode 100644
index 000000000..1406450fa
--- /dev/null
+++ b/resources/scripts/components/server/UptimeDuration.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+
+export default ({ uptime }: { uptime: number }) => {
+ const hours = Math.floor(Math.floor(uptime) / 60 / 60);
+ const remainder = Math.floor(uptime - (hours * 60 * 60));
+ const minutes = Math.floor(remainder / 60);
+ const seconds = remainder % 60;
+
+ return (
+ <>
+ {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}
+ >
+ );
+};
From 749dc70e7101345f253448ba23542cf85d5eac98 Mon Sep 17 00:00:00 2001
From: Dane Everitt
Date: Sun, 3 Oct 2021 13:50:16 -0700
Subject: [PATCH 007/126] Unfuck lock file
---
yarn.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index 45a407243..eccd4dcd3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6374,7 +6374,7 @@ fsevents@^1.2.7:
dependencies:
nan: ^2.9.2
node-pre-gyp: ^0.10.0
- checksum: 4b49b2de89a358a52e6c2db76113a22a99a803d10fb6f452a9e8708052ee9f2f1947c1ccb9940ef238036e05d8ade3875c569458a670d4a73bf3c920d04c4483
+ checksum: b31f577c1aac62e6e51df61e243b74fd5e9e157bb5c99a248b64f0b99940dcbcc1a7d693f880eec5195fbf1fbb91ccb39f1ddcaf0b10e835bc12bad8950a4098
languageName: node
linkType: hard
@@ -6383,7 +6383,7 @@ fsevents@^1.2.7:
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=1cc4b2"
dependencies:
node-gyp: latest
- checksum: b5712ac3858d8f77dbbf9f19e0c7f4a9aa0b336416a814be49d846d076c4f2fe4b7bf69846be8b7c9b23319c318e157f4cd5eb0eefcca015632fe7bfd82a34d8
+ checksum: 78db9daf1f6526a49cefee3917cc988f62dc7f25b5dd80ad6de4ffc4af7f0cab7491ac737626ff53e482a111bc53aac9e411fe3602458eca36f6a003ecf69c16
languageName: node
linkType: hard
From 1eed25dcc75a2cf9d0b951cd1baef05d566a26a3 Mon Sep 17 00:00:00 2001
From: Matthew Penner
Date: Sun, 3 Oct 2021 14:23:06 -0600
Subject: [PATCH 008/126] ui(admin): finish egg variable editing
---
.../Eggs/EggVariableController.php | 65 ++++++++++++++
.../Variables/StoreEggVariableRequest.php | 22 +++++
.../Variables/UpdateEggVariablesRequest.php | 25 ++++++
app/Models/EggVariable.php | 1 -
.../Variables/VariableCreationService.php | 23 ++---
.../Eggs/Variables/VariableUpdateService.php | 32 +++----
resources/scripts/api/admin/eggs/createEgg.ts | 2 +-
.../api/admin/eggs/createEggVariable.ts | 21 +++++
resources/scripts/api/admin/eggs/getEgg.ts | 4 +-
.../api/admin/eggs/updateEggVariables.ts | 24 +++++
.../nests/eggs/EggVariablesContainer.tsx | 90 +++++++++++++------
.../scripts/components/elements/Checkbox.tsx | 37 +++-----
routes/api-application.php | 2 +
13 files changed, 251 insertions(+), 97 deletions(-)
create mode 100644 app/Http/Controllers/Api/Application/Eggs/EggVariableController.php
create mode 100644 app/Http/Requests/Api/Application/Eggs/Variables/StoreEggVariableRequest.php
create mode 100644 app/Http/Requests/Api/Application/Eggs/Variables/UpdateEggVariablesRequest.php
create mode 100644 resources/scripts/api/admin/eggs/createEggVariable.ts
create mode 100644 resources/scripts/api/admin/eggs/updateEggVariables.ts
diff --git a/app/Http/Controllers/Api/Application/Eggs/EggVariableController.php b/app/Http/Controllers/Api/Application/Eggs/EggVariableController.php
new file mode 100644
index 000000000..7ffb86399
--- /dev/null
+++ b/app/Http/Controllers/Api/Application/Eggs/EggVariableController.php
@@ -0,0 +1,65 @@
+connection = $connection;
+ $this->variableCreationService = $variableCreationService;
+ $this->variableUpdateService = $variableUpdateService;
+ }
+
+ /**
+ * Creates a new egg variable.
+ *
+ * @throws \Pterodactyl\Exceptions\Service\Egg\Variable\BadValidationRuleException
+ * @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
+ */
+ public function store(StoreEggVariableRequest $request, Egg $egg): array
+ {
+ $variable = $this->variableCreationService->handle($egg->id, $request->validated());
+
+ return $this->fractal->item($variable)
+ ->transformWith(EggVariableTransformer::class)
+ ->toArray();
+ }
+
+ /**
+ * Updates multiple egg variables.
+ *
+ * @throws \Throwable
+ */
+ public function update(UpdateEggVariablesRequest $request, Egg $egg): array
+ {
+ $validated = $request->validated();
+
+ $this->connection->transaction(function () use($egg, $validated) {
+ foreach ($validated as $data) {
+ $this->variableUpdateService->handle($egg, $data);
+ }
+ });
+
+ return $this->fractal->collection($egg->refresh()->variables)
+ ->transformWith(EggVariableTransformer::class)
+ ->toArray();
+ }
+}
diff --git a/app/Http/Requests/Api/Application/Eggs/Variables/StoreEggVariableRequest.php b/app/Http/Requests/Api/Application/Eggs/Variables/StoreEggVariableRequest.php
new file mode 100644
index 000000000..9c674a9d8
--- /dev/null
+++ b/app/Http/Requests/Api/Application/Eggs/Variables/StoreEggVariableRequest.php
@@ -0,0 +1,22 @@
+ 'required|string|min:1|max:191',
+ 'description' => 'sometimes|string|nullable',
+ 'env_variable' => 'required|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
+ 'default_value' => 'present',
+ 'user_viewable' => 'required|boolean',
+ 'user_editable' => 'required|boolean',
+ 'rules' => 'bail|required|string',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Api/Application/Eggs/Variables/UpdateEggVariablesRequest.php b/app/Http/Requests/Api/Application/Eggs/Variables/UpdateEggVariablesRequest.php
new file mode 100644
index 000000000..363a2fece
--- /dev/null
+++ b/app/Http/Requests/Api/Application/Eggs/Variables/UpdateEggVariablesRequest.php
@@ -0,0 +1,25 @@
+ 'array',
+ '*.id' => 'required|integer',
+ '*.name' => 'sometimes|string|min:1|max:191',
+ '*.description' => 'sometimes|string|nullable',
+ '*.env_variable' => 'sometimes|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
+ '*.default_value' => 'sometimes|present',
+ '*.user_viewable' => 'sometimes|boolean',
+ '*.user_editable' => 'sometimes|boolean',
+ '*.rules' => 'sometimes|string',
+ ];
+ }
+}
diff --git a/app/Models/EggVariable.php b/app/Models/EggVariable.php
index 98e3da2c9..bb5938292 100644
--- a/app/Models/EggVariable.php
+++ b/app/Models/EggVariable.php
@@ -14,7 +14,6 @@ namespace Pterodactyl\Models;
* @property string $rules
* @property \Carbon\CarbonImmutable $created_at
* @property \Carbon\CarbonImmutable $updated_at
- * @property bool $required
* @property \Pterodactyl\Models\Egg $egg
* @property \Pterodactyl\Models\ServerVariable $serverVariable
*
diff --git a/app/Services/Eggs/Variables/VariableCreationService.php b/app/Services/Eggs/Variables/VariableCreationService.php
index fa758265b..11fafb44b 100644
--- a/app/Services/Eggs/Variables/VariableCreationService.php
+++ b/app/Services/Eggs/Variables/VariableCreationService.php
@@ -3,31 +3,21 @@
namespace Pterodactyl\Services\Eggs\Variables;
use Pterodactyl\Models\EggVariable;
-use Illuminate\Contracts\Validation\Factory;
+use Illuminate\Contracts\Validation\Factory as Validator;
use Pterodactyl\Traits\Services\ValidatesValidationRules;
-use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
use Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException;
class VariableCreationService
{
use ValidatesValidationRules;
- /**
- * @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
- */
- private $repository;
-
- /**
- * @var \Illuminate\Contracts\Validation\Factory
- */
- private $validator;
+ private Validator $validator;
/**
* VariableCreationService constructor.
*/
- public function __construct(EggVariableRepositoryInterface $repository, Factory $validator)
+ public function __construct(Validator $validator)
{
- $this->repository = $repository;
$this->validator = $validator;
}
@@ -35,7 +25,7 @@ class VariableCreationService
* Return the validation factory instance to be used by rule validation
* checking in the trait.
*/
- protected function getValidator(): Factory
+ protected function getValidator(): Validator
{
return $this->validator;
}
@@ -43,7 +33,6 @@ class VariableCreationService
/**
* Create a new variable for a given Egg.
*
- * @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\BadValidationRuleException
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
*/
@@ -59,7 +48,8 @@ class VariableCreationService
$options = array_get($data, 'options') ?? [];
- return $this->repository->create([
+ /** @var \Pterodactyl\Models\EggVariable $model */
+ $model = EggVariable::query()->create([
'egg_id' => $egg,
'name' => $data['name'] ?? '',
'description' => $data['description'] ?? '',
@@ -69,5 +59,6 @@ class VariableCreationService
'user_editable' => in_array('user_editable', $options),
'rules' => $data['rules'] ?? '',
]);
+ return $model;
}
}
diff --git a/app/Services/Eggs/Variables/VariableUpdateService.php b/app/Services/Eggs/Variables/VariableUpdateService.php
index da4426c33..866f2157f 100644
--- a/app/Services/Eggs/Variables/VariableUpdateService.php
+++ b/app/Services/Eggs/Variables/VariableUpdateService.php
@@ -3,6 +3,7 @@
namespace Pterodactyl\Services\Eggs\Variables;
use Illuminate\Support\Str;
+use Pterodactyl\Models\Egg;
use Pterodactyl\Models\EggVariable;
use Illuminate\Contracts\Validation\Factory;
use Pterodactyl\Exceptions\DisplayException;
@@ -14,11 +15,6 @@ class VariableUpdateService
{
use ValidatesValidationRules;
- /**
- * @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
- */
- private $repository;
-
/**
* @var \Illuminate\Contracts\Validation\Factory
*/
@@ -27,9 +23,8 @@ class VariableUpdateService
/**
* VariableUpdateService constructor.
*/
- public function __construct(EggVariableRepositoryInterface $repository, Factory $validator)
+ public function __construct(Factory $validator)
{
- $this->repository = $repository;
$this->validator = $validator;
}
@@ -45,27 +40,22 @@ class VariableUpdateService
/**
* Update a specific egg variable.
*
- * @return mixed
- *
* @throws \Pterodactyl\Exceptions\DisplayException
- * @throws \Pterodactyl\Exceptions\Model\DataValidationException
- * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
*/
- public function handle(EggVariable $variable, array $data)
+ public function handle(Egg $egg, array $data)
{
if (!is_null(array_get($data, 'env_variable'))) {
if (in_array(strtoupper(array_get($data, 'env_variable')), explode(',', EggVariable::RESERVED_ENV_NAMES))) {
throw new ReservedVariableNameException(trans('exceptions.service.variables.reserved_name', ['name' => array_get($data, 'env_variable')]));
}
- $search = $this->repository->setColumns('id')->findCountWhere([
- ['env_variable', '=', $data['env_variable']],
- ['egg_id', '=', $variable->egg_id],
- ['id', '!=', $variable->id],
- ]);
+ $count = $egg->variables()
+ ->where('egg_variables.env_variable',$data['env_variable'])
+ ->where('egg_variables.id', '!=', $data['id'])
+ ->count();
- if ($search > 0) {
+ if ($count > 0) {
throw new DisplayException(trans('exceptions.service.variables.env_not_unique', ['name' => array_get($data, 'env_variable')]));
}
}
@@ -80,13 +70,13 @@ class VariableUpdateService
$options = array_get($data, 'options') ?? [];
- return $this->repository->withoutFreshModel()->update($variable->id, [
+ $egg->variables()->where('egg_variables.id', $data['id'])->update([
'name' => $data['name'] ?? '',
'description' => $data['description'] ?? '',
'env_variable' => $data['env_variable'] ?? '',
'default_value' => $data['default_value'] ?? '',
- 'user_viewable' => in_array('user_viewable', $options),
- 'user_editable' => in_array('user_editable', $options),
+ 'user_viewable' => $data['user_viewable'],
+ 'user_editable' => $data['user_editable'],
'rules' => $data['rules'] ?? '',
]);
}
diff --git a/resources/scripts/api/admin/eggs/createEgg.ts b/resources/scripts/api/admin/eggs/createEgg.ts
index 5a2f8c964..f269d696e 100644
--- a/resources/scripts/api/admin/eggs/createEgg.ts
+++ b/resources/scripts/api/admin/eggs/createEgg.ts
@@ -4,7 +4,7 @@ import { Egg, rawDataToEgg } from '@/api/admin/eggs/getEgg';
export default (egg: Partial): Promise => {
return new Promise((resolve, reject) => {
http.post(
- '/api/application/eggs/',
+ '/api/application/eggs',
{
nest_id: egg.nestId,
name: egg.name,
diff --git a/resources/scripts/api/admin/eggs/createEggVariable.ts b/resources/scripts/api/admin/eggs/createEggVariable.ts
new file mode 100644
index 000000000..4226eef15
--- /dev/null
+++ b/resources/scripts/api/admin/eggs/createEggVariable.ts
@@ -0,0 +1,21 @@
+import http from '@/api/http';
+import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
+
+export default (eggId: number, variable: Omit): Promise => {
+ return new Promise((resolve, reject) => {
+ http.post(
+ `/api/application/eggs/${eggId}`,
+ {
+ name: variable.name,
+ description: variable.description,
+ env_variable: variable.envVariable,
+ default_value: variable.defaultValue,
+ user_viewable: variable.userViewable,
+ user_editable: variable.userEditable,
+ rules: variable.rules,
+ },
+ )
+ .then(({ data }) => resolve(rawDataToEggVariable(data)))
+ .catch(reject);
+ });
+};
diff --git a/resources/scripts/api/admin/eggs/getEgg.ts b/resources/scripts/api/admin/eggs/getEgg.ts
index 48e139301..be0ca0395 100644
--- a/resources/scripts/api/admin/eggs/getEgg.ts
+++ b/resources/scripts/api/admin/eggs/getEgg.ts
@@ -12,12 +12,11 @@ export interface EggVariable {
userViewable: boolean;
userEditable: boolean;
rules: string;
- required: boolean;
createdAt: Date;
updatedAt: Date;
}
-const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({
+export const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({
id: attributes.id,
eggId: attributes.egg_id,
name: attributes.name,
@@ -27,7 +26,6 @@ const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable
userViewable: attributes.user_viewable,
userEditable: attributes.user_editable,
rules: attributes.rules,
- required: attributes.required,
createdAt: new Date(attributes.created_at),
updatedAt: new Date(attributes.updated_at),
});
diff --git a/resources/scripts/api/admin/eggs/updateEggVariables.ts b/resources/scripts/api/admin/eggs/updateEggVariables.ts
new file mode 100644
index 000000000..498fda0ba
--- /dev/null
+++ b/resources/scripts/api/admin/eggs/updateEggVariables.ts
@@ -0,0 +1,24 @@
+import http from '@/api/http';
+import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
+
+export default (eggId: number, variables: Omit[]): Promise => {
+ return new Promise((resolve, reject) => {
+ http.patch(
+ `/api/application/eggs/${eggId}/variables`,
+ variables.map(variable => {
+ return {
+ id: variable.id,
+ name: variable.name,
+ description: variable.description,
+ env_variable: variable.envVariable,
+ default_value: variable.defaultValue,
+ user_viewable: variable.userViewable,
+ user_editable: variable.userEditable,
+ rules: variable.rules,
+ };
+ }),
+ )
+ .then(({ data }) => resolve((data.data || []).map(rawDataToEggVariable)))
+ .catch(reject);
+ });
+};
diff --git a/resources/scripts/components/admin/nests/eggs/EggVariablesContainer.tsx b/resources/scripts/components/admin/nests/eggs/EggVariablesContainer.tsx
index 41388a07e..f771a6f25 100644
--- a/resources/scripts/components/admin/nests/eggs/EggVariablesContainer.tsx
+++ b/resources/scripts/components/admin/nests/eggs/EggVariablesContainer.tsx
@@ -1,14 +1,17 @@
-import { Form, Formik, useFormikContext } from 'formik';
-import React from 'react';
+import { Form, Formik, FormikHelpers, useFormikContext } from 'formik';
+import React, { useEffect } from 'react';
import tw from 'twin.macro';
-import { object } from 'yup';
+import { array, boolean, object, string } from 'yup';
import { Egg, EggVariable } from '@/api/admin/eggs/getEgg';
+import updateEggVariables from '@/api/admin/eggs/updateEggVariables';
import AdminBox from '@/components/admin/AdminBox';
+import Button from '@/components/elements/Button';
import Checkbox from '@/components/elements/Checkbox';
import Field, { FieldRow, TextareaField } from '@/components/elements/Field';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
+import useFlash from '@/plugins/useFlash';
-function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
+function EggVariableForm ({ variable: { name }, i }: { variable: EggVariable, i: number }) {
const { isSubmitting } = useFormikContext();
return (
@@ -16,16 +19,16 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
@@ -49,22 +52,22 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
{
- //
+ const { clearAndAddHttpError } = useFlash();
+
+ const submit = (values: EggVariable[], { setSubmitting }: FormikHelpers) => {
+ updateEggVariables(egg.id, values)
+ .then(variables => console.log(variables))
+ .catch(error => clearAndAddHttpError({ key: 'egg', error }))
+ .then(() => setSubmitting(false));
};
+ useEffect(() => {
+ console.log(egg.relations?.variables || []);
+ }, []);
+
return (
-
+ {({ isSubmitting, isValid }) => (
+
+ )}
);
}
diff --git a/resources/scripts/components/elements/Checkbox.tsx b/resources/scripts/components/elements/Checkbox.tsx
index b3954e708..25c9da037 100644
--- a/resources/scripts/components/elements/Checkbox.tsx
+++ b/resources/scripts/components/elements/Checkbox.tsx
@@ -1,38 +1,23 @@
-import Label from '@/components/elements/Label';
+import { Field } from 'formik';
import React from 'react';
-import { Field, FieldProps } from 'formik';
-import Input from '@/components/elements/Input';
import tw from 'twin.macro';
+import Label from '@/components/elements/Label';
interface Props {
+ id: string;
name: string;
label?: string;
className?: string;
}
-type OmitFields = 'ref' | 'name' | 'value' | 'type';
-
-type InputProps = Omit;
-
-const Checkbox = ({ name, label, className, ...props }: Props & InputProps) => (
-
- {({ field }: FieldProps) => {
- return (
-
-
- {label &&
-
-
-
}
-
- );
- }}
-
+const Checkbox = ({ id, name, label, className }: Props) => (
+
+
+ {label &&
+
+
+
}
+
);
export default Checkbox;
diff --git a/routes/api-application.php b/routes/api-application.php
index d9000f59f..67c3a5c50 100644
--- a/routes/api-application.php
+++ b/routes/api-application.php
@@ -35,8 +35,10 @@ Route::group(['prefix' => '/eggs'], function () {
Route::get('/{egg}', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'view']);
Route::post('/', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'store']);
+ Route::post('/{egg}/variables', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggVariableController::class, 'store']);
Route::patch('/{egg}', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'update']);
+ Route::patch('/{egg}/variables', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggVariableController::class, 'update']);
Route::delete('/{egg}', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'delete']);
});
From b2aa05dc07c83b59e9f2fe838d9bfd568f855e17 Mon Sep 17 00:00:00 2001
From: Matthew Penner
Date: Sun, 3 Oct 2021 15:51:35 -0600
Subject: [PATCH 009/126] ui(admin): add new egg variable option
---
.../api/admin/eggs/createEggVariable.ts | 2 +-
resources/scripts/api/admin/eggs/getEgg.ts | 17 ++--
.../api/admin/eggs/updateEggVariables.ts | 24 +++--
.../components/admin/nests/eggs/EggRouter.tsx | 45 ++--------
.../admin/nests/eggs/EggSettingsContainer.tsx | 2 +-
.../nests/eggs/EggVariablesContainer.tsx | 89 ++++++++++---------
.../admin/nests/eggs/NewVariableButton.tsx | 87 ++++++++++++++++++
.../admin/servers/ServerStartupContainer.tsx | 4 +-
8 files changed, 168 insertions(+), 102 deletions(-)
create mode 100644 resources/scripts/components/admin/nests/eggs/NewVariableButton.tsx
diff --git a/resources/scripts/api/admin/eggs/createEggVariable.ts b/resources/scripts/api/admin/eggs/createEggVariable.ts
index 4226eef15..dd5ee38fe 100644
--- a/resources/scripts/api/admin/eggs/createEggVariable.ts
+++ b/resources/scripts/api/admin/eggs/createEggVariable.ts
@@ -4,7 +4,7 @@ import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
export default (eggId: number, variable: Omit): Promise => {
return new Promise((resolve, reject) => {
http.post(
- `/api/application/eggs/${eggId}`,
+ `/api/application/eggs/${eggId}/variables`,
{
name: variable.name,
description: variable.description,
diff --git a/resources/scripts/api/admin/eggs/getEgg.ts b/resources/scripts/api/admin/eggs/getEgg.ts
index be0ca0395..5e380e113 100644
--- a/resources/scripts/api/admin/eggs/getEgg.ts
+++ b/resources/scripts/api/admin/eggs/getEgg.ts
@@ -1,6 +1,7 @@
import { Nest } from '@/api/admin/nests/getNests';
import { rawDataToServer, Server } from '@/api/admin/servers/getServers';
import http, { FractalResponseData, FractalResponseList } from '@/api/http';
+import useSWR from 'swr';
export interface EggVariable {
id: number;
@@ -88,10 +89,16 @@ export const rawDataToEgg = ({ attributes }: FractalResponseData): Egg => ({
},
});
-export default (id: number, include: string[] = []): Promise => {
- return new Promise((resolve, reject) => {
- http.get(`/api/application/eggs/${id}`, { params: { include: include.join(',') } })
- .then(({ data }) => resolve(rawDataToEgg(data)))
- .catch(reject);
+export const getEgg = async (id: number): Promise => {
+ const { data } = await http.get(`/api/application/eggs/${id}`, { params: { include: [ 'variables' ] } });
+
+ return rawDataToEgg(data);
+};
+
+export default (id: number) => {
+ return useSWR(`egg:${id}`, async () => {
+ const { data } = await http.get(`/api/application/eggs/${id}`, { params: { include: [ 'variables' ] } });
+
+ return rawDataToEgg(data);
});
};
diff --git a/resources/scripts/api/admin/eggs/updateEggVariables.ts b/resources/scripts/api/admin/eggs/updateEggVariables.ts
index 498fda0ba..3ccfe3d38 100644
--- a/resources/scripts/api/admin/eggs/updateEggVariables.ts
+++ b/resources/scripts/api/admin/eggs/updateEggVariables.ts
@@ -1,22 +1,20 @@
import http from '@/api/http';
import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
-export default (eggId: number, variables: Omit[]): Promise => {
+export default (eggId: number, variables: Omit[]): Promise => {
return new Promise((resolve, reject) => {
http.patch(
`/api/application/eggs/${eggId}/variables`,
- variables.map(variable => {
- return {
- id: variable.id,
- name: variable.name,
- description: variable.description,
- env_variable: variable.envVariable,
- default_value: variable.defaultValue,
- user_viewable: variable.userViewable,
- user_editable: variable.userEditable,
- rules: variable.rules,
- };
- }),
+ variables.map(variable => ({
+ id: variable.id,
+ name: variable.name,
+ description: variable.description,
+ env_variable: variable.envVariable,
+ default_value: variable.defaultValue,
+ user_viewable: variable.userViewable,
+ user_editable: variable.userEditable,
+ rules: variable.rules,
+ })),
)
.then(({ data }) => resolve((data.data || []).map(rawDataToEggVariable)))
.catch(reject);
diff --git a/resources/scripts/components/admin/nests/eggs/EggRouter.tsx b/resources/scripts/components/admin/nests/eggs/EggRouter.tsx
index 1d591869e..0e11921fa 100644
--- a/resources/scripts/components/admin/nests/eggs/EggRouter.tsx
+++ b/resources/scripts/components/admin/nests/eggs/EggRouter.tsx
@@ -1,54 +1,23 @@
import EggInstallContainer from '@/components/admin/nests/eggs/EggInstallContainer';
import EggVariablesContainer from '@/components/admin/nests/eggs/EggVariablesContainer';
-import React, { useEffect, useState } from 'react';
+import React from 'react';
import { useLocation } from 'react-router';
import tw from 'twin.macro';
import { Route, Switch, useRouteMatch } from 'react-router-dom';
-import { action, Action, Actions, createContextStore, useStoreActions } from 'easy-peasy';
-import getEgg, { Egg } from '@/api/admin/eggs/getEgg';
+import getEgg from '@/api/admin/eggs/getEgg';
import AdminContentBlock from '@/components/admin/AdminContentBlock';
import Spinner from '@/components/elements/Spinner';
import FlashMessageRender from '@/components/FlashMessageRender';
-import { ApplicationStore } from '@/state';
import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation';
import EggSettingsContainer from '@/components/admin/nests/eggs/EggSettingsContainer';
-interface ctx {
- egg: Egg | undefined;
- setEgg: Action;
-}
-
-export const Context = createContextStore({
- egg: undefined,
-
- setEgg: action((state, payload) => {
- state.egg = payload;
- }),
-});
-
const EggRouter = () => {
const location = useLocation();
const match = useRouteMatch<{ id?: string }>();
- const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes);
- const [ loading, setLoading ] = useState(true);
+ const { data: egg } = getEgg(Number(match.params?.id));
- const egg = Context.useStoreState(state => state.egg);
- const setEgg = Context.useStoreActions(actions => actions.setEgg);
-
- useEffect(() => {
- clearFlashes('egg');
-
- getEgg(Number(match.params?.id), [ 'variables' ])
- .then(egg => setEgg(egg))
- .catch(error => {
- console.error(error);
- clearAndAddHttpError({ key: 'egg', error });
- })
- .then(() => setLoading(false));
- }, []);
-
- if (loading || egg === undefined) {
+ if (egg === undefined) {
return (
@@ -109,9 +78,5 @@ const EggRouter = () => {
};
export default () => {
- return (
-
-
-
- );
+ return ;
};
diff --git a/resources/scripts/components/admin/nests/eggs/EggSettingsContainer.tsx b/resources/scripts/components/admin/nests/eggs/EggSettingsContainer.tsx
index f8dc1c365..9ee665f15 100644
--- a/resources/scripts/components/admin/nests/eggs/EggSettingsContainer.tsx
+++ b/resources/scripts/components/admin/nests/eggs/EggSettingsContainer.tsx
@@ -162,7 +162,7 @@ const EggProcessContainer = forwardRef(
-
+
{name}}>
-
-
+ <>
@@ -52,26 +59,38 @@ function EggVariableForm ({ variable: { name }, i }: { variable: EggVariable, i:
+ >
+ );
+}
+
+function EggVariableBox ({ variable, prefix }: { variable: EggVariable, prefix: string }) {
+ const { isSubmitting } = useFormikContext();
+
+ return (
+ {variable.name}}>
+
+
+
);
}
@@ -79,43 +98,33 @@ function EggVariableForm ({ variable: { name }, i }: { variable: EggVariable, i:
export default function EggVariablesContainer ({ egg }: { egg: Egg }) {
const { clearAndAddHttpError } = useFlash();
+ const { mutate } = getEgg(egg.id);
+
const submit = (values: EggVariable[], { setSubmitting }: FormikHelpers) => {
updateEggVariables(egg.id, values)
- .then(variables => console.log(variables))
+ .then(async (variables) => await mutate(egg => ({ ...egg!, relations: { variables: variables } })))
.catch(error => clearAndAddHttpError({ key: 'egg', error }))
.then(() => setSubmitting(false));
};
- useEffect(() => {
- console.log(egg.relations?.variables || []);
- }, []);
-
return (
{({ isSubmitting, isValid }) => (