264 lines
6.8 KiB
TypeScript
264 lines
6.8 KiB
TypeScript
import { authInstance, languageInstance, mobxFetch } from "@shared";
|
|
import { makeAutoObservable, runInAction } from "mobx";
|
|
import { getVehicleSessionsApi } from "./api";
|
|
import { Vehicle, VehicleMaintenanceSession } from "./types";
|
|
|
|
export type { Vehicle, VehicleMaintenanceSession } from "./types";
|
|
|
|
class VehicleStore {
|
|
vehicles: {
|
|
data: Vehicle[];
|
|
loaded: boolean;
|
|
} = {
|
|
data: [],
|
|
loaded: false,
|
|
};
|
|
vehicle: Record<string, Vehicle> = {};
|
|
vehicleSessions: VehicleMaintenanceSession[] | null = null;
|
|
vehicleSessionsLoading = false;
|
|
vehicleSessionsError: string | null = null;
|
|
|
|
constructor() {
|
|
makeAutoObservable(this);
|
|
}
|
|
|
|
private normalizeVehicleItem = (item: any): Vehicle => {
|
|
if (item && typeof item === "object" && "vehicle" in item) {
|
|
return {
|
|
vehicle: item.vehicle ?? {},
|
|
device_status: item.device_status,
|
|
} as Vehicle;
|
|
}
|
|
|
|
return {
|
|
vehicle: item ?? {},
|
|
} as Vehicle;
|
|
};
|
|
|
|
private mergeVehicleInCaches = (updatedVehicle: any) => {
|
|
if (!updatedVehicle) return;
|
|
|
|
const updatedId = updatedVehicle.id;
|
|
const updatedUuid = updatedVehicle.uuid;
|
|
|
|
const mergeItem = (item: Vehicle): Vehicle => ({
|
|
...item,
|
|
vehicle: {
|
|
...item.vehicle,
|
|
...updatedVehicle,
|
|
},
|
|
});
|
|
|
|
this.vehicles.data = this.vehicles.data.map((item) => {
|
|
const sameId = updatedId != null && item.vehicle.id === updatedId;
|
|
const sameUuid =
|
|
updatedUuid != null &&
|
|
item.vehicle.uuid != null &&
|
|
item.vehicle.uuid === updatedUuid;
|
|
|
|
if (!sameId && !sameUuid) return item;
|
|
|
|
return mergeItem(item);
|
|
});
|
|
|
|
if (updatedId != null) {
|
|
const existing = this.vehicle[updatedId];
|
|
this.vehicle[updatedId] = existing
|
|
? mergeItem(existing)
|
|
: ({ vehicle: updatedVehicle } as Vehicle);
|
|
return;
|
|
}
|
|
|
|
if (updatedUuid != null) {
|
|
const entry = Object.entries(this.vehicle).find(
|
|
([, item]) => item.vehicle.uuid === updatedUuid,
|
|
);
|
|
|
|
if (entry) {
|
|
const [key, item] = entry;
|
|
this.vehicle[key] = mergeItem(item);
|
|
}
|
|
}
|
|
};
|
|
|
|
getVehicles = async () => {
|
|
const response = await languageInstance("ru").get(`/vehicle`);
|
|
const vehiclesList = Array.isArray(response.data)
|
|
? response.data
|
|
: Array.isArray(response.data?.vehicles)
|
|
? response.data.vehicles
|
|
: [];
|
|
|
|
runInAction(() => {
|
|
this.vehicles.data = vehiclesList.map(this.normalizeVehicleItem);
|
|
this.vehicles.loaded = true;
|
|
});
|
|
};
|
|
|
|
deleteVehicle = async (id: number) => {
|
|
await languageInstance("ru").delete(`/vehicle/${id}`);
|
|
|
|
runInAction(() => {
|
|
this.vehicles.data = this.vehicles.data.filter(
|
|
(vehicle) => vehicle.vehicle.id !== id,
|
|
);
|
|
});
|
|
};
|
|
|
|
getVehicle = async (id: number) => {
|
|
const response = await languageInstance("ru").get(`/vehicle/${id}`);
|
|
const normalizedVehicle = this.normalizeVehicleItem(response.data);
|
|
|
|
runInAction(() => {
|
|
this.vehicle[id] = normalizedVehicle;
|
|
});
|
|
};
|
|
|
|
createVehicle = async (
|
|
tailNumber: string,
|
|
type: number,
|
|
carrier: string,
|
|
carrierId: number,
|
|
model?: string,
|
|
) => {
|
|
const payload: Record<string, unknown> = {
|
|
tail_number: tailNumber,
|
|
type,
|
|
carrier,
|
|
carrier_id: carrierId,
|
|
};
|
|
// TODO: когда будет бекенд — добавить model в payload и в ответ
|
|
if (model != null && model !== "") payload.model = model;
|
|
const response = await languageInstance("ru").post("/vehicle", payload);
|
|
const normalizedVehicle = this.normalizeVehicleItem(response.data);
|
|
|
|
runInAction(() => {
|
|
this.vehicles.data.push(normalizedVehicle);
|
|
if (normalizedVehicle.vehicle?.id != null) {
|
|
this.vehicle[normalizedVehicle.vehicle.id] = normalizedVehicle;
|
|
}
|
|
});
|
|
};
|
|
|
|
editVehicleData: {
|
|
tail_number: string;
|
|
type: number;
|
|
carrier: string;
|
|
carrier_id: number;
|
|
model: string;
|
|
snapshot_update_blocked: boolean;
|
|
} = {
|
|
tail_number: "",
|
|
type: 0,
|
|
carrier: "",
|
|
carrier_id: 0,
|
|
model: "",
|
|
snapshot_update_blocked: false,
|
|
};
|
|
|
|
setEditVehicleData = (data: {
|
|
tail_number: string;
|
|
type: number;
|
|
carrier: string;
|
|
carrier_id: number;
|
|
model?: string;
|
|
snapshot_update_blocked?: boolean;
|
|
}) => {
|
|
this.editVehicleData = {
|
|
...this.editVehicleData,
|
|
...data,
|
|
};
|
|
};
|
|
|
|
editVehicle = async (
|
|
id: number,
|
|
data: {
|
|
tail_number: string;
|
|
type: number;
|
|
carrier: string;
|
|
carrier_id: number;
|
|
model?: string;
|
|
snapshot_update_blocked?: boolean;
|
|
},
|
|
) => {
|
|
const payload: Record<string, unknown> = {
|
|
tail_number: data.tail_number,
|
|
type: data.type,
|
|
carrier: data.carrier,
|
|
carrier_id: data.carrier_id,
|
|
};
|
|
if (data.model != null && data.model !== "") payload.model = data.model;
|
|
if (data.snapshot_update_blocked != null)
|
|
payload.snapshot_update_blocked = data.snapshot_update_blocked;
|
|
const response = await languageInstance("ru").patch(
|
|
`/vehicle/${id}`,
|
|
payload,
|
|
);
|
|
const normalizedVehicle = this.normalizeVehicleItem(response.data);
|
|
const updatedVehiclePayload = {
|
|
...normalizedVehicle.vehicle,
|
|
model: normalizedVehicle.vehicle.model ?? data.model,
|
|
snapshot_update_blocked:
|
|
normalizedVehicle.vehicle.snapshot_update_blocked ??
|
|
data.snapshot_update_blocked,
|
|
};
|
|
|
|
runInAction(() => {
|
|
this.mergeVehicleInCaches({
|
|
...updatedVehiclePayload,
|
|
id,
|
|
});
|
|
});
|
|
};
|
|
|
|
setMaintenanceMode = async (uuid: string, enabled: boolean) => {
|
|
const response = await authInstance.post(
|
|
`/devices/${uuid}/maintenance-mode`,
|
|
{
|
|
enabled,
|
|
},
|
|
);
|
|
const normalizedVehicle = this.normalizeVehicleItem(response.data);
|
|
|
|
runInAction(() => {
|
|
this.mergeVehicleInCaches({
|
|
...normalizedVehicle.vehicle,
|
|
uuid,
|
|
maintenance_mode_on:
|
|
normalizedVehicle.vehicle.maintenance_mode_on ?? enabled,
|
|
});
|
|
});
|
|
};
|
|
|
|
setDemoMode = async (uuid: string, enabled: boolean) => {
|
|
const response = await authInstance.post(`/devices/${uuid}/demo-mode`, {
|
|
enabled,
|
|
});
|
|
const normalizedVehicle = this.normalizeVehicleItem(response.data);
|
|
|
|
runInAction(() => {
|
|
this.mergeVehicleInCaches({
|
|
...normalizedVehicle.vehicle,
|
|
uuid,
|
|
demo_mode_enabled:
|
|
normalizedVehicle.vehicle.demo_mode_enabled ?? enabled,
|
|
});
|
|
});
|
|
};
|
|
|
|
getVehicleSessions = mobxFetch<
|
|
number,
|
|
VehicleMaintenanceSession[],
|
|
VehicleStore
|
|
>({
|
|
store: this,
|
|
value: "vehicleSessions",
|
|
loading: "vehicleSessionsLoading",
|
|
error: "vehicleSessionsError",
|
|
resetValue: true,
|
|
fn: getVehicleSessionsApi,
|
|
});
|
|
}
|
|
|
|
export const vehicleStore = new VehicleStore();
|