dispatch: fix dispatch after update

This commit is contained in:
2026-02-02 11:17:49 +03:30
parent 176ee774f0
commit 296ac6d198
2 changed files with 313 additions and 129 deletions

View File

@@ -9,7 +9,7 @@ import {
MenuItem,
Select,
TextField,
Tooltip,
Tooltip
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers";
import moment from "moment";
@@ -18,7 +18,7 @@ import axios from "axios";
import {
LOADING_END,
LOADING_START,
OPEN_MODAL,
OPEN_MODAL
} from "../../../../lib/redux/slices/appSlice";
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
@@ -29,7 +29,13 @@ import { formatJustDate } from "../../../../utils/formatTime";
import { RiSearchLine } from "react-icons/ri";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
export const SlaughterInventoryInProvinceBars = ({ type }) => {
export const SlaughterInventoryInProvinceBars = ({
type,
useExternalFilters = false,
filterValues = {},
onAfterUpdate,
refreshTrigger
}) => {
const [selectedDate1, setSelectedDate1] = useState(
moment(new Date()).format("YYYY-MM-DD")
);
@@ -53,42 +59,60 @@ export const SlaughterInventoryInProvinceBars = ({ type }) => {
const [tableData, setTableData] = useState([]);
const [quota, setQuota] = useState("all");
const effectiveFilters = useExternalFilters
? {
selectedDate1: filterValues.selectedDate1 ?? selectedDate1,
selectedDate2: filterValues.selectedDate2 ?? selectedDate2,
withDate: filterValues.withDate ?? withDate,
textValue: filterValues.textValue ?? textValue,
quota: filterValues.quota ?? quota
}
: {
selectedDate1,
selectedDate2,
withDate,
textValue,
quota
};
const fetchApiData = useCallback(
async (page) => {
async (pageNum) => {
dispatch(LOADING_START());
const response = await axios.get(
`bars_for_kill_house/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${
withDate
? `&date1=${selectedDate1}${
`bars_for_kill_house/?search=filter&value=${
effectiveFilters.textValue
}&role=${getRoleFromUrl()}${
effectiveFilters.withDate
? `&date1=${effectiveFilters.selectedDate1}${
checkPathStartsWith("slaughter")
? `&role_key=${selectedSubUser?.key}`
: ""
}&date2=${selectedDate2}`
}&date2=${effectiveFilters.selectedDate2}`
: ``
}&page=${page}&page_size=${perPage}&type=${type}&quota=${quota}`
}&page=${pageNum}&page_size=${perPage}&type=${type}&quota=${
effectiveFilters.quota
}`
);
dispatch(LOADING_END());
setData(response.data.results);
setTotalRows(response.data.count);
},
[
textValue,
withDate,
selectedDate1,
selectedDate2,
effectiveFilters.textValue,
effectiveFilters.withDate,
effectiveFilters.selectedDate1,
effectiveFilters.selectedDate2,
effectiveFilters.quota,
perPage,
type,
quota,
dispatch,
setData,
selectedSubUser?.key,
setTotalRows,
selectedSubUser?.key
]
);
const handlePageChange = (page) => {
fetchApiData(page);
setPage(page);
const handlePageChange = (pageNum) => {
fetchApiData(pageNum);
setPage(pageNum);
};
const handlePerRowsChange = (perRows) => {
@@ -96,10 +120,25 @@ export const SlaughterInventoryInProvinceBars = ({ type }) => {
setPage(1);
};
const updateTable = () => {
fetchApiData(page !== 0 ? page : 1);
const updateTable = async () => {
const currentPage = page !== 0 ? page : 1;
await fetchApiData(currentPage);
onAfterUpdate?.();
};
useEffect(() => {
if (!useExternalFilters) {
fetchApiData(1);
}
}, [fetchApiData, useExternalFilters]);
useEffect(() => {
if (useExternalFilters && refreshTrigger !== undefined) {
fetchApiData(1);
setPage(1);
}
}, [refreshTrigger, useExternalFilters]);
useEffect(() => {
const d = data?.map((item, i) => {
return [
@@ -148,24 +187,20 @@ export const SlaughterInventoryInProvinceBars = ({ type }) => {
updateTable={updateTable}
item={item}
/>
),
)
})
);
}}
>
<SettingsIcon fontSize="small" />
</IconButton>
</Tooltip>,
</Tooltip>
];
});
setTableData(d);
}, [data]);
useEffect(() => {
fetchApiData(1);
}, [fetchApiData]);
const handleSubmit = async (event) => {
event.preventDefault();
dispatch(LOADING_START());
@@ -190,109 +225,111 @@ export const SlaughterInventoryInProvinceBars = ({ type }) => {
return (
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
<Grid
container
xs={12}
justifyContent="start"
alignItems="center"
gap={2}
>
{!useExternalFilters && (
<Grid
container
style={{
borderStyle: "solid",
borderWidth: "1px",
padding: "10px",
borderRadius: "15px",
borderColor: "gray",
justifyContent: "left",
}}
xs={12}
justifyContent="start"
alignItems="center"
gap={2}
>
{type === "notentered" && (
<Grid
container
style={{
borderStyle: "solid",
borderWidth: "1px",
padding: "10px",
borderRadius: "15px",
borderColor: "gray",
justifyContent: "left"
}}
>
{type === "notentered" && (
<Grid>
<FormControlLabel
control={
<Checkbox
checked={withDate}
onChange={() => setWithDate(!withDate)}
color="primary"
/>
}
/>
</Grid>
)}
<Grid>
<FormControlLabel
control={
<Checkbox
checked={withDate}
onChange={() => setWithDate(!withDate)}
color="primary"
<DatePicker
disabled={!withDate}
label="از تاریخ"
id="date"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
}
)}
value={selectedDate1}
onChange={(e) => {
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
}}
/>
</Grid>
<Grid>
<DatePicker
disabled={!withDate}
label="تا تاریخ"
id="date"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
)}
value={selectedDate2}
onChange={(e) => {
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
}}
/>
</Grid>
)}
<Grid>
<DatePicker
disabled={!withDate}
label="از تاریخ"
id="date"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
)}
value={selectedDate1}
onChange={(e) => {
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
}}
/>
</Grid>
<Grid>
<DatePicker
disabled={!withDate}
label="تا تاریخ"
id="date"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
)}
value={selectedDate2}
onChange={(e) => {
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
}}
/>
<FormControl size="small" style={{ minWidth: 150 }}>
<InputLabel>نوع فروش</InputLabel>
<Select
value={quota}
onChange={(e) => setQuota(e.target.value)}
label="نوع فروش"
>
<MenuItem value="all">همه</MenuItem>
<MenuItem value="governmental">دولتی</MenuItem>
<MenuItem value="free">آزاد</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid>
<form onSubmit={handleSubmit}>
<TextField
id="outlined-basic"
size="small"
label="جستجو"
variant="outlined"
style={{ width: 250 }}
onChange={handleTextChange}
/>
<Button
type="submit"
onClick={handleSubmit}
endIcon={<RiSearchLine />}
>
جستجو
</Button>
</form>
</Grid>
</Grid>
<Grid>
<FormControl size="small" style={{ minWidth: 150 }}>
<InputLabel>نوع فروش</InputLabel>
<Select
value={quota}
onChange={(e) => setQuota(e.target.value)}
label="نوع فروش"
>
<MenuItem value="all">همه</MenuItem>
<MenuItem value="governmental">دولتی</MenuItem>
<MenuItem value="free">آزاد</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid>
<form onSubmit={handleSubmit}>
<TextField
id="outlined-basic"
size="small"
label="جستجو"
variant="outlined"
style={{ width: 250 }}
onChange={handleTextChange}
/>
<Button
type="submit"
onClick={handleSubmit}
endIcon={<RiSearchLine />}
>
جستجو
</Button>
</form>
</Grid>
</Grid>
)}
<ResponsiveTable
data={tableData}
@@ -319,7 +356,7 @@ export const SlaughterInventoryInProvinceBars = ({ type }) => {
"درصد افت در لحظه",
"درصد افت ورود به انبار",
"تاریخ ورود به انبار",
"عملیات",
"عملیات"
]}
handlePageChange={handlePageChange}
totalRows={totalRows}

View File

@@ -1,6 +1,17 @@
import React, { useEffect, useState } from "react";
import { Grid } from "../../../../components/grid/Grid";
import {
Button,
Checkbox,
FormControl,
FormControlLabel,
InputLabel,
MenuItem,
Select,
TextField
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers";
import moment from "moment";
import { Tab, Tabs } from "@mui/material";
import { SPACING } from "../../../../data/spacing";
import { SlaughterShowProducts } from "../slaughter-show-products/SlaughterShowProducts";
@@ -11,6 +22,7 @@ import { useDispatch } from "react-redux";
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
import { useSelector } from "react-redux";
import { RiSearchLine } from "react-icons/ri";
export const SlaughterInventory = () => {
const [value, setValue] = useState("0");
@@ -24,12 +36,36 @@ export const SlaughterInventory = () => {
const dispatch = useDispatch();
// Shared filter state for both province bars tables
const [selectedDate1, setSelectedDate1] = useState(
moment(new Date()).format("YYYY-MM-DD")
);
const [selectedDate2, setSelectedDate2] = useState(
moment(new Date()).format("YYYY-MM-DD")
);
const [withDate, setWithDate] = useState(false);
const [textValue, setTextValue] = useState("");
const [quota, setQuota] = useState("all");
const [refreshTrigger, setRefreshTrigger] = useState(0);
const filterValues = {
selectedDate1,
selectedDate2,
withDate,
textValue,
quota
};
const handleFilterSubmit = () => {
setRefreshTrigger((t) => t + 1);
};
useEffect(() => {
dispatch(
slaughterGetBarsInfo({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
: ""
})
).then((r) => {
setBarsInfo(r.payload.data);
@@ -78,8 +114,8 @@ export const SlaughterInventory = () => {
barsInfo?.totalEnteredBarsCarcassesWeight?.toLocaleString(),
barsInfo?.totalNotEnteredBars?.toLocaleString(),
barsInfo?.totalNotEnteredBarsQuantity?.toLocaleString(),
barsInfo?.totalNotEnteredKillHouseRequestsWeight?.toLocaleString(),
],
barsInfo?.totalNotEnteredKillHouseRequestsWeight?.toLocaleString()
]
]}
columns={[
"تعداد کل بارها",
@@ -91,16 +127,127 @@ export const SlaughterInventory = () => {
"وزن کل لاشه وارد شده (کیلوگرم)",
"تعداد کل بارهای وارد نشده",
"حجم کل بار وارد نشده (قطعه)",
"وزن کل بار وارد نشده (کیلوگرم)",
"وزن کل بار وارد نشده (کیلوگرم)"
]}
allColors={{ color: "#f3bda3", text: "#332a3d" }}
/>
<Grid container mt={SPACING.MEDIUM} mb={SPACING.MEDIUM}>
<SlaughterInventoryInProvinceBars type="notentered" />
<Grid
container
xs={12}
justifyContent="start"
alignItems="center"
gap={2}
pt={SPACING.MEDIUM}
>
<Grid
container
style={{
borderStyle: "solid",
borderWidth: "1px",
padding: "10px",
borderRadius: "15px",
borderColor: "gray",
justifyContent: "left"
}}
>
<Grid>
<FormControlLabel
control={
<Checkbox
checked={withDate}
onChange={() => setWithDate(!withDate)}
color="primary"
/>
}
label="فیلتر تاریخ"
/>
</Grid>
<Grid>
<DatePicker
disabled={!withDate}
label="از تاریخ"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
)}
value={selectedDate1}
onChange={(e) => {
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
}}
/>
</Grid>
<Grid>
<DatePicker
disabled={!withDate}
label="تا تاریخ"
renderInput={(params) => (
<TextField
size="small"
style={{ width: "160px" }}
{...params}
/>
)}
value={selectedDate2}
onChange={(e) => {
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
}}
/>
</Grid>
</Grid>
<Grid>
<FormControl size="small" style={{ minWidth: 150 }}>
<InputLabel>نوع فروش</InputLabel>
<Select
value={quota}
onChange={(e) => setQuota(e.target.value)}
label="نوع فروش"
>
<MenuItem value="all">همه</MenuItem>
<MenuItem value="governmental">دولتی</MenuItem>
<MenuItem value="free">آزاد</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid>
<TextField
size="small"
label="جستجو"
variant="outlined"
style={{ width: 250 }}
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
/>
<Button
sx={{ ml: 1 }}
variant="contained"
onClick={handleFilterSubmit}
endIcon={<RiSearchLine />}
>
جستجو
</Button>
</Grid>
</Grid>
<Grid container mt={SPACING.MEDIUM} mb={SPACING.MEDIUM}>
<SlaughterInventoryInProvinceBars type="entered" />
<SlaughterInventoryInProvinceBars
type="notentered"
useExternalFilters
filterValues={filterValues}
onAfterUpdate={() => setRefreshTrigger((t) => t + 1)}
refreshTrigger={refreshTrigger}
/>
</Grid>
<Grid container mt={SPACING.MEDIUM} mb={SPACING.MEDIUM}>
<SlaughterInventoryInProvinceBars
type="entered"
useExternalFilters
filterValues={filterValues}
refreshTrigger={refreshTrigger}
/>
</Grid>
</Grid>
</Grid>