diff --git a/.env.local.example b/.env.local.example index fa7066f..0977cbb 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,3 +1,3 @@ -NEXT_PUBLIC_VERSION="0.3.8" +NEXT_PUBLIC_VERSION="0.4.0" NEXT_PUBLIC_API_URL="https://rms.witel.ir" NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map" \ No newline at end of file diff --git a/package.json b/package.json index 36ec3d1..f9593c8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@mui/material": "^5.15.6", "@mui/material-nextjs": "^5.15.6", "@mui/x-date-pickers": "^6.19.5", + "@mui/x-tree-view": "^7.11.0", "axios": "^1.7.2", "date-fns": "^3.3.1", "date-fns-jalali": "^2.13.0-0", diff --git a/src/components/dashboard/inquiryPrivacyFencing/Actions/Create/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/Actions/Create/index.jsx index db8c5c0..de81370 100644 --- a/src/components/dashboard/inquiryPrivacyFencing/Actions/Create/index.jsx +++ b/src/components/dashboard/inquiryPrivacyFencing/Actions/Create/index.jsx @@ -1,12 +1,15 @@ "use client"; import DialogTransition from "@/core/components/DialogTransition"; import { AddCircle, Close } from "@mui/icons-material"; -import { Button, Dialog, DialogTitle, IconButton } from "@mui/material"; +import { Button, Dialog, DialogTitle, IconButton, useMediaQuery } from "@mui/material"; import CreateOrUpdateForm from "../../Forms/CreateOrUpdate"; import { SET_INQUIRE_PRIVACY_FENCING } from "@/core/utils/routes"; import { useState } from "react"; +import { useTheme } from "@emotion/react"; const InquiryPrivacyFencingCreate = ({ mutate }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [open, setOpen] = useState(false); const handleOpen = () => { @@ -19,11 +22,22 @@ const InquiryPrivacyFencingCreate = ({ mutate }) => { return ( <> - + {isMobile ? ( + + + + ) : ( + + )} - + ایجاد پاسخ به استعلام { formData.append('rah_type_id', data.rah_type_id) formData.append('rah_type', data.rah_type_id) formData.append('name_mehvar_id', 1) - formData.append('name_mehvar_fa', data.name_mehvar_id) + formData.append('name_mehvar_fa', data.name_mehvar_fa) formData.append('mizan_harim', data.mizan_harim) formData.append('arze_navar', data.arze_navar) formData.append('samt_id', data.samt_id) diff --git a/src/components/dashboard/inquiryPrivacyFencing/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/index.jsx index 832cd3b..c8dd8c9 100644 --- a/src/components/dashboard/inquiryPrivacyFencing/index.jsx +++ b/src/components/dashboard/inquiryPrivacyFencing/index.jsx @@ -1,351 +1,15 @@ "use client"; -import { useMemo } from "react"; -import Toolbar from "@/components/dashboard/inquiryPrivacyFencing/Toolbar"; -import DataTable from "@/core/components/DataTable"; -import { Box } from "@mui/material"; -import { GET_INQUIRY_PRIVACY_FENCING_ROUTE } from "@/core/utils/routes"; +import PageTitle from "@/core/components/PageTitle"; +import InquiryPrivacyFencingList from "./inquiryPrivacyFencingList"; +import { Stack } from "@mui/material"; const InquiryPrivacyFencingPage = () => { - const columns = useMemo( - () => [ - { - accessorKey: "dabirkhaneh_number", - header: "شماره دبیرخانه درخواست", - id: "dabirkhaneh_number", - enableColumnFilter: false, - datatype: "text", - filterFn: "notEquals", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "marjae_pasokh", - header: "مرجع درخواست کننده پاسخ به استعلام", - id: "marjae_pasokh", - enableColumnFilter: false, - datatype: "text", - filterFn: "equals", - columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "fuzzy"], - }, - { - accessorKey: "motaghazi_is_legal", - header: "متقاضی", - id: "motaghazi_is_legal", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "nameh_date", - header: "تاریخ نامه درخواست", - id: "nameh_date", - enableColumnFilter: false, - datatype: "date", - filterFn: "equals", - }, - { - accessorKey: "motaghazi_type", - header: "نوع متقاضی", - id: "motaghazi_type", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "motaghazi_firstname", - header: "نام متقاضی", - id: "motaghazi_firstname", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "motaghazi_lastname", - header: "نام خانوادگی متقاضی", - id: "motaghazi_lastname", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "national_id", - header: "کد ملی/شناسه ملی", - id: "national_id", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "tel_number", - header: "تلفن", - id: "tel_number", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "mobile_number", - header: "تلفن همراه", - id: "mobile_number", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "address", - header: "آدرس", - id: "address", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "edare_kol", - header: "اداره كل راهداری", - id: "edare_kol", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "edare_shahri", - header: "اداره شهرستان", - id: "edare_shahri", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "rah_type", - header: "نوع راه", - id: "rah_type", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "name_mehvar_fa", - header: "نام محور", - id: "name_mehvar_fa", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "mizan_harim", - header: "میزان حریم", - id: "mizan_harim", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "arze_navar", - header: "عرض نوار تاسیساتی زیربنایی", - id: "arze_navar", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "samt", - header: "سمت", - id: "samt", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "kilometr", - header: "كيلومتر", - id: "kilometr", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "zone", - header: "zone", - id: "zone", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "karbari_type", - header: "نوع کاربری", - id: "karbari_type", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "tarh_title", - header: "عنوان طرح", - id: "tarh_title", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "masahat_zirbana", - header: "مساحت زیربنا", - id: "masahat_zirbana", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "ehdasat_type", - header: "نوع احداثات", - id: "ehdasat_type", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "divarkeshi_distance", - header: "فاصله دیوارکشی از آکس محور", - id: "divarkeshi_distance", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "mahale_ejra", - header: "محل اجرا", - id: "mahale_ejra", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "traffic", - header: "میزان ترافیک", - id: "traffic", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "vaziat_eghtesadi", - header: "وضعیت اقتصادی", - id: "vaziat_eghtesadi", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "has_access", - header: "آیا راه دسترسی از قبل وجود دارد؟", - id: "has_access", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "shomare_estelam_harim", - header: "شماره استعلام دفتر ایمنی و حریم", - id: "shomare_estelam_harim", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "max_month", - header: "ماه", - id: "max_month", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "max_day", - header: "روز", - id: "max_day", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "shomare_tahaodname", - header: "شماره تعهدنامه", - id: "shomare_tahaodname", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "shomare_daftarkhaneh", - header: "شماره دفترخانه", - id: "shomare_daftarkhaneh", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "description", - header: "توضیحات", - id: "description", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - { - accessorKey: "ronevesht", - header: "رونوشت", - id: "ronevesht", - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["equals", "notEquals", "contains"], - }, - ], - [] - ); - return ( - + + + + ); }; export default InquiryPrivacyFencingPage; diff --git a/src/components/dashboard/inquiryPrivacyFencing/inquiryPrivacyFencingList/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/inquiryPrivacyFencingList/index.jsx new file mode 100644 index 0000000..86a2840 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacyFencing/inquiryPrivacyFencingList/index.jsx @@ -0,0 +1,255 @@ +"use client"; + +import { useMemo } from "react"; +import Toolbar from "@/components/dashboard/inquiryPrivacyFencing/Toolbar"; +import DataTable from "@/core/components/DataTable"; +import { GET_INQUIRY_PRIVACY_FENCING_ROUTE } from "@/core/utils/routes"; +import { Box } from "@mui/material"; +import PageTitle from "@/core/components/PageTitle"; + +const InquiryPrivacyFencingList = () => { + const columns = useMemo( + () => [ + { + accessorKey: "dabirkhaneh_number", + header: "شماره دبیرخانه درخواست", + id: "dabirkhaneh_number", + enableColumnFilter: false, + datatype: "text", + filterFn: "notEquals", + }, + { + accessorKey: "marjae_pasokh", + header: "مرجع درخواست کننده پاسخ به استعلام", + id: "marjae_pasokh", + enableColumnFilter: false, + datatype: "text", + filterFn: "equals", + }, + { + accessorKey: "motaghazi_is_legal", + header: "متقاضی", + id: "motaghazi_is_legal", + enableColumnFilter: false, + }, + { + accessorKey: "nameh_date", + header: "تاریخ نامه درخواست", + id: "nameh_date", + enableColumnFilter: false, + }, + { + accessorKey: "motaghazi_type", + header: "نوع متقاضی", + id: "motaghazi_type", + enableColumnFilter: false, + }, + { + accessorKey: "motaghazi_firstname", + header: "نام متقاضی", + id: "motaghazi_firstname", + enableColumnFilter: false, + }, + { + accessorKey: "motaghazi_lastname", + header: "نام خانوادگی متقاضی", + id: "motaghazi_lastname", + enableColumnFilter: false, + }, + { + accessorKey: "national_id", + header: "کد ملی/شناسه ملی", + id: "national_id", + enableColumnFilter: false, + }, + { + accessorKey: "tel_number", + header: "تلفن", + id: "tel_number", + enableColumnFilter: false, + }, + { + accessorKey: "mobile_number", + header: "تلفن همراه", + id: "mobile_number", + enableColumnFilter: false, + }, + { + accessorKey: "address", + header: "آدرس", + id: "address", + enableColumnFilter: false, + }, + { + accessorKey: "edare_kol", + header: "اداره كل راهداری", + id: "edare_kol", + enableColumnFilter: false, + }, + { + accessorKey: "edare_shahri", + header: "اداره شهرستان", + id: "edare_shahri", + enableColumnFilter: false, + }, + { + accessorKey: "rah_type", + header: "نوع راه", + id: "rah_type", + enableColumnFilter: false, + }, + { + accessorKey: "name_mehvar_fa", + header: "نام محور", + id: "name_mehvar_fa", + enableColumnFilter: false, + }, + { + accessorKey: "mizan_harim", + header: "میزان حریم", + id: "mizan_harim", + enableColumnFilter: false, + }, + { + accessorKey: "arze_navar", + header: "عرض نوار تاسیساتی زیربنایی", + id: "arze_navar", + enableColumnFilter: false, + }, + { + accessorKey: "samt", + header: "سمت", + id: "samt", + enableColumnFilter: false, + }, + { + accessorKey: "kilometr", + header: "كيلومتر", + id: "kilometr", + enableColumnFilter: false, + }, + { + accessorKey: "zone", + header: "zone", + id: "zone", + enableColumnFilter: false, + }, + { + accessorKey: "karbari_type", + header: "نوع کاربری", + id: "karbari_type", + enableColumnFilter: false, + }, + { + accessorKey: "tarh_title", + header: "عنوان طرح", + id: "tarh_title", + enableColumnFilter: false, + }, + { + accessorKey: "masahat_zirbana", + header: "مساحت زیربنا", + id: "masahat_zirbana", + enableColumnFilter: false, + }, + { + accessorKey: "ehdasat_type", + header: "نوع احداثات", + id: "ehdasat_type", + enableColumnFilter: false, + }, + { + accessorKey: "divarkeshi_distance", + header: "فاصله دیوارکشی از آکس محور", + id: "divarkeshi_distance", + enableColumnFilter: false, + }, + { + accessorKey: "mahale_ejra", + header: "محل اجرا", + id: "mahale_ejra", + enableColumnFilter: false, + }, + { + accessorKey: "traffic", + header: "میزان ترافیک", + id: "traffic", + enableColumnFilter: false, + }, + { + accessorKey: "vaziat_eghtesadi", + header: "وضعیت اقتصادی", + id: "vaziat_eghtesadi", + enableColumnFilter: false, + }, + { + accessorKey: "has_access", + header: "آیا راه دسترسی از قبل وجود دارد؟", + id: "has_access", + enableColumnFilter: false, + }, + { + accessorKey: "shomare_estelam_harim", + header: "شماره استعلام دفتر ایمنی و حریم", + id: "shomare_estelam_harim", + enableColumnFilter: false, + }, + { + accessorKey: "max_month", + header: "ماه", + id: "max_month", + enableColumnFilter: false, + }, + { + accessorKey: "max_day", + header: "روز", + id: "max_day", + enableColumnFilter: false, + }, + { + accessorKey: "shomare_tahaodname", + header: "شماره تعهدنامه", + id: "shomare_tahaodname", + enableColumnFilter: false, + }, + { + accessorKey: "shomare_daftarkhaneh", + header: "شماره دفترخانه", + id: "shomare_daftarkhaneh", + enableColumnFilter: false, + }, + { + accessorKey: "description", + header: "توضیحات", + id: "description", + enableColumnFilter: false, + }, + { + accessorKey: "ronevesht", + header: "رونوشت", + id: "ronevesht", + enableColumnFilter: false, + }, + ], + [], + ); + + return ( + <> + + + + + ); +}; +export default InquiryPrivacyFencingList; + diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index db3a6f1..1f51695 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -1,35 +1,49 @@ import DataTable_Paper from "./table/Paper"; import { useMaterialReactTable } from "material-react-table"; import { FA_DATATABLE_LOCALIZATION } from "./localization/fa/datatable"; -import useTableSetting from "@/lib/hooks/useTableSetting"; import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects"; import useDataTable from "@/lib/hooks/useDataTable"; import { useMemo, useState } from "react"; import useRequest from "@/lib/hooks/useRequest"; import useSWR from "swr"; +import { flattenObjectOfObjects } from "@/core/utils/flattenObjectOfObjects"; const DataTable_Main = (props) => { const request = useRequest(); - const isEmptyObject = (obj) => obj && Object.keys(obj).length === 0 && obj.constructor === Object; - const { filterData, sortData, setSortData, hideData, setHideData } = useDataTable(); - const { need_filter, table_url, user_id, page_name, table_name, columns, initialStateProps, TableToolbar } = props; + const { filterData, sortData, setSortData, hideData } = useDataTable(); + const { + need_filter, + table_url, + user_id, + page_name, + table_name, + columns, + initialStateProps, + TableToolbar, + table_title, + } = props; const flatColumns = flattenArrayOfObjects(columns, "columns"); - const { settingStore, hideAction } = useTableSetting(); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); - - const onColumnVisibilityChange = (event) => { - setHideData(event); - }; - + const flattenHideData = flattenObjectOfObjects(hideData); const onSortingChange = (event) => { setSortData(event); }; const fetchUrl = useMemo(() => { + const isValueEmpty = (value) => { + if (Array.isArray(value)) { + return value.length === 0 || value.every(v => v === ""); + } + return value === "" || value === null || value === undefined; + }; + const filteredFilterData = Object.values(filterData).filter( + (filter) => !isValueEmpty(filter.value), + ); + const params = new URLSearchParams(); params.set("start", `${pagination.pageIndex * pagination.pageSize}`); params.set("size", pagination.pageSize); - params.set("filters", JSON.stringify(isEmptyObject(filterData) ? [] : [filterData])); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); params.set("sorting", JSON.stringify(sortData)); return `${table_url}?${params}`; }, [table_url, filterData, pagination, columns, sortData]); @@ -56,13 +70,13 @@ const DataTable_Main = (props) => { data: data?.data ?? [], initialState: { density: "compact", - columnVisibility: hideData, + columnVisibility: flattenHideData, sorting: sortData, ...initialStateProps, }, state: { showProgressBars: isValidating, - columnVisibility: hideData, + columnVisibility: flattenHideData, sorting: sortData, pagination, }, @@ -93,7 +107,6 @@ const DataTable_Main = (props) => { manualPagination: true, manualSorting: true, onPaginationChange: setPagination, - onColumnVisibilityChange: onColumnVisibilityChange, onSortingChange: onSortingChange, renderTopToolbarCustomActions: ({ table }) => ( <> @@ -106,6 +119,7 @@ const DataTable_Main = (props) => { return ( { - const { - options: { - icons: { ViewColumnIcon }, - localization, - }, - } = table; - - const [anchorEl, setAnchorEl] = useState(null); - - const handleClick = (event) => { - setAnchorEl(event.currentTarget); - }; - - return ( - <> - - - - - - {anchorEl && } - - ); -}; -export default DataTable_ShowHideColumnsButton; diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index a9bef12..7f0337e 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -18,15 +18,15 @@ const columnFilterModeOptionFa = { }; function FilterBodyField({ - column, - filterParameters, - handleChange, - handleBlur, - setFieldValue, - errors, - touched, - resetForm, -}) { + column, + filterParameters, + handleChange, + handleBlur, + setFieldValue, + errors, + touched, + resetForm, + }) { const [anchorEl, setAnchorEl] = useState(null); const defaultFilterTranslation = columnFilterModeOptionFa[filterParameters.filterFn] || filterParameters.filterFn; @@ -48,8 +48,8 @@ function FilterBodyField({ touched={touched} /> ) : filterParameters.datatype === "numeric" && - filterParameters.filterFn === "equals" && - Array.isArray(column.columnSelectOption) ? ( + filterParameters.filterFn === "equals" && + Array.isArray(column.columnSelectOption) ? ( - + فیلتر diff --git a/src/core/components/DataTable/filter/FilterOptionList.jsx b/src/core/components/DataTable/filter/FilterOptionList.jsx index 86a4745..48492e1 100644 --- a/src/core/components/DataTable/filter/FilterOptionList.jsx +++ b/src/core/components/DataTable/filter/FilterOptionList.jsx @@ -4,14 +4,15 @@ import { ListItem, Menu } from "@mui/material"; import { useState } from "react"; function FilterOptionList({ - column, - filterType, - filterOption, - anchorEl, - columnFilterModeOptionFa, - setAnchorEl, - setFieldValue, -}) { + column, + filterType, + filterOption, + anchorEl, + columnFilterModeOptionFa, + setAnchorEl, + setFieldValue, + }) { + const [selectedFilter, setSelectedFilter] = useState(filterType); const handleChangeItem = (event, index) => { diff --git a/src/core/components/DataTable/hide/HideBody.jsx b/src/core/components/DataTable/hide/HideBody.jsx new file mode 100644 index 0000000..d6e18cb --- /dev/null +++ b/src/core/components/DataTable/hide/HideBody.jsx @@ -0,0 +1,53 @@ +"use client"; + +import { Box, Drawer, styled } from "@mui/material"; +import HideBodyField from "@/core/components/DataTable/hide/HideBodyField"; +import HideHeader from "@/core/components/DataTable/hide/HideHeader"; +import useDataTable from "@/lib/hooks/useDataTable"; +import HideOrShowAll from "@/core/components/DataTable/hide/HideOrShowAll"; + +const ScrollBox = styled(Box)({ + flexGrow: 1, + overflowY: "scroll", + maxWidth: "450px", + "::-webkit-scrollbar": { + width: "5px", + }, + "::-webkit-scrollbar-track": { + boxShadow: "inset 0 0 5px #fff", + borderRadius: "5px", + }, + "::-webkit-scrollbar-thumb": { + background: "#155175", + borderRadius: "0px", + }, +}); + +function HideBody({ columns, drawerState, setDrawerState }) { + const { hideData, setHideData } = useDataTable(); + + return ( + setDrawerState(false)} + sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%" }} + > + + + + + {columns.map((column) => ( + + ))} + + + + ); +} + +export default HideBody; \ No newline at end of file diff --git a/src/core/components/DataTable/hide/HideBodyField.jsx b/src/core/components/DataTable/hide/HideBodyField.jsx new file mode 100644 index 0000000..fe3dc2d --- /dev/null +++ b/src/core/components/DataTable/hide/HideBodyField.jsx @@ -0,0 +1,80 @@ +import { alpha, Box, Checkbox, styled, Typography } from "@mui/material"; +import { SimpleTreeView } from "@mui/x-tree-view"; +import { TreeItem, treeItemClasses } from "@mui/x-tree-view/TreeItem"; + +const CustomTreeItem = styled(TreeItem)(({ theme }) => ({ + [`& .${treeItemClasses.content}`]: { + padding: theme.spacing(0.5, 0.5), + margin: theme.spacing(0.2, 0), + gap: 0, + }, + [`& .${treeItemClasses.iconContainer}`]: { + "& .close": { + opacity: 0.3, + }, + }, + [`& .${treeItemClasses.groupTransition}`]: { + marginLeft: 16, + paddingLeft: 16, + borderLeft: `1px dashed ${alpha(theme.palette.text.primary, 0.4)}`, + }, +})); + +function HideBodyField({ column, hideData, setHideData }) { + const handleCheckboxChange = () => { + setHideData(prevData => { + const updateHideData = (data, id) => { + if (data.hasOwnProperty(id)) { + return { ...data, [id]: !data[id] }; + } + const updatedData = { ...data }; + for (const key in data) { + if (data[key] && typeof data[key] === "object") { + updatedData[key] = updateHideData(data[key], id); + } + } + return updatedData; + }; + + return updateHideData(prevData, column.id); + }); + }; + + const labelContent = (() => { + if (typeof hideData[column.id] === "boolean") { + return ( + + + {column.header} + + ); + } else { + return ( + + {column.header} + + ); + } + })(); + + return ( + + + {column.columns?.map((subColumn) => ( + + ))} + + + ); +} + +export default HideBodyField; \ No newline at end of file diff --git a/src/core/components/DataTable/hide/HideButton.jsx b/src/core/components/DataTable/hide/HideButton.jsx new file mode 100644 index 0000000..de919fe --- /dev/null +++ b/src/core/components/DataTable/hide/HideButton.jsx @@ -0,0 +1,21 @@ +"use client"; + +import ViewColumnIcon from "@mui/icons-material/ViewColumn"; +import { IconButton, Tooltip } from "@mui/material"; + +function HideButton({ drawerState, setDrawerState }) { + return ( + + { + setDrawerState(!drawerState); + }} + aria-label="hide table column" + > + + + + ); +} + +export default HideButton; diff --git a/src/core/components/DataTable/hide/HideHeader.jsx b/src/core/components/DataTable/hide/HideHeader.jsx new file mode 100644 index 0000000..5adcf25 --- /dev/null +++ b/src/core/components/DataTable/hide/HideHeader.jsx @@ -0,0 +1,34 @@ +"use client"; + +import { Box, IconButton, Typography } from "@mui/material"; +import CancelIcon from "@mui/icons-material/Cancel"; +import ViewColumnIcon from "@mui/icons-material/ViewColumn"; + +function FilterHeader({ setDrawerState }) { + return ( + + + + + نمایش/مخفی کردن ستون ها + + + setDrawerState(false)}> + + + + ); +} + +export default FilterHeader; diff --git a/src/core/components/DataTable/hide/HideOrShowAll.jsx b/src/core/components/DataTable/hide/HideOrShowAll.jsx new file mode 100644 index 0000000..3c9131a --- /dev/null +++ b/src/core/components/DataTable/hide/HideOrShowAll.jsx @@ -0,0 +1,70 @@ +"use client"; + +import { Box, Button } from "@mui/material"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; + +const setAllValues = (obj, value) => { + const result = {}; + for (const key in obj) { + if (typeof obj[key] === "object" && obj[key] !== null) { + result[key] = setAllValues(obj[key], value); + } else { + result[key] = value; + } + } + return result; +}; + +const allValuesAre = (obj, value) => { + for (const key in obj) { + if (typeof obj[key] === "object" && obj[key] !== null) { + if (!allValuesAre(obj[key], value)) { + return false; + } + } else if (obj[key] !== value) { + return false; + } + } + return true; +}; + +function HideOrShowAll({ hideData, setHideData }) { + const handleShowAll = () => { + const newHideData = setAllValues(hideData, true); + setHideData(newHideData); + }; + + const handleHideAll = () => { + const newHideData = setAllValues(hideData, false); + setHideData(newHideData); + }; + + const allHidden = allValuesAre(hideData, false); + const allVisible = allValuesAre(hideData, true); + + return ( + + + + + ); +} + +export default HideOrShowAll; \ No newline at end of file diff --git a/src/core/components/DataTable/hide/index.jsx b/src/core/components/DataTable/hide/index.jsx new file mode 100644 index 0000000..b917c56 --- /dev/null +++ b/src/core/components/DataTable/hide/index.jsx @@ -0,0 +1,24 @@ +"use client"; + +import { useState } from "react"; +import HideButton from "@/core/components/DataTable/hide/HideButton"; +import HideBody from "@/core/components/DataTable/hide/HideBody"; + +function HideColumn({ columns, user_id, page_name, table_name }) { + const [open, setOpen] = useState(false); + return ( + <> + + + + ); +} + +export default HideColumn; diff --git a/src/core/components/DataTable/menus/ShowHideColumnsMenu.js b/src/core/components/DataTable/menus/ShowHideColumnsMenu.js deleted file mode 100644 index cb0423c..0000000 --- a/src/core/components/DataTable/menus/ShowHideColumnsMenu.js +++ /dev/null @@ -1,116 +0,0 @@ -import { Box, Button, Divider, Menu } from "@mui/material"; -import { useMemo, useState } from "react"; -import DataTable_ShowHideColumnsMenuItems from "./ShowHideColumnsMenuItems"; - -const DataTable_ShowHideColumnsMenu = ({ anchorEl, setAnchorEl, table, ...rest }) => { - const { - getAllColumns, - getAllLeafColumns, - getCenterLeafColumns, - getIsAllColumnsVisible, - getIsSomeColumnsPinned, - getIsSomeColumnsVisible, - getLeftLeafColumns, - getRightLeafColumns, - getState, - options: { - enableColumnOrdering, - enableColumnPinning, - enableHiding, - localization, - mrtTheme: { menuBackgroundColor }, - }, - } = table; - - const { columnOrder, columnPinning, density } = getState(); - - const handleToggleAllColumns = (value) => { - getAllLeafColumns() - .filter((col) => col.columnDef.enableHiding !== false) - .forEach((col) => col.toggleVisibility(value)); - }; - - const allColumns = useMemo(() => { - const columns = getAllColumns(); - if (columnOrder.length > 0 && !columns.some((col) => col.columnDef.columnDefType === "group")) { - return [ - ...getLeftLeafColumns(), - ...Array.from(new Set(columnOrder)).map((colId) => - getCenterLeafColumns().find((col) => col?.id === colId) - ), - ...getRightLeafColumns(), - ].filter(Boolean); - } - return columns; - }, [ - columnOrder, - columnPinning, - getAllColumns(), - getCenterLeafColumns(), - getLeftLeafColumns(), - getRightLeafColumns(), - ]); - - const isNestedColumns = allColumns.some((col) => col.columnDef.columnDefType === "group"); - - const [hoveredColumn, setHoveredColumn] = useState(null); - - return ( - setAnchorEl(null)} - open={!!anchorEl} - {...rest} - > - - {enableHiding && ( - - )} - {enableColumnOrdering && ( - - )} - {enableColumnPinning && ( - - )} - {enableHiding && ( - - )} - - - {allColumns.map((column, index) => ( - - ))} - - ); -}; -export default DataTable_ShowHideColumnsMenu; diff --git a/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js b/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js deleted file mode 100644 index 97c2e5d..0000000 --- a/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js +++ /dev/null @@ -1,154 +0,0 @@ -import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils"; -import { Box, FormControlLabel, MenuItem, Switch, Tooltip, Typography } from "@mui/material"; -import { useRef, useState } from "react"; -import DataTable_GrabHandleButton from "../buttons/GrabHandleButton"; - -const DataTable_ShowHideColumnsMenuItems = ({ - allColumns, - column, - hoveredColumn, - isNestedColumns, - setHoveredColumn, - table, - ...rest -}) => { - const { - getState, - options: { - enableColumnOrdering, - enableHiding, - localization, - mrtTheme: { draggingBorderColor }, - }, - setColumnOrder, - } = table; - - const { columnOrder } = getState(); - const { columnDef } = column; - const { columnDefType } = columnDef; - - const switchChecked = column.getIsVisible(); - - const handleToggleColumnHidden = (column) => { - if (columnDefType === "group") { - column?.columns?.forEach?.((childColumn) => { - childColumn.toggleVisibility(!switchChecked); - }); - } else { - column.toggleVisibility(); - } - }; - - const menuItemRef = useRef(null); - - const [isDragging, setIsDragging] = useState(false); - - const handleDragStart = (e) => { - setIsDragging(true); - try { - e.dataTransfer.setDragImage(menuItemRef.current, 0, 0); - } catch (e) { - console.error(e); - } - }; - - const handleDragEnd = (_e) => { - setIsDragging(false); - setHoveredColumn(null); - if (hoveredColumn) { - setColumnOrder(reorderColumn(column, hoveredColumn, columnOrder)); - } - }; - - const handleDragEnter = (_e) => { - if (!isDragging && columnDef.enableColumnOrdering !== false) { - setHoveredColumn(column); - } - }; - - if (!columnDef.header || columnDef.visibleInShowHideMenu === false) { - return null; - } - - return ( - <> - ({ - alignItems: "center", - justifyContent: "flex-start", - my: 0, - opacity: isDragging ? 0.5 : 1, - outline: isDragging - ? `2px dashed ${theme.palette.grey[500]}` - : hoveredColumn?.id === column.id - ? `2px dashed ${draggingBorderColor}` - : "none", - outlineOffset: "-2px", - pl: `${(column.depth + 0.5) * 2}rem`, - py: "6px", - ...parseFromValuesOrFunc(rest?.sx, theme), - })} - > - - {columnDefType !== "group" && - enableColumnOrdering && - !isNestedColumns && - (columnDef.enableColumnOrdering !== false ? ( - - ) : ( - - ))} - {enableHiding ? ( - - - - } - disabled={!column.getCanHide()} - label={columnDef.header} - onChange={() => handleToggleColumnHidden(column)} - /> - ) : ( - {columnDef.header} - )} - - - {column.columns?.map((c, i) => ( - - ))} - - ); -}; -export default DataTable_ShowHideColumnsMenuItems; diff --git a/src/core/components/DataTable/reset/ResetStorage.jsx b/src/core/components/DataTable/reset/ResetStorage.jsx new file mode 100644 index 0000000..6d8a534 --- /dev/null +++ b/src/core/components/DataTable/reset/ResetStorage.jsx @@ -0,0 +1,22 @@ +"use client"; + +import { IconButton, Tooltip } from "@mui/material"; +import AutorenewIcon from "@mui/icons-material/Autorenew"; +import useTableSetting from "@/lib/hooks/useTableSetting"; + +function ResetStorage({ user_id, page_name, table_name }) { + const { resetAction } = useTableSetting(); + const reset = () => { + resetAction(user_id, page_name, table_name); + }; + + return ( + + + + + + ); +} + +export default ResetStorage; \ No newline at end of file diff --git a/src/core/components/DataTable/table/Paper.js b/src/core/components/DataTable/table/Paper.js index 289cabd..05a0dbb 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -5,16 +5,17 @@ import DataTable_TopToolbar from "../toolbar/TopToolbar"; import DataTable_TableContainer from "./TableContainer"; const DataTable_Paper = ({ - table, - table_name, - columns, - user_id, - page_name, - mutate, - need_filter, - table_url, - ...rest -}) => { + table, + table_name, + columns, + user_id, + page_name, + mutate, + need_filter, + table_url, + table_title, + ...rest + }) => { const { getState, options: { @@ -49,19 +50,19 @@ const DataTable_Paper = ({ style={{ ...(isFullScreen ? { - bottom: 0, - height: "100dvh", - left: 0, - margin: 0, - maxHeight: "100dvh", - maxWidth: "100dvw", - padding: 0, - position: "fixed", - right: 0, - top: 0, - width: "100dvw", - zIndex: 999, - } + bottom: 0, + height: "100dvh", + left: 0, + margin: 0, + maxHeight: "100dvh", + maxWidth: "100dvw", + padding: 0, + position: "fixed", + right: 0, + top: 0, + width: "100dvw", + zIndex: 999, + } : {}), ...paperProps?.style, }} @@ -84,6 +85,7 @@ const DataTable_Paper = ({ user_id={user_id} page_name={page_name} table_name={table_name} + table_title={table_title} /> ))} diff --git a/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js b/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js deleted file mode 100644 index 9250b89..0000000 --- a/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js +++ /dev/null @@ -1,44 +0,0 @@ -import { parseFromValuesOrFunc } from "@/core/utils/utils"; -import { Box } from "@mui/material"; -import DataTable_ShowHideColumnsButton from "../buttons/ShowHideColumnsButton"; -import DataTable_ToggleFiltersButton from "../buttons/ToggleFiltersButton"; - -const DataTable_ToolbarInternalButtons = ({ table, ...rest }) => { - const { - options: { - columnFilterDisplayMode, - enableColumnFilters, - enableColumnOrdering, - enableColumnPinning, - enableFilters, - enableHiding, - renderToolbarInternalActions, - }, - } = table; - - return ( - ({ - alignItems: "center", - display: "flex", - zIndex: 3, - ...parseFromValuesOrFunc(rest?.sx, theme), - })} - > - {renderToolbarInternalActions?.({ - table, - }) ?? ( - <> - {enableFilters && enableColumnFilters && columnFilterDisplayMode !== "popover" && ( - - )} - {(enableHiding || enableColumnOrdering || enableColumnPinning) && ( - - )} - - )} - - ); -}; -export default DataTable_ToolbarInternalButtons; diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 88ad219..fc21ae7 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -1,12 +1,23 @@ import { getCommonToolbarStyles, parseFromValuesOrFunc } from "@/core/utils/utils"; -import { Box, useMediaQuery } from "@mui/material"; +import { Box, Typography, useMediaQuery } from "@mui/material"; import DataTable_LinearProgressBar from "./LinearProgressBar"; import DataTable_TablePagination from "./TablePagination"; -import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import FilterColumn from "@/core/components/DataTable/filter"; -import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; +import UpdateTable from "@/core/components/DataTable/update/UpdateTable"; +import ResetStorage from "@/core/components/DataTable/reset/ResetStorage"; +import HideColumn from "@/core/components/DataTable/hide"; -const DataTable_TopToolbar = ({ mutate, need_filter, table, columns, table_url, user_id, page_name, table_name }) => { +const DataTable_TopToolbar = ({ + mutate, + need_filter, + table, + columns, + table_url, + user_id, + page_name, + table_name, + table_title, + }) => { const { getState, options: { @@ -46,11 +57,12 @@ const DataTable_TopToolbar = ({ mutate, need_filter, table, columns, table_url, > - {renderTopToolbarCustomActions?.({ table }) ?? } + {renderTopToolbarCustomActions?.({ table })} + {table_title || ""} {enableToolbarInternalActions && ( - + + + {need_filter && ( )} - )} diff --git a/src/core/components/DataTable/refactor/RefactorTable.jsx b/src/core/components/DataTable/update/UpdateTable.jsx similarity index 53% rename from src/core/components/DataTable/refactor/RefactorTable.jsx rename to src/core/components/DataTable/update/UpdateTable.jsx index e9ed9ff..8a60c8d 100644 --- a/src/core/components/DataTable/refactor/RefactorTable.jsx +++ b/src/core/components/DataTable/update/UpdateTable.jsx @@ -2,18 +2,18 @@ import { IconButton, Tooltip } from "@mui/material"; import RestartAltIcon from "@mui/icons-material/RestartAlt"; -function RefactorTable({ mutate }) { - const refactor = () => { +function UpdateTable({ mutate }) { + const update = () => { mutate(); }; return ( - - + + ); } -export default RefactorTable; +export default UpdateTable; diff --git a/src/core/components/NotificationDesign/AskForKeepData.jsx b/src/core/components/NotificationDesign/AskForKeepData.jsx index 58475c1..203a3db 100644 --- a/src/core/components/NotificationDesign/AskForKeepData.jsx +++ b/src/core/components/NotificationDesign/AskForKeepData.jsx @@ -5,9 +5,11 @@ 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"; +import { flattenObjectOfObjects } from "@/core/utils/flattenObjectOfObjects"; function AskForKeepData({ filterData, sortData, hideData, user_id, page_name, table_name, columns }) { const { filterAction, sortAction, hideAction } = useTableSetting(); + const flattenHideData = flattenObjectOfObjects(hideData); const onSaveFilter = () => { const filteredItems = Object.keys(filterData) @@ -26,7 +28,7 @@ function AskForKeepData({ filterData, sortData, hideData, user_id, page_name, ta .filter(Boolean); filterAction(user_id, page_name, table_name, filteredItems, columns); sortAction(user_id, page_name, table_name, sortData, columns); - hideAction(user_id, page_name, table_name, hideData, columns); + hideAction(user_id, page_name, table_name, flattenHideData, columns); toast.dismiss({ containerId: "datatable" }); }; @@ -37,42 +39,33 @@ function AskForKeepData({ filterData, sortData, hideData, user_id, page_name, ta return ( - + ذخیره سازی تغییرات - + آیا مایل به ذخیره تغییر های اعمال شده برای دفعات بعد هستید؟ - + - + ); } -export default AskForKeepData; +export default AskForKeepData; \ No newline at end of file diff --git a/src/core/components/PageTitle.jsx b/src/core/components/PageTitle.jsx new file mode 100644 index 0000000..605ad47 --- /dev/null +++ b/src/core/components/PageTitle.jsx @@ -0,0 +1,12 @@ +"use client"; + +import { Chip, Divider, Typography } from "@mui/material"; + +const PageTitle = ({ title }) => { + return ( + {title}} /> + ); +}; +export default PageTitle; + diff --git a/src/core/utils/flattenArrayOfObjects.js b/src/core/utils/flattenArrayOfObjects.js index 5b1564c..ec3cc23 100644 --- a/src/core/utils/flattenArrayOfObjects.js +++ b/src/core/utils/flattenArrayOfObjects.js @@ -1,10 +1,10 @@ export const flattenArrayOfObjects = (array, key) => { return array.reduce((acc, obj) => { + acc.push(obj); if (Array.isArray(obj[key])) { - acc.push(...flattenArrayOfObjects(obj[key])); - } else { - acc.push(obj); + acc.push(...flattenArrayOfObjects(obj[key], key)); } return acc; }, []); }; + diff --git a/src/core/utils/flattenObjectOfObjects.jsx b/src/core/utils/flattenObjectOfObjects.jsx new file mode 100644 index 0000000..3fdac84 --- /dev/null +++ b/src/core/utils/flattenObjectOfObjects.jsx @@ -0,0 +1,12 @@ +export const flattenObjectOfObjects = (obj, res = {}) => { + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + if (typeof obj[key] === "object" && obj[key] !== null) { + flattenObjectOfObjects(obj[key], res); + } else { + res[key] = obj[key]; + } + } + } + return res; +}; \ No newline at end of file diff --git a/src/lib/contexts/DataTable.js b/src/lib/contexts/DataTable.js index 3ada093..f5a625d 100644 --- a/src/lib/contexts/DataTable.js +++ b/src/lib/contexts/DataTable.js @@ -19,44 +19,64 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns } useEffect(() => { if (!settingStore) return; - const values = flatColumns.reduce((acc, column) => { + const filterValues = 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 + 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: filter?.value || [], - filterFn: filter?.filterFn || column._filterFn, + value: storeFilter?.value || [], + filterFn: storeFilter?.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, + value: storeFilter?.value || ["", ""], + filterFn: storeFilter?.filterFn || column._filterFn, datatype: column.datatype, }; } else { acc[column.id] = { id: column.id, - value: filter?.value || "", - filterFn: filter?.filterFn || column._filterFn, + value: storeFilter?.value || "", + filterFn: storeFilter?.filterFn || column._filterFn, datatype: column.datatype, }; } return acc; }, {}); - setFilterData(values); - setInitFilter(values); + setFilterData(filterValues); + setInitFilter(filterValues); setSortData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []); setInitSort(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []); - setHideData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"] || {}); - setInitHide(settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"] || {}); setInitStates(true); }, [settingStore, isInitStates]); + useEffect(() => { + const getHideValues = (columns) => { + return columns.reduce((acc, column) => { + const columnId = column.id; + const storeHide = settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"]?.[columnId]; + + // If the column has nested columns, process them recursively + 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); + }, [settingStore, isInitStates]); + useEffect(() => { if ( JSON.stringify(initFilter) !== JSON.stringify(filterData) || @@ -81,7 +101,7 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns } position: "bottom-left", draggable: true, autoClose: false, - } + }, ); } else { toast.update("keep_data", { diff --git a/src/lib/contexts/tableSetting.js b/src/lib/contexts/tableSetting.js index b5b63d9..064fab2 100644 --- a/src/lib/contexts/tableSetting.js +++ b/src/lib/contexts/tableSetting.js @@ -21,6 +21,23 @@ export const TableSettingProvider = ({ children }) => { const filterAction = (user_id, page_name, table_name, settingValue, columns) => { updateSettingStorage(user_id, page_name, table_name, "filters", settingValue, columns); }; + const resetAction = (user_id, page_name, table_name) => { + const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; + const userSettings = prevLocalStorage[user_id] || {}; + const pageSettings = userSettings[page_name] || {}; + delete pageSettings[table_name]; + const resetData = { + ...prevLocalStorage, + [user_id]: { + ...userSettings, + [page_name]: { + ...pageSettings, + }, + }, + }; + localStorage.setItem("_setting-app", JSON.stringify(resetData)); + setSettingStore(resetData); + }; const updateSettingStorage = (user_id, page_name, table_name, settingType, settingValue, columns) => { const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; const userSettings = prevLocalStorage[user_id] || {}; @@ -46,7 +63,7 @@ export const TableSettingProvider = ({ children }) => { ...tableSettings, [settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings }, }, - columns + columns, ), }, }, @@ -117,7 +134,7 @@ export const TableSettingProvider = ({ children }) => { }; return ( - + {children} ); diff --git a/src/lib/hooks/useTableSetting.js b/src/lib/hooks/useTableSetting.js index e9e6cef..c841ffc 100644 --- a/src/lib/hooks/useTableSetting.js +++ b/src/lib/hooks/useTableSetting.js @@ -2,8 +2,8 @@ import { useContext } from "react"; import { TableSettingContext } from "../contexts/tableSetting"; const useTableSetting = () => { - const { settingStore, hideAction, sortAction, filterAction } = useContext(TableSettingContext); - return { settingStore, hideAction, sortAction, filterAction }; + const { settingStore, hideAction, sortAction, filterAction, resetAction } = useContext(TableSettingContext); + return { settingStore, hideAction, sortAction, filterAction, resetAction }; }; export default useTableSetting;