Feature/amiriis mission new tasks

This commit is contained in:
AmirHossein Mahmoodi
2025-07-28 07:35:45 +00:00
parent fc9706bb0e
commit c6ccc39829
62 changed files with 2561 additions and 894 deletions

View File

@@ -51,15 +51,16 @@ const DataTable_Main = (props) => {
const params = new URLSearchParams();
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
params.set("size", pagination.pageSize);
if (specialFilter) {
const filteredSpecialFilterData = Object.values(specialFilter).filter(
(filter) => !isArrayEmpty(filter.value)
);
params.set("filters", JSON.stringify(filteredSpecialFilterData || []));
} else {
const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty);
params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData));
}
const filteredSpecialFilterData = specialFilter
? Object.values(specialFilter).filter((filter) => !isArrayEmpty(filter.value))
: [];
const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty);
const combinedFilters = [...filteredSpecialFilterData, ...filteredFilterData];
params.set("filters", JSON.stringify(combinedFilters));
params.set(
"sorting",
JSON.stringify(

View File

@@ -9,7 +9,18 @@ import { parseISO } from "date-fns";
const parseIfString = (val) =>
val instanceof Date ? val : typeof val === "string" && val !== "" ? parseISO(val) : null;
function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperText, placeholder, error, label }) {
function MuiTimePicker({
value,
setFieldValue,
views = ["hours", "minutes"],
name,
minTime,
maxTime,
helperText,
placeholder,
error,
label,
}) {
// Ensure value, minTime, maxTime are Date objects
const parsedValue = parseIfString(value);
const parsedMinTime = parseIfString(minTime);
@@ -28,9 +39,10 @@ function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperTex
id={name}
closeOnSelect
label={label}
format="HH:mm"
ampm={false}
timeSteps={{ hours: 1, minutes: 5 }}
views={["hours", "minutes"]}
views={views}
name={name}
onChange={(newValue) => {
setFieldValue(name, newValue);

View File

@@ -1,11 +1,10 @@
"use client";
import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import { Autocomplete, CircularProgress, TextField } from "@mui/material";
import { useEffect, useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import { debounce } from "@mui/material/utils";
import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) => {
const RahdarCode = ({ title = "راهدار", rahdarsCode, setRahdarsCode, error, multiple = true }) => {
const [inputValue, setInputValue] = useState(""); // مدیریت مقدار تایپ‌شده
const [options, setOptions] = useState([]);
const [loading, setLoading] = useState(false);
@@ -13,30 +12,27 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) =>
useEffect(() => {
const fetchRahdarCodes = (inputValue, controller) => {
const debouncer = debounce((query) => {
if ((query || "").length < 3) {
setOptions([]);
return;
}
setLoading(true);
requestServer(`${GET_RAHDARANS_LIST_SEARCH}?code=${query}`, "get", {
requestOptions: { signal: controller.signal },
if ((inputValue || "").length < 3) {
setOptions([]);
return;
}
setLoading(true);
requestServer(`${GET_RAHDARANS_LIST_SEARCH}?code=${inputValue}`, "get", {
requestOptions: { signal: controller.signal },
})
.then((response) => {
const combinedArray = rahdarsCode
? [...rahdarsCode, ...response.data.data]
: [...response.data.data];
const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
setOptions(uniqueArray || []);
})
.then((response) => {
const combinedArray = rahdarsCode
? [...rahdarsCode, ...response.data.data]
: [...response.data.data];
const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
setOptions(uniqueArray || []);
})
.catch(() => {
setOptions([]);
})
.finally(() => {
setLoading(false);
});
}, 500);
debouncer(inputValue);
.catch(() => {
setOptions([]);
})
.finally(() => {
setLoading(false);
});
};
const controller = new AbortController();
@@ -64,17 +60,17 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) =>
return option.code === (value?.code || value);
}}
loading={loading}
loadingText="درحال جستجوی کد راهدار"
loadingText={`درحال جستجوی کد ${title}`}
noOptionsText={
(inputValue || "").length < 3 ? "حداقل سه رقم از کد راهدار را وارد کنید" : "کد راهداری یافت نشد"
(inputValue || "").length < 3 ? `حداقل سه رقم کد ملی ${title} را وارد کنید` : `${title}ی یافت نشد`
}
fullWidth
renderInput={(params) => (
<TextField
{...params}
label={multiple ? "راهداران" : "راهدار"}
label={multiple ? `${title}ان` : `${title}`}
fullWidth
placeholder={multiple ? "کد راهداران را وارد کنید" : "کد راهدار را وارد کنید"}
placeholder={multiple ? `کد ملی ${title}ان را وارد کنید` : `کد ملی ${title} را وارد کنید`}
error={!!error}
helperText={error?.message}
InputLabelProps={{

View File

@@ -0,0 +1,93 @@
"use client";
import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import { Autocomplete, CircularProgress, TextField } from "@mui/material";
import { useEffect, useState } from "react";
const RahdarNameOrCode = ({ title = "راهدار", rahdarsName, setRahdarsName, error, multiple = true }) => {
const [inputValue, setInputValue] = useState(""); // مدیریت مقدار تایپ‌شده
const [options, setOptions] = useState([]);
const [loading, setLoading] = useState(false);
const requestServer = useRequest();
useEffect(() => {
const fetchRahdarNames = (inputValue, controller) => {
if ((inputValue || "").length < 3) {
setOptions([]);
return;
}
setLoading(true);
requestServer(`${GET_RAHDARANS_LIST_SEARCH}?search=${inputValue}`, "get", {
requestOptions: { signal: controller.signal },
})
.then((response) => {
const combinedArray = rahdarsName
? [...rahdarsName, ...response.data.data]
: [...response.data.data];
const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
setOptions(uniqueArray || []);
})
.catch(() => {
setOptions([]);
})
.finally(() => {
setLoading(false);
});
};
const controller = new AbortController();
fetchRahdarNames(inputValue, controller);
return () => controller.abort();
}, [inputValue]);
return (
<Autocomplete
multiple={multiple} // قابلیت انتخاب چندگانه داینامیک
value={rahdarsName} // آرایه موارد انتخاب‌شده
size="small"
onChange={(event, newValue) => {
setRahdarsName(multiple ? newValue || [] : newValue || null); // مدیریت حالت چندگانه و تک‌گانه
}}
inputValue={inputValue} // مقدار تایپ‌شده
onInputChange={(event, newInputValue) => {
setInputValue(newInputValue || ""); // به‌روزرسانی مقدار تایپ‌شده
}}
options={options} // گزینه‌های موجود
getOptionLabel={(option) => (typeof option === "string" ? option : `${option.code} - ${option.name}`)}
isOptionEqualToValue={(option, value) => {
if (!value) return false;
if (value === "") return option.code === "";
return option.code === (value?.code || value);
}}
loading={loading}
loadingText={`درحال جستجوی ${title}`}
noOptionsText={(inputValue || "").length < 3 ? `حداقل سه کاراکتر وارد کنید` : `${title}ی یافت نشد`}
fullWidth
renderInput={(params) => (
<TextField
{...params}
label={multiple ? `${title}ان` : `${title}`}
fullWidth
placeholder={
multiple ? `نام یا کدملی ${title}ان را وارد کنید` : `نام یا کدملی ${title} را وارد کنید`
}
error={!!error}
helperText={error?.message}
InputLabelProps={{
shrink: true,
}}
InputProps={{
...params.InputProps,
endAdornment: (
<>
{loading ? <CircularProgress size="25px" color="inherit" /> : null}
{params.InputProps.endAdornment}
</>
),
}}
/>
)}
/>
);
};
export default RahdarNameOrCode;

View File

@@ -1,4 +1,4 @@
export const machineType = [
{ id: "grader", name_fa: "گریدر" },
{ id: "loder", name_fa: "لودر" },
{ id: "گریدر", name_fa: "گریدر" },
{ id: "لودر", name_fa: "لودر" },
];

View File

@@ -0,0 +1,5 @@
export const missionCategoryTypes = [
{ id: 1, name_fa: "فعالیت روزانه" },
{ id: 2, name_fa: "گشت راهداری" },
{ id: 3, name_fa: "واکنش سریع" },
];

View File

@@ -0,0 +1,5 @@
export const missionRegions = [
{ id: 1, name_fa: "داخل شهر" },
{ id: 2, name_fa: "بیرون شهر - داخل محدوده" },
{ id: 3, name_fa: "بیرون شهر - خارج محدوده" },
];

View File

@@ -0,0 +1,4 @@
export const missionTypes = [
{ id: 1, name_fa: "ساعتی" },
{ id: 2, name_fa: "روزانه" },
];

View File

@@ -96,6 +96,7 @@ export const pageMenu = [
label: "ماموریت ها",
type: "menu",
icon: <Mediation sx={{ width: "inherit", height: "inherit" }} />,
badges: [{ key: "mission.total" }],
hasSubitems: true,
Subitems: [
{
@@ -103,6 +104,7 @@ export const pageMenu = [
label: "کارتابل",
type: "page",
route: "/dashboard/road-missions/operator",
badges: [{ key: "mission.request_portal" }],
permissions: [
"manage-request-portal-country",
"manage-request-portal-province",
@@ -114,6 +116,7 @@ export const pageMenu = [
label: "نقلیه",
type: "page",
route: "/dashboard/road-missions/transportation",
badges: [{ key: "mission.transportation" }],
permissions: ["manage-transportation-unit"],
},
{
@@ -121,6 +124,7 @@ export const pageMenu = [
label: "کنترل",
type: "page",
route: "/dashboard/road-missions/control",
badges: [{ key: "mission.control" }],
permissions: ["manage-control-unit"],
},
],

View File

@@ -96,6 +96,7 @@ export const pageMenuDev = [
label: "ماموریت ها",
type: "menu",
icon: <Mediation sx={{ width: "inherit", height: "inherit" }} />,
badges: [{ key: "mission.total" }],
hasSubitems: true,
Subitems: [
{
@@ -103,6 +104,7 @@ export const pageMenuDev = [
label: "کارتابل",
type: "page",
route: "/dashboard/road-missions/operator",
badges: [{ key: "mission.request_portal" }],
permissions: [
"manage-request-portal-country",
"manage-request-portal-province",
@@ -114,6 +116,7 @@ export const pageMenuDev = [
label: "نقلیه",
type: "page",
route: "/dashboard/road-missions/transportation",
badges: [{ key: "mission.transportation" }],
permissions: ["manage-transportation-unit"],
},
{
@@ -121,6 +124,7 @@ export const pageMenuDev = [
label: "کنترل",
type: "page",
route: "/dashboard/road-missions/control",
badges: [{ key: "mission.control" }],
permissions: ["manage-control-unit"],
},
],

View File

@@ -29,57 +29,66 @@ export const ADD_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/store";
export const UPDATE_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/update";
//road patrol
export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_index";
export const EXPORT_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_report";
export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_index";
export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_report";
export const EXPORT_PROVINCE_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrol_reports/province_activity_excel";
export const EXPORT_COUNTRY_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrol_reports/country_activity_excel";
export const DELETE_ROAD_PATROL_SUPERVISOR = api + "/api/v3/road_patrols/delete";
export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator";
export const EXPORT_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator/excel";
export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor";
export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor/excel";
export const DELETE_ROAD_PATROL_SUPERVISOR = api + "/api/v3/road_patrols/operator/delete";
export const GET_CMMS_MACHINE_ROAD_PATROL = api + "/api/v3/road_patrols/machines";
export const GET_ROAD_PATROL_OPERATOR_REPORT = api + "/v2/road_patrols/operator/report";
export const GET_ROAD_PATROL_SUPERVISOR_REPORT = api + "/v2/road_patrols/operator/report";
export const GET_RAHDARAN_ROAD_POTROL = api + "/api/v3/road_patrols/rahdaran";
export const CREATE_PATROL = api + "/api/v3/road_patrols/store";
export const CREATE_PATROL = api + "/api/v3/road_patrols/operator/store";
export const GET_FMS_DATA = api + "/api/v3/fms_vehicle/get_activity";
export const GET_OTP_TOKEN = api + "/api/v3/otp/get_token";
export const GET_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/country_activity";
export const GET_CITY_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/province_activity";
export const GET_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/road_patrols/report/country_activity";
export const GET_CITY_ACTIVITY_REPORT = api + "/api/v3/road_patrols/report/province_activity";
export const EXPORT_COUNTRY_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrols/report/country_activity_excel";
export const EXPORT_PROVINCE_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrols/report/province_activity_excel";
// road items
export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_index";
export const EXPORT_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_report";
export const GET_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_index";
export const EXPORT_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_report";
export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM =
api + "/api/v3/road_item_reports/province_activity_excel_per_item";
export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM =
api + "/api/v3/road_item_reports/country_activity_excel_per_item";
export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
api + "/api/v3/road_item_reports/province_activity_excel_per_sub_item";
export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
api + "/api/v3/road_item_reports/country_activity_excel_per_sub_item";
export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor";
export const EXPORT_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor/excel";
export const GET_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator";
export const EXPORT_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator/excel";
export const GET_ROAD_ITEMS_ITEM = api + "/api/v3/items";
export const GET_ROAD_ITEMS_SUB_ITEM = api + "/api/v3/sub_items";
export const GET_EDARAT_LISTS = api + "/public/contents/edarate_shahri_by_province";
export const CREATE_ROAD_ITEMS = api + "/api/v3/road_items/store";
export const UPDATE_ROAD_ITEMS = api + "/api/v3/road_items/update";
export const VERIFY_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervisor";
export const REJECT_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervisor";
export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete";
export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore";
export const CREATE_ROAD_ITEMS = api + "/api/v3/road_items/operator";
export const UPDATE_ROAD_ITEMS = api + "/api/v3/road_items/operator";
export const VERIFY_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/confirm";
export const REJECT_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/reject";
export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/operator";
export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/reject";
export const GET_CAR_LIST_SEARCH = api + "/api/v3/cmms_machines/search";
export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search";
export const GET_OBSERVED_GASHT_LIST = api + "/api/v3/observed_items/filter";
export const GET_ROAD_ITEMS_REPORT_MAP = api + "/api/v3/road_item_reports/activities_on_map";
export const GET_ROAD_ITEM = api + "/api/v3/road_item_reports/show_on_map";
export const GET_PROVINCE_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/country_activity_per_item";
export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/province_activity_per_item";
export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/country_activity_per_sub_item";
export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/province_activity_per_sub_item";
export const GET_IMAGES_ROAD_ITEM = api + "/api/v3/road_items/files";
export const GET_CMMS_MACHINE_ROAD_ITEM = api + "/api/v3/road_items/machines";
export const GET_RAHDARAN_ROAD_ITEM = api + "/api/v3/road_items/rahdaran";
export const GET_ROAD_ITEMS_REPORT_MAP = api + "/api/v3/road_items/reports/activities_on_map";
export const GET_ROAD_ITEM = api + "/api/v3/road_items/reports/show_on_map";
export const GET_PROVINCE_ACTIVITY_PER_ITEM = api + "/api/v3/road_items/reports/country_activity_per_item";
export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_items/reports/province_activity_per_item";
export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_items/reports/country_activity_per_sub_item";
export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_items/reports/province_activity_per_sub_item";
export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM =
api + "/api/v3/road_items/reports/country_activity_excel_per_item";
export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM =
api + "/api/v3/road_item/reports/province_activity_excel_per_item";
export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
api + "/api/v3/road_items/reports/country_activity_excel_per_sub_item";
export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
api + "/api/v3/road_items/reports/province_activity_excel_per_sub_item";
export const GET_IMAGES_ROAD_ITEM = api + "/api/v3/road_items/details/files";
export const GET_CMMS_MACHINE_ROAD_ITEM = api + "/api/v3/road_items/details/machines";
export const GET_RAHDARAN_ROAD_ITEM = api + "/api/v3/road_items/details/rahdaran";
// damage items
export const GET_RECEIPT_DAMAGE_ITEMS_LIST = api + "/api/v3/damages";
@@ -185,6 +194,7 @@ export const REQUEST_MISSION = api + "/api/v3/missions/request_portal";
export const UPDATE_REQUEST_MISSION = api + "/api/v3/missions/request_portal";
export const DELETE_REQUEST_MISSION = api + "/api/v3/missions/request_portal";
export const GET_RAHDARAN_BY_ID = api + "/api/v3/missions/details/rahdaran";
export const GET_MACHINES_BY_ID = api + "/api/v3/missions/details/machines";
export const ALLOCATE_REQUEST_MISSION = api + "/api/v3/missions/transportation_unit/allocate";
export const DEALLOCATE_REQUEST_MISSION = api + "/api/v3/missions/transportation_unit/deallocate";
export const START_MISSION = api + "/api/v3/missions/control_unit/start";