This commit is contained in:
cracklesparkle
2024-12-06 12:42:34 +09:00
parent bd0a317e76
commit e9595f9703
16 changed files with 770 additions and 390 deletions

View File

@ -1,10 +1,46 @@
import useSWR from 'swr'
import { fetcher } from '../../http/axiosInstance'
import { BASE_URL } from '../../constants'
import { Checkbox, Divider, Flex, Grid, Stack, Text } from '@mantine/core'
import { IObjectParam, IParam } from '../../interfaces/objects'
import { decodeDoubleEncodedString } from '../../utils/format'
import TCBParameter from './TCBParameter'
import TableValue from './TableValue'
export function formatNumericValue(format: string, value: string) {
// Extract precision and scale from the format string
const regex = /numeric\((\d+),(\d+)\)/;
const match = format.match(regex);
if (!match) return value; // return original if format is not correct
const precision = parseInt(match[1], 10); // Total number of digits
const scale = parseInt(match[2], 10); // Number of digits after the decimal point
// Convert value to a number and handle cases like empty value or invalid input
const numericValue = parseFloat(value);
if (isNaN(numericValue)) {
return '0'.padStart(precision - scale, '0') + '.' + '0'.repeat(scale); // fallback in case of invalid value
}
// Ensure the value has the correct number of digits after the decimal point (scale)
let formattedValue = numericValue.toFixed(scale);
// Ensure the total length doesn't exceed the precision
const totalDigits = formattedValue.replace('.', '').length;
if (totalDigits > precision) {
// Truncate the value if it exceeds the total precision
formattedValue = numericValue.toPrecision(precision);
}
// Pad with leading zeros if necessary (if it's an integer and the precision is greater than the scale)
const [integerPart, decimalPart] = formattedValue.split('.');
// Ensure the integer part doesn't exceed the precision
const paddedInteger = integerPart.padStart(precision - scale, '0');
// Reassemble the number
return `${paddedInteger}.${decimalPart.padEnd(scale, '0')}`;
}
interface ObjectParameterProps {
showLabel?: boolean,
@ -12,56 +48,61 @@ interface ObjectParameterProps {
}
const ObjectParameter = ({
param,
showLabel = true
param
}: ObjectParameterProps) => {
const { data: paramData } = useSWR(
`/general/params/all?param_id=${param.id_param}`,
(url) => fetcher(url, BASE_URL.ems).then(res => res[0] as IParam),
{
revalidateOnFocus: false
revalidateOnFocus: false,
revalidateIfStale: false
}
)
const Parameter = (type: string, name: string, value: unknown, vtable: string) => {
const Parameter = (type: string, name: string, value: unknown, vtable: string, unit: string | null) => {
switch (type) {
case 'bit':
return (
<Flex direction='row' align='center' gap='sm'>
<Checkbox defaultChecked={value as boolean} />
<Text>{name}</Text>
</Flex>
)
case 'varchar(200)':
return (
<Text>
{decodeDoubleEncodedString(value as string)}
</Text>
)
case 'varchar(5)':
return (
<Text>
{decodeDoubleEncodedString(value as string)}
</Text>
<TableValue value={value} name={name} type='boolean' />
)
case 'bigint':
return (
<Text>
{(value as string)}
</Text>
<TableValue value={value} name={name} type='number' />
)
case 'tinyint':
return (
<TableValue value={value} name={name} type='number' />
)
// TODO: Calculate from calc procedures
case 'calculate':
return (
<TableValue value={value} name={name} type='value' />
)
case 'GTCB':
return (
<TCBParameter value={value as string} vtable={vtable} />
<TCBParameter value={value as string} vtable={vtable} name={name} />
)
case 'TCB':
return (
<TCBParameter value={value as string} vtable={vtable} />
<TCBParameter value={value as string} vtable={vtable} name={name} />
)
case type.match(/varchar\((\d+)\)/)?.input:
return (
<TableValue value={value} name={name} type='string' />
)
case type.match(/numeric\((\d+),(\d+)\)/)?.input:
return (
<TableValue value={value} name={name} type='number' unit={unit} />
)
case 'year':
return (
<TableValue value={value} name={name} type='number' />
)
default:
return (
<div>
{type}
{value as string}
</div>
)
}
@ -70,12 +111,7 @@ const ObjectParameter = ({
return (
<>
{paramData &&
<Stack gap={0}>
{showLabel &&
<Divider my="xs" label={paramData.name} labelPosition="left" />
}
{Parameter(paramData.format, paramData.name, param.value, paramData.vtable)}
</Stack>
Parameter(paramData.format, paramData.name, param.value, paramData.vtable, paramData.unit)
}
</>
)