From 3658345821a62b4fbb4a63905d296685235dae3a Mon Sep 17 00:00:00 2001 From: Amin Ghasempoor Date: Tue, 11 Feb 2025 07:52:38 +0000 Subject: [PATCH] Feature/excel print --- .../roadItems/operator/ExcelPrint/index.jsx | 15 ++-- .../dashboard/roadItems/operator/Toolbar.jsx | 2 +- .../{ => ItemsReports}/ExcelPrint/index.jsx | 18 +++-- .../reports/ItemsReports/ReportLists.jsx | 5 +- .../reports/ItemsReports/TableToolbar.jsx | 10 +++ .../roadItems/reports/ItemsReports/index.jsx | 14 +++- .../SubItemsReports/ExcelPrint/index.jsx | 77 +++++++++++++++++++ .../reports/SubItemsReports/SubItemsList.jsx | 5 +- .../reports/SubItemsReports/TableToolbar.jsx | 10 +++ .../reports/SubItemsReports/index.jsx | 15 +++- .../roadItems/supervisor/ExcelPrint/index.jsx | 16 ++-- .../roadItems/supervisor/Toolbar.jsx | 6 +- .../operator/Actions/Create/index.jsx | 2 +- .../roadPatrols/operator/ExcelPrint/index.jsx | 49 ++++++++---- .../Forms/CreatePatrol/CompeleteRequest.jsx | 6 +- .../Forms/CreatePatrol/PatrolDetailInfo.jsx | 13 +--- .../MachinePerformanceContent.jsx | 9 ++- .../MachinePerformanceForm/StopsInfo.jsx | 9 ++- .../roadPatrols/operator/Toolbar.jsx | 2 +- .../roadPatrols/reports/ExcelPrint/index.jsx | 69 ++++++++++------- .../roadPatrols/reports/ReportLists.jsx | 4 +- .../dashboard/roadPatrols/reports/Toolbar.jsx | 6 +- .../dashboard/roadPatrols/reports/index.jsx | 13 +++- .../supervisor/ExcelPrint/index.jsx | 50 ++++++++---- .../MachinePerformanceContent.jsx | 11 ++- .../MachinePerformanceForm/StopsInfo.jsx | 4 +- .../MachinePerformanceForm/index.jsx | 2 +- .../roadPatrols/supervisor/Toolbar.jsx | 6 +- src/core/components/DataTable/Main.js | 19 +---- .../utils/DataTableFilterDataStructure.js | 9 +++ src/core/utils/isArrayEmpty.js | 6 ++ src/core/utils/routes.js | 26 +++++-- 32 files changed, 373 insertions(+), 135 deletions(-) rename src/components/dashboard/roadItems/reports/{ => ItemsReports}/ExcelPrint/index.jsx (77%) create mode 100644 src/components/dashboard/roadItems/reports/ItemsReports/TableToolbar.jsx create mode 100644 src/components/dashboard/roadItems/reports/SubItemsReports/ExcelPrint/index.jsx create mode 100644 src/components/dashboard/roadItems/reports/SubItemsReports/TableToolbar.jsx create mode 100644 src/core/utils/DataTableFilterDataStructure.js create mode 100644 src/core/utils/isArrayEmpty.js diff --git a/src/components/dashboard/roadItems/operator/ExcelPrint/index.jsx b/src/components/dashboard/roadItems/operator/ExcelPrint/index.jsx index 4cf871f..8862da8 100644 --- a/src/components/dashboard/roadItems/operator/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadItems/operator/ExcelPrint/index.jsx @@ -7,6 +7,8 @@ import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; import { EXPORT_ROAD_ITEMS_OPERATOR_LIST } from "@/core/utils/routes"; import { useTheme } from "@emotion/react"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; const PrintExcel = ({ table, filterData }) => { const theme = useTheme(); @@ -14,8 +16,7 @@ const PrintExcel = ({ table, filterData }) => { const [loading, setLoading] = useState(false); const requestServer = useRequest({ notificationSuccess: true }); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { - if (filter.value) { - // Check if there's an active filter + if (filter.value && (!Array.isArray(filter.value) || filter.value.some((item) => item.trim() !== ""))) { acc.push({ id: key, value: filter.value }); } return acc; @@ -23,10 +24,14 @@ const PrintExcel = ({ table, filterData }) => { const filterParams = useMemo(() => { const params = new URLSearchParams(); - activeFilters.length > 0 && + if (activeFilters.length > 0) { activeFilters.map((filter, index) => { - params.set(`${filter.id}`, filter.value); + const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); }); + } else { + params.set("filters", JSON.stringify([])); + } return params; }, [activeFilters]); @@ -36,7 +41,7 @@ const PrintExcel = ({ table, filterData }) => { requestOptions: { responseType: "blob" }, }) .then((response) => { - const filename = `خروجی کارتابل فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + const filename = `خروجی کارتابل عملیات فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) .catch(() => {}) diff --git a/src/components/dashboard/roadItems/operator/Toolbar.jsx b/src/components/dashboard/roadItems/operator/Toolbar.jsx index 4990a23..d8c6fad 100644 --- a/src/components/dashboard/roadItems/operator/Toolbar.jsx +++ b/src/components/dashboard/roadItems/operator/Toolbar.jsx @@ -6,7 +6,7 @@ import ObservedGashtCreate from "./Actions/ObservedGashtCreate"; const Toolbar = ({ table, filterData, mutate }) => { return ( - {/**/} + diff --git a/src/components/dashboard/roadItems/reports/ExcelPrint/index.jsx b/src/components/dashboard/roadItems/reports/ItemsReports/ExcelPrint/index.jsx similarity index 77% rename from src/components/dashboard/roadItems/reports/ExcelPrint/index.jsx rename to src/components/dashboard/roadItems/reports/ItemsReports/ExcelPrint/index.jsx index eb86d27..0e70403 100644 --- a/src/components/dashboard/roadItems/reports/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadItems/reports/ItemsReports/ExcelPrint/index.jsx @@ -5,7 +5,10 @@ import moment from "jalali-moment"; import FileSaver from "file-saver"; import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; -import { EXPORT_ROAD_ITEMS_OPERATOR_LIST } from "@/core/utils/routes"; +import { + EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM, + EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM, +} from "@/core/utils/routes"; import { useTheme } from "@emotion/react"; const PrintExcel = ({ table, filterData }) => { @@ -15,8 +18,7 @@ const PrintExcel = ({ table, filterData }) => { const requestServer = useRequest({ notificationSuccess: true }); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { if (filter.value) { - // Check if there's an active filter - acc.push({ id: key, value: filter.value }); + acc.push({ id: filter.id, value: filter.value }); } return acc; }, []); @@ -32,11 +34,17 @@ const PrintExcel = ({ table, filterData }) => { const clickHandler = () => { setLoading(true); - requestServer(`${EXPORT_ROAD_ITEMS_OPERATOR_LIST}?${filterParams}`, "get", { + const CountryOrProvince = activeFilters.find((item) => item.id === "province_id"); + const requestUrl = + CountryOrProvince.value === "-1" + ? EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM + : EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM; + + requestServer(`${requestUrl}?${filterParams}`, "get", { requestOptions: { responseType: "blob" }, }) .then((response) => { - const filename = `خروجی کارتابل گزارشات فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + const filename = `خروجی کارتابل گزارشات فعالیت روزانه براساس ایتم تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) .catch(() => {}) diff --git a/src/components/dashboard/roadItems/reports/ItemsReports/ReportLists.jsx b/src/components/dashboard/roadItems/reports/ItemsReports/ReportLists.jsx index 8646e22..80821f8 100644 --- a/src/components/dashboard/roadItems/reports/ItemsReports/ReportLists.jsx +++ b/src/components/dashboard/roadItems/reports/ItemsReports/ReportLists.jsx @@ -2,8 +2,9 @@ import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import { Box } from "@mui/material"; import { useMemo } from "react"; +import Toolbar from "./TableToolbar"; -const ReportLists = ({ itemsList, data }) => { +const ReportLists = ({ itemsList, data, specialFilter }) => { const columns = useMemo(() => { const dynamicColumns = itemsList?.map((item) => ({ @@ -85,6 +86,8 @@ const ReportLists = ({ itemsList, data }) => { page_name={"roadItemReportByItems"} table_name={"roadItemReportByItemsList"} enablePagination={false} + TableToolbar={Toolbar} + specialFilter={specialFilter} /> ); diff --git a/src/components/dashboard/roadItems/reports/ItemsReports/TableToolbar.jsx b/src/components/dashboard/roadItems/reports/ItemsReports/TableToolbar.jsx new file mode 100644 index 0000000..32c4395 --- /dev/null +++ b/src/components/dashboard/roadItems/reports/ItemsReports/TableToolbar.jsx @@ -0,0 +1,10 @@ +import PrintExcel from "./ExcelPrint"; + +const Toolbar = ({ table, filterData }) => { + return ( + <> + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/roadItems/reports/ItemsReports/index.jsx b/src/components/dashboard/roadItems/reports/ItemsReports/index.jsx index 137ed83..1efb794 100644 --- a/src/components/dashboard/roadItems/reports/ItemsReports/index.jsx +++ b/src/components/dashboard/roadItems/reports/ItemsReports/index.jsx @@ -18,6 +18,7 @@ const ReportPage = () => { const [data, setData] = useState(null); const { itemsList, loadingItemsList, errorItemsList } = useRoadItemGetItems(); const { data: userPermissions } = usePermissions(); + const { user } = useAuth(); const requestServer = useRequest(); const hasProvincesPermission = userPermissions.includes("show-road-item-supervise-cartable"); @@ -27,11 +28,22 @@ const ReportPage = () => { date_to: moment(new Date()).format("YYYY-MM-DD"), province_id: hasProvincesPermission ? "-1" : user.province_id, }; + const defaultFilter = [ + { value: `${defaultValues.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${defaultValues.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${defaultValues.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]; + const [specialFilter, setSpecialFilter] = useState(defaultFilter); const onSearchSubmit = async (data) => { const params = new URLSearchParams(); params.set("from_date", `${data.from_date}`); params.set("date_to", `${data.date_to}`); + setSpecialFilter([ + { value: `${data.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${data.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${data.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]); if (data.province_id === "-1") { try { const response = await requestServer(`${GET_PROVINCE_ACTIVITY_PER_ITEM}?${params}`); @@ -158,7 +170,7 @@ const ReportPage = () => { خطا در دریافت اطلاعات!!! ) : ( - + )} ); diff --git a/src/components/dashboard/roadItems/reports/SubItemsReports/ExcelPrint/index.jsx b/src/components/dashboard/roadItems/reports/SubItemsReports/ExcelPrint/index.jsx new file mode 100644 index 0000000..443135b --- /dev/null +++ b/src/components/dashboard/roadItems/reports/SubItemsReports/ExcelPrint/index.jsx @@ -0,0 +1,77 @@ +"use client"; +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; +import { useMemo, useState } from "react"; +import moment from "jalali-moment"; +import FileSaver from "file-saver"; +import DescriptionIcon from "@mui/icons-material/Description"; +import useRequest from "@/lib/hooks/useRequest"; +import { useTheme } from "@emotion/react"; +import { + EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM, + EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM, +} from "@/core/utils/routes"; + +const PrintExcel = ({ table, filterData }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [loading, setLoading] = useState(false); + const requestServer = useRequest({ notificationSuccess: true }); + const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { + if (filter.value) { + acc.push({ id: filter.id, value: filter.value }); + } + return acc; + }, []); + + const filterParams = useMemo(() => { + const params = new URLSearchParams(); + activeFilters.length > 0 && + activeFilters.map((filter, index) => { + params.set(`${filter.id}`, filter.value); + }); + return params; + }, [activeFilters]); + + const clickHandler = () => { + setLoading(true); + const CountryOrProvince = activeFilters.find((item) => item.id === "province_id"); + const requestUrl = + CountryOrProvince.value === "-1" + ? EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM + : EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM; + requestServer(`${requestUrl}?${filterParams}`, "get", { + requestOptions: { responseType: "blob" }, + }) + .then((response) => { + const filename = `خروجی کارتابل گزارشات فعالیت روزانه براساس موارد اقدام شده تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + FileSaver.saveAs(response.data, filename); + }) + .catch(() => {}) + .finally(() => { + setLoading(false); + }); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + + ); +}; +export default PrintExcel; diff --git a/src/components/dashboard/roadItems/reports/SubItemsReports/SubItemsList.jsx b/src/components/dashboard/roadItems/reports/SubItemsReports/SubItemsList.jsx index 3ab9fc1..d92a366 100644 --- a/src/components/dashboard/roadItems/reports/SubItemsReports/SubItemsList.jsx +++ b/src/components/dashboard/roadItems/reports/SubItemsReports/SubItemsList.jsx @@ -1,7 +1,8 @@ import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import { Box } from "@mui/material"; +import Toolbar from "./TableToolbar"; -const SubItemsList = ({ data }) => { +const SubItemsList = ({ data, specialFilter }) => { return ( { page_name={"roadItemReportBySubItems"} table_name={"roadItemReportBySubItemsList"} enablePagination={false} + TableToolbar={Toolbar} + specialFilter={specialFilter} /> ); diff --git a/src/components/dashboard/roadItems/reports/SubItemsReports/TableToolbar.jsx b/src/components/dashboard/roadItems/reports/SubItemsReports/TableToolbar.jsx new file mode 100644 index 0000000..32c4395 --- /dev/null +++ b/src/components/dashboard/roadItems/reports/SubItemsReports/TableToolbar.jsx @@ -0,0 +1,10 @@ +import PrintExcel from "./ExcelPrint"; + +const Toolbar = ({ table, filterData }) => { + return ( + <> + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/roadItems/reports/SubItemsReports/index.jsx b/src/components/dashboard/roadItems/reports/SubItemsReports/index.jsx index 1601b48..b5c8237 100644 --- a/src/components/dashboard/roadItems/reports/SubItemsReports/index.jsx +++ b/src/components/dashboard/roadItems/reports/SubItemsReports/index.jsx @@ -106,12 +106,25 @@ const SubItemsReports = () => { province_id: hasProvincesPermission ? "-1" : user.province_id, item: 1, }; + const defaultFilter = [ + { value: `${defaultValues.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${defaultValues.item}`, datatype: "numeric", id: "item", fn: "equals" }, + { value: `${defaultValues.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${defaultValues.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]; + const [specialFilter, setSpecialFilter] = useState(defaultFilter); const onSearchSubmit = async (data) => { const params = new URLSearchParams(); params.set("from_date", `${data.from_date}`); params.set("date_to", `${data.date_to}`); params.set("item", `${data.item}`); + setSpecialFilter([ + { value: `${data.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${data.item}`, datatype: "numeric", id: "item", fn: "equals" }, + { value: `${data.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${data.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]); if (data.province_id === "-1") { try { const response = await requestServer(`${GET_PROVINCE_ACTIVITY_PER_SUB_ITEM}?${params}`); @@ -235,7 +248,7 @@ const SubItemsReports = () => { handleSubmit={handleSubmit} onSearchSubmit={onSearchSubmit} /> - {!data ? : } + {!data ? : } ); }; diff --git a/src/components/dashboard/roadItems/supervisor/ExcelPrint/index.jsx b/src/components/dashboard/roadItems/supervisor/ExcelPrint/index.jsx index 1cc0b2c..eca9fff 100644 --- a/src/components/dashboard/roadItems/supervisor/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadItems/supervisor/ExcelPrint/index.jsx @@ -6,6 +6,8 @@ import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; import { EXPORT_ROAD_ITEMS_SUPERVISOR_LIST } from "@/core/utils/routes"; import { useTheme } from "@emotion/react"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; const PrintExcel = ({ table, filterData }) => { const [loading, setLoading] = useState(false); @@ -13,8 +15,7 @@ const PrintExcel = ({ table, filterData }) => { const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const requestServer = useRequest(); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { - if (filter.value) { - // Check if there's an active filter + if (filter.value && (!Array.isArray(filter.value) || filter.value.some((item) => item.trim() !== ""))) { acc.push({ id: key, value: filter.value }); } return acc; @@ -22,20 +23,23 @@ const PrintExcel = ({ table, filterData }) => { const filterParams = useMemo(() => { const params = new URLSearchParams(); - activeFilters.length > 0 && + if (activeFilters.length > 0) { activeFilters.map((filter, index) => { - params.set(`${filter.id}`, filter.value); + const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); }); + } else { + params.set("filters", JSON.stringify([])); + } return params; }, [activeFilters]); - const clickHandler = () => { setLoading(true); requestServer(`${EXPORT_ROAD_ITEMS_SUPERVISOR_LIST}?${filterParams}`, "get", { requestOptions: { responseType: "blob" }, }) .then((response) => { - const filename = `خروجی کارتابل فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + const filename = `خروجی کارتابل ارزیابی فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) .catch(() => {}) diff --git a/src/components/dashboard/roadItems/supervisor/Toolbar.jsx b/src/components/dashboard/roadItems/supervisor/Toolbar.jsx index 47cb9a9..32c4395 100644 --- a/src/components/dashboard/roadItems/supervisor/Toolbar.jsx +++ b/src/components/dashboard/roadItems/supervisor/Toolbar.jsx @@ -1,6 +1,10 @@ import PrintExcel from "./ExcelPrint"; const Toolbar = ({ table, filterData }) => { - return <>{/**/}; + return ( + <> + + + ); }; export default Toolbar; diff --git a/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx b/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx index 5c2f233..97ce660 100644 --- a/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx +++ b/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx @@ -22,7 +22,7 @@ const OperatorCreate = ({ mutate }) => { ) : ( - )} diff --git a/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx b/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx index 1c635c8..a5fb3b4 100644 --- a/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx @@ -1,17 +1,21 @@ -import { Button, CircularProgress } from "@mui/material"; +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; import { useMemo, useState } from "react"; import moment from "jalali-moment"; import FileSaver from "file-saver"; import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; import { EXPORT_ROAD_PATROL_OPERATOR_LIST } from "@/core/utils/routes"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; +import { useTheme } from "@emotion/react"; const PrintExcel = ({ table, filterData }) => { const [loading, setLoading] = useState(false); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const requestServer = useRequest(); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { - if (filter.value) { - // Check if there's an active filter + if (filter.value && (!Array.isArray(filter.value) || filter.value.some((item) => item.trim() !== ""))) { acc.push({ id: key, value: filter.value }); } return acc; @@ -19,10 +23,14 @@ const PrintExcel = ({ table, filterData }) => { const filterParams = useMemo(() => { const params = new URLSearchParams(); - activeFilters.length > 0 && + if (activeFilters.length > 0) { activeFilters.map((filter, index) => { - params.set(`${filter.id}`, filter.value); + const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); }); + } else { + params.set("filters", JSON.stringify([])); + } return params; }, [activeFilters]); @@ -32,7 +40,7 @@ const PrintExcel = ({ table, filterData }) => { requestOptions: { responseType: "blob" }, }) .then((response) => { - const filename = `خروجی کارتابل عملیات تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + const filename = `خروجی کارتابل عملیات گشت راهداری تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) .catch(() => {}) @@ -42,16 +50,25 @@ const PrintExcel = ({ table, filterData }) => { }; return ( - + <> + {isMobile ? ( + + + + ) : ( + + )} + ); }; diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/CompeleteRequest.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/CompeleteRequest.jsx index e13b779..40f59da 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/CompeleteRequest.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/CompeleteRequest.jsx @@ -92,7 +92,7 @@ const CompeleteRequest = ({ allData, handlePrev, mutate, setOpen }) => { setOtpSended(true); setDelayPerRequest(true); setValueSend("phoneNumber", data.phoneNumber); - } catch (error) { } + } catch (error) {} }; const sendData = useCallback( @@ -287,8 +287,8 @@ const CompeleteRequest = ({ allData, handlePrev, mutate, setOpen }) => { {delayPerRequest ? formatCounter(counter) : isSubmittingOtp - ? "درحال دریافت کد ..." - : "دریافت کد"} + ? "درحال دریافت کد ..." + : "دریافت کد"} diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx index 91cc822..14fd172 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx @@ -4,7 +4,7 @@ import MapLoading from "@/core/components/MapLayer/Loading"; import ShowPlak from "@/core/components/ShowPlak"; import { formatSecondsToHHMMSS } from "@/core/utils/formatSecondsToHHMMSS"; import AddRoadIcon from "@mui/icons-material/AddRoad"; -import BadgeIcon from '@mui/icons-material/Badge'; +import BadgeIcon from "@mui/icons-material/Badge"; import DirectionsCarFilledIcon from "@mui/icons-material/DirectionsCarFilled"; import ElectricCarIcon from "@mui/icons-material/ElectricCar"; import LocalGasStationIcon from "@mui/icons-material/LocalGasStation"; @@ -12,16 +12,7 @@ import QrCode2Icon from "@mui/icons-material/QrCode2"; import QueryBuilderIcon from "@mui/icons-material/QueryBuilder"; import ShareLocationIcon from "@mui/icons-material/ShareLocation"; import WatchLaterIcon from "@mui/icons-material/WatchLater"; -import { - Box, - Card, - CardContent, - Chip, - Divider, - Fade, - Stack, - Typography -} from "@mui/material"; +import { Box, Card, CardContent, Chip, Divider, Fade, Stack, Typography } from "@mui/material"; import moment from "jalali-moment"; import dynamic from "next/dynamic"; import React, { useEffect } from "react"; diff --git a/src/components/dashboard/roadPatrols/operator/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx b/src/components/dashboard/roadPatrols/operator/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx index c16b10d..8570f58 100644 --- a/src/components/dashboard/roadPatrols/operator/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx +++ b/src/components/dashboard/roadPatrols/operator/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx @@ -44,7 +44,7 @@ const MachinePerformanceContent = ({ machinesLists }) => { return ( <> - + { - + { return ( - + { return ( - {/**/} + ); }; diff --git a/src/components/dashboard/roadPatrols/reports/ExcelPrint/index.jsx b/src/components/dashboard/roadPatrols/reports/ExcelPrint/index.jsx index 414a9cb..192d4fb 100644 --- a/src/components/dashboard/roadPatrols/reports/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadPatrols/reports/ExcelPrint/index.jsx @@ -1,16 +1,21 @@ -import { Button, CircularProgress } from "@mui/material"; +"use client"; +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; import { useMemo, useState } from "react"; import moment from "jalali-moment"; import FileSaver from "file-saver"; import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; +import { useTheme } from "@emotion/react"; +import { EXPORT_COUNTRY_ROAD_PATROL_REPORTS, EXPORT_PROVINCE_ROAD_PATROL_REPORTS } from "@/core/utils/routes"; const PrintExcel = ({ table, filterData }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [loading, setLoading] = useState(false); - const requestServer = useRequest(); + const requestServer = useRequest({ notificationSuccess: true }); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { - if (filter) { - acc.push({ id: key, value: filter }); + if (filter.value) { + acc.push({ id: filter.id, value: filter.value }); } return acc; }, []); @@ -25,31 +30,43 @@ const PrintExcel = ({ table, filterData }) => { }, [activeFilters]); const clickHandler = () => { - // setLoading(true); - // requestServer(`${EXPORT_ROAD_PATROL_OPERATOR_LIST}?${filterParams}`, "get", { - // requestOptions: { responseType: "blob" }, - // }) - // .then((response) => { - // const filename = `خروجی کارتابل گزارشات گشت راهداری تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; - // FileSaver.saveAs(response.data, filename); - // }) - // .catch(() => {}) - // .finally(() => { - // setLoading(false); - // }); + setLoading(true); + const CountryOrProvince = activeFilters.find((item) => item.id === "province_id"); + const requestUrl = + CountryOrProvince.value === "-1" ? EXPORT_COUNTRY_ROAD_PATROL_REPORTS : EXPORT_PROVINCE_ROAD_PATROL_REPORTS; + requestServer(`${requestUrl}?${filterParams}`, "get", { + requestOptions: { responseType: "blob" }, + }) + .then((response) => { + const filename = `خروجی کارتابل گزارشات گشت راهداری تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + FileSaver.saveAs(response.data, filename); + }) + .catch(() => {}) + .finally(() => { + setLoading(false); + }); }; return ( - + <> + {isMobile ? ( + + + + ) : ( + + )} + ); }; export default PrintExcel; diff --git a/src/components/dashboard/roadPatrols/reports/ReportLists.jsx b/src/components/dashboard/roadPatrols/reports/ReportLists.jsx index 4a3d8e5..76f6cef 100644 --- a/src/components/dashboard/roadPatrols/reports/ReportLists.jsx +++ b/src/components/dashboard/roadPatrols/reports/ReportLists.jsx @@ -4,7 +4,7 @@ import { Box } from "@mui/material"; import { useMemo } from "react"; import Toolbar from "./Toolbar"; -const ReportLists = ({ data }) => { +const ReportLists = ({ data, specialFilter }) => { const columns = useMemo(() => { return [ { @@ -195,12 +195,12 @@ const ReportLists = ({ data }) => { return ( ); diff --git a/src/components/dashboard/roadPatrols/reports/Toolbar.jsx b/src/components/dashboard/roadPatrols/reports/Toolbar.jsx index 5dc6e42..7dd930f 100644 --- a/src/components/dashboard/roadPatrols/reports/Toolbar.jsx +++ b/src/components/dashboard/roadPatrols/reports/Toolbar.jsx @@ -2,6 +2,10 @@ import PrintExcel from "./ExcelPrint"; import { Box } from "@mui/material"; const Toolbar = ({ table, filterData, mutate }) => { - return {/**/}; + return ( + + + + ); }; export default Toolbar; diff --git a/src/components/dashboard/roadPatrols/reports/index.jsx b/src/components/dashboard/roadPatrols/reports/index.jsx index 12743aa..a71eb35 100644 --- a/src/components/dashboard/roadPatrols/reports/index.jsx +++ b/src/components/dashboard/roadPatrols/reports/index.jsx @@ -25,11 +25,22 @@ const ReportPage = () => { date_to: moment(new Date()).format("YYYY-MM-DD"), province_id: hasProvincesPermission ? "-1" : user.province_id, }; + const defaultFilter = [ + { value: `${defaultValues.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${defaultValues.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${defaultValues.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]; + const [specialFilter, setSpecialFilter] = useState(defaultFilter); const onSearchSubmit = async (data) => { const params = new URLSearchParams(); params.set("from_date", `${data.from_date}`); params.set("date_to", `${data.date_to}`); + setSpecialFilter([ + { value: `${data.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${data.from_date}`, datatype: "date", id: "from_date", fn: "between" }, + { value: `${data.date_to}`, datatype: "date", id: "date_to", fn: "between" }, + ]); if (data.province_id === "-1") { try { const response = await requestServer(`${GET_PROVINCE_ACTIVITY_REPORT}?${params}`); @@ -115,7 +126,7 @@ const ReportPage = () => { handleSubmit={handleSubmit} onSearchSubmit={onSearchSubmit} /> - {!data ? : } + {!data ? : } ); }; diff --git a/src/components/dashboard/roadPatrols/supervisor/ExcelPrint/index.jsx b/src/components/dashboard/roadPatrols/supervisor/ExcelPrint/index.jsx index e5ba95a..ba176bb 100644 --- a/src/components/dashboard/roadPatrols/supervisor/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/ExcelPrint/index.jsx @@ -1,17 +1,21 @@ -import { Button, CircularProgress } from "@mui/material"; +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; import { useMemo, useState } from "react"; import moment from "jalali-moment"; import FileSaver from "file-saver"; import DescriptionIcon from "@mui/icons-material/Description"; import useRequest from "@/lib/hooks/useRequest"; import { EXPORT_ROAD_PATROL_SUPERVISOR_LIST } from "@/core/utils/routes"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; +import { useTheme } from "@emotion/react"; const PrintExcel = ({ table, filterData }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [loading, setLoading] = useState(false); const requestServer = useRequest(); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { - if (filter.value) { - // Check if there's an active filter + if (filter.value && (!Array.isArray(filter.value) || filter.value.some((item) => item.trim() !== ""))) { acc.push({ id: key, value: filter.value }); } return acc; @@ -19,10 +23,14 @@ const PrintExcel = ({ table, filterData }) => { const filterParams = useMemo(() => { const params = new URLSearchParams(); - activeFilters.length > 0 && + if (activeFilters.length > 0) { activeFilters.map((filter, index) => { - params.set(`${filter.id}`, filter.value); + const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); }); + } else { + params.set("filters", JSON.stringify([])); + } return params; }, [activeFilters]); @@ -32,7 +40,7 @@ const PrintExcel = ({ table, filterData }) => { requestOptions: { responseType: "blob" }, }) .then((response) => { - const filename = `خروجی کارتابل ارزیابی تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + const filename = `خروجی کارتابل ارزیابی گشت راهداری تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) .catch(() => {}) @@ -42,17 +50,25 @@ const PrintExcel = ({ table, filterData }) => { }; return ( - + <> + {isMobile ? ( + + + + ) : ( + + )} + ); }; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx index 93c0874..8570f58 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/MachinePerformanceContent.jsx @@ -44,7 +44,7 @@ const MachinePerformanceContent = ({ machinesLists }) => { return ( <> - + { - + { ); }; -export default MachinePerformanceContent; \ No newline at end of file +export default MachinePerformanceContent; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/StopsInfo.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/StopsInfo.jsx index 0415b7c..24b45cc 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/StopsInfo.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/StopsInfo.jsx @@ -5,7 +5,7 @@ import LocalGasStationIcon from "@mui/icons-material/LocalGasStation"; import QrCode2Icon from "@mui/icons-material/QrCode2"; import AddRoadIcon from "@mui/icons-material/AddRoad"; import DirectionsCarFilledIcon from "@mui/icons-material/DirectionsCarFilled"; -import BadgeIcon from '@mui/icons-material/Badge'; +import BadgeIcon from "@mui/icons-material/Badge"; import { formatSecondsToHHMMSS } from "@/core/utils/formatSecondsToHHMMSS"; import ShowPlak from "@/core/components/ShowPlak"; @@ -162,4 +162,4 @@ const StopsInfo = ({ selectedPoint, staticData }) => { ); }; -export default StopsInfo; \ No newline at end of file +export default StopsInfo; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/index.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/index.jsx index 3eb7b87..7e2902f 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/index.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinePerformanceForm/index.jsx @@ -48,4 +48,4 @@ const MachinePerformanceForm = ({ row }) => { ); }; -export default MachinePerformanceForm; \ No newline at end of file +export default MachinePerformanceForm; diff --git a/src/components/dashboard/roadPatrols/supervisor/Toolbar.jsx b/src/components/dashboard/roadPatrols/supervisor/Toolbar.jsx index 47cb9a9..32c4395 100644 --- a/src/components/dashboard/roadPatrols/supervisor/Toolbar.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/Toolbar.jsx @@ -1,6 +1,10 @@ import PrintExcel from "./ExcelPrint"; const Toolbar = ({ table, filterData }) => { - return <>{/**/}; + return ( + <> + + + ); }; export default Toolbar; diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index eb11e54..e9a3a37 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -7,6 +7,8 @@ import { useCallback, useMemo, useState } from "react"; import useRequest from "@/lib/hooks/useRequest"; import useSWR from "swr"; import { flattenObjectOfObjects } from "@/core/utils/flattenObjectOfObjects"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; const DataTable_Main = (props) => { const request = useRequest(); @@ -37,26 +39,13 @@ const DataTable_Main = (props) => { 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) + (filter) => !isArrayEmpty(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 = DataTableFilterDataStructure(filterData, isArrayEmpty); params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); } params.set("sorting", JSON.stringify(sortData)); diff --git a/src/core/utils/DataTableFilterDataStructure.js b/src/core/utils/DataTableFilterDataStructure.js new file mode 100644 index 0000000..c88bdfc --- /dev/null +++ b/src/core/utils/DataTableFilterDataStructure.js @@ -0,0 +1,9 @@ +export default function DataTableFilterDataStructure(filterData, isValueEmpty) { + return Object.values(filterData) + .filter((filter) => !isValueEmpty(filter.value)) + .map(({ filterMode, id, ...rest }) => ({ + ...rest, + id: id.replace(/__/g, "."), + fn: filterMode, + })); +} diff --git a/src/core/utils/isArrayEmpty.js b/src/core/utils/isArrayEmpty.js new file mode 100644 index 0000000..81624fb --- /dev/null +++ b/src/core/utils/isArrayEmpty.js @@ -0,0 +1,6 @@ +export default function isArrayEmpty(value) { + if (Array.isArray(value)) { + return value.length === 0 || value.every((v) => v === ""); + } + return value === "" || value === null || value === undefined; +} diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index a217a6e..2e5a8f8 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -30,23 +30,33 @@ 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 + "/v2/road_patrols/operator/cartable/report"; +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 + "/v2/road_patrols/supervisor/cartable/report"; +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_REPORT = api + "/v2/road_patrols/operator/report"; export const GET_ROAD_PATROL_SUPERVISOR_REPORT = api + "/v2/road_patrols/supervisor/report"; export const CREATE_PATROL = api + "/api/v3/road_patrols/store"; export const GET_FMS_DATA = api + "/api/v3/fms_vehicle/get_activity"; export const GET_OTP_TOKEN = api + "/v2/get_otp_token"; -export const GET_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/province_activity"; -export const GET_CITY_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/city_activity"; +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"; // 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_ITEM = api + "/v2/items"; export const GET_ROAD_ITEMS_SUB_ITEM = api + "/v2/sub_items"; export const GET_EDARAT_LISTS = api + "/public/contents/edarate_shahri_by_province"; @@ -59,10 +69,10 @@ 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"; -export const GET_PROVINCE_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/province_activity_per_item"; -export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/city_activity_per_item"; -export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/province_activity_per_sub_item"; -export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/city_activity_per_sub_item"; +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"; // activity code log export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity";