fix path for /route route

This commit is contained in:
maxim 2025-03-17 03:30:41 +03:00
parent b0181f988b
commit 7ee4334381
3 changed files with 83 additions and 17 deletions

View File

@ -74,16 +74,34 @@ export const RouteCreate = () => {
<TextField <TextField
{...register('path', { {...register('path', {
required: 'Это поле является обязательным', required: 'Это поле является обязательным',
setValueAs: (value) => String(value), setValueAs: (value: string) => {
try {
// Парсим строку в массив массивов
return JSON.parse(value)
} catch {
return []
}
},
validate: (value: unknown) => {
if (!Array.isArray(value)) return 'Неверный формат'
if (!value.every((point: unknown) => Array.isArray(point) && point.length === 2)) {
return 'Каждая точка должна быть массивом из двух координат'
}
if (!value.every((point: unknown[]) => point.every((coord: unknown) => !isNaN(Number(coord)) && typeof coord === 'number'))) {
return 'Координаты должны быть числами'
}
return true
},
})} })}
error={!!(errors as any)?.path} error={!!(errors as any)?.path}
helperText={(errors as any)?.path?.message} helperText={(errors as any)?.path?.message} // 'Формат: [[lat1,lon1], [lat2,lon2], ...]'
margin="normal" margin="normal"
fullWidth fullWidth
InputLabelProps={{shrink: true}} InputLabelProps={{shrink: true}}
type="text" type="text"
label={'Путь'} label={'Координаты маршрута'}
name="path" name="path"
placeholder="[[1.1, 2.2], [2.1, 4.5]]"
/> />
</Box> </Box>
</Create> </Create>

View File

@ -66,18 +66,45 @@ export const RouteEdit = () => {
(Прямой / Обратный) (Прямой / Обратный)
</Typography> </Typography>
<TextField <Controller
{...register('path', {
setValueAs: (value) => String(value),
})}
error={!!(errors as any)?.path}
helperText={(errors as any)?.path?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Путь'}
name="path" name="path"
control={control}
defaultValue={[]}
rules={{
required: 'Это поле является обязательным',
validate: (value: unknown) => {
if (!Array.isArray(value)) return 'Неверный формат'
if (!value.every((point: unknown) => Array.isArray(point) && point.length === 2)) {
return 'Каждая точка должна быть массивом из двух координат'
}
if (!value.every((point: unknown[]) => point.every((coord: unknown) => !isNaN(Number(coord)) && typeof coord === 'number'))) {
return 'Координаты должны быть числами'
}
return true
},
}}
render={({field, fieldState: {error}}) => (
<TextField
{...field}
value={Array.isArray(field.value) ? JSON.stringify(field.value) : ''}
onChange={(e) => {
try {
const parsed = JSON.parse(e.target.value)
field.onChange(parsed)
} catch {
field.onChange([])
}
}}
error={!!error}
helperText={error?.message || 'Формат: [[lat1,lon1], [lat2,lon2], ...]'}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Координаты маршрута'}
placeholder="[[1.1, 2.2], [2.1, 4.5]]"
/>
)}
/> />
</Box> </Box>
</Edit> </Edit>

View File

@ -180,7 +180,28 @@ export const RouteShow = () => {
const fields = [ const fields = [
{label: 'Перевозчик', data: 'carrier'}, {label: 'Перевозчик', data: 'carrier'},
{label: 'Номер маршрута', data: 'route_number'}, {label: 'Номер маршрута', data: 'route_number'},
{label: 'Путь', data: 'path'}, {
label: 'Координаты маршрута',
data: 'path',
render: (value: number[][]) => (
<Box
sx={{
fontFamily: 'monospace',
bgcolor: (theme) => theme.palette.background.paper,
p: 2,
borderRadius: 1,
maxHeight: '200px',
overflow: 'auto',
}}
>
{value?.map((point, index) => (
<Typography key={index} sx={{mb: 0.5}}>
Точка {index + 1}: [{point[0]}, {point[1]}]
</Typography>
))}
</Box>
),
},
] ]
const stationFields: Array<{label: string; data: keyof StationItem}> = [ const stationFields: Array<{label: string; data: keyof StationItem}> = [
@ -196,12 +217,12 @@ export const RouteShow = () => {
return ( return (
<Show isLoading={isLoading}> <Show isLoading={isLoading}>
<Stack gap={4}> <Stack gap={4}>
{fields.map(({label, data}) => ( {fields.map(({label, data, render}) => (
<Stack key={data} gap={1}> <Stack key={data} gap={1}>
<Typography variant="body1" fontWeight="bold"> <Typography variant="body1" fontWeight="bold">
{label} {label}
</Typography> </Typography>
<TextField value={record?.[data]} /> {render ? render(record?.[data]) : <TextField value={record?.[data]} />}
</Stack> </Stack>
))} ))}