forked from pterodactyl/panel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVariableBox.tsx
More file actions
127 lines (119 loc) · 5.37 KB
/
VariableBox.tsx
File metadata and controls
127 lines (119 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import React, { memo, useState } from 'react';
import { ServerEggVariable } from '@/api/server/types';
import TitledGreyBox from '@/components/elements/TitledGreyBox';
import { usePermissions } from '@/plugins/usePermissions';
import InputSpinner from '@/components/elements/InputSpinner';
import Input from '@/components/elements/Input';
import Switch from '@/components/elements/Switch';
import tw from 'twin.macro';
import { debounce } from 'debounce';
import updateStartupVariable from '@/api/server/updateStartupVariable';
import useFlash from '@/plugins/useFlash';
import FlashMessageRender from '@/components/FlashMessageRender';
import getServerStartup from '@/api/swr/getServerStartup';
import Select from '@/components/elements/Select';
import isEqual from 'react-fast-compare';
import { ServerContext } from '@/state/server';
interface Props {
variable: ServerEggVariable;
}
const VariableBox = ({ variable }: Props) => {
const FLASH_KEY = `server:startup:${variable.envVariable}`;
const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
const [loading, setLoading] = useState(false);
const [canEdit] = usePermissions(['startup.update']);
const { clearFlashes, clearAndAddHttpError } = useFlash();
const { mutate } = getServerStartup(uuid);
const setVariableValue = debounce((value: string) => {
setLoading(true);
clearFlashes(FLASH_KEY);
updateStartupVariable(uuid, variable.envVariable, value)
.then(([response, invocation]) =>
mutate(
(data) => ({
...data,
invocation,
variables: (data.variables || []).map((v) =>
v.envVariable === response.envVariable ? response : v
),
}),
false
)
)
.catch((error) => {
console.error(error);
clearAndAddHttpError({ error, key: FLASH_KEY });
})
.then(() => setLoading(false));
}, 500);
const useSwitch = variable.rules.some((v) => v === 'boolean' || v === 'in:0,1');
const selectValues = variable.rules.find((v) => v.startsWith('in:'))?.split(',') || [];
return (
<TitledGreyBox
title={
<p css={tw`text-sm uppercase`}>
{!variable.isEditable && (
<span css={tw`bg-neutral-700 text-xs py-1 px-2 rounded-full mr-2 mb-1`}>Read Only</span>
)}
{variable.name}
</p>
}
>
<FlashMessageRender byKey={FLASH_KEY} css={tw`mb-2 md:mb-4`} />
<InputSpinner visible={loading}>
{useSwitch ? (
<>
<Switch
readOnly={!canEdit || !variable.isEditable}
name={variable.envVariable}
defaultChecked={variable.serverValue === '1'}
onChange={() => {
if (canEdit && variable.isEditable) {
setVariableValue(variable.serverValue === '1' ? '0' : '1');
}
}}
/>
</>
) : (
<>
{selectValues.length > 0 ? (
<>
<Select
onChange={(e) => setVariableValue(e.target.value)}
name={variable.envVariable}
defaultValue={variable.serverValue}
disabled={!canEdit || !variable.isEditable}
>
{selectValues.map((selectValue) => (
<option
key={selectValue.replace('in:', '')}
value={selectValue.replace('in:', '')}
>
{selectValue.replace('in:', '')}
</option>
))}
</Select>
</>
) : (
<>
<Input
onKeyUp={(e) => {
if (canEdit && variable.isEditable) {
setVariableValue(e.currentTarget.value);
}
}}
readOnly={!canEdit || !variable.isEditable}
name={variable.envVariable}
defaultValue={variable.serverValue}
placeholder={variable.defaultValue}
/>
</>
)}
</>
)}
</InputSpinner>
<p css={tw`mt-1 text-xs text-neutral-300`}>{variable.description}</p>
</TitledGreyBox>
);
};
export default memo(VariableBox, isEqual);