ui(admin): finish egg variable editing
This commit is contained in:
parent
749dc70e71
commit
1eed25dcc7
13 changed files with 251 additions and 97 deletions
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Application\Eggs;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Egg;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Pterodactyl\Services\Eggs\Variables\VariableUpdateService;
|
||||||
|
use Pterodactyl\Services\Eggs\Variables\VariableCreationService;
|
||||||
|
use Pterodactyl\Transformers\Api\Application\EggVariableTransformer;
|
||||||
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Eggs\Variables\StoreEggVariableRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Eggs\Variables\UpdateEggVariablesRequest;
|
||||||
|
|
||||||
|
class EggVariableController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
private ConnectionInterface $connection;
|
||||||
|
|
||||||
|
private VariableCreationService $variableCreationService;
|
||||||
|
|
||||||
|
private VariableUpdateService $variableUpdateService;
|
||||||
|
|
||||||
|
public function __construct(ConnectionInterface $connection, VariableCreationService $variableCreationService, VariableUpdateService $variableUpdateService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Eggs\Variables;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\EggVariable;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
|
||||||
|
class StoreEggVariableRequest extends ApplicationApiRequest
|
||||||
|
{
|
||||||
|
public function rules(array $rules = null): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => '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',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Eggs\Variables;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\EggVariable;
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
|
||||||
|
class UpdateEggVariablesRequest extends ApplicationApiRequest
|
||||||
|
{
|
||||||
|
public function rules(array $rules = null): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'*' => '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',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ namespace Pterodactyl\Models;
|
||||||
* @property string $rules
|
* @property string $rules
|
||||||
* @property \Carbon\CarbonImmutable $created_at
|
* @property \Carbon\CarbonImmutable $created_at
|
||||||
* @property \Carbon\CarbonImmutable $updated_at
|
* @property \Carbon\CarbonImmutable $updated_at
|
||||||
* @property bool $required
|
|
||||||
* @property \Pterodactyl\Models\Egg $egg
|
* @property \Pterodactyl\Models\Egg $egg
|
||||||
* @property \Pterodactyl\Models\ServerVariable $serverVariable
|
* @property \Pterodactyl\Models\ServerVariable $serverVariable
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,31 +3,21 @@
|
||||||
namespace Pterodactyl\Services\Eggs\Variables;
|
namespace Pterodactyl\Services\Eggs\Variables;
|
||||||
|
|
||||||
use Pterodactyl\Models\EggVariable;
|
use Pterodactyl\Models\EggVariable;
|
||||||
use Illuminate\Contracts\Validation\Factory;
|
use Illuminate\Contracts\Validation\Factory as Validator;
|
||||||
use Pterodactyl\Traits\Services\ValidatesValidationRules;
|
use Pterodactyl\Traits\Services\ValidatesValidationRules;
|
||||||
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
|
||||||
use Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException;
|
use Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException;
|
||||||
|
|
||||||
class VariableCreationService
|
class VariableCreationService
|
||||||
{
|
{
|
||||||
use ValidatesValidationRules;
|
use ValidatesValidationRules;
|
||||||
|
|
||||||
/**
|
private Validator $validator;
|
||||||
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Validation\Factory
|
|
||||||
*/
|
|
||||||
private $validator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VariableCreationService constructor.
|
* VariableCreationService constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(EggVariableRepositoryInterface $repository, Factory $validator)
|
public function __construct(Validator $validator)
|
||||||
{
|
{
|
||||||
$this->repository = $repository;
|
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +25,7 @@ class VariableCreationService
|
||||||
* Return the validation factory instance to be used by rule validation
|
* Return the validation factory instance to be used by rule validation
|
||||||
* checking in the trait.
|
* checking in the trait.
|
||||||
*/
|
*/
|
||||||
protected function getValidator(): Factory
|
protected function getValidator(): Validator
|
||||||
{
|
{
|
||||||
return $this->validator;
|
return $this->validator;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +33,6 @@ class VariableCreationService
|
||||||
/**
|
/**
|
||||||
* Create a new variable for a given Egg.
|
* 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\BadValidationRuleException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +48,8 @@ class VariableCreationService
|
||||||
|
|
||||||
$options = array_get($data, 'options') ?? [];
|
$options = array_get($data, 'options') ?? [];
|
||||||
|
|
||||||
return $this->repository->create([
|
/** @var \Pterodactyl\Models\EggVariable $model */
|
||||||
|
$model = EggVariable::query()->create([
|
||||||
'egg_id' => $egg,
|
'egg_id' => $egg,
|
||||||
'name' => $data['name'] ?? '',
|
'name' => $data['name'] ?? '',
|
||||||
'description' => $data['description'] ?? '',
|
'description' => $data['description'] ?? '',
|
||||||
|
@ -69,5 +59,6 @@ class VariableCreationService
|
||||||
'user_editable' => in_array('user_editable', $options),
|
'user_editable' => in_array('user_editable', $options),
|
||||||
'rules' => $data['rules'] ?? '',
|
'rules' => $data['rules'] ?? '',
|
||||||
]);
|
]);
|
||||||
|
return $model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Pterodactyl\Services\Eggs\Variables;
|
namespace Pterodactyl\Services\Eggs\Variables;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Pterodactyl\Models\Egg;
|
||||||
use Pterodactyl\Models\EggVariable;
|
use Pterodactyl\Models\EggVariable;
|
||||||
use Illuminate\Contracts\Validation\Factory;
|
use Illuminate\Contracts\Validation\Factory;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
@ -14,11 +15,6 @@ class VariableUpdateService
|
||||||
{
|
{
|
||||||
use ValidatesValidationRules;
|
use ValidatesValidationRules;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Contracts\Validation\Factory
|
* @var \Illuminate\Contracts\Validation\Factory
|
||||||
*/
|
*/
|
||||||
|
@ -27,9 +23,8 @@ class VariableUpdateService
|
||||||
/**
|
/**
|
||||||
* VariableUpdateService constructor.
|
* VariableUpdateService constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(EggVariableRepositoryInterface $repository, Factory $validator)
|
public function __construct(Factory $validator)
|
||||||
{
|
{
|
||||||
$this->repository = $repository;
|
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,27 +40,22 @@ class VariableUpdateService
|
||||||
/**
|
/**
|
||||||
* Update a specific egg variable.
|
* Update a specific egg variable.
|
||||||
*
|
*
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
* @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 (!is_null(array_get($data, 'env_variable'))) {
|
||||||
if (in_array(strtoupper(array_get($data, 'env_variable')), explode(',', EggVariable::RESERVED_ENV_NAMES))) {
|
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')]));
|
throw new ReservedVariableNameException(trans('exceptions.service.variables.reserved_name', ['name' => array_get($data, 'env_variable')]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$search = $this->repository->setColumns('id')->findCountWhere([
|
$count = $egg->variables()
|
||||||
['env_variable', '=', $data['env_variable']],
|
->where('egg_variables.env_variable',$data['env_variable'])
|
||||||
['egg_id', '=', $variable->egg_id],
|
->where('egg_variables.id', '!=', $data['id'])
|
||||||
['id', '!=', $variable->id],
|
->count();
|
||||||
]);
|
|
||||||
|
|
||||||
if ($search > 0) {
|
if ($count > 0) {
|
||||||
throw new DisplayException(trans('exceptions.service.variables.env_not_unique', ['name' => array_get($data, 'env_variable')]));
|
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') ?? [];
|
$options = array_get($data, 'options') ?? [];
|
||||||
|
|
||||||
return $this->repository->withoutFreshModel()->update($variable->id, [
|
$egg->variables()->where('egg_variables.id', $data['id'])->update([
|
||||||
'name' => $data['name'] ?? '',
|
'name' => $data['name'] ?? '',
|
||||||
'description' => $data['description'] ?? '',
|
'description' => $data['description'] ?? '',
|
||||||
'env_variable' => $data['env_variable'] ?? '',
|
'env_variable' => $data['env_variable'] ?? '',
|
||||||
'default_value' => $data['default_value'] ?? '',
|
'default_value' => $data['default_value'] ?? '',
|
||||||
'user_viewable' => in_array('user_viewable', $options),
|
'user_viewable' => $data['user_viewable'],
|
||||||
'user_editable' => in_array('user_editable', $options),
|
'user_editable' => $data['user_editable'],
|
||||||
'rules' => $data['rules'] ?? '',
|
'rules' => $data['rules'] ?? '',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Egg, rawDataToEgg } from '@/api/admin/eggs/getEgg';
|
||||||
export default (egg: Partial<Egg>): Promise<Egg> => {
|
export default (egg: Partial<Egg>): Promise<Egg> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
http.post(
|
http.post(
|
||||||
'/api/application/eggs/',
|
'/api/application/eggs',
|
||||||
{
|
{
|
||||||
nest_id: egg.nestId,
|
nest_id: egg.nestId,
|
||||||
name: egg.name,
|
name: egg.name,
|
||||||
|
|
21
resources/scripts/api/admin/eggs/createEggVariable.ts
Normal file
21
resources/scripts/api/admin/eggs/createEggVariable.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import http from '@/api/http';
|
||||||
|
import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
|
||||||
|
|
||||||
|
export default (eggId: number, variable: Omit<EggVariable, 'id' | 'eggId' | 'createdAt' | 'updatedAt'>): Promise<EggVariable> => {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
};
|
|
@ -12,12 +12,11 @@ export interface EggVariable {
|
||||||
userViewable: boolean;
|
userViewable: boolean;
|
||||||
userEditable: boolean;
|
userEditable: boolean;
|
||||||
rules: string;
|
rules: string;
|
||||||
required: boolean;
|
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({
|
export const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({
|
||||||
id: attributes.id,
|
id: attributes.id,
|
||||||
eggId: attributes.egg_id,
|
eggId: attributes.egg_id,
|
||||||
name: attributes.name,
|
name: attributes.name,
|
||||||
|
@ -27,7 +26,6 @@ const rawDataToEggVariable = ({ attributes }: FractalResponseData): EggVariable
|
||||||
userViewable: attributes.user_viewable,
|
userViewable: attributes.user_viewable,
|
||||||
userEditable: attributes.user_editable,
|
userEditable: attributes.user_editable,
|
||||||
rules: attributes.rules,
|
rules: attributes.rules,
|
||||||
required: attributes.required,
|
|
||||||
createdAt: new Date(attributes.created_at),
|
createdAt: new Date(attributes.created_at),
|
||||||
updatedAt: new Date(attributes.updated_at),
|
updatedAt: new Date(attributes.updated_at),
|
||||||
});
|
});
|
||||||
|
|
24
resources/scripts/api/admin/eggs/updateEggVariables.ts
Normal file
24
resources/scripts/api/admin/eggs/updateEggVariables.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import http from '@/api/http';
|
||||||
|
import { EggVariable, rawDataToEggVariable } from '@/api/admin/eggs/getEgg';
|
||||||
|
|
||||||
|
export default (eggId: number, variables: Omit<EggVariable, 'eggId' | 'createdAt' | 'updatedAt'>[]): Promise<EggVariable> => {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,14 +1,17 @@
|
||||||
import { Form, Formik, useFormikContext } from 'formik';
|
import { Form, Formik, FormikHelpers, useFormikContext } from 'formik';
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import tw from 'twin.macro';
|
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 { Egg, EggVariable } from '@/api/admin/eggs/getEgg';
|
||||||
|
import updateEggVariables from '@/api/admin/eggs/updateEggVariables';
|
||||||
import AdminBox from '@/components/admin/AdminBox';
|
import AdminBox from '@/components/admin/AdminBox';
|
||||||
|
import Button from '@/components/elements/Button';
|
||||||
import Checkbox from '@/components/elements/Checkbox';
|
import Checkbox from '@/components/elements/Checkbox';
|
||||||
import Field, { FieldRow, TextareaField } from '@/components/elements/Field';
|
import Field, { FieldRow, TextareaField } from '@/components/elements/Field';
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
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();
|
const { isSubmitting } = useFormikContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -16,16 +19,16 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
|
||||||
<SpinnerOverlay visible={isSubmitting}/>
|
<SpinnerOverlay visible={isSubmitting}/>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
id={'name'}
|
id={`[${i}].name`}
|
||||||
name={'name'}
|
name={`[${i}].name`}
|
||||||
label={'Name'}
|
label={'Name'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
css={tw`mb-6`}
|
css={tw`mb-6`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextareaField
|
<TextareaField
|
||||||
id={'description'}
|
id={`[${i}].description`}
|
||||||
name={'description'}
|
name={`[${i}].description`}
|
||||||
label={'Description'}
|
label={'Description'}
|
||||||
rows={3}
|
rows={3}
|
||||||
css={tw`mb-4`}
|
css={tw`mb-4`}
|
||||||
|
@ -33,15 +36,15 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
|
||||||
|
|
||||||
<FieldRow>
|
<FieldRow>
|
||||||
<Field
|
<Field
|
||||||
id={'envVariable'}
|
id={`[${i}].envVariable`}
|
||||||
name={'envVariable'}
|
name={`[${i}].envVariable`}
|
||||||
label={'Environment Variable'}
|
label={'Environment Variable'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
id={'defaultValue'}
|
id={`[${i}].defaultValue`}
|
||||||
name={'defaultValue'}
|
name={`[${i}].defaultValue`}
|
||||||
label={'Default Value'}
|
label={'Default Value'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
/>
|
/>
|
||||||
|
@ -49,22 +52,22 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
|
||||||
|
|
||||||
<div css={tw`flex flex-row mb-6`}>
|
<div css={tw`flex flex-row mb-6`}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id={'userViewable'}
|
id={`[${i}].userViewable`}
|
||||||
name={'userViewable'}
|
name={`[${i}].userViewable`}
|
||||||
label={'User Viewable'}
|
label={'User Viewable'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id={'userEditable'}
|
id={`[${i}].userEditable`}
|
||||||
name={'userEditable'}
|
name={`[${i}].userEditable`}
|
||||||
label={'User Editable'}
|
label={'User Editable'}
|
||||||
css={tw`ml-auto`}
|
css={tw`ml-auto`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
id={'rules'}
|
id={`[${i}].rules`}
|
||||||
name={'rules'}
|
name={`[${i}].rules`}
|
||||||
label={'Validation Rules'}
|
label={'Validation Rules'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
css={tw`mb-2`}
|
css={tw`mb-2`}
|
||||||
|
@ -74,23 +77,52 @@ function EggVariableForm ({ variable: { name } }: { variable: EggVariable }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EggVariablesContainer ({ egg }: { egg: Egg }) {
|
export default function EggVariablesContainer ({ egg }: { egg: Egg }) {
|
||||||
const submit = () => {
|
const { clearAndAddHttpError } = useFlash();
|
||||||
//
|
|
||||||
|
const submit = (values: EggVariable[], { setSubmitting }: FormikHelpers<EggVariable[]>) => {
|
||||||
|
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 (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
initialValues={{
|
initialValues={egg.relations?.variables || []}
|
||||||
}}
|
validationSchema={array().of(
|
||||||
validationSchema={object().shape({
|
object().shape({
|
||||||
})}
|
name: string().required().min(1).max(191),
|
||||||
|
description: string(),
|
||||||
|
envVariable: string().required().min(1).max(191),
|
||||||
|
defaultValue: string(),
|
||||||
|
userViewable: boolean().required(),
|
||||||
|
userEditable: boolean().required(),
|
||||||
|
rules: string().required(),
|
||||||
|
}),
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Form>
|
{({ isSubmitting, isValid }) => (
|
||||||
<div css={tw`grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-6`}>
|
<Form>
|
||||||
{egg.relations?.variables?.map(v => <EggVariableForm key={v.id} variable={v}/>)}
|
<div css={tw`flex flex-col mb-16`}>
|
||||||
</div>
|
<div css={tw`grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-6`}>
|
||||||
</Form>
|
{egg.relations?.variables?.map((v, i) => <EggVariableForm key={v.id} i={i} variable={v}/>)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div css={tw`bg-neutral-700 rounded shadow-md py-2 pr-6 mt-6`}>
|
||||||
|
<div css={tw`flex flex-row`}>
|
||||||
|
<Button type="submit" size="small" css={tw`ml-auto`} disabled={isSubmitting || !isValid}>
|
||||||
|
Save Changes
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,23 @@
|
||||||
import Label from '@/components/elements/Label';
|
import { Field } from 'formik';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Field, FieldProps } from 'formik';
|
|
||||||
import Input from '@/components/elements/Input';
|
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
|
import Label from '@/components/elements/Label';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type OmitFields = 'ref' | 'name' | 'value' | 'type';
|
const Checkbox = ({ id, name, label, className }: Props) => (
|
||||||
|
<div css={tw`flex flex-row`} className={className}>
|
||||||
type InputProps = Omit<JSX.IntrinsicElements['input'], OmitFields>;
|
<Field type={'checkbox'} id={id} name={name} css={[ label && tw`mr-2` ]}/>
|
||||||
|
{label &&
|
||||||
const Checkbox = ({ name, label, className, ...props }: Props & InputProps) => (
|
<div css={tw`flex-1`}>
|
||||||
<Field name={name}>
|
<Label noBottomSpacing>{label}</Label>
|
||||||
{({ field }: FieldProps) => {
|
</div>}
|
||||||
return (
|
</div>
|
||||||
<div css={tw`flex flex-row`} className={className}>
|
|
||||||
<Input
|
|
||||||
{...field}
|
|
||||||
{...props}
|
|
||||||
css={tw`w-5 h-5 mr-2`}
|
|
||||||
type={'checkbox'}
|
|
||||||
/>
|
|
||||||
{label &&
|
|
||||||
<div css={tw`flex-1`}>
|
|
||||||
<Label noBottomSpacing>{label}</Label>
|
|
||||||
</div>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Field>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Checkbox;
|
export default Checkbox;
|
||||||
|
|
|
@ -35,8 +35,10 @@ Route::group(['prefix' => '/eggs'], function () {
|
||||||
Route::get('/{egg}', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'view']);
|
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('/', [\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}', [\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']);
|
Route::delete('/{egg}', [\Pterodactyl\Http\Controllers\Api\Application\Eggs\EggController::class, 'delete']);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue