212 lines
6.4 KiB
JavaScript
212 lines
6.4 KiB
JavaScript
import { createContext, useEffect, useState } from "react";
|
|
import { toast } from "react-toastify";
|
|
import useTableSetting from "@/lib/hooks/useTableSetting";
|
|
import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects";
|
|
import AskForKeepData from "@/core/components/NotificationDesign/AskForKeepData";
|
|
import { LinearProgress } from "@mui/material";
|
|
|
|
export const DataTableContext = createContext();
|
|
|
|
const DataTableProvider = ({
|
|
children,
|
|
user_id,
|
|
page_name,
|
|
table_name,
|
|
columns,
|
|
initialSort = [],
|
|
}) => {
|
|
const { settingStore } = useTableSetting();
|
|
const [isInitStates, setInitStates] = useState(false);
|
|
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
|
const [initFilter, setInitFilter] = useState({});
|
|
const [filterData, setFilterData] = useState({});
|
|
const [initSort, setInitSort] = useState(initialSort || []);
|
|
const [sortData, setSortData] = useState(initialSort || []);
|
|
const [initHide, setInitHide] = useState({});
|
|
const [hideData, setHideData] = useState({});
|
|
const [isDirty, setIsDirty] = useState(false);
|
|
const [isAnyDirty, setIsAnyDirty] = useState(false);
|
|
|
|
useEffect(() => {
|
|
let hasAnyConflict = false;
|
|
const hasConflict =
|
|
JSON.stringify(hideData) !== JSON.stringify(initHide) ||
|
|
JSON.stringify(sortData) !== JSON.stringify(initSort) ||
|
|
JSON.stringify(filterData) !== JSON.stringify(initFilter);
|
|
|
|
const CheckFilterValues = Object.values(filterData).every((innerObject) => {
|
|
if (
|
|
innerObject.datatype === "date" &&
|
|
innerObject.filterMode === "between"
|
|
) {
|
|
return (
|
|
Array.isArray(innerObject.value) &&
|
|
innerObject.value.length === 2 &&
|
|
innerObject.value.every((v) => v === "")
|
|
);
|
|
} else {
|
|
return innerObject.value === "";
|
|
}
|
|
});
|
|
const flattenObject = (obj) => {
|
|
let result = {};
|
|
for (const key in obj) {
|
|
if (typeof obj[key] === "object" && obj[key] !== null) {
|
|
Object.assign(result, flattenObject(obj[key])); // باز کردن اشیای تودرتو
|
|
} else {
|
|
result[key] = obj[key];
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
// تبدیل آبجکت به آبجکت فلت شده
|
|
const flatHideData = flattenObject(hideData);
|
|
|
|
const CheckHideValues = Object.values(flatHideData).every(
|
|
(value) => value === true,
|
|
);
|
|
hasAnyConflict =
|
|
!CheckHideValues ||
|
|
JSON.stringify(sortData) !== JSON.stringify(initialSort) ||
|
|
!CheckFilterValues;
|
|
|
|
setIsDirty(hasConflict);
|
|
setIsAnyDirty(hasAnyConflict);
|
|
}, [hideData, sortData, filterData, initHide, initSort, initFilter]);
|
|
|
|
useEffect(() => {
|
|
if (!settingStore) return;
|
|
const filterValues = flatColumns.reduce((acc, column) => {
|
|
if (!column.enableColumnFilter) return acc;
|
|
const storeFilter = settingStore?.[user_id]?.[page_name]?.[table_name]?.[
|
|
"filters"
|
|
]?.find((filter) => filter.id === column.id);
|
|
if (column.datatype === "array") {
|
|
acc[column.id] = {
|
|
id: column.id,
|
|
value: storeFilter?.value || [],
|
|
filterMode: storeFilter?.filterMode || column.filterMode,
|
|
datatype: column.datatype,
|
|
};
|
|
} else if (column.filterMode === "between") {
|
|
acc[column.id] = {
|
|
id: column.id,
|
|
value: storeFilter?.value || ["", ""],
|
|
filterMode: storeFilter?.filterMode || column.filterMode,
|
|
datatype: column.datatype,
|
|
};
|
|
} else {
|
|
acc[column.id] = {
|
|
id: column.id,
|
|
value: storeFilter?.value || "",
|
|
filterMode: storeFilter?.filterMode || column.filterMode,
|
|
datatype: column.datatype,
|
|
};
|
|
}
|
|
return acc;
|
|
}, {});
|
|
|
|
const getHideValues = (columns) => {
|
|
return columns.reduce((acc, column) => {
|
|
const columnId = column.id;
|
|
const storeHide =
|
|
settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"]?.[
|
|
columnId
|
|
];
|
|
if (column.columns && column.columns.length > 0) {
|
|
acc[columnId] = getHideValues(column.columns);
|
|
} else {
|
|
acc[columnId] = storeHide !== undefined ? storeHide : true;
|
|
}
|
|
|
|
return acc;
|
|
}, {});
|
|
};
|
|
|
|
const hideValues = getHideValues(columns);
|
|
setHideData(hideValues);
|
|
setInitHide(hideValues);
|
|
setFilterData(filterValues);
|
|
setInitFilter(filterValues);
|
|
setSortData(
|
|
settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ||
|
|
initialSort,
|
|
);
|
|
setInitSort(
|
|
settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ||
|
|
initialSort,
|
|
);
|
|
setInitStates(true);
|
|
}, [settingStore]);
|
|
|
|
useEffect(() => {
|
|
if (
|
|
JSON.stringify(initFilter) !== JSON.stringify(filterData) ||
|
|
JSON.stringify(initSort) !== JSON.stringify(sortData) ||
|
|
JSON.stringify(initHide) !== JSON.stringify(hideData)
|
|
) {
|
|
if (!toast.isActive("keep_data", "filtering")) {
|
|
toast(
|
|
<AskForKeepData
|
|
filterData={filterData}
|
|
sortData={sortData}
|
|
hideData={hideData}
|
|
user_id={user_id}
|
|
page_name={page_name}
|
|
table_name={table_name}
|
|
columns={flatColumns}
|
|
/>,
|
|
{
|
|
containerId: "filtering",
|
|
toastId: "keep_data",
|
|
className: "filter-toast",
|
|
position: "bottom-left",
|
|
draggable: true,
|
|
autoClose: false,
|
|
},
|
|
);
|
|
} else {
|
|
toast.update("keep_data", {
|
|
containerId: "filtering",
|
|
toastId: "keep_data",
|
|
render: (
|
|
<AskForKeepData
|
|
filterData={filterData}
|
|
sortData={sortData}
|
|
hideData={hideData}
|
|
user_id={user_id}
|
|
page_name={page_name}
|
|
table_name={table_name}
|
|
columns={flatColumns}
|
|
/>
|
|
),
|
|
});
|
|
}
|
|
} else {
|
|
toast.dismiss({ containerId: "datatable" });
|
|
}
|
|
}, [filterData, sortData, hideData]);
|
|
|
|
if (!isInitStates) return <LinearProgress sx={{ borderRadius: 2 }} />;
|
|
|
|
return (
|
|
<DataTableContext.Provider
|
|
value={{
|
|
filterData,
|
|
setFilterData,
|
|
sortData,
|
|
setSortData,
|
|
hideData,
|
|
setHideData,
|
|
isDirty,
|
|
isAnyDirty,
|
|
}}
|
|
>
|
|
{children}
|
|
</DataTableContext.Provider>
|
|
);
|
|
};
|
|
|
|
export default DataTableProvider;
|