From c453288a588d1a1e0911b65dc91c36fa423bea57 Mon Sep 17 00:00:00 2001 From: ste87 Date: Sat, 14 Mar 2026 16:12:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20Speed/ServerBuildSettingsC?= =?UTF-8?q?ard.tsx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Speed/ServerBuildSettingsCard.tsx | 175 ++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 Speed/ServerBuildSettingsCard.tsx diff --git a/Speed/ServerBuildSettingsCard.tsx b/Speed/ServerBuildSettingsCard.tsx new file mode 100644 index 0000000..c30e74c --- /dev/null +++ b/Speed/ServerBuildSettingsCard.tsx @@ -0,0 +1,175 @@ +import { AdminServerContext } from '@/state/admin/server' +import { useFlashKey } from '@/util/useFlash' +import { zodResolver } from '@hookform/resolvers/zod' +import { FormProvider, useForm } from 'react-hook-form' +import { useTranslation } from 'react-i18next' +import { z } from 'zod' + +import updateBuild from '@/api/admin/servers/updateBuild' + +import Button from '@/components/elements/Button' +import FlashMessageRender from '@/components/elements/FlashMessageRenderer' +import FormCard from '@/components/elements/FormCard' +import TextInputForm from '@/components/elements/forms/TextInputForm' + +import AddressesMultiSelectForm from '@/components/admin/servers/AddressesMultiSelectForm' + + +const ServerBuildSettingsCard = () => { + const server = AdminServerContext.useStoreState(state => state.server.data!) + const setServer = AdminServerContext.useStoreActions( + actions => actions.server.setServer + ) + const { clearFlashes, clearAndAddHttpError } = useFlashKey( + `admin.servers.${server.uuid}.settings.hardware.build` + ) + const { t: tStrings } = useTranslation('strings') + const { t } = useTranslation('admin.servers.settings') + const { t: tIndex } = useTranslation('admin.servers.index') + + const pluckedAddressIds = [ + ...server.limits.addresses.ipv4.map(address => address.id.toString()), + ...server.limits.addresses.ipv6.map(address => address.id.toString()), + ] + + const schema = z.object({ + cpu: z.preprocess(Number, z.number().min(1)), + memory: z.preprocess(Number, z.number().min(16)), + disk: z.preprocess(Number, z.number().min(1)), + addressIds: z.array(z.preprocess(Number, z.number())), + snapshotLimit: z.union([ + z.literal(''), + z.preprocess(Number, z.number().min(0)), + ]), + backupLimit: z.union([ + z.literal(''), + z.preprocess(Number, z.number().min(0)), + ]), + bandwidthLimit: z.union([ + z.literal(''), + z.preprocess(Number, z.number().min(0)), + ]), + bandwidthUsage: z.preprocess(Number, z.number().min(0)), + }) + + const form = useForm({ + resolver: zodResolver(schema), + defaultValues: { + cpu: server.limits.cpu.toString(), + memory: (server.limits.memory / 1048576).toString(), + disk: (server.limits.disk / 1048576).toString(), + addressIds: pluckedAddressIds, + snapshotLimit: server.limits.snapshots?.toString() ?? '', + backupLimit: server.limits.backups?.toString() ?? '', + bandwidthLimit: server.limits.bandwidth + ? (server.limits.bandwidth / 1048576).toString() + : '', + bandwidthUsage: (server.usages.bandwidth / 1048576).toString(), + }, + }) + + const submit = async (_data: any) => { + const { + memory, + disk, + snapshotLimit, + backupLimit, + bandwidthLimit, + bandwidthUsage, + ...data + } = _data as z.infer + clearFlashes() + + try { + const newServer = await updateBuild(server.uuid, { + memory: memory * 1048576, + disk: disk * 1048576, + snapshotLimit: snapshotLimit !== '' ? snapshotLimit : null, + backupLimit: backupLimit !== '' ? backupLimit : null, + bandwidthLimit: + bandwidthLimit !== '' ? bandwidthLimit * 1048576 : null, + bandwidthUsage: bandwidthUsage * 1048576, + ...data, + }) + + setServer(newServer) + + form.reset({ + cpu: data.cpu.toString(), + memory: memory.toString(), + disk: disk.toString(), + addressIds: data.addressIds.map(id => id.toString()), + snapshotLimit: snapshotLimit.toString() ?? '', + backupLimit: backupLimit.toString() ?? '', + bandwidthLimit: + bandwidthLimit !== '' ? bandwidthLimit.toString() : '', + bandwidthUsage: bandwidthUsage.toString(), + }) + } catch (error) { + clearAndAddHttpError(error as any) + } + } + + return ( + + +
+ + {t('build.title')} +
+ + + + + + + + + +
+
+ + + +
+
+
+ ) +} + +export default ServerBuildSettingsCard \ No newline at end of file