Apply new eslint rules; default to prettier for styling

This commit is contained in:
DaneEveritt 2022-06-26 15:13:52 -04:00
parent f22cce8881
commit dc84af9937
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
218 changed files with 3876 additions and 3564 deletions

View file

@ -17,23 +17,30 @@ import InputSpinner from '@/components/elements/InputSpinner';
import useFlash from '@/plugins/useFlash';
const StartupContainer = () => {
const [ loading, setLoading ] = useState(false);
const [loading, setLoading] = useState(false);
const { clearFlashes, clearAndAddHttpError } = useFlash();
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const variables = ServerContext.useStoreState(({ server }) => ({
variables: server.data!.variables,
invocation: server.data!.invocation,
dockerImage: server.data!.dockerImage,
}), isEqual);
const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
const variables = ServerContext.useStoreState(
({ server }) => ({
variables: server.data!.variables,
invocation: server.data!.invocation,
dockerImage: server.data!.dockerImage,
}),
isEqual
);
const { data, error, isValidating, mutate } = getServerStartup(uuid, {
...variables,
dockerImages: { [variables.dockerImage]: variables.dockerImage },
});
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
const isCustomImage = data && !Object.values(data.dockerImages).map(v => v.toLowerCase()).includes(variables.dockerImage.toLowerCase());
const setServerFromState = ServerContext.useStoreActions((actions) => actions.server.setServerFromState);
const isCustomImage =
data &&
!Object.values(data.dockerImages)
.map((v) => v.toLowerCase())
.includes(variables.dockerImage.toLowerCase());
useEffect(() => {
// Since we're passing in initial data this will not trigger on mount automatically. We
@ -45,86 +52,85 @@ const StartupContainer = () => {
useDeepCompareEffect(() => {
if (!data) return;
setServerFromState(s => ({
setServerFromState((s) => ({
...s,
invocation: data.invocation,
variables: data.variables,
}));
}, [ data ]);
}, [data]);
const updateSelectedDockerImage = useCallback((v: React.ChangeEvent<HTMLSelectElement>) => {
setLoading(true);
clearFlashes('startup:image');
const updateSelectedDockerImage = useCallback(
(v: React.ChangeEvent<HTMLSelectElement>) => {
setLoading(true);
clearFlashes('startup:image');
const image = v.currentTarget.value;
setSelectedDockerImage(uuid, image)
.then(() => setServerFromState(s => ({ ...s, dockerImage: image })))
.catch(error => {
console.error(error);
clearAndAddHttpError({ key: 'startup:image', error });
})
.then(() => setLoading(false));
}, [ uuid ]);
const image = v.currentTarget.value;
setSelectedDockerImage(uuid, image)
.then(() => setServerFromState((s) => ({ ...s, dockerImage: image })))
.catch((error) => {
console.error(error);
clearAndAddHttpError({ key: 'startup:image', error });
})
.then(() => setLoading(false));
},
[uuid]
);
return (
!data ?
(!error || (error && isValidating)) ?
<Spinner centered size={Spinner.Size.LARGE}/>
:
<ServerError
title={'Oops!'}
message={httpErrorToHuman(error)}
onRetry={() => mutate()}
/>
:
<ServerContentBlock title={'Startup Settings'} showFlashKey={'startup:image'}>
<div css={tw`md:flex`}>
<TitledGreyBox title={'Startup Command'} css={tw`flex-1`}>
<div css={tw`px-1 py-2`}>
<p css={tw`font-mono bg-neutral-900 rounded py-2 px-4`}>
{data.invocation}
return !data ? (
!error || (error && isValidating) ? (
<Spinner centered size={Spinner.Size.LARGE} />
) : (
<ServerError title={'Oops!'} message={httpErrorToHuman(error)} onRetry={() => mutate()} />
)
) : (
<ServerContentBlock title={'Startup Settings'} showFlashKey={'startup:image'}>
<div css={tw`md:flex`}>
<TitledGreyBox title={'Startup Command'} css={tw`flex-1`}>
<div css={tw`px-1 py-2`}>
<p css={tw`font-mono bg-neutral-900 rounded py-2 px-4`}>{data.invocation}</p>
</div>
</TitledGreyBox>
<TitledGreyBox title={'Docker Image'} css={tw`flex-1 lg:flex-none lg:w-1/3 mt-8 md:mt-0 md:ml-10`}>
{Object.keys(data.dockerImages).length > 1 && !isCustomImage ? (
<>
<InputSpinner visible={loading}>
<Select
disabled={Object.keys(data.dockerImages).length < 2}
onChange={updateSelectedDockerImage}
defaultValue={variables.dockerImage}
>
{Object.keys(data.dockerImages).map((key) => (
<option key={data.dockerImages[key]} value={data.dockerImages[key]}>
{key}
</option>
))}
</Select>
</InputSpinner>
<p css={tw`text-xs text-neutral-300 mt-2`}>
This is an advanced feature allowing you to select a Docker image to use when running
this server instance.
</p>
</div>
</TitledGreyBox>
<TitledGreyBox title={'Docker Image'} css={tw`flex-1 lg:flex-none lg:w-1/3 mt-8 md:mt-0 md:ml-10`}>
{Object.keys(data.dockerImages).length > 1 && !isCustomImage ?
<>
<InputSpinner visible={loading}>
<Select
disabled={(Object.keys(data.dockerImages)).length < 2}
onChange={updateSelectedDockerImage}
defaultValue={variables.dockerImage}
>
{Object.keys(data.dockerImages).map(key => (
<option key={data.dockerImages[key]} value={data.dockerImages[key]}>
{key}
</option>
))}
</Select>
</InputSpinner>
</>
) : (
<>
<Input disabled readOnly value={variables.dockerImage} />
{isCustomImage && (
<p css={tw`text-xs text-neutral-300 mt-2`}>
This is an advanced feature allowing you to select a Docker image to use when
running this server instance.
</p>
</>
:
<>
<Input disabled readOnly value={variables.dockerImage}/>
{isCustomImage &&
<p css={tw`text-xs text-neutral-300 mt-2`}>
This {'server\'s'} Docker image has been manually set by an administrator and cannot
This {"server's"} Docker image has been manually set by an administrator and cannot
be changed through this UI.
</p>
}
</>
}
</TitledGreyBox>
</div>
<h3 css={tw`mt-8 mb-2 text-2xl`}>Variables</h3>
<div css={tw`grid gap-8 md:grid-cols-2`}>
{data.variables.map(variable => <VariableBox key={variable.envVariable} variable={variable}/>)}
</div>
</ServerContentBlock>
)}
</>
)}
</TitledGreyBox>
</div>
<h3 css={tw`mt-8 mb-2 text-2xl`}>Variables</h3>
<div css={tw`grid gap-8 md:grid-cols-2`}>
{data.variables.map((variable) => (
<VariableBox key={variable.envVariable} variable={variable} />
))}
</div>
</ServerContentBlock>
);
};

View file

@ -22,9 +22,9 @@ interface Props {
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 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);
@ -33,35 +33,42 @@ const VariableBox = ({ variable }: Props) => {
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 => {
.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(',') || [];
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.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`}/>
<FlashMessageRender byKey={FLASH_KEY} css={tw`mb-2 md:mb-4`} />
<InputSpinner visible={loading}>
{useSwitch ?
{useSwitch ? (
<>
<Switch
readOnly={!canEdit || !variable.isEditable}
@ -74,26 +81,30 @@ const VariableBox = ({ variable }: Props) => {
}}
/>
</>
:
) : (
<>
{selectValues.length > 0 ?
{selectValues.length > 0 ? (
<>
<Select
onChange={e => setVariableValue(e.target.value)}
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>
{selectValues.map((selectValue) => (
<option
key={selectValue.replace('in:', '')}
value={selectValue.replace('in:', '')}
>
{selectValue.replace('in:', '')}
</option>
))}
</Select>
</>
:
) : (
<>
<Input
onKeyUp={e => {
onKeyUp={(e) => {
if (canEdit && variable.isEditable) {
setVariableValue(e.currentTarget.value);
}
@ -104,13 +115,11 @@ const VariableBox = ({ variable }: Props) => {
placeholder={variable.defaultValue}
/>
</>
}
)}
</>
}
)}
</InputSpinner>
<p css={tw`mt-1 text-xs text-neutral-300`}>
{variable.description}
</p>
<p css={tw`mt-1 text-xs text-neutral-300`}>{variable.description}</p>
</TitledGreyBox>
);
};