Merge branch 'develop' into 'feature/gasht_submit'

# Conflicts:
#   src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo.jsx
This commit is contained in:
AmirHossein Mahmoodi
2025-01-06 09:41:42 +00:00
45 changed files with 1475 additions and 169 deletions

View File

@@ -1,30 +1,36 @@
"use client";
import { useEffect, useState, memo } from "react";
import useRequest from "@/lib/hooks/useRequest";
import { useEffect } from "react";
import { ACTIVITY_LOG } from "@/core/utils/routes";
const ActivityCodeLog = ({ activity_code }) => {
const ActivityCodeLog = memo(({ activity_code }) => {
const requestServer = useRequest({ notificationShow: false });
const [hasLogged, setHasLogged] = useState(false);
useEffect(() => {
if (!activity_code) return;
if (!activity_code || hasLogged) return;
const fetchSubItems = async () => {
const controller = new AbortController();
const fetchActivityLog = async () => {
try {
await requestServer(ACTIVITY_LOG, "post", {
data: {
activityCode: activity_code,
},
data: { activityCode: activity_code },
signal: controller.signal,
});
} catch (error) {
console.error(error); // Always helpful to log the error for debugging.
}
setHasLogged(true);
} catch (error) {}
};
fetchSubItems();
}, [activity_code, requestServer]);
fetchActivityLog();
return null; // Ensure the component still renders something.
};
return () => {
controller.abort();
};
}, [activity_code, hasLogged, requestServer]);
return null;
});
export default ActivityCodeLog;

View File

@@ -23,6 +23,7 @@ const DataTable_Main = (props) => {
table_title,
RowActions,
specific_data,
specialFilter,
} = props;
const flatColumns = flattenArrayOfObjects(columns, "columns");
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
@@ -33,29 +34,34 @@ const DataTable_Main = (props) => {
};
const fetchUrl = useMemo(() => {
const params = new URLSearchParams();
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
params.set("size", pagination.pageSize);
const isValueEmpty = (value) => {
if (Array.isArray(value)) {
return value.length === 0 || value.every((v) => v === "");
}
return value === "" || value === null || value === undefined;
};
if (specialFilter) {
const filteredSpecialFilterData = Object.values(specialFilter).filter(
(filter) => !isValueEmpty(filter.value)
);
params.set("filters", JSON.stringify(filteredSpecialFilterData || []));
} else {
const filteredFilterData = Object.values(filterData)
.filter((filter) => !isValueEmpty(filter.value))
.map(({ filterMode, id, ...rest }) => ({
...rest,
id: id.replace(/__/g, "."),
fn: filterMode,
}));
const filteredFilterData = Object.values(filterData)
.filter((filter) => !isValueEmpty(filter.value))
.map(({ filterMode, id, ...rest }) => ({
...rest,
id: id.replace(/__/g, "."),
fn: filterMode,
}));
const params = new URLSearchParams();
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
params.set("size", pagination.pageSize);
params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData));
params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData));
}
params.set("sorting", JSON.stringify(sortData));
return `${table_url}?${params}`;
}, [table_url, filterData, pagination, columns, sortData]);
}, [table_url, filterData, pagination, columns, sortData, specialFilter]);
const fetcher = async (url) => {
try {
const response = await request(url);
@@ -143,5 +149,4 @@ const DataTable_Main = (props) => {
/>
);
};
export default DataTable_Main;

View File

@@ -23,8 +23,8 @@ const createCustomIcon = (size, iconUrl, labelText, color) => {
</div>
<div style="width: 5px; height: 20px; background: ${color}; margin: auto;border-bottom-left-radius: 50%; border-bottom-right-radius: 50%;"></div>
</div>`,
iconSize: [100, 50], // Adjust icon size to fit your content
iconAnchor: [50, 25], // Adjust to position the marker correctly
iconSize: [50, 50],
iconAnchor: [25, 50],
});
}

View File

@@ -23,8 +23,8 @@ const createCustomIcon = (size, iconUrl, labelText, color) => {
</div>
<div style="width: 5px; height: 20px; background: ${color}; margin: auto;border-bottom-left-radius: 50%; border-bottom-right-radius: 50%;"></div>
</div>`,
iconSize: [100, 50], // Adjust icon size to fit your content
iconAnchor: [50, 25], // Adjust to position the marker correctly
iconSize: [50, 50],
iconAnchor: [25, 50],
});
}
return L.icon({
@@ -111,6 +111,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
setStartPosition({ lat: center.lat, lng: center.lng });
setIsStartLocked(true);
setStartIconColor("#1CAC66");
map.panBy([25, 25])
}
},
}}
@@ -182,6 +183,13 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
setEndPosition({ lat: center.lat, lng: center.lng });
setIsEndLocked(true);
setEndIconColor("#D13131");
map.fitBounds(
[
startPosition,
map.getCenter(),
],
{ paddingTopLeft: [16, 16], paddingBottomRight: [16, 16] }
);
}
},
}}

View File

@@ -59,9 +59,11 @@ function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperTex
},
}}
/>
<FormHelperText id="component-helper-text" sx={{ color: error ? "#d32f2f" : "unset" }}>
{helperText ? helperText : ""}
</FormHelperText>
{helperText ? (
<FormHelperText id="component-helper-text" sx={{ color: error ? "#d32f2f" : "unset" }}>
{helperText}
</FormHelperText>
) : null}
</LocalizationProvider>
</Box>
);

View File

@@ -64,9 +64,11 @@ function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperTex
},
}}
/>
<FormHelperText id="component-helper-text" sx={{ color: error ? "#d32f2f" : "unset" }}>
{helperText ? helperText : ""}
</FormHelperText>
{helperText ? (
<FormHelperText id="component-helper-text" sx={{ color: error ? "#d32f2f" : "unset" }}>
{helperText}
</FormHelperText>
) : null}
</LocalizationProvider>
</Box>
);

View File

@@ -2,16 +2,24 @@
import { Box, Typography } from "@mui/material";
import { usePermissions } from "@/lib/hooks/usePermissions";
import { useEffect, useState } from "react";
function WithPermission({ children, permission_name }) {
const { data, error, isLoading } = usePermissions();
const [cachedData, setCachedData] = useState(null);
if (error || isLoading || !data || !permission_name) {
useEffect(() => {
if (data) {
setCachedData(data);
}
}, [data]);
if (error || isLoading || !cachedData || !permission_name) {
return null;
}
const hasPermission =
permission_name.includes("all") || permission_name.some((permission) => data.includes(permission));
permission_name.includes("all") || permission_name.some((permission) => cachedData.includes(permission));
if (!hasPermission) {
return (

View File

@@ -54,6 +54,7 @@ export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete";
export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore";
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";
// activity code log
export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity";

View File

@@ -1,5 +1,6 @@
"use client";
import { createTheme } from "@mui/material";
import { grey } from '@mui/material/colors';
const theme = createTheme({
direction: "rtl",
@@ -16,6 +17,9 @@ const theme = createTheme({
main: "#015688",
contrastText: "#fff",
},
secondary: {
main: grey[700],
}
},
components: {
MuiBackdrop: {