diff --git a/backend/prisma/seed/config.seed.ts b/backend/prisma/seed/config.seed.ts index bf786c8..4cf3647 100644 --- a/backend/prisma/seed/config.seed.ts +++ b/backend/prisma/seed/config.seed.ts @@ -57,7 +57,7 @@ const configVariables: ConfigVariables = { secret: false, }, maxSize: { - type: "number", + type: "filesize", defaultValue: "1000000000", secret: false, }, @@ -66,7 +66,7 @@ const configVariables: ConfigVariables = { defaultValue: "9", }, chunkSize: { - type: "number", + type: "filesize", defaultValue: "10000000", secret: false, }, diff --git a/backend/src/config/config.service.ts b/backend/src/config/config.service.ts index 9c4e167..29e2e51 100644 --- a/backend/src/config/config.service.ts +++ b/backend/src/config/config.service.ts @@ -30,8 +30,10 @@ export class ConfigService extends EventEmitter { const value = configVariable.value ?? configVariable.defaultValue; - if (configVariable.type == "number") return parseInt(value); - if (configVariable.type == "boolean") return value == "true"; + if (configVariable.type == "number" || configVariable.type == "filesize") + return parseInt(value); + if (configVariable.type == "boolean") + return value == "true"; if (configVariable.type == "string" || configVariable.type == "text") return value; } diff --git a/frontend/src/components/admin/configuration/AdminConfigInput.tsx b/frontend/src/components/admin/configuration/AdminConfigInput.tsx index 6bf730d..28a18f7 100644 --- a/frontend/src/components/admin/configuration/AdminConfigInput.tsx +++ b/frontend/src/components/admin/configuration/AdminConfigInput.tsx @@ -8,6 +8,7 @@ import { } from "@mantine/core"; import { useForm } from "@mantine/form"; import { AdminConfig, UpdateConfig } from "../../../types/config.type"; +import FileSizeInput from "../../core/FileSizeInput"; const AdminConfigInput = ({ configVariable, @@ -71,6 +72,15 @@ const AdminConfigInput = ({ {...form.getInputProps("numberValue")} placeholder={configVariable.defaultValue} onChange={(number) => onValueChange(configVariable, number)} + w={201} + /> + )} + {configVariable.type == "filesize" && ( + onValueChange(configVariable, bytes)} + w={201} /> )} {configVariable.type == "boolean" && ( diff --git a/frontend/src/components/core/FileSizeInput.tsx b/frontend/src/components/core/FileSizeInput.tsx new file mode 100644 index 0000000..edc2915 --- /dev/null +++ b/frontend/src/components/core/FileSizeInput.tsx @@ -0,0 +1,76 @@ +import { NativeSelect, NumberInput } from "@mantine/core"; +import { useState } from "react"; + +const multipliers = { + B: 1, + KB: 1000, + KiB: 1024, + MB: 1000 ** 2, + MiB: 1024 ** 2, + GB: 1000 ** 3, + GiB: 1024 ** 3, + TB: 1000 ** 4, + TiB: 1024 ** 4, +} + +const units = (["B", "KB", "KiB", "MB", "MiB", "GB", "GiB", "TB", "TiB"] as const).map(unit => ({ label: unit, value: unit })); + +function getLargestApplicableUnit(value: number) { + return units.findLast(unit => value % multipliers[unit.value] === 0) || units[0]; +} + +const FileSizeInput = ({ + label, + value, + onChange, + ...restProps +}: { + label?: string; + value: number; + onChange: (number: number) => void; + [key: string]: any; +}) => { + const [unit, setUnit] = useState(getLargestApplicableUnit(value).value); + const [inputValue, setInputValue] = useState(value / multipliers[unit]); + const unitSelect = ( + { + const unit = event.currentTarget.value as typeof units[number]["value"]; + setUnit(unit); + onChange(multipliers[unit] * inputValue); + }} + /> + ); + + return ( + { + const inputVal = value || 0; + setInputValue(inputVal); + onChange(multipliers[unit] * inputVal); + }} + {...restProps} + /> + ); +}; + +export default FileSizeInput; diff --git a/frontend/src/components/share/FileSizeInput.tsx b/frontend/src/components/share/FileSizeInput.tsx deleted file mode 100644 index b44023e..0000000 --- a/frontend/src/components/share/FileSizeInput.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { Col, Grid, NumberInput, Select } from "@mantine/core"; -import { useEffect, useState } from "react"; -import { - byteToUnitAndSize, - unitAndSizeToByte, -} from "../../utils/fileSize.util"; - -const FileSizeInput = ({ - label, - value, - onChange, -}: { - label: string; - value: number; - onChange: (number: number) => void; -}) => { - const [unit, setUnit] = useState("MB"); - const [size, setSize] = useState(100); - - useEffect(() => { - const { unit, size } = byteToUnitAndSize(value); - setUnit(unit); - setSize(size); - }, [value]); - - return ( - - - { - if (value) { - setSize(value); - onChange(unitAndSizeToByte(unit, value)); - } - }} - /> - - -