Skip to content

Commit 82d7fa1

Browse files
committed
Support setting notes on allocations; closes pterodactyl#561
1 parent 2278927 commit 82d7fa1

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

resources/scripts/api/getServers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default (query?: string, includeAdmin?: boolean): Promise<PaginatedResult
1111
},
1212
})
1313
.then(({ data }) => resolve({
14-
items: (data.data || []).map((datum: any) => rawDataToServerObject(datum.attributes)),
14+
items: (data.data || []).map((datum: any) => rawDataToServerObject(datum)),
1515
pagination: getPaginationSet(data.meta.pagination),
1616
}))
1717
.catch(reject);

resources/scripts/components/elements/Input.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ const checkboxStyle = css<Props>`
3636

3737
const inputStyle = css<Props>`
3838
// Reset to normal styling.
39-
${tw`appearance-none w-full min-w-0`};
39+
resize: none;
40+
${tw`appearance-none outline-none w-full min-w-0`};
4041
${tw`p-3 border rounded text-sm transition-all duration-150`};
4142
${tw`bg-neutral-600 border-neutral-500 hover:border-neutral-400 text-neutral-200 shadow-none`};
4243
@@ -49,8 +50,8 @@ const inputStyle = css<Props>`
4950
${tw`shadow-none`};
5051
}
5152
52-
&:focus {
53-
${tw`shadow-md border-neutral-400`};
53+
&:not(:disabled):not(:read-only):focus {
54+
${tw`shadow-md border-primary-400`};
5455
}
5556
5657
&:disabled {

resources/scripts/components/server/network/NetworkContainer.tsx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import tw from 'twin.macro';
33
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
44
import { faNetworkWired } from '@fortawesome/free-solid-svg-icons';
@@ -14,28 +14,45 @@ import { Allocation } from '@/api/server/getServer';
1414
import Spinner from '@/components/elements/Spinner';
1515
import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation';
1616
import useFlash from '@/plugins/useFlash';
17+
import { Textarea } from '@/components/elements/Input';
18+
import setServerAllocationNotes from '@/api/server/network/setServerAllocationNotes';
19+
import { debounce } from 'debounce';
20+
import InputSpinner from '@/components/elements/InputSpinner';
1721

1822
const Code = styled.code`${tw`font-mono py-1 px-2 bg-neutral-900 rounded text-sm block`}`;
1923
const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`;
2024

2125
const NetworkContainer = () => {
22-
const server = useServer();
26+
const { uuid, allocations } = useServer();
2327
const { clearFlashes, clearAndAddHttpError } = useFlash();
24-
const { data, error, mutate } = useSWR<Allocation[]>(server.uuid, key => getServerAllocations(key), { initialData: server.allocations });
28+
const [ loading, setLoading ] = useState<false | number>(false);
29+
const { data, error, mutate } = useSWR<Allocation[]>(uuid, key => getServerAllocations(key), { initialData: allocations });
2530

2631
const setPrimaryAllocation = (id: number) => {
2732
clearFlashes('server:network');
2833

2934
const initial = data;
3035
mutate(data?.map(a => a.id === id ? { ...a, isDefault: true } : { ...a, isDefault: false }), false);
3136

32-
setPrimaryServerAllocation(server.uuid, id)
37+
setPrimaryServerAllocation(uuid, id)
3338
.catch(error => {
3439
clearAndAddHttpError({ key: 'server:network', error });
3540
mutate(initial, false);
3641
});
3742
};
3843

44+
const setAllocationNotes = debounce((id: number, notes: string) => {
45+
setLoading(id);
46+
clearFlashes('server:network');
47+
48+
setServerAllocationNotes(uuid, id, notes)
49+
.then(() => mutate(data?.map(a => a.id === id ? { ...a, notes } : a), false))
50+
.catch(error => {
51+
clearAndAddHttpError({ key: 'server:network', error });
52+
})
53+
.then(() => setLoading(false));
54+
}, 750);
55+
3956
useEffect(() => {
4057
if (error) {
4158
clearAndAddHttpError({ key: 'server:network', error });
@@ -47,8 +64,8 @@ const NetworkContainer = () => {
4764
{!data ?
4865
<Spinner size={'large'} centered/>
4966
:
50-
data.map(({ id, ip, port, alias, isDefault }, index) => (
51-
<GreyRowBox key={`${ip}:${port}`} css={index > 0 ? tw`mt-2` : undefined}>
67+
data.map(({ id, ip, port, alias, notes, isDefault }, index) => (
68+
<GreyRowBox key={`${ip}:${port}`} css={index > 0 ? tw`mt-2` : undefined} $hoverable={false}>
5269
<div css={tw`pl-4 pr-6 text-neutral-400`}>
5370
<FontAwesomeIcon icon={faNetworkWired}/>
5471
</div>
@@ -60,7 +77,17 @@ const NetworkContainer = () => {
6077
<Code>:{port}</Code>
6178
<Label>Port</Label>
6279
</div>
63-
<div css={tw`flex-1 text-right`}>
80+
<div css={tw`px-8 flex-1 self-start`}>
81+
<InputSpinner visible={loading === id}>
82+
<Textarea
83+
css={tw`bg-neutral-800 hover:border-neutral-600 border-transparent`}
84+
placeholder={'Notes'}
85+
defaultValue={notes || undefined}
86+
onChange={e => setAllocationNotes(id, e.currentTarget.value)}
87+
/>
88+
</InputSpinner>
89+
</div>
90+
<div css={tw`w-32 text-right`}>
6491
{isDefault ?
6592
<span css={tw`bg-green-500 py-1 px-2 rounded text-green-50 text-xs`}>
6693
Primary

0 commit comments

Comments
 (0)