diff --git a/src/app/(withAuth)/dashboard/template.js b/src/app/(withAuth)/dashboard/template.js index 9b2fea8..62759c6 100644 --- a/src/app/(withAuth)/dashboard/template.js +++ b/src/app/(withAuth)/dashboard/template.js @@ -2,7 +2,6 @@ import {Box, Stack} from "@mui/material"; import HeaderWithLogo from "@/components/layouts/dashboard/headerWithLogo"; import HeaderWithSidebar from "@/components/layouts/dashboard/headerWithSidebar"; import 'react-toastify/dist/ReactToastify.css'; -import {ToastContainer} from "react-toastify"; const Template = ({children}) => { return ( @@ -10,7 +9,6 @@ const Template = ({children}) => { {children} - ) diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 359e13e..659d11f 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -87,11 +87,10 @@ function HomeComponent() { id: "price", enableColumnFilter: true, datatype: "numeric", - filterFn: "between", + filterFn: "equals", columnFilterModeOptions: [ "equals", "notEquals", - "between" ], }, { diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index 89fda97..09300df 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -4,6 +4,7 @@ import {FA_DATATABLE_LOCALIZATION} from "./localization/fa/datatable"; import useTableSetting from "@/lib/hooks/useTableSetting"; import {flattenArrayOfObjects} from "@/core/utils/flattenArrayOfObjects"; import Toolbar from "@/components/home/Toolbar"; +import useDataTable from "@/lib/hooks/useDataTable"; const data = [ { @@ -74,6 +75,7 @@ const data = [ ]; const DataTable_Main = (props) => { + const {filterData} = useDataTable(); const {userId, pageName, tableName, columns, initialStateProps} = props const flatColumns = flattenArrayOfObjects(columns, 'columns') diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx index a214186..17f830c 100644 --- a/src/core/components/DataTable/filter/FilterBody.jsx +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -3,12 +3,13 @@ import {Box, Button, Drawer, styled} from "@mui/material"; import {Form, Formik} from "formik"; import useTableSetting from "@/lib/hooks/useTableSetting"; -import {useEffect, useState} from "react"; +import {useEffect, useRef, useState} from "react"; import FilterHeader from "@/core/components/DataTable/filter/FilterHeader"; import * as Yup from "yup"; import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField"; import {toast} from "react-toastify"; import AskForKeep from "@/core/components/NotificationDesign/AskForKeep"; +import useDataTable from "@/lib/hooks/useDataTable"; const ScrollBox = styled(Box)({ flexGrow: 1, @@ -30,6 +31,13 @@ const ScrollBox = styled(Box)({ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tableName}) { const {settingStore, filterAction} = useTableSetting(); const [initialValues, setInitialValues] = useState({}); + const [validationSchema, setValidationSchema] = useState({}); + const {filterData, setFilterData} = useDataTable(); + const filterDataRef = useRef(filterData); // Create a ref to hold the latest filterData + + useEffect(() => { + filterDataRef.current = filterData; // Update ref whenever filterData changes + }, [filterData]); useEffect(() => { const values = columns.reduce((acc, column) => { @@ -37,18 +45,21 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); if (column.datatype === 'array') { acc[column.id] = { + id: column.id, value: filter?.value || [], filterFn: filter?.fn || column._filterFn, datatype: column.datatype }; } else if (column._filterFn === "between") { acc[column.id] = { + id: column.id, value: filter?.value || ["", ""], filterFn: filter?.fn || column._filterFn, datatype: column.datatype }; } else { acc[column.id] = { + id: column.id, value: filter?.value || '', filterFn: filter?.fn || column._filterFn, datatype: column.datatype @@ -56,39 +67,47 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab } return acc; }, {}); - setInitialValues(values); - }, [columns, settingStore, userId, pageName, tableName]); + setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values); + }, [columns, settingStore, userId, pageName, tableName, filterData]); + + + useEffect(() => { + const generatedSchema = Yup.object().shape( + Object.keys(initialValues).reduce((acc, key) => { + const initialValue = initialValues[key]; + if (initialValue.filterFn === "between") { + acc[key] = Yup.object().shape({ + value: Yup.array() + .of(Yup.string().nullable()) + .test({ + test(value, ctx) { + const [start, end] = value || ["", ""]; + if (initialValue.datatype === "numeric" && parseInt(end, 10) <= parseInt(start, 10)) { + return ctx.createError({ + message: `مقدار وارده باید بیشتر از (${start}) باشد`, + }); + } else if ((start && !end) || (!start && end)) { + return ctx.createError({ + message: "این بخش را تکمیل نمایید", + }); + } + return true; + }, + }), + }); + } + return acc; + }, {}) + ); + + setValidationSchema(generatedSchema); + }, [initialValues]); - const validationSchema = Yup.object().shape( - columns.reduce((acc, column) => { - if (column._filterFn === "between") { - acc[column.id] = Yup.object().shape({ - value: Yup.array() - .of(Yup.string().nullable()) - .test({ - test(value, ctx) { - const [start, end] = value || ["", ""]; - if (column.datatype === "numeric" && start && end && parseInt(end, 10) <= parseInt(start, 10)) { - return ctx.createError({ - message: `مقدار وارده باید بیشتر از (${start}) باشد`, - }); - } else if ((start && !end) || (!start && end)) { - return ctx.createError({ - message: "این بخش را تکمیل نمایید", - }); - } - return true; - }, - }), - }); - } - return acc; - }, {}) - ); const handleSubmit = (values, {setSubmitting}) => { toast.dismiss({containerId: "filtering"}); setDrawerState(false); + setFilterData(values); toast(, { containerId: "filtering", className: "filter-toast", @@ -100,6 +119,15 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab }; const onSaveFilter = () => { + const currentFilterData = filterDataRef.current; // Use the ref to get the latest filterData + const arrayOfObjects = Object.keys(currentFilterData).map(key => { + const value = currentFilterData[key].value; + if (value !== "" && + !(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) { + return currentFilterData[key]; + } + }).filter(Boolean); + console.log("arrayOfObjects", arrayOfObjects); toast.dismiss({containerId: "filtering"}); }; @@ -168,7 +196,6 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab - )} diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index 1a91c05..b12e770 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -36,7 +36,7 @@ function FilterBodyField({ return ( <> - {column.datatype === "numeric" && filterParameters.filterFn === "between" ? ( + {filterParameters.datatype === "numeric" && filterParameters.filterFn === "between" ? ( - ) : column.datatype === "numeric" && filterParameters.filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( + ) : filterParameters.datatype === "numeric" && filterParameters.filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( - ) : column.datatype === "date" && filterParameters.filterFn === "equals" ? ( + ) : filterParameters.datatype === "date" && filterParameters.filterFn === "equals" ? ( - ) : column.datatype === "date" && filterParameters.filterFn === "between" ? ( + ) : filterParameters.datatype === "date" && filterParameters.filterFn === "between" ? ( - ) : column.datatype === "array" && filterParameters.filterFn === "equals" ? ( + ) : filterParameters.datatype === "array" && filterParameters.filterFn === "equals" ? ( { return ( - + + + ); }; diff --git a/src/lib/contexts/DataTable.jsx b/src/lib/contexts/DataTable.jsx new file mode 100644 index 0000000..975b859 --- /dev/null +++ b/src/lib/contexts/DataTable.jsx @@ -0,0 +1,15 @@ +import {createContext, useState} from "react"; + +export const DataTableContext = createContext(); + +const DataTableProvider = ({children}) => { + const [filterData, setFilterData] = useState({}); + + return ( + + {children} + + ); +}; + +export default DataTableProvider; \ No newline at end of file diff --git a/src/lib/hooks/useDataTable.jsx b/src/lib/hooks/useDataTable.jsx new file mode 100644 index 0000000..ba7acb5 --- /dev/null +++ b/src/lib/hooks/useDataTable.jsx @@ -0,0 +1,9 @@ +import {useContext} from "react"; +import {DataTableContext} from "@/lib/contexts/DataTable"; + +const useTableSetting = () => { + const {filterData, setFilterData} = useContext(DataTableContext); + return {filterData, setFilterData}; +}; + +export default useTableSetting;