Merge branch 'feature/mohammad_refactor_filter' into 'develop'
Feature/mohammad refactor filter See merge request witel-front-end/rms!8
This commit is contained in:
@@ -41,4 +41,4 @@
|
|||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"prettier": "^3.3.2"
|
"prettier": "^3.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,4 @@
|
|||||||
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
|
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
|
||||||
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
||||||
background-color: #d0dfe8;
|
background-color: #d0dfe8;
|
||||||
border: 1px dashed #095b8c;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ const Layout = ({ children }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
export default Layout;
|
export default Layout;
|
||||||
@@ -76,65 +76,43 @@ const data = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const DataTable_Main = (props) => {
|
const DataTable_Main = (props) => {
|
||||||
const { filterData } = useDataTable();
|
const { filterData, sortData, setSortData } = useDataTable();
|
||||||
const { table_url, user_id, page_name, table_name, columns, initialStateProps } = props;
|
const { table_url, user_id, page_name, table_name, columns, initialStateProps } = props;
|
||||||
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||||
const { settingStore, hideAction, sortAction } = useTableSetting();
|
const { settingStore, hideAction } = useTableSetting();
|
||||||
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
||||||
const filters = Object.keys(filterData)
|
|
||||||
.map((key) => {
|
|
||||||
const value = filterData[key].value;
|
|
||||||
if (
|
|
||||||
value !== "" &&
|
|
||||||
!(
|
|
||||||
Array.isArray(value) &&
|
|
||||||
(value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === ""))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return filterData[key];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
const storedFilters = settingStore?.[user_id]?.[page_name]?.[table_name]?.filters;
|
|
||||||
const finalFilters = storedFilters || filters;
|
|
||||||
|
|
||||||
const fetchUrl = useMemo(() => {
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
|
|
||||||
params.set("size", pagination.pageSize);
|
|
||||||
params.set("filters", JSON.stringify(finalFilters ?? []));
|
|
||||||
params.set("sorting", JSON.stringify(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ?? []));
|
|
||||||
return `${table_url}?${params}`;
|
|
||||||
}, [table_url, finalFilters, pagination, columns]);
|
|
||||||
|
|
||||||
const onColumnVisibilityChange = (event) => {
|
const onColumnVisibilityChange = (event) => {
|
||||||
const settingValue = event();
|
const settingValue = event();
|
||||||
hideAction(user_id, page_name, table_name, settingValue, flatColumns);
|
hideAction(user_id, page_name, table_name, settingValue, flatColumns);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSortingChange = (event) => {
|
const onSortingChange = (event) => {
|
||||||
const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
|
setSortData(event);
|
||||||
sortAction(user_id, page_name, table_name, settingValue, flatColumns);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchUrl = useMemo(() => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
|
||||||
|
params.set("size", pagination.pageSize);
|
||||||
|
params.set("filters", JSON.stringify(filterData ?? []));
|
||||||
|
params.set("sorting", JSON.stringify(sortData));
|
||||||
|
return `${table_url}?${params}`;
|
||||||
|
}, [table_url, filterData, pagination, columns]);
|
||||||
|
|
||||||
const table = useMaterialReactTable({
|
const table = useMaterialReactTable({
|
||||||
localization: FA_DATATABLE_LOCALIZATION,
|
localization: FA_DATATABLE_LOCALIZATION,
|
||||||
columns,
|
columns,
|
||||||
data: data,
|
data: data,
|
||||||
// manualSorting: true,
|
|
||||||
renderTopToolbarCustomActions: ({ table }) => (
|
|
||||||
<>
|
|
||||||
<Toolbar columns={flatColumns} />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
initialState: {
|
initialState: {
|
||||||
density: "compact",
|
density: "compact",
|
||||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
||||||
sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [],
|
sorting: sortData,
|
||||||
...initialStateProps,
|
...initialStateProps,
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
||||||
sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [],
|
sorting: sortData,
|
||||||
pagination,
|
pagination,
|
||||||
},
|
},
|
||||||
muiTableHeadProps: {
|
muiTableHeadProps: {
|
||||||
@@ -162,10 +140,15 @@ const DataTable_Main = (props) => {
|
|||||||
},
|
},
|
||||||
manualFiltering: true,
|
manualFiltering: true,
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
onPaginationChange: setPagination,
|
|
||||||
manualSorting: true,
|
manualSorting: true,
|
||||||
|
onPaginationChange: setPagination,
|
||||||
onColumnVisibilityChange: onColumnVisibilityChange,
|
onColumnVisibilityChange: onColumnVisibilityChange,
|
||||||
onSortingChange: onSortingChange,
|
onSortingChange: onSortingChange,
|
||||||
|
renderTopToolbarCustomActions: ({ table }) => (
|
||||||
|
<>
|
||||||
|
<Toolbar columns={flatColumns} />
|
||||||
|
</>
|
||||||
|
),
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,10 @@
|
|||||||
import { Box, Button, Drawer, styled } from "@mui/material";
|
import { Box, Button, Drawer, styled } from "@mui/material";
|
||||||
import { Form, Formik } from "formik";
|
import { Form, Formik } from "formik";
|
||||||
import useTableSetting from "@/lib/hooks/useTableSetting";
|
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import FilterHeader from "@/core/components/DataTable/filter/FilterHeader";
|
import FilterHeader from "@/core/components/DataTable/filter/FilterHeader";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField";
|
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";
|
import useDataTable from "@/lib/hooks/useDataTable";
|
||||||
|
|
||||||
const ScrollBox = styled(Box)({
|
const ScrollBox = styled(Box)({
|
||||||
@@ -29,46 +27,13 @@ const ScrollBox = styled(Box)({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name, table_name }) {
|
function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name, table_name }) {
|
||||||
const { settingStore, filterAction } = useTableSetting();
|
const { settingStore } = useTableSetting();
|
||||||
const [initialValues, setInitialValues] = useState({});
|
const [initialValues, setInitialValues] = useState({});
|
||||||
const [validationSchema, setValidationSchema] = useState({});
|
const [validationSchema, setValidationSchema] = useState({});
|
||||||
const { filterData, setFilterData } = useDataTable();
|
const { filterData, setFilterData } = useDataTable();
|
||||||
const filterDataRef = useRef(filterData);
|
|
||||||
useEffect(() => {
|
|
||||||
filterDataRef.current = filterData;
|
|
||||||
}, [filterData]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const values = columns.reduce((acc, column) => {
|
setInitialValues(filterData);
|
||||||
if (!column.enableColumnFilter) return acc;
|
|
||||||
const filter = 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: 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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values);
|
|
||||||
}, [columns, settingStore, user_id, page_name, table_name, filterData]);
|
}, [columns, settingStore, user_id, page_name, table_name, filterData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -107,49 +72,16 @@ function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name,
|
|||||||
}, [initialValues]);
|
}, [initialValues]);
|
||||||
|
|
||||||
const handleSubmit = (values, { setSubmitting }) => {
|
const handleSubmit = (values, { setSubmitting }) => {
|
||||||
toast.dismiss({ containerId: "filtering" });
|
|
||||||
setDrawerState(false);
|
setDrawerState(false);
|
||||||
setFilterData(values);
|
setFilterData(values);
|
||||||
toast(<AskForKeep onSaveFilter={onSaveFilter} />, {
|
|
||||||
containerId: "filtering",
|
|
||||||
className: "filter-toast",
|
|
||||||
position: "bottom-left",
|
|
||||||
draggable: true,
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSaveFilter = () => {
|
|
||||||
const currentFilterData = filterDataRef.current;
|
|
||||||
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);
|
|
||||||
filterAction(user_id, page_name, table_name, arrayOfObjects, columns);
|
|
||||||
toast.dismiss({ containerId: "filtering" });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
open={drawerState}
|
open={drawerState}
|
||||||
onClose={() => setDrawerState(false)}
|
onClose={() => setDrawerState(false)}
|
||||||
sx={{
|
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%" }}
|
||||||
overflowY: "hidden",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
height: "100%",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<FilterHeader setDrawerState={setDrawerState} />
|
<FilterHeader setDrawerState={setDrawerState} />
|
||||||
{Object.keys(initialValues).length > 0 && (
|
{Object.keys(initialValues).length > 0 && (
|
||||||
|
|||||||
@@ -32,12 +32,7 @@ function FilterOptionList({
|
|||||||
key={index}
|
key={index}
|
||||||
onClick={(event) => handleChangeItem(event, index)}
|
onClick={(event) => handleChangeItem(event, index)}
|
||||||
selected={option === selectedFilter}
|
selected={option === selectedFilter}
|
||||||
sx={{
|
sx={{ cursor: "pointer", width: "100px", display: "flex", justifyContent: "center" }}
|
||||||
cursor: "pointer",
|
|
||||||
width: "100px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{columnFilterModeOptionFa[option]}
|
{columnFilterModeOptionFa[option]}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import ClearIcon from "@mui/icons-material/Clear";
|
|||||||
import moment from "jalali-moment";
|
import moment from "jalali-moment";
|
||||||
|
|
||||||
function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) {
|
function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex", flexDirection: "column", my: 1 }}>
|
<Box sx={{ display: "flex", flexDirection: "column", my: 1 }}>
|
||||||
<LocalizationProvider
|
<LocalizationProvider
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ import DataTableProvider from "@/lib/contexts/DataTable";
|
|||||||
|
|
||||||
const DataTable = (props) => {
|
const DataTable = (props) => {
|
||||||
return (
|
return (
|
||||||
<DataTableProvider>
|
<DataTableProvider
|
||||||
|
user_id={props.user_id}
|
||||||
|
page_name={props.page_name}
|
||||||
|
table_name={props.table_name}
|
||||||
|
columns={props.columns}
|
||||||
|
>
|
||||||
<DataTable_Main {...props} />
|
<DataTable_Main {...props} />
|
||||||
</DataTableProvider>
|
</DataTableProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import SaveIcon from "@mui/icons-material/Save";
|
|
||||||
import { Box, Button, Typography } from "@mui/material";
|
|
||||||
import DownloadIcon from "@mui/icons-material/Download";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
|
|
||||||
function AskForKeep({ onSaveFilter }) {
|
|
||||||
const handleDismiss = () => {
|
|
||||||
toast.dismiss({ containerId: "filtering" });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box sx={{ width: "100%" }}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
mb: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography color="#155175" variant="subtitle1" sx={{ fontWeight: "500" }}>
|
|
||||||
ذخیره سازی اطلاعات
|
|
||||||
</Typography>
|
|
||||||
<SaveIcon sx={{ color: "#155175" }} />
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "column" }}>
|
|
||||||
<Typography variant="caption">آیا مایل به ذخیره فیلتر های اعمال شده برای دفعات بعد هستید؟</Typography>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ display: "flex", gap: 1, mt: 1 }}>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={handleDismiss}
|
|
||||||
sx={{
|
|
||||||
backgroundColor: "#792626",
|
|
||||||
":hover": { backgroundColor: "#792626" },
|
|
||||||
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
رد کردن
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
component="label"
|
|
||||||
endIcon={<DownloadIcon />}
|
|
||||||
onClick={onSaveFilter}
|
|
||||||
sx={{
|
|
||||||
backgroundColor: "#155175",
|
|
||||||
":hover": { backgroundColor: "#155175" },
|
|
||||||
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
ذخیره فیلتر
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AskForKeep;
|
|
||||||
|
|||||||
78
src/core/components/NotificationDesign/AskForKeepData.jsx
Normal file
78
src/core/components/NotificationDesign/AskForKeepData.jsx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import SaveIcon from "@mui/icons-material/Save";
|
||||||
|
import { Box, Button, Typography } from "@mui/material";
|
||||||
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||||
|
|
||||||
|
function AskForKeepData({ filterData, sortData, user_id, page_name, table_name, columns }) {
|
||||||
|
const { filterAction, sortAction } = useTableSetting();
|
||||||
|
|
||||||
|
const onSaveFilter = () => {
|
||||||
|
const filteredItems = Object.keys(filterData)
|
||||||
|
.map((key) => {
|
||||||
|
const value = filterData[key].value;
|
||||||
|
if (
|
||||||
|
value !== "" &&
|
||||||
|
!(
|
||||||
|
Array.isArray(value) &&
|
||||||
|
(value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === ""))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return filterData[key];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
filterAction(user_id, page_name, table_name, filteredItems, columns);
|
||||||
|
|
||||||
|
sortAction(user_id, page_name, table_name, sortData, columns);
|
||||||
|
toast.dismiss({ containerId: "datatable" });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDismiss = () => {
|
||||||
|
toast.dismiss({ containerId: "datatable" });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: "100%" }}>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1 }}>
|
||||||
|
<Typography color="#155175" variant="subtitle1" sx={{ fontWeight: "500" }}>
|
||||||
|
ذخیره سازی تغییرات
|
||||||
|
</Typography>
|
||||||
|
<SaveIcon sx={{ color: "#155175" }} />
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "flex", flexDirection: "column" }}>
|
||||||
|
<Typography variant="caption">آیا مایل به ذخیره تغییر های اعمال شده برای دفعات بعد هستید؟</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "flex", gap: 1, mt: 1 }}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={handleDismiss}
|
||||||
|
sx={{
|
||||||
|
backgroundColor: "#792626",
|
||||||
|
":hover": { backgroundColor: "#792626" },
|
||||||
|
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
رد کردن
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
component="label"
|
||||||
|
endIcon={<DownloadIcon />}
|
||||||
|
onClick={onSaveFilter}
|
||||||
|
sx={{
|
||||||
|
backgroundColor: "#155175",
|
||||||
|
":hover": { backgroundColor: "#155175" },
|
||||||
|
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
ذخیره
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AskForKeepData;
|
||||||
110
src/lib/contexts/DataTable.jsx
Normal file
110
src/lib/contexts/DataTable.jsx
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import { createContext, useEffect, useState } from "react";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import AskForKeepData from "@/core/components/NotificationDesign/AskForKeepData";
|
||||||
|
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||||
|
import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects";
|
||||||
|
|
||||||
|
export const DataTableContext = createContext();
|
||||||
|
|
||||||
|
const DataTableProvider = ({ children, user_id, page_name, table_name, columns }) => {
|
||||||
|
const { settingStore } = useTableSetting();
|
||||||
|
const [isInitStates, setInitStates] = useState(false);
|
||||||
|
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||||
|
const [initFilter, setInitFilter] = useState({});
|
||||||
|
const [initSort, setInitSort] = useState([]);
|
||||||
|
const [filterData, setFilterData] = useState({});
|
||||||
|
const [sortData, setSortData] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!settingStore) return;
|
||||||
|
const values = flatColumns.reduce((acc, column) => {
|
||||||
|
if (!column.enableColumnFilter) return acc;
|
||||||
|
const filter = 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: filter?.value || [],
|
||||||
|
filterFn: filter?.filterFn || column._filterFn,
|
||||||
|
datatype: column.datatype,
|
||||||
|
};
|
||||||
|
} else if (column._filterFn === "between") {
|
||||||
|
acc[column.id] = {
|
||||||
|
id: column.id,
|
||||||
|
value: filter?.value || ["", ""],
|
||||||
|
filterFn: filter?.filterFn || column._filterFn,
|
||||||
|
datatype: column.datatype,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
acc[column.id] = {
|
||||||
|
id: column.id,
|
||||||
|
value: filter?.value || "",
|
||||||
|
filterFn: filter?.filterFn || column._filterFn,
|
||||||
|
datatype: column.datatype,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
setFilterData(values);
|
||||||
|
setSortData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
|
||||||
|
setInitFilter(values);
|
||||||
|
setInitSort(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
|
||||||
|
setInitStates(true);
|
||||||
|
}, [settingStore, isInitStates]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
JSON.stringify(initFilter) !== JSON.stringify(filterData) ||
|
||||||
|
JSON.stringify(initSort) !== JSON.stringify(sortData)
|
||||||
|
) {
|
||||||
|
if (!toast.isActive("keep_data", "datatable")) {
|
||||||
|
toast(
|
||||||
|
<AskForKeepData
|
||||||
|
filterData={filterData}
|
||||||
|
sortData={sortData}
|
||||||
|
user_id={user_id}
|
||||||
|
page_name={page_name}
|
||||||
|
table_name={table_name}
|
||||||
|
columns={flatColumns}
|
||||||
|
/>,
|
||||||
|
{
|
||||||
|
containerId: "datatable",
|
||||||
|
toastId: "keep_data",
|
||||||
|
className: "filter-toast",
|
||||||
|
position: "bottom-left",
|
||||||
|
draggable: true,
|
||||||
|
autoClose: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
toast.update("keep_data", {
|
||||||
|
containerId: "datatable",
|
||||||
|
toastId: "keep_data",
|
||||||
|
render: (
|
||||||
|
<AskForKeepData
|
||||||
|
filterData={filterData}
|
||||||
|
sortData={sortData}
|
||||||
|
user_id={user_id}
|
||||||
|
page_name={page_name}
|
||||||
|
table_name={table_name}
|
||||||
|
columns={flatColumns}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.dismiss({ containerId: "datatable" });
|
||||||
|
}
|
||||||
|
}, [filterData, sortData]);
|
||||||
|
|
||||||
|
if (!isInitStates) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataTableContext.Provider value={{ filterData, setFilterData, sortData, setSortData }}>
|
||||||
|
{children}
|
||||||
|
</DataTableContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataTableProvider;
|
||||||
@@ -96,10 +96,7 @@ export const TableSettingProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (values.hides) {
|
if (values.hides) {
|
||||||
const hidesArray = Object.entries(values.hides).map((e) => ({
|
const hidesArray = Object.entries(values.hides).map((e) => ({ id: e[0], value: e[1] }));
|
||||||
id: e[0],
|
|
||||||
value: e[1],
|
|
||||||
}));
|
|
||||||
if (hidesArray.length > 0) {
|
if (hidesArray.length > 0) {
|
||||||
const _list = [];
|
const _list = [];
|
||||||
for (const hide of hidesArray) {
|
for (const hide of hidesArray) {
|
||||||
@@ -136,15 +133,7 @@ export const TableSettingProvider = ({ children }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableSettingContext.Provider
|
<TableSettingContext.Provider value={{ settingStore, hideAction, sortAction, filterAction, refactorAction }}>
|
||||||
value={{
|
|
||||||
settingStore,
|
|
||||||
hideAction,
|
|
||||||
sortAction,
|
|
||||||
filterAction,
|
|
||||||
refactorAction,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</TableSettingContext.Provider>
|
</TableSettingContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
9
src/lib/hooks/useDataTable.jsx
Normal file
9
src/lib/hooks/useDataTable.jsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { DataTableContext } from "@/lib/contexts/DataTable";
|
||||||
|
|
||||||
|
const useTableSetting = () => {
|
||||||
|
const { filterData, setFilterData, sortData, setSortData } = useContext(DataTableContext);
|
||||||
|
return { filterData, setFilterData, sortData, setSortData };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTableSetting;
|
||||||
9
src/lib/hooks/useTableSetting.jsx
Normal file
9
src/lib/hooks/useTableSetting.jsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { TableSettingContext } from "../contexts/tableSetting";
|
||||||
|
|
||||||
|
const useTableSetting = () => {
|
||||||
|
const { settingStore, hideAction, sortAction, filterAction, refactorAction } = useContext(TableSettingContext);
|
||||||
|
return { settingStore, hideAction, sortAction, filterAction, refactorAction };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTableSetting;
|
||||||
Reference in New Issue
Block a user