([]);
const [isLoading, setIsLoading] = useState(false);
+ const [paginationModel, setPaginationModel] = useState({
+ page: 0,
+ pageSize: 50,
+ });
const { language } = languageStore;
useEffect(() => {
@@ -75,25 +79,6 @@ export const StationListPage = observer(() => {
);
},
},
- {
- field: "direction",
- headerName: "Направление",
- width: 200,
- align: "center",
- headerAlign: "center",
-
- renderCell: (params: GridRenderCellParams) => {
- return (
-
- {params.row.direction ? "Прямой" : "Обратный"}
-
- );
- },
- },
{
field: "actions",
headerName: "Действия",
@@ -134,7 +119,6 @@ export const StationListPage = observer(() => {
},
];
- // Фильтрация станций по выбранному городу
const filteredStations = () => {
const { selectedCityId } = selectedCityStore;
if (!selectedCityId) {
@@ -149,7 +133,6 @@ export const StationListPage = observer(() => {
id: station.id,
name: station.name,
description: station.description,
- direction: station.direction,
}));
return (
@@ -162,29 +145,75 @@ export const StationListPage = observer(() => {
- 0 ? 1 : 0 }}
- >
+
{
- setIds(Array.from(newSelection.ids) as number[]);
+ paginationModel={paginationModel}
+ onPaginationModelChange={setPaginationModel}
+ pageSizeOptions={[50]}
+ onRowSelectionModelChange={(newSelection: any) => {
+ if (Array.isArray(newSelection)) {
+ const selectedIds = newSelection
+ .map((id: string | number) => {
+ const numId =
+ typeof id === "string"
+ ? Number.parseInt(id, 10)
+ : Number(id);
+ return numId;
+ })
+ .filter(
+ (id: number) =>
+ !Number.isNaN(id) && id !== null && id !== undefined
+ );
+ setIds(selectedIds);
+ } else if (
+ newSelection &&
+ typeof newSelection === "object" &&
+ "ids" in newSelection
+ ) {
+ const idsSet = newSelection.ids as Set;
+ const selectedIds = Array.from(idsSet)
+ .map((id: string | number) => {
+ const numId =
+ typeof id === "string"
+ ? Number.parseInt(id, 10)
+ : Number(id);
+ return numId;
+ })
+ .filter(
+ (id: number) =>
+ !Number.isNaN(id) && id !== null && id !== undefined
+ );
+ setIds(selectedIds);
+ } else {
+ setIds([]);
+ }
}}
- hideFooter
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
slots={{
noRowsOverlay: () => (
diff --git a/src/pages/Station/StationPreviewPage/index.tsx b/src/pages/Station/StationPreviewPage/index.tsx
index 6abfa92..14f5827 100644
--- a/src/pages/Station/StationPreviewPage/index.tsx
+++ b/src/pages/Station/StationPreviewPage/index.tsx
@@ -67,21 +67,6 @@ export const StationPreviewPage = observer(() => {
{stationPreview[id!]?.[language]?.data.system_name}
-
-
Направление
-
- {stationPreview[id!]?.[language]?.data.direction
- ? "Прямой"
- : "Обратный"}
-
-
-
{stationPreview[id!]?.[language]?.data.address && (
Адрес
diff --git a/src/pages/User/UserListPage/index.tsx b/src/pages/User/UserListPage/index.tsx
index ae87cd8..3ab95fa 100644
--- a/src/pages/User/UserListPage/index.tsx
+++ b/src/pages/User/UserListPage/index.tsx
@@ -16,6 +16,10 @@ export const UserListPage = observer(() => {
const [rowId, setRowId] = useState(null);
const [ids, setIds] = useState([]);
const [isLoading, setIsLoading] = useState(false);
+ const [paginationModel, setPaginationModel] = useState({
+ page: 0,
+ pageSize: 50,
+ });
useEffect(() => {
const fetchUsers = async () => {
@@ -126,29 +130,39 @@ export const UserListPage = observer(() => {
- 0 ? 1 : 0 }}
- >
-
-
+ {ids.length > 0 && (
+
+
+
+ )}
{
- setIds(Array.from(newSelection.ids) as number[]);
+ paginationModel={paginationModel}
+ onPaginationModelChange={setPaginationModel}
+ pageSizeOptions={[50]}
+ onRowSelectionModelChange={(newSelection: any) => {
+ if (Array.isArray(newSelection)) {
+ const selectedIds = newSelection.map((id: string | number) => Number(id));
+ setIds(selectedIds);
+ } else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
+ const idsSet = newSelection.ids as Set;
+ const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
+ setIds(selectedIds);
+ } else {
+ setIds([]);
+ }
}}
- hideFooter
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
slots={{
noRowsOverlay: () => (
diff --git a/src/pages/Vehicle/VehicleEditPage/index.tsx b/src/pages/Vehicle/VehicleEditPage/index.tsx
index 55a5bd4..11d7fc5 100644
--- a/src/pages/Vehicle/VehicleEditPage/index.tsx
+++ b/src/pages/Vehicle/VehicleEditPage/index.tsx
@@ -6,6 +6,7 @@ import {
FormControl,
InputLabel,
Button,
+ Box,
} from "@mui/material";
import { observer } from "mobx-react-lite";
import { ArrowLeft, Loader2, Save } from "lucide-react";
@@ -16,6 +17,7 @@ import {
languageStore,
VEHICLE_TYPES,
vehicleStore,
+ LoadingSpinner,
} from "@shared";
import { toast } from "react-toastify";
@@ -31,6 +33,8 @@ export const VehicleEditPage = observer(() => {
} = vehicleStore;
const { getCarriers } = carrierStore;
const { language } = languageStore;
+ const [isLoading, setIsLoading] = useState(false);
+ const [isLoadingData, setIsLoadingData] = useState(true);
useEffect(() => {
// Устанавливаем русский язык при загрузке страницы
@@ -38,31 +42,58 @@ export const VehicleEditPage = observer(() => {
}, []);
useEffect(() => {
- (async () => {
- await getVehicle(Number(id));
- await getCarriers(language);
+ const fetchAndSetVehicleData = async () => {
+ if (!id) {
+ setIsLoadingData(false);
+ return;
+ }
- setEditVehicleData({
- tail_number: vehicle[Number(id)]?.vehicle.tail_number,
- type: vehicle[Number(id)]?.vehicle.type,
- carrier: vehicle[Number(id)]?.vehicle.carrier,
- carrier_id: vehicle[Number(id)]?.vehicle.carrier_id,
- });
- })();
+ setIsLoadingData(true);
+ try {
+ await getVehicle(Number(id));
+ await getCarriers(language);
+
+ setEditVehicleData({
+ tail_number: vehicle[Number(id)]?.vehicle.tail_number,
+ type: vehicle[Number(id)]?.vehicle.type,
+ carrier: vehicle[Number(id)]?.vehicle.carrier,
+ carrier_id: vehicle[Number(id)]?.vehicle.carrier_id,
+ });
+ } finally {
+ setIsLoadingData(false);
+ }
+ };
+
+ fetchAndSetVehicleData();
}, [id, language]);
- const [isLoading, setIsLoading] = useState(false);
const handleEdit = async () => {
try {
setIsLoading(true);
await editVehicle(Number(id), editVehicleData);
toast.success("Транспортное средство успешно обновлено");
- navigate("/vehicle");
+ navigate("/devices");
} catch (error) {
toast.error("Ошибка при обновлении транспортного средства");
} finally {
setIsLoading(false);
}
};
+
+ if (isLoadingData) {
+ return (
+
+
+
+ );
+ }
+
return (
diff --git a/src/pages/Vehicle/VehicleListPage/index.tsx b/src/pages/Vehicle/VehicleListPage/index.tsx
index 5b23808..5f0a7df 100644
--- a/src/pages/Vehicle/VehicleListPage/index.tsx
+++ b/src/pages/Vehicle/VehicleListPage/index.tsx
@@ -18,6 +18,10 @@ export const VehicleListPage = observer(() => {
const [rowId, setRowId] = useState(null);
const [ids, setIds] = useState([]);
const [isLoading, setIsLoading] = useState(false);
+ const [paginationModel, setPaginationModel] = useState({
+ page: 0,
+ pageSize: 50,
+ });
const { language } = languageStore;
useEffect(() => {
@@ -148,29 +152,39 @@ export const VehicleListPage = observer(() => {
/>
- 0 ? 1 : 0 }}
- >
-
-
+ {ids.length > 0 && (
+
+
+
+ )}
{
- setIds(Array.from(newSelection.ids) as number[]);
+ paginationModel={paginationModel}
+ onPaginationModelChange={setPaginationModel}
+ pageSizeOptions={[50]}
+ onRowSelectionModelChange={(newSelection: any) => {
+ if (Array.isArray(newSelection)) {
+ const selectedIds = newSelection.map((id: string | number) => Number(id));
+ setIds(selectedIds);
+ } else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
+ const idsSet = newSelection.ids as Set;
+ const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
+ setIds(selectedIds);
+ } else {
+ setIds([]);
+ }
}}
- hideFooter
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
slots={{
noRowsOverlay: () => (
diff --git a/src/shared/store/StationsStore/index.ts b/src/shared/store/StationsStore/index.ts
index 4fc37a8..7f4bbd7 100644
--- a/src/shared/store/StationsStore/index.ts
+++ b/src/shared/store/StationsStore/index.ts
@@ -13,7 +13,6 @@ type StationLanguageData = {
type StationCommonData = {
city_id: number;
- direction: boolean;
description: string;
icon: string;
latitude: number;
@@ -44,7 +43,6 @@ type Station = {
city: string;
city_id: number;
description: string;
- direction: boolean;
icon: string;
latitude: number;
longitude: number;
@@ -123,7 +121,6 @@ class StationsStore {
common: {
city: "",
city_id: 0,
- direction: false,
description: "",
icon: "",
latitude: 0,
@@ -169,7 +166,6 @@ class StationsStore {
common: {
city: "",
city_id: 0,
- direction: false,
description: "",
icon: "",
latitude: 0,
@@ -252,7 +248,6 @@ class StationsStore {
common: {
city: ruResponse.data.city,
city_id: ruResponse.data.city_id,
- direction: ruResponse.data.direction,
description: ruResponse.data.description,
icon: ruResponse.data.icon,
latitude: ruResponse.data.latitude,
@@ -277,7 +272,6 @@ class StationsStore {
editStation = async (id: number) => {
const commonDataPayload = {
city_id: this.editStationData.common.city_id,
- direction: this.editStationData.common.direction,
icon: this.editStationData.common.icon,
latitude: this.editStationData.common.latitude,
longitude: this.editStationData.common.longitude,
@@ -405,7 +399,6 @@ class StationsStore {
const { language } = languageStore;
let commonDataPayload: Partial = {
city_id: this.createStationData.common.city_id,
- direction: this.createStationData.common.direction,
icon: this.createStationData.common.icon,
latitude: this.createStationData.common.latitude,
longitude: this.createStationData.common.longitude,
@@ -479,7 +472,6 @@ class StationsStore {
common: {
city: "",
city_id: 0,
- direction: false,
icon: "",
latitude: 0,
description: "",
@@ -526,7 +518,6 @@ class StationsStore {
common: {
city: "",
city_id: 0,
- direction: false,
description: "",
icon: "",
latitude: 0,
@@ -575,7 +566,6 @@ class StationsStore {
// Формируем commonDataPayload как в editStation, с обновленными transfers
const commonDataPayload = {
city_id: stationData.city_id,
- direction: stationData.direction,
latitude: stationData.latitude,
longitude: stationData.longitude,
offset_x: stationData.offset_x,
diff --git a/src/widgets/DevicesTable/index.tsx b/src/widgets/DevicesTable/index.tsx
index f2dd807..ebc103c 100644
--- a/src/widgets/DevicesTable/index.tsx
+++ b/src/widgets/DevicesTable/index.tsx
@@ -5,18 +5,18 @@ import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
-import { Check, Copy, RotateCcw, Trash2, X } from "lucide-react";
+import { Check, Copy, Pencil, RotateCcw, Trash2, X } from "lucide-react";
import {
authInstance,
devicesStore,
Modal,
snapshotStore,
vehicleStore,
+ Vehicle,
} from "@shared";
import { useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { Button, Checkbox, Typography } from "@mui/material";
-import { Vehicle } from "@shared";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";
import { DeleteModal } from "@widgets";
@@ -47,6 +47,7 @@ const formatDate = (dateString: string | null) => {
};
type TableRowData = {
+ vehicle_id: number;
tail_number: number;
online: boolean;
lastUpdate: string | null;
@@ -56,6 +57,7 @@ type TableRowData = {
device_uuid: string | null;
};
function createData(
+ vehicle_id: number,
tail_number: number,
online: boolean,
lastUpdate: string | null,
@@ -65,6 +67,7 @@ function createData(
device_uuid: string | null
): TableRowData {
return {
+ vehicle_id,
tail_number,
online,
lastUpdate,
@@ -80,6 +83,7 @@ const transformDevicesToRows = (vehicles: Vehicle[]): TableRowData[] => {
const uuid = vehicle.vehicle.uuid;
if (!uuid)
return {
+ vehicle_id: vehicle.vehicle.id,
tail_number: vehicle.vehicle.tail_number,
online: false,
lastUpdate: null,
@@ -89,6 +93,7 @@ const transformDevicesToRows = (vehicles: Vehicle[]): TableRowData[] => {
device_uuid: null,
};
return createData(
+ vehicle.vehicle.id,
vehicle.vehicle.tail_number,
vehicle.device_status?.online ?? false,
vehicle.device_status?.last_update ?? null,
@@ -404,37 +409,54 @@ export const DevicesTable = observer(() => {
-
))}