Skip to content

Commit 81bd67c

Browse files
committed
Add ability for user to change server's name
1 parent 564d947 commit 81bd67c

File tree

7 files changed

+168
-3
lines changed

7 files changed

+168
-3
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
4+
5+
use Illuminate\Http\Response;
6+
use Pterodactyl\Models\Server;
7+
use Pterodactyl\Repositories\Eloquent\ServerRepository;
8+
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
9+
use Pterodactyl\Http\Requests\Api\Client\Servers\Settings\RenameServerRequest;
10+
11+
class SettingsController extends ClientApiController
12+
{
13+
/**
14+
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
15+
*/
16+
private $repository;
17+
18+
/**
19+
* SettingsController constructor.
20+
*
21+
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
22+
*/
23+
public function __construct(ServerRepository $repository)
24+
{
25+
parent::__construct();
26+
27+
$this->repository = $repository;
28+
}
29+
30+
/**
31+
* Renames a server.
32+
*
33+
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Settings\RenameServerRequest $request
34+
* @param \Pterodactyl\Models\Server $server
35+
* @return \Illuminate\Http\Response
36+
*
37+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
38+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
39+
*/
40+
public function rename(RenameServerRequest $request, Server $server)
41+
{
42+
$this->repository->update($server->id, [
43+
'name' => $request->input('name'),
44+
]);
45+
46+
return Response::create('', Response::HTTP_NO_CONTENT);
47+
}
48+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Settings;
4+
5+
use Pterodactyl\Models\Server;
6+
use Pterodactyl\Contracts\Http\ClientPermissionsRequest;
7+
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
8+
9+
class RenameServerRequest extends ClientApiRequest implements ClientPermissionsRequest
10+
{
11+
/**
12+
* Returns the permissions string indicating which permission should be used to
13+
* validate that the authenticated user has permission to perform this action aganist
14+
* the given resource (server).
15+
*
16+
* @return string
17+
*/
18+
public function permission(): string
19+
{
20+
return 'settings.rename';
21+
}
22+
23+
/**
24+
* The rules to apply when validating this request.
25+
*
26+
* @return array
27+
*/
28+
public function rules(): array
29+
{
30+
return [
31+
'name' => Server::getRules()['name'],
32+
];
33+
}
34+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import http from '@/api/http';
2+
3+
export default (uuid: string, name: string): Promise<void> => {
4+
return new Promise((resolve, reject) => {
5+
http.post(`/api/client/servers/${uuid}/settings/rename`, { name })
6+
.then(() => resolve())
7+
.catch(reject);
8+
});
9+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import { ServerContext } from '@/state/server';
3+
import TitledGreyBox from '@/components/elements/TitledGreyBox';
4+
import { Form, FormikProps, withFormik } from 'formik';
5+
import { Server } from '@/api/server/getServer';
6+
import { ActionCreator } from 'easy-peasy';
7+
import renameServer from '@/api/server/renameServer';
8+
import Field from '@/components/elements/Field';
9+
import { object, string } from 'yup';
10+
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
11+
12+
interface OwnProps {
13+
server: Server;
14+
setServer: ActionCreator<Server>;
15+
}
16+
17+
interface Values {
18+
name: string;
19+
}
20+
21+
const RenameServerBox = ({ isSubmitting, ...props }: OwnProps & FormikProps<Values>) => (
22+
<TitledGreyBox title={'Change Server Name'} className={'relative'}>
23+
<SpinnerOverlay size={'normal'} visible={isSubmitting}/>
24+
<Form className={'mb-0'}>
25+
<Field
26+
id={'name'}
27+
name={'name'}
28+
label={'Server Name'}
29+
type={'text'}
30+
/>
31+
<div className={'mt-6 text-right'}>
32+
<button type={'submit'} className={'btn btn-sm btn-primary'}>
33+
Save
34+
</button>
35+
</div>
36+
</Form>
37+
</TitledGreyBox>
38+
);
39+
40+
const EnhancedForm = withFormik<OwnProps, Values>({
41+
displayName: 'RenameServerBoxForm',
42+
43+
mapPropsToValues: props => ({
44+
name: props.server.name,
45+
}),
46+
47+
validationSchema: () => object().shape({
48+
name: string().required().min(1),
49+
}),
50+
51+
handleSubmit: (values, { props, setSubmitting }) => {
52+
renameServer(props.server.uuid, values.name)
53+
.then(() => props.setServer({ ...props.server, name: values.name }))
54+
.catch(error => {
55+
console.error(error);
56+
})
57+
.then(() => setSubmitting(false));
58+
},
59+
})(RenameServerBox);
60+
61+
export default () => {
62+
const server = ServerContext.useStoreState(state => state.server.data!);
63+
const setServer = ServerContext.useStoreActions(actions => actions.server.setServer);
64+
65+
return <EnhancedForm server={server} setServer={setServer}/>;
66+
};

resources/scripts/components/server/settings/SettingsContainer.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import { ServerContext } from '@/state/server';
44
import { useStoreState } from 'easy-peasy';
55
import { ApplicationStore } from '@/state';
66
import { UserData } from '@/state/user';
7+
import RenameServerBox from '@/components/server/settings/RenameServerBox';
78

89
export default () => {
910
const user = useStoreState<ApplicationStore, UserData>(state => state.user.data!);
1011
const server = ServerContext.useStoreState(state => state.server.data!);
1112

1213
return (
13-
<div className={'my-10 mb-6 flex'}>
14-
<TitledGreyBox title={'SFTP Details'} className={'w-full md:w-1/2'}>
14+
<div className={'my-10 mb-6 md:flex'}>
15+
<TitledGreyBox title={'SFTP Details'} className={'w-full md:flex-1 md:mr-6'}>
1516
<div>
1617
<label className={'input-dark-label'}>Server Address</label>
1718
<input
@@ -38,6 +39,9 @@ export default () => {
3839
</div>
3940
</div>
4041
</TitledGreyBox>
42+
<div className={'w-full mt-6 md:flex-1 md:mt-0'}>
43+
<RenameServerBox/>
44+
</div>
4145
</div>
4246
);
4347
};

resources/scripts/routers/ServerRouter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
4747
<Provider store={ServerContext.useStore()}>
4848
<WebsocketHandler/>
4949
<TransitionRouter>
50-
<div className={'w-full mx-auto'} style={{ maxWidth: '1200px' }}>
50+
<div className={'w-full mx-auto px-3'} style={{ maxWidth: '1200px' }}>
5151
{!server ?
5252
<div className={'flex justify-center m-20'}>
5353
<Spinner size={'large'}/>

routes/api-client.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,8 @@
6363
Route::group(['prefix' => '/users'], function () {
6464
Route::get('/', 'Servers\SubuserController@index');
6565
});
66+
67+
Route::group(['prefix' => '/settings'], function () {
68+
Route::post('/rename', 'Servers\SettingsController@rename');
69+
});
6670
});

0 commit comments

Comments
 (0)