ui(admin): add "working" React admin ui

This commit is contained in:
Matthew Penner 2022-12-15 19:06:14 -07:00
parent d1c7494933
commit 5402584508
No known key found for this signature in database
199 changed files with 13387 additions and 151 deletions

View file

@ -0,0 +1,31 @@
import { faCogs } from '@fortawesome/free-solid-svg-icons';
import { useFormikContext } from 'formik';
import type { ReactNode } from 'react';
import tw from 'twin.macro';
import { useServerFromRoute } from '@/api/admin/server';
import AdminBox from '@/components/admin/AdminBox';
import OwnerSelect from '@/components/admin/servers/OwnerSelect';
import Field from '@/components/elements/Field';
export default ({ children }: { children?: ReactNode }) => {
const { data: server } = useServerFromRoute();
const { isSubmitting } = useFormikContext();
return (
<AdminBox icon={faCogs} title={'Settings'} isLoading={isSubmitting}>
<div css={tw`grid grid-cols-1 xl:grid-cols-2 gap-4 lg:gap-6`}>
<Field
id={'name'}
name={'name'}
label={'Server Name'}
type={'text'}
placeholder={'My Amazing Server'}
/>
<Field id={'externalId'} name={'externalId'} label={'External Identifier'} type={'text'} />
<OwnerSelect selected={server?.relationships.user} />
{children}
</div>
</AdminBox>
);
};

View file

@ -0,0 +1,38 @@
import { faConciergeBell } from '@fortawesome/free-solid-svg-icons';
import { useFormikContext } from 'formik';
import tw from 'twin.macro';
import AdminBox from '@/components/admin/AdminBox';
import Field from '@/components/elements/Field';
export default () => {
const { isSubmitting } = useFormikContext();
return (
<AdminBox icon={faConciergeBell} title={'Feature Limits'} isLoading={isSubmitting}>
<div css={tw`grid grid-cols-1 xl:grid-cols-2 gap-4 lg:gap-6`}>
<Field
id={'featureLimits.allocations'}
name={'featureLimits.allocations'}
label={'Allocation Limit'}
type={'number'}
description={'The total number of allocations a user is allowed to create for this server.'}
/>
<Field
id={'featureLimits.backups'}
name={'featureLimits.backups'}
label={'Backup Limit'}
type={'number'}
description={'The total number of backups that can be created for this server.'}
/>
<Field
id={'featureLimits.databases'}
name={'featureLimits.databases'}
label={'Database Limit'}
type={'number'}
description={'The total number of databases a user is allowed to create for this server.'}
/>
</div>
</AdminBox>
);
};

View file

@ -0,0 +1,68 @@
import { faNetworkWired } from '@fortawesome/free-solid-svg-icons';
import { useFormikContext } from 'formik';
import tw from 'twin.macro';
import getAllocations from '@/api/admin/nodes/getAllocations';
import { useServerFromRoute } from '@/api/admin/server';
import AdminBox from '@/components/admin/AdminBox';
import Label from '@/components/elements/Label';
import Select from '@/components/elements/Select';
import type { Option } from '@/components/elements/SelectField';
import SelectField, { AsyncSelectField } from '@/components/elements/SelectField';
export default () => {
const { isSubmitting } = useFormikContext();
const { data: server } = useServerFromRoute();
const loadOptions = async (inputValue: string, callback: (options: Option[]) => void) => {
if (!server) {
// eslint-disable-next-line node/no-callback-literal
callback([] as Option[]);
return;
}
const allocations = await getAllocations(server.nodeId, { ip: inputValue, server_id: '0' });
callback(
allocations.map(a => {
return { value: a.id.toString(), label: a.getDisplayText() };
}),
);
};
return (
<AdminBox icon={faNetworkWired} title={'Networking'} isLoading={isSubmitting}>
<div css={tw`grid grid-cols-1 gap-4 lg:gap-6`}>
<div>
<Label htmlFor={'allocationId'}>Primary Allocation</Label>
<Select id={'allocationId'} name={'allocationId'}>
{server?.relationships.allocations?.map(a => (
<option key={a.id} value={a.id}>
{a.getDisplayText()}
</option>
))}
</Select>
</div>
<AsyncSelectField
id={'addAllocations'}
name={'addAllocations'}
label={'Add Allocations'}
loadOptions={loadOptions}
isMulti
/>
<SelectField
id={'removeAllocations'}
name={'removeAllocations'}
label={'Remove Allocations'}
options={
server?.relationships.allocations?.map(a => {
return { value: a.id.toString(), label: a.getDisplayText() };
}) || []
}
isMulti
isSearchable
/>
</div>
</AdminBox>
);
};

View file

@ -0,0 +1,73 @@
import { faBalanceScale } from '@fortawesome/free-solid-svg-icons';
import { useFormikContext } from 'formik';
import tw from 'twin.macro';
import AdminBox from '@/components/admin/AdminBox';
import Field from '@/components/elements/Field';
import FormikSwitch from '@/components/elements/FormikSwitch';
export default () => {
const { isSubmitting } = useFormikContext();
return (
<AdminBox icon={faBalanceScale} title={'Resources'} isLoading={isSubmitting}>
<div css={tw`grid grid-cols-1 xl:grid-cols-2 gap-4 lg:gap-6`}>
<Field
id={'limits.cpu'}
name={'limits.cpu'}
label={'CPU Limit'}
type={'text'}
description={
'Each thread on the system is considered to be 100%. Setting this value to 0 will allow the server to use CPU time without restriction.'
}
/>
<Field
id={'limits.threads'}
name={'limits.threads'}
label={'CPU Pinning'}
type={'text'}
description={
'Advanced: Enter the specific CPU cores that this server can run on, or leave blank to allow all cores. This can be a single number, and or a comma seperated list, and or a dashed range. Example: 0, 0-1,3, or 0,1,3,4. It is recommended to leave this value blank and let the CPU handle balancing the load.'
}
/>
<Field
id={'limits.memory'}
name={'limits.memory'}
label={'Memory Limit'}
type={'number'}
description={
'The maximum amount of memory allowed for this container. Setting this to 0 will allow unlimited memory in a container.'
}
/>
<Field id={'limits.swap'} name={'limits.swap'} label={'Swap Limit'} type={'number'} />
<Field
id={'limits.disk'}
name={'limits.disk'}
label={'Disk Limit'}
type={'number'}
description={
'This server will not be allowed to boot if it is using more than this amount of space. If a server goes over this limit while running it will be safely stopped and locked until enough space is available. Set to 0 to allow unlimited disk usage.'
}
/>
<Field
id={'limits.io'}
name={'limits.io'}
label={'Block IO Proportion'}
type={'number'}
description={
'Advanced: The IO performance of this server relative to other running containers on the system. Value should be between 10 and 1000.'
}
/>
<div css={tw`xl:col-span-2 bg-neutral-800 border border-neutral-900 shadow-inner p-4 rounded`}>
<FormikSwitch
name={'limits.oomDisabled'}
label={'Out of Memory Killer'}
description={
'Enabling the Out of Memory Killer may cause server processes to exit unexpectedly.'
}
/>
</div>
</div>
</AdminBox>
);
};