diff --git a/src/components/LinkedItems.tsx b/src/components/LinkedItems.tsx index ce62f74..6f6c8d0 100644 --- a/src/components/LinkedItems.tsx +++ b/src/components/LinkedItems.tsx @@ -106,17 +106,19 @@ export const LinkedItems = ( - {!props.dontRecurse && + {!props.dontRecurse && ( <> - } + )} ); -} +}; -export const LinkedItemsContents = ({ +export const LinkedItemsContents = < + T extends { id: number; [key: string]: any } +>({ parentId, parentResource, childResource, @@ -128,7 +130,7 @@ export const LinkedItemsContents = ) => { const { language } = languageStore; const { setArticleModalOpenAction, setArticleIdAction } = articleStore; @@ -154,7 +156,7 @@ export const LinkedItemsContents = { - if(!updatedLinkedItems?.length) return; + if (!updatedLinkedItems?.length) return; setLinkedItems(updatedLinkedItems); }, [updatedLinkedItems]); @@ -173,7 +175,7 @@ export const LinkedItemsContents = { - if (childResource === "article" && type==="edit") { + if ( + childResource === "article" && + type === "edit" + ) { setArticleModalOpenAction(true); setArticleIdAction(item.id); } - if (childResource === "station" && type==="edit") { + if ( + childResource === "station" && + type === "edit" + ) { setStationModalOpenAction(true); setStationIdAction(item.id); setRouteIdAction(Number(parentId)); @@ -434,25 +442,15 @@ export const LinkedItemsContents = item.id === selectedItemId - ) || null - } - onChange={(_, newValue) => - setSelectedItemId(newValue?.id || null) + availableItems?.find((item) => item.id === selectedItemId) || null } + onChange={(_, newValue) => setSelectedItemId(newValue?.id || null)} options={availableItems} getOptionLabel={(item) => String(item[fields[0].data])} renderInput={(params) => ( - + )} - isOptionEqualToValue={(option, value) => - option.id === value?.id - } + isOptionEqualToValue={(option, value) => option.id === value?.id} filterOptions={(options, { inputValue }) => { const searchWords = inputValue .toLowerCase() @@ -495,17 +493,32 @@ export const LinkedItemsContents = { - const newValue = Number(e.target.value); + const rawValue = e.target.value; + const numericValue = Number(rawValue); const maxValue = linkedItems.length + 1; - const value = Math.max(1, Math.min(newValue, maxValue)); - setMediaOrder(value); + + if (isNaN(numericValue)) { + return; + } else { + let newValue = numericValue; + + if (newValue < 10 && newValue > 0) { + setMediaOrder(numericValue); + } + + if (newValue > maxValue) { + newValue = maxValue; + } + + setMediaOrder(newValue); + } }} fullWidth - slotProps={{inputLabel: {shrink: true}}} + InputLabelProps={{ shrink: true }} /> )} @@ -513,7 +526,9 @@ export const LinkedItemsContents = Добавить diff --git a/src/pages/route/create.tsx b/src/pages/route/create.tsx index f1a3ace..7d6d190 100644 --- a/src/pages/route/create.tsx +++ b/src/pages/route/create.tsx @@ -8,6 +8,7 @@ import { } from "@mui/material"; import { Create, useAutocomplete } from "@refinedev/mui"; import { useForm } from "@refinedev/react-hook-form"; +import { useState } from "react"; import { Controller } from "react-hook-form"; export const RouteCreate = () => { @@ -16,6 +17,7 @@ export const RouteCreate = () => { refineCore: { formLoading }, register, control, + setValue, formState: { errors }, } = useForm({ refineCoreProps: { @@ -23,6 +25,16 @@ export const RouteCreate = () => { }, }); + const directions = [ + { + label: "Прямой", + value: true, + }, + { + label: "Обратный", + value: false, + }, + ]; const { autocompleteProps: carrierAutocompleteProps } = useAutocomplete({ resource: "carrier", onSearch: (value) => [ @@ -34,22 +46,25 @@ export const RouteCreate = () => { ], }); - const { autocompleteProps: governorAppealAutocompleteProps } = useAutocomplete({ - resource: "article", + const { autocompleteProps: governorAppealAutocompleteProps } = + useAutocomplete({ + resource: "article", - onSearch: (value) => [ - { - field: "heading", - operator: "contains", - value, - }, - { - field: "media_type", - operator: "contains", - value, - }, - ] - }); + onSearch: (value) => [ + { + field: "heading", + operator: "contains", + value, + }, + { + field: "media_type", + operator: "contains", + value, + }, + ], + }); + + const [routeDirection, setRouteDirection] = useState(false); return ( @@ -111,37 +126,12 @@ export const RouteCreate = () => { helperText={(errors as any)?.route_number?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="text" label={"Номер маршрута *"} name="route_number" /> - ( - field.onChange(e.target.checked)} - /> - } - /> - )} - /> - - (Прямой / Обратный) - - { helperText={(errors as any)?.path?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="text" label={"Координаты маршрута *"} name="path" @@ -209,9 +199,9 @@ export const RouteCreate = () => { helperText={(errors as any)?.route_sys_number?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" - label={"Системный номер маршрута *"} + label={"Номер маршрута в Говорящем Городе *"} name="route_sys_number" /> @@ -256,7 +246,44 @@ export const RouteCreate = () => { )} /> )} - /> + /> + + + + el.value == false)} + onChange={(_, element) => { + if (element) { + setValue("route_direction", element.value); + setRouteDirection(element.value); + } + }} + renderInput={(params) => ( + + )} + /> + + + {routeDirection ? "Прямой" : "Обратный"} + { helperText={(errors as any)?.scale_min?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Масштаб (мин)"} name="scale_min" @@ -282,7 +309,7 @@ export const RouteCreate = () => { helperText={(errors as any)?.scale_max?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Масштаб (макс)"} name="scale_max" @@ -297,7 +324,7 @@ export const RouteCreate = () => { helperText={(errors as any)?.rotate?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Поворот"} name="rotate" @@ -312,7 +339,7 @@ export const RouteCreate = () => { helperText={(errors as any)?.center_latitude?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Центр. широта"} name="center_latitude" @@ -327,7 +354,7 @@ export const RouteCreate = () => { helperText={(errors as any)?.center_longitude?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Центр. долгота"} name="center_longitude" diff --git a/src/pages/route/edit.tsx b/src/pages/route/edit.tsx index 821a3de..5aea5ef 100644 --- a/src/pages/route/edit.tsx +++ b/src/pages/route/edit.tsx @@ -18,7 +18,7 @@ import { stationFields, vehicleFields, } from "./types"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { META_LANGUAGE, languageStore } from "@stores"; import { observer } from "mobx-react-lite"; import { LanguageSelector } from "@ui"; @@ -32,11 +32,25 @@ export const RouteEdit = observer(() => { formState: { errors }, refineCore: { queryResult }, setValue, + getValues, watch, } = useForm({ - refineCoreProps: META_LANGUAGE(language) + refineCoreProps: META_LANGUAGE(language), }); + const routeDirectionFromServer = watch("route_direction"); + + const [routeDirection, setRouteDirection] = useState(false); const navigate = useNavigate(); + const directions = [ + { + label: "Прямой", + value: true, + }, + { + label: "Обратный", + value: false, + }, + ]; const { id: routeId } = useParams<{ id: string }>(); @@ -59,35 +73,40 @@ export const RouteEdit = observer(() => { value, }, ], - ...META_LANGUAGE(language) + ...META_LANGUAGE(language), }); - const { autocompleteProps: governorAppealAutocompleteProps } = useAutocomplete({ - resource: "article", + const { autocompleteProps: governorAppealAutocompleteProps } = + useAutocomplete({ + resource: "article", - onSearch: (value) => [ - { - field: "heading", - operator: "contains", - value, - }, - { - field: "media_type", - operator: "contains", - value, - }, - ], - ...META_LANGUAGE(language) - }); + onSearch: (value) => [ + { + field: "heading", + operator: "contains", + value, + }, + { + field: "media_type", + operator: "contains", + value, + }, + ], + ...META_LANGUAGE(language), + }); + + useEffect(() => { + if (routeDirectionFromServer) { + setRouteDirection(routeDirectionFromServer); + } + }, [routeDirectionFromServer]); return ( - + @@ -144,37 +163,36 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.route_number?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="text" label={"Номер маршрута"} name="route_number" /> - ( - field.onChange(e.target.checked)} - /> - } + + + + el.value == routeDirection)} + onChange={(_, element) => { + if (element) { + setValue("route_direction", element.value); + setRouteDirection(element.value); + } + }} + renderInput={(params) => ( + )} /> - - (Прямой / Обратный) - - { return "Введите хотя бы одну пару координат"; if ( !value.every( - (point: unknown) => Array.isArray(point) && point.length === 2 + (point: unknown) => + Array.isArray(point) && point.length === 2 ) ) { return "Каждая строка должна содержать две координаты"; @@ -220,12 +239,12 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.path?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="text" label={"Координаты маршрута *"} name="path" placeholder="55.7558 37.6173 - 55.7539 37.6208" +55.7539 37.6208" multiline rows={4} sx={{ @@ -241,53 +260,53 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.route_sys_number?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" - label={"Системный номер маршрута *"} + label={"Номер маршрута в Говорящем Городе *"} name="route_sys_number" /> ( - option.id === field.value - ) ?? null - } - onChange={(_, value) => { - field.onChange(value?.id ?? ""); - }} - getOptionLabel={(item) => { - return item ? item.heading : ""; - }} - isOptionEqualToValue={(option, value) => { - return option.id === value?.id; - }} - filterOptions={(options, { inputValue }) => { - return options.filter((option) => - option.heading - .toLowerCase() - .includes(inputValue.toLowerCase()) - ); - }} - renderInput={(params) => ( - - )} - /> - )} + control={control} + name="governor_appeal" + defaultValue={null} + render={({ field }) => ( + option.id === field.value + ) ?? null + } + onChange={(_, value) => { + field.onChange(value?.id ?? ""); + }} + getOptionLabel={(item) => { + return item ? item.heading : ""; + }} + isOptionEqualToValue={(option, value) => { + return option.id === value?.id; + }} + filterOptions={(options, { inputValue }) => { + return options.filter((option) => + option.heading + .toLowerCase() + .includes(inputValue.toLowerCase()) + ); + }} + renderInput={(params) => ( + + )} + /> + )} /> { helperText={(errors as any)?.scale_min?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Масштаб (мин)"} name="scale_min" @@ -314,7 +333,7 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.scale_max?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Масштаб (макс)"} name="scale_max" @@ -329,7 +348,7 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.rotate?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Поворот"} name="rotate" @@ -344,7 +363,7 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.center_latitude?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Центр. широта"} name="center_latitude" @@ -359,12 +378,11 @@ export const RouteEdit = observer(() => { helperText={(errors as any)?.center_longitude?.message} margin="normal" fullWidth - slotProps={{inputLabel: {shrink: true}}} + slotProps={{ inputLabel: { shrink: true } }} type="number" label={"Центр. долгота"} name="center_longitude" /> - {routeId && ( @@ -390,9 +408,9 @@ export const RouteEdit = observer(() => { )} - -