From 0445fc833142576c9395e359a76b97f3caaf46dc Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 29 Apr 2024 16:35:27 +0330 Subject: [PATCH 01/28] clear structure of datatable directories --- src/app/page.js | 144 +----------- src/components/CustomToolbar.jsx | 20 -- src/components/DataTableTest.jsx | 104 --------- src/components/MapTest.jsx | 41 ---- src/components/home/Toolbar.jsx | 20 ++ .../{DataTableMain.jsx => home/index.jsx} | 77 ++++--- src/core/components/DataTable/Main.js | 4 +- .../DataTable/filter}/BetweenNumberFilter.jsx | 0 .../filter/DatePicker}/BetweenDateFilter.jsx | 14 +- .../filter/DatePicker}/MuiDatePicker.jsx | 0 .../DataTable/filter}/FilterColumn.jsx | 95 ++++---- .../DataTable/filter}/SelectBox.jsx | 0 .../DataTable/filter}/SelectBoxMultiple.jsx | 0 .../filter/TextFieldWithFnBox}/FilterBox.jsx | 0 .../TextFieldWithFnBox.jsx | 20 +- src/core/components/DataTable/index.js | 205 +++++++++--------- src/core/components/DataTable/table/Paper.js | 138 ++++++------ .../DataTable/toolbar/TopToolbar.js | 24 +- 18 files changed, 321 insertions(+), 585 deletions(-) delete mode 100644 src/components/CustomToolbar.jsx delete mode 100644 src/components/DataTableTest.jsx delete mode 100644 src/components/MapTest.jsx create mode 100644 src/components/home/Toolbar.jsx rename src/components/{DataTableMain.jsx => home/index.jsx} (64%) rename src/{components => core/components/DataTable/filter}/BetweenNumberFilter.jsx (100%) rename src/{components => core/components/DataTable/filter/DatePicker}/BetweenDateFilter.jsx (56%) rename src/{components => core/components/DataTable/filter/DatePicker}/MuiDatePicker.jsx (100%) rename src/{components => core/components/DataTable/filter}/FilterColumn.jsx (75%) rename src/{components => core/components/DataTable/filter}/SelectBox.jsx (100%) rename src/{components => core/components/DataTable/filter}/SelectBoxMultiple.jsx (100%) rename src/{components => core/components/DataTable/filter/TextFieldWithFnBox}/FilterBox.jsx (100%) rename src/{components => core/components/DataTable/filter/TextFieldWithFnBox}/TextFieldWithFnBox.jsx (59%) diff --git a/src/app/page.js b/src/app/page.js index ed41c91..9d660d7 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,148 +1,8 @@ 'use client' -import DataTable from "@/core/components/DataTable"; -import { useMemo } from "react"; +import HomeComponent from "@/components/home"; function Page() { - const columns = useMemo( - () => [ - { - accessorKey: 'fullname', - header: 'نام کامل', - id: "fullname", - columns: [ - { - accessorKey: 'name.firstName', - header: 'نام', - id: "firstName", - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - enableClickToCopy: true, - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], - }, - { - accessorKey: 'name.lastName', - header: 'نام خانوادگی', - id: "lastName", - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], - }, - ], - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], - }, - { - accessorKey: 'address', - header: 'آدرس', - id: "address", - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], - }, - { - accessorKey: 'city', - header: 'شهر', - id: "city", - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains", - "lessThan", - "greaterThan", - "between", - ], - - }, - { - accessorKey: 'state', - header: 'وضعیت', - id: "state", - text: 'نام', - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], - }, - { - accessorKey: 'state', - header: 'محدوده', - id: "betweenNum", - text: 'محدوده', - enableColumnFilter: true, - datatype: "text", - filterFn: "betweenNum", - columnFilterModeOptions: [], - }, - { - accessorKey: 'state', - header: 'تاریخ', - id: "betweenDate", - text: 'تاریخ', - enableColumnFilter: true, - datatype: "text", - filterFn: "betweenDate", - columnFilterModeOptions: [], - }, - { - accessorKey: 'state', - header: 'شلکت', - id: "select2", - text: 'تاریخ', - type: 'select2', - enableColumnFilter: true, - datatype: "text", - filterFn: "equals", - columnFilterModeOptions: [], - }, - { - accessorKey: 'state', - header: 'سلکت', - id: "select", - text: 'تنتنت', - type: 'select', - enableColumnFilter: true, - datatype: "text", - filterFn: "equals", - columnFilterModeOptions: [], - }, - ], - [], - ); - - return ( - <> - - - - ); + return ; } export default Page; diff --git a/src/components/CustomToolbar.jsx b/src/components/CustomToolbar.jsx deleted file mode 100644 index 344b5da..0000000 --- a/src/components/CustomToolbar.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import FilterColumn from "@/components/FilterColumn"; - -const CustomToolbar = ({columns}) => { - return ( - - ) -} -export default CustomToolbar - - - - - - - - - - - - diff --git a/src/components/DataTableTest.jsx b/src/components/DataTableTest.jsx deleted file mode 100644 index bf610fb..0000000 --- a/src/components/DataTableTest.jsx +++ /dev/null @@ -1,104 +0,0 @@ -"use client" -import {useMemo, useState} from 'react'; -import {MaterialReactTable} from 'material-react-table'; -import useTableSetting from "@/lib/hooks/useTableSetting"; -import {IconButton, Tooltip, Typography} from "@mui/material"; -import CustomToolbar from "@/components/CustomToolbar"; - - -const data = [ - { - name: { - firstName: 'John', - lastName: 'Doe', - }, - address: '261 Erdman Ford', - city: 'East Daphne', - state: 'Kentucky', - }, - { - name: { - firstName: 'Jane', - lastName: 'Doe', - }, - address: '769 Dominic Grove', - city: 'Columbus', - state: 'Ohio', - }, - { - name: { - firstName: 'Joe', - lastName: 'Doe', - }, - address: '566 Brakus Inlet', - city: 'South Linda', - state: 'West Virginia', - }, - { - name: { - firstName: 'Kevin', - lastName: 'Vandy', - }, - address: '722 Emie Stream', - city: 'Lincoln', - state: 'Nebraska', - }, - { - name: { - firstName: 'Joshua', - lastName: 'Rolluffs', - }, - address: '32188 Larkin Turnpike', - city: 'Charleston', - state: 'South Carolina', - }, -]; - -function RefreshIcon() { - return null; -} - -const TestDataTable = ({columns}) => { - const [userId, setUserId] = useState(2); - const [pageName, setPageName] = useState('loan'); - const [tableName, setTableName] = useState('loan_table'); - const {settingStore, hideAction, filterAction, sortAction,} = useTableSetting(); - - const onColumnVisibilityChange = (event) => { - const settingValue = event(); - hideAction(userId, pageName, tableName, settingValue, columns); - }; - const onSortingChange = (event) => { - const settingValue = event(settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || []); - sortAction(userId, pageName, tableName, settingValue, columns); - } - - return ( - <> - {settingStore?.[userId]?.[pageName]?.[tableName]?.['summary']} - (<> - - )} - initialState={{ - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] - }} - state={{ - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] - }} - onColumnVisibilityChange={onColumnVisibilityChange} - onSortingChange={onSortingChange} - /> - - ); -}; - -export default TestDataTable; - diff --git a/src/components/MapTest.jsx b/src/components/MapTest.jsx deleted file mode 100644 index 8ccea0a..0000000 --- a/src/components/MapTest.jsx +++ /dev/null @@ -1,41 +0,0 @@ -"use client" -import {Typography} from "@mui/material"; - -const data = [ - { - id : "hello", - Subitems : [ - {id : "amin",firstName : "amin", lastName:"ali",Subitems : [{id : "shahrokh",shahrokh : "shahrokh"}], hasSubitems : true, showSubitems : false}, - {id : "amir",firstName : "amir", lastName:"akbar", hasSubitems : false, showSubitems : false}, - ], - hasSubitems : true, - showSubitems : false - }, - { - id : "hi", - Subitems : [ - {id : "ali",firstName : "ali", lastName:"ali", hasSubitems : false, showSubitems : false}, - {id : "akbar",firstName : "akbar", lastName:"akbar", hasSubitems : false, showSubitems : false}, - ], - hasSubitems : true, - showSubitems : false - } -] -const MapTest = () => { - const Amin = data.map((item) => { - return item.hasSubitems ? {...item, Subitems: item.Subitems.map((subitem) => true ? { - ...subitem, showSubitems: !item.showSubitems - } : subitem)} : item - }) - - - console.log(Amin) - - - return ( - <> - hello - - ) -} -export default MapTest \ No newline at end of file diff --git a/src/components/home/Toolbar.jsx b/src/components/home/Toolbar.jsx new file mode 100644 index 0000000..437f6ee --- /dev/null +++ b/src/components/home/Toolbar.jsx @@ -0,0 +1,20 @@ +import {Button} from "@mui/material"; + +const Toolbar = ({columns}) => { + return ( + + ) +} +export default Toolbar + + + + + + + + + + + + diff --git a/src/components/DataTableMain.jsx b/src/components/home/index.jsx similarity index 64% rename from src/components/DataTableMain.jsx rename to src/components/home/index.jsx index a6e8c91..b059e6a 100644 --- a/src/components/DataTableMain.jsx +++ b/src/components/home/index.jsx @@ -1,30 +1,43 @@ -import DataTableTest from "@/components/DataTableTest"; -import FilterColumn from "@/components/FilterColumn"; +'use client' +import DataTable from "@/core/components/DataTable"; import {useMemo} from "react"; -import {Button} from "@mui/material"; -function DataTableMain() { +function HomeComponent() { const columns = useMemo( () => [ { - accessorKey: 'name.firstName', - header: 'نام', - size: 150, - id: "firstName", - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" + accessorKey: 'fullname', + header: 'نام کامل', + id: "fullname", + columns: [ + { + accessorKey: 'name.firstName', + header: 'نام', + id: "firstName", + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + enableClickToCopy: true, + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains" + ], + }, + { + accessorKey: 'name.lastName', + header: 'نام خانوادگی', + id: "lastName", + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains" + ], + }, ], - }, - { - accessorKey: 'name.lastName', - header: 'نام خانوادگی', - size: 150, - id: "lastName", enableColumnFilter: true, datatype: "text", filterFn: "contains", @@ -37,7 +50,6 @@ function DataTableMain() { { accessorKey: 'address', header: 'آدرس', - size: 200, id: "address", enableColumnFilter: true, datatype: "text", @@ -51,7 +63,6 @@ function DataTableMain() { { accessorKey: 'city', header: 'شهر', - size: 150, id: "city", enableColumnFilter: true, datatype: "text", @@ -69,9 +80,8 @@ function DataTableMain() { { accessorKey: 'state', header: 'وضعیت', - size: 150, id: "state", - text:'نام', + text: 'نام', enableColumnFilter: true, datatype: "text", filterFn: "contains", @@ -84,9 +94,8 @@ function DataTableMain() { { accessorKey: 'state', header: 'محدوده', - size: 150, id: "betweenNum", - text:'محدوده', + text: 'محدوده', enableColumnFilter: true, datatype: "text", filterFn: "betweenNum", @@ -95,9 +104,8 @@ function DataTableMain() { { accessorKey: 'state', header: 'تاریخ', - size: 150, id: "betweenDate", - text:'تاریخ', + text: 'تاریخ', enableColumnFilter: true, datatype: "text", filterFn: "betweenDate", @@ -106,9 +114,8 @@ function DataTableMain() { { accessorKey: 'state', header: 'شلکت', - size: 150, id: "select2", - text:'تاریخ', + text: 'تاریخ', type: 'select2', enableColumnFilter: true, datatype: "text", @@ -118,9 +125,8 @@ function DataTableMain() { { accessorKey: 'state', header: 'سلکت', - size: 150, id: "select", - text:'تنتنت', + text: 'تنتنت', type: 'select', enableColumnFilter: true, datatype: "text", @@ -130,12 +136,13 @@ function DataTableMain() { ], [], ); + return ( <> - + ); } -export default DataTableMain; +export default HomeComponent; diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index 4a38956..d6efd7a 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -1,4 +1,4 @@ -import { useMaterialReactTable } from "material-react-table"; +import {useMaterialReactTable} from "material-react-table"; import DataTable_Paper from "./table/Paper"; const isTableInstanceProp = (props) => props.table !== undefined; @@ -13,7 +13,7 @@ const DataTable_Main = (props) => { table = useMaterialReactTable(props); } - return ; + return ; }; export default DataTable_Main; diff --git a/src/components/BetweenNumberFilter.jsx b/src/core/components/DataTable/filter/BetweenNumberFilter.jsx similarity index 100% rename from src/components/BetweenNumberFilter.jsx rename to src/core/components/DataTable/filter/BetweenNumberFilter.jsx diff --git a/src/components/BetweenDateFilter.jsx b/src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx similarity index 56% rename from src/components/BetweenDateFilter.jsx rename to src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx index e8e8c18..0e4a325 100644 --- a/src/components/BetweenDateFilter.jsx +++ b/src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx @@ -1,8 +1,8 @@ import {Grid} from '@mui/material'; -import MuiDatePicker from "@/components/MuiDatePicker"; +import MuiDatePicker from "@/core/components/DataTable/filter/DatePicker/MuiDatePicker"; import {useEffect, useState} from "react"; -const BetWeenDateFilter = ({formik, id , defaultValue}) => { +const BetWeenDateFilter = ({formik, id, defaultValue}) => { useEffect(() => { formik.setFieldValue(`${id}[0]`, defaultValue?.[0] || ''); formik.setFieldValue(`${id}[1]`, defaultValue?.[1] || ''); @@ -19,10 +19,14 @@ const BetWeenDateFilter = ({formik, id , defaultValue}) => { return ( - handleDateChange(0, value)}/> + handleDateChange(0, value)}/> - - handleDateChange(1, value)}/> + + handleDateChange(1, value)}/> ); diff --git a/src/components/MuiDatePicker.jsx b/src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx similarity index 100% rename from src/components/MuiDatePicker.jsx rename to src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx diff --git a/src/components/FilterColumn.jsx b/src/core/components/DataTable/filter/FilterColumn.jsx similarity index 75% rename from src/components/FilterColumn.jsx rename to src/core/components/DataTable/filter/FilterColumn.jsx index 08e42c0..1daa295 100644 --- a/src/components/FilterColumn.jsx +++ b/src/core/components/DataTable/filter/FilterColumn.jsx @@ -1,21 +1,17 @@ "use client" -import { - Box, - Button, Divider, Drawer, - FormControl, IconButton, styled, Typography -} from '@mui/material'; +import {Box, Button, Divider, Drawer, FormControl, IconButton, styled, Tooltip, Typography} from '@mui/material'; import {useFormik} from 'formik'; -import TextFieldWithFnBox from "@/components/TextFieldWithFnBox"; +import TextFieldWithFnBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox"; import {useEffect, useState} from "react"; import useTableSetting from "@/lib/hooks/useTableSetting"; -import BetweenNumberFilter from "@/components/BetweenNumberFilter"; -import BetWeenDateFilter from "@/components/BetweenDateFilter"; -import SelectBoxMultiple from "@/components/SelectBoxMultiple"; -import SelectBox from "@/components/SelectBox"; +import BetweenNumberFilter from "@/core/components/DataTable/filter/BetweenNumberFilter"; +import BetWeenDateFilter from "@/core/components/DataTable/filter/DatePicker/BetweenDateFilter"; +import SelectBoxMultiple from "@/core/components/DataTable/filter/SelectBoxMultiple"; +import SelectBox from "@/core/components/DataTable/filter/SelectBox"; +import FilterAltIcon from '@mui/icons-material/FilterAlt'; import CloseIcon from '@mui/icons-material/Close'; -import { useTheme } from '@mui/material/styles'; -function FilterColumn({ columns }) { +function FilterColumn({columns}) { const [open, setOpen] = useState(false); const [selectedFilters, setSelectedFilters] = useState([]); const [userId, setUserId] = useState(2); @@ -23,7 +19,7 @@ function FilterColumn({ columns }) { const [tableName, setTableName] = useState('loan_table'); const {settingStore, hideAction, filterAction, sortAction,} = useTableSetting(); - const DrawerHeader = styled('div')(({ theme }) => ({ + const DrawerHeader = styled('div')(({theme}) => ({ display: 'flex', alignItems: 'center', padding: theme.spacing(0, 1), @@ -48,7 +44,7 @@ function FilterColumn({ columns }) { updatedFilters[filterIndex].fn = filterFn; setSelectedFilters(updatedFilters); } else { - const newFilter = { id: fieldName, fn: filterFn }; + const newFilter = {id: fieldName, fn: filterFn}; const updatedFilters = [...selectedFilters, newFilter]; setSelectedFilters(updatedFilters); } @@ -59,11 +55,9 @@ function FilterColumn({ columns }) { const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); if (column.filterFn === 'betweenNum' || column.filterFn === 'betweenDate') { acc[column.id] = filter?.value || ["", ""]; - } - else if ( column.type === 'select2' ) { + } else if (column.type === 'select2') { acc[column.id] = filter?.value || []; - } - else { + } else { acc[column.id] = filter?.value || ''; } } @@ -76,7 +70,7 @@ function FilterColumn({ columns }) { const updatedFilters = selectedFilters.map(filter => { const value = values[filter.id]; if (value !== undefined) { - return { ...filter, value }; + return {...filter, value}; } return filter; }); @@ -84,7 +78,7 @@ function FilterColumn({ columns }) { const filterIndex = updatedFilters.findIndex(filter => filter.id === fieldName); if (filterIndex === -1 && value !== '' && value !== null && value !== undefined) { const column = columns.find(col => col.id === fieldName); - updatedFilters.push({ id: fieldName, value, fn: column.filterFn, datatype: column.datatype }); + updatedFilters.push({id: fieldName, value, fn: column.filterFn, datatype: column.datatype}); } }); @@ -107,29 +101,33 @@ function FilterColumn({ columns }) { return ( <> - - + + + + + فیلتر @@ -137,7 +135,7 @@ function FilterColumn({ columns }) { - + {columns.map((column, index) => ( column.enableColumnFilter && @@ -188,10 +186,11 @@ function FilterColumn({ columns }) { ))} - - - - + + + + diff --git a/src/components/SelectBox.jsx b/src/core/components/DataTable/filter/SelectBox.jsx similarity index 100% rename from src/components/SelectBox.jsx rename to src/core/components/DataTable/filter/SelectBox.jsx diff --git a/src/components/SelectBoxMultiple.jsx b/src/core/components/DataTable/filter/SelectBoxMultiple.jsx similarity index 100% rename from src/components/SelectBoxMultiple.jsx rename to src/core/components/DataTable/filter/SelectBoxMultiple.jsx diff --git a/src/components/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx similarity index 100% rename from src/components/FilterBox.jsx rename to src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx diff --git a/src/components/TextFieldWithFnBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx similarity index 59% rename from src/components/TextFieldWithFnBox.jsx rename to src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx index 6ba443b..18600dc 100644 --- a/src/components/TextFieldWithFnBox.jsx +++ b/src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx @@ -1,9 +1,17 @@ -import {IconButton, Paper, TextField} from '@mui/material'; +import {IconButton, TextField} from '@mui/material'; import ArtTrackIcon from '@mui/icons-material/ArtTrack'; import {useEffect, useState} from "react"; -import FilterBox from "@/components/FilterBox"; +import FilterBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox"; -const TextFieldWithFnBox = ({formik, id , header, defaultValue, defaultFilter , columnFilterModeOptions ,onSelectFilter}) => { +const TextFieldWithFnBox = ({ + formik, + id, + header, + defaultValue, + defaultFilter, + columnFilterModeOptions, + onSelectFilter + }) => { const [anchorEl, setAnchorEl] = useState(null); const [open, setOpen] = useState(false); @@ -35,7 +43,7 @@ const TextFieldWithFnBox = ({formik, id , header, defaultValue, defaultFilter , InputProps={{ endAdornment: ( - + ) }} @@ -43,7 +51,9 @@ const TextFieldWithFnBox = ({formik, id , header, defaultValue, defaultFilter , position: 'relative' }} /> - + ); }; diff --git a/src/core/components/DataTable/index.js b/src/core/components/DataTable/index.js index f453ade..408994a 100644 --- a/src/core/components/DataTable/index.js +++ b/src/core/components/DataTable/index.js @@ -1,123 +1,122 @@ -import { useMaterialReactTable } from "material-react-table"; +import {useMaterialReactTable} from "material-react-table"; import DataTable_Main from "./Main"; -import { FA_DATATABLE_LOCALIZATION } from "./localization/fa/datatable"; -import CustomToolbar from "@/components/CustomToolbar"; +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"; const data = [ - { - name: { - firstName: 'John', - lastName: 'Doe', + { + name: { + firstName: 'John', + lastName: 'Doe', + }, + address: '261 Erdman Ford', + city: 'East Daphne', + state: 'Kentucky', }, - address: '261 Erdman Ford', - city: 'East Daphne', - state: 'Kentucky', - }, - { - name: { - firstName: 'Jane', - lastName: 'Doe', + { + name: { + firstName: 'Jane', + lastName: 'Doe', + }, + address: '769 Dominic Grove', + city: 'Columbus', + state: 'Ohio', }, - address: '769 Dominic Grove', - city: 'Columbus', - state: 'Ohio', - }, - { - name: { - firstName: 'Joe', - lastName: 'Doe', + { + name: { + firstName: 'Joe', + lastName: 'Doe', + }, + address: '566 Brakus Inlet', + city: 'South Linda', + state: 'West Virginia', }, - address: '566 Brakus Inlet', - city: 'South Linda', - state: 'West Virginia', - }, - { - name: { - firstName: 'Kevin', - lastName: 'Vandy', + { + name: { + firstName: 'Kevin', + lastName: 'Vandy', + }, + address: '722 Emie Stream', + city: 'Lincoln', + state: 'Nebraska', }, - address: '722 Emie Stream', - city: 'Lincoln', - state: 'Nebraska', - }, - { - name: { - firstName: 'Joshua', - lastName: 'Rolluffs', + { + name: { + firstName: 'Joshua', + lastName: 'Rolluffs', + }, + address: '32188 Larkin Turnpike', + city: 'Charleston', + state: 'South Carolina', }, - address: '32188 Larkin Turnpike', - city: 'Charleston', - state: 'South Carolina', - }, ]; const DataTable = (props) => { - const { userId, pageName, tableName, columns, initialStateProps } = props - const { settingStore, hideAction, sortAction } = useTableSetting(); - const flatColumns = flattenArrayOfObjects(columns,'columns') + const {userId, pageName, tableName, columns, initialStateProps} = props + const {settingStore, hideAction, sortAction} = useTableSetting(); + const flatColumns = flattenArrayOfObjects(columns, 'columns') - const onColumnVisibilityChange = (event) => { - const settingValue = event(); - hideAction(userId, pageName, tableName, settingValue, flatColumns); - }; - const onSortingChange = (event) => { - const settingValue = event(settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || []); - sortAction(userId, pageName, tableName, settingValue, flatColumns); - } + const onColumnVisibilityChange = (event) => { + const settingValue = event(); + hideAction(userId, pageName, tableName, settingValue, flatColumns); + }; + const onSortingChange = (event) => { + const settingValue = event(settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || []); + sortAction(userId, pageName, tableName, settingValue, flatColumns); + } - const table = useMaterialReactTable({ - localization: FA_DATATABLE_LOCALIZATION, - columns, - data: data, - // manualSorting: true, - renderTopToolbarCustomActions: ({ table }) => (<> - - ), - initialState: { - density: 'compact', - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [], - ...initialStateProps - }, - state: { - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] - }, - muiTableHeadProps: { - sx: { - borderTop: "1px solid #e1e1e1", - borderBottom: "2px solid #e1e1e1", - } - }, - muiTableHeadCellProps: { - sx: { - color: "primary.main", - borderLeft: "1px solid #e1e1e1", - "&:first-of-type": { - borderLeft: "unset" - } - }, - }, - muiTableBodyCellProps: { - sx: { - borderLeft: "1px solid #e1e1e1", - "&:first-of-type": { - borderLeft: "unset" - } - }, - }, - onColumnVisibilityChange: onColumnVisibilityChange, - onSortingChange: onSortingChange, - ...props - }) + const table = useMaterialReactTable({ + localization: FA_DATATABLE_LOCALIZATION, + columns, + data: data, + // manualSorting: true, + renderTopToolbarCustomActions: ({table}) => (<> + + ), + initialState: { + density: 'compact', + columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], + sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [], + ...initialStateProps + }, + state: { + columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], + sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] + }, + muiTableHeadProps: { + sx: { + borderTop: "1px solid #e1e1e1", + borderBottom: "2px solid #e1e1e1", + } + }, + muiTableHeadCellProps: { + sx: { + color: "primary.main", + borderLeft: "1px solid #e1e1e1", + "&:first-of-type": { + borderLeft: "unset" + } + }, + }, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + "&:first-of-type": { + borderLeft: "unset" + } + }, + }, + onColumnVisibilityChange: onColumnVisibilityChange, + onSortingChange: onSortingChange, + ...props + }) - - return ; + return ; }; export default DataTable; diff --git a/src/core/components/DataTable/table/Paper.js b/src/core/components/DataTable/table/Paper.js index db3bbec..ede47c1 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -1,78 +1,78 @@ -import { parseFromValuesOrFunc } from "@/core/utils/utils"; -import { Paper } from "@mui/material"; +import {parseFromValuesOrFunc} from "@/core/utils/utils"; +import {Paper} from "@mui/material"; import DataTable_BottomToolbar from "../toolbar/BottomToolbar"; import DataTable_TopToolbar from "../toolbar/TopToolbar"; import DataTable_TableContainer from "./TableContainer"; -const DataTable_Paper = ({ table, ...rest }) => { - const { - getState, - options: { - enableBottomToolbar, - enableTopToolbar, - mrtTheme: { baseBackgroundColor }, - muiTablePaperProps, - renderBottomToolbar, - renderTopToolbar, - }, - refs: { tablePaperRef }, - } = table; +const DataTable_Paper = ({table, ...rest}) => { + const { + getState, + options: { + enableBottomToolbar, + enableTopToolbar, + mrtTheme: {baseBackgroundColor}, + muiTablePaperProps, + renderBottomToolbar, + renderTopToolbar, + }, + refs: {tablePaperRef}, + } = table; - const { isFullScreen } = getState(); + const {isFullScreen} = getState(); - const paperProps = { - ...parseFromValuesOrFunc(muiTablePaperProps, { table }), - ...rest, - }; + const paperProps = { + ...parseFromValuesOrFunc(muiTablePaperProps, {table}), + ...rest, + }; - return ( - { - tablePaperRef.current = ref; - if (paperProps?.ref) { - //@ts-ignore - paperProps.ref.current = ref; - } - }} - 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, - } - : {}), - ...paperProps?.style, - }} - sx={(theme) => ({ - backgroundColor: baseBackgroundColor, - backgroundImage: 'unset', - overflow: 'hidden', - transition: 'all 100ms ease-in-out', - ...(parseFromValuesOrFunc(paperProps?.sx, theme)), - })} - > - {enableTopToolbar && - (parseFromValuesOrFunc(renderTopToolbar, { table }) ?? ( - - ))} - - {enableBottomToolbar && - (parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? ( - - ))} - - ); + return ( + { + tablePaperRef.current = ref; + if (paperProps?.ref) { + //@ts-ignore + paperProps.ref.current = ref; + } + }} + 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, + } + : {}), + ...paperProps?.style, + }} + sx={(theme) => ({ + backgroundColor: baseBackgroundColor, + backgroundImage: 'unset', + overflow: 'hidden', + transition: 'all 100ms ease-in-out', + ...(parseFromValuesOrFunc(paperProps?.sx, theme)), + })} + > + {enableTopToolbar && + (parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( + + ))} + + {enableBottomToolbar && + (parseFromValuesOrFunc(renderBottomToolbar, {table}) ?? ( + + ))} + + ); }; export default DataTable_Paper; diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 4eb0aba..46bae3e 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -1,10 +1,11 @@ -import { getCommonToolbarStyles, parseFromValuesOrFunc } from "@/core/utils/utils"; -import { Box, useMediaQuery } from "@mui/material"; +import {getCommonToolbarStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; +import {Box, 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/FilterColumn"; -const DataTable_TopToolbar = ({ table }) => { +const DataTable_TopToolbar = ({table, columns}) => { const { getState, options: { @@ -14,14 +15,14 @@ const DataTable_TopToolbar = ({ table }) => { positionPagination, renderTopToolbarCustomActions, }, - refs: { topToolbarRef }, + refs: {topToolbarRef}, } = table; - const { isFullScreen, showGlobalFilter } = getState(); + const {isFullScreen, showGlobalFilter} = getState(); const isMobile = useMediaQuery('(max-width:720px)'); const isTablet = useMediaQuery('(max-width:1024px)'); - const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, { table }); + const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, {table}); const stackAlertBanner = isMobile || @@ -39,7 +40,7 @@ const DataTable_TopToolbar = ({ table }) => { } }} sx={(theme) => ({ - ...getCommonToolbarStyles({ table, theme }), + ...getCommonToolbarStyles({table, theme}), position: isFullScreen ? 'sticky' : 'relative', top: isFullScreen ? '0' : undefined, ...(parseFromValuesOrFunc(toolbarProps?.sx, theme)), @@ -59,7 +60,7 @@ const DataTable_TopToolbar = ({ table }) => { width: '100%', }} > - {renderTopToolbarCustomActions?.({ table }) ?? } + {renderTopToolbarCustomActions?.({table}) ?? } {enableToolbarInternalActions && ( { justifyContent: 'flex-end', }} > - + + )} {enablePagination && ['both', 'top'].includes(positionPagination ?? '') && ( - + )} - + ); } From b40c19fb3415d8d26662d13e5807f4aa1e6637de Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 4 May 2024 13:44:26 +0330 Subject: [PATCH 02/28] solve header table colorize --- .../components/DataTable/head/TableHead.js | 21 +-- .../DataTable/head/TableHeadCell.js | 126 +++++++++--------- .../components/DataTable/head/TableHeadRow.js | 86 +++++------- 3 files changed, 111 insertions(+), 122 deletions(-) diff --git a/src/core/components/DataTable/head/TableHead.js b/src/core/components/DataTable/head/TableHead.js index 055a4ed..5e5dd99 100644 --- a/src/core/components/DataTable/head/TableHead.js +++ b/src/core/components/DataTable/head/TableHead.js @@ -1,12 +1,12 @@ -import { parseFromValuesOrFunc } from "@/core/utils/utils"; -import { TableHead } from "@mui/material"; +import {parseFromValuesOrFunc} from "@/core/utils/utils"; +import {TableHead} from "@mui/material"; import DataTable_TableHeadRow from "./TableHeadRow"; const DataTable_TableHead = ({ - columnVirtualizer, - table, - ...rest -}) => { + columnVirtualizer, + table, + ...rest + }) => { const { getState, options: { @@ -15,12 +15,12 @@ const DataTable_TableHead = ({ muiTableHeadProps, positionToolbarAlertBanner, }, - refs: { tableHeadRef }, + refs: {tableHeadRef}, } = table; - const { isFullScreen, showAlertBanner } = getState(); + const {isFullScreen, showAlertBanner} = getState(); const tableHeadProps = { - ...parseFromValuesOrFunc(muiTableHeadProps, { table }), + ...parseFromValuesOrFunc(muiTableHeadProps, {table}), ...rest, }; @@ -47,12 +47,13 @@ const DataTable_TableHead = ({ > {table .getHeaderGroups() - .map((headerGroup) => ( + .map((headerGroup, index) => ( )) } diff --git a/src/core/components/DataTable/head/TableHeadCell.js b/src/core/components/DataTable/head/TableHeadCell.js index 78a9933..6248d63 100644 --- a/src/core/components/DataTable/head/TableHeadCell.js +++ b/src/core/components/DataTable/head/TableHeadCell.js @@ -1,16 +1,16 @@ -import { getCommonMRTCellStyles, parseFromValuesOrFunc } from "@/core/utils/utils"; -import { useTheme } from "@emotion/react"; -import { Box, TableCell } from "@mui/material"; -import { MRT_TableHeadCellSortLabel } from "material-react-table"; -import { useMemo } from "react"; +import {getCommonMRTCellStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; +import {useTheme} from "@emotion/react"; +import {Box, TableCell} from "@mui/material"; +import {MRT_TableHeadCellSortLabel} from "material-react-table"; +import {useMemo} from "react"; const DataTable_TableHeadCell = ({ - columnVirtualizer, - header, - staticColumnIndex, - table, - ...rest -}) => { + columnVirtualizer, + header, + staticColumnIndex, + table, + ...rest + }) => { const theme = useTheme(); const { getState, @@ -24,10 +24,10 @@ const DataTable_TableHeadCell = ({ enableGrouping, enableMultiSort, layoutMode, - mrtTheme: { draggingBorderColor }, + mrtTheme: {draggingBorderColor}, muiTableHeadCellProps, }, - refs: { tableHeadCellRefs }, + refs: {tableHeadCellRefs}, setHoveredColumn, } = table; const { @@ -38,12 +38,12 @@ const DataTable_TableHeadCell = ({ hoveredColumn, showColumnFilters, } = getState(); - const { column } = header; - const { columnDef } = column; - const { columnDefType } = columnDef; + const {column} = header; + const {columnDef} = column; + const {columnDefType} = columnDef; const tableCellProps = { - ...parseFromValuesOrFunc(muiTableHeadCellProps, { column, table }), + ...parseFromValuesOrFunc(muiTableHeadCellProps, {column, table}), ...parseFromValuesOrFunc(columnDef.muiTableHeadCellProps, { column, table, @@ -93,8 +93,8 @@ const DataTable_TableHeadCell = ({ if (showResizeBorder) { return columnResizeDirection === 'ltr' - ? { borderRight: borderStyle } - : { borderLeft: borderStyle }; + ? {borderRight: borderStyle} + : {borderLeft: borderStyle}; } const draggingBorders = borderStyle ? { @@ -172,47 +172,47 @@ const DataTable_TableHeadCell = ({ }} {...tableCellProps} sx={(theme) => ({ - '& :hover': { - '.MuiButtonBase-root': { - opacity: 1, + '& :hover': { + '.MuiButtonBase-root': { + opacity: 1, + }, }, - }, - flexDirection: layoutMode?.startsWith('grid') ? 'column' : undefined, - fontWeight: 'bold', - overflow: 'visible', - p: - density === 'compact' - ? '0.5rem' - : density === 'comfortable' - ? columnDefType === 'display' - ? '0.75rem' - : '1rem' - : columnDefType === 'display' - ? '1rem 1.25rem' - : '1.5rem', - pb: - columnDefType === 'display' - ? 0 - : showColumnFilters || density === 'compact' - ? '0.4rem' - : '0.6rem', - pt: - columnDefType === 'group' || density === 'compact' - ? '0.25rem' - : density === 'comfortable' - ? '.75rem' - : '1.25rem', - userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined, - verticalAlign: 'middle', - ...getCommonMRTCellStyles({ - column, - header, - table, - tableCellProps, - theme, - }), - ...draggingBorders, - } + flexDirection: layoutMode?.startsWith('grid') ? 'column' : undefined, + fontWeight: 'bold', + overflow: 'visible', + p: + density === 'compact' + ? '0.5rem' + : density === 'comfortable' + ? columnDefType === 'display' + ? '0.75rem' + : '1rem' + : columnDefType === 'display' + ? '1rem 1.25rem' + : '1.5rem', + pb: + columnDefType === 'display' + ? 0 + : showColumnFilters || density === 'compact' + ? '0.4rem' + : '0.6rem', + pt: + columnDefType === 'group' || density === 'compact' + ? '0.25rem' + : density === 'comfortable' + ? '.75rem' + : '1.25rem', + userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined, + verticalAlign: 'middle', + ...getCommonMRTCellStyles({ + column, + header, + table, + tableCellProps, + theme, + }), + ...draggingBorders, + } )} > {tableCellProps.children ?? ( @@ -225,7 +225,7 @@ const DataTable_TableHeadCell = ({ tableCellProps?.align === 'right' ? 'row-reverse' : 'row', justifyContent: columnDefType === 'group' || - tableCellProps?.align === 'center' + tableCellProps?.align === 'center' ? 'center' : column.getCanResize() ? 'space-between' @@ -262,6 +262,9 @@ const DataTable_TableHeadCell = ({ minWidth: `${Math.min(columnDef.header?.length ?? 0, 4)}ch`, overflow: columnDefType === 'data' ? 'hidden' : undefined, textOverflow: 'ellipsis', + color: "#fff", + fontSize: "14px", + fontWeight: "500", whiteSpace: (columnDef.header?.length ?? 0) < 20 ? 'nowrap' @@ -271,7 +274,8 @@ const DataTable_TableHeadCell = ({ {HeaderElement} {(column.getCanSort() && columnDefType !== 'group') && ( - + )} diff --git a/src/core/components/DataTable/head/TableHeadRow.js b/src/core/components/DataTable/head/TableHeadRow.js index f876cf1..8c2202a 100644 --- a/src/core/components/DataTable/head/TableHeadRow.js +++ b/src/core/components/DataTable/head/TableHeadRow.js @@ -1,24 +1,25 @@ -import { parseFromValuesOrFunc } from "@/core/utils/utils"; -import { TableRow } from "@mui/material"; +import {parseFromValuesOrFunc} from "@/core/utils/utils"; +import {TableRow} from "@mui/material"; import DataTable_TableHeadCell from "./TableHeadCell"; const DataTable_TableHeadRow = ({ - columnVirtualizer, - headerGroup, - table, - ...rest -}) => { + columnVirtualizer, + headerGroup, + table, + index, // Add index prop + ...rest + }) => { const { options: { enableStickyHeader, layoutMode, - mrtTheme: { baseBackgroundColor }, muiTableHeadRowProps, }, } = table; + const {virtualColumns, virtualPaddingLeft, virtualPaddingRight} = + columnVirtualizer ?? {}; - const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = - columnVirtualizer ?? {}; + const backgroundColor = index % 2 === 0 ? '#2070af' : '#ff5c0f'; const tableRowProps = { ...parseFromValuesOrFunc(muiTableHeadRowProps, { @@ -26,51 +27,34 @@ const DataTable_TableHeadRow = ({ table, }), ...rest, + sx: (theme) => ({ // Access theme from the sx function + ...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}), + backgroundColor, // Apply background color + display: layoutMode?.startsWith('grid') ? 'flex' : undefined, + position: enableStickyHeader && layoutMode === 'semantic' ? 'sticky' : 'relative', + top: 0, + }), }; return ( - ({ - backgroundColor: baseBackgroundColor, - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, - position: - enableStickyHeader && layoutMode === 'semantic' - ? 'sticky' - : 'relative', - top: 0, - ...(parseFromValuesOrFunc(tableRowProps?.sx, theme)), + + {virtualPaddingLeft && } + {(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader, staticColumnIndex) => { + const header = columnVirtualizer ? headerGroup.headers[headerOrVirtualHeader.index] : headerOrVirtualHeader; + + return header ? ( + + ) : null; })} - > - {virtualPaddingLeft ? ( - - ) : null} - {(virtualColumns ?? headerGroup.headers).map( - (headerOrVirtualHeader, staticColumnIndex) => { - let header = headerOrVirtualHeader; - - if (columnVirtualizer) { - staticColumnIndex = (headerOrVirtualHeader) - .index; - header = headerGroup.headers[staticColumnIndex]; - } - - return header ? ( - - ) : null; - }, - )} - {virtualPaddingRight ? ( - - ) : null} + {virtualPaddingRight && } ); +}; -} -export default DataTable_TableHeadRow \ No newline at end of file +export default DataTable_TableHeadRow; \ No newline at end of file From 3ccd198a72dda0d3b9a59f319148b3fa0a29c3a9 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 6 May 2024 17:19:11 +0330 Subject: [PATCH 03/28] improve some option in reset table --- src/components/home/index.jsx | 1 - .../filter/TextFieldWithFnBox/FilterBox.jsx | 22 +++++++++++---- .../components/DataTable/head/TableHeadRow.js | 2 +- .../DataTable/refactor/RefactorTable.jsx | 28 +++++++++++++++++++ .../DataTable/toolbar/TopToolbar.js | 2 ++ src/lib/contexts/tableSetting.jsx | 21 ++++++++++++-- src/lib/hooks/useTableSetting.jsx | 10 +++---- 7 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 src/core/components/DataTable/refactor/RefactorTable.jsx diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index b059e6a..f919b3d 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -73,7 +73,6 @@ function HomeComponent() { "contains", "lessThan", "greaterThan", - "between", ], }, diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx index f887918..25f10c6 100644 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx +++ b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx @@ -1,6 +1,17 @@ -import { Popper, Paper, List, ListItem, ListItemText, ClickAwayListener } from '@mui/material'; +import {ClickAwayListener, List, ListItem, ListItemText, Paper, Popper} from '@mui/material'; -function FilterBox({anchorEl , open = false, handleClose = () => {} , columnFilterModeOptions , onSelectFilter , defaultFilter}) { +const columnFilterModeOptionFa = { + equals: "برابر", + notEquals: "نابرابر", + contains: "شامل", + lessThan: "کوچکتر", + greaterThan: "بزرگتر", +} + +function FilterBox({ + anchorEl, open = false, handleClose = () => { + }, columnFilterModeOptions, onSelectFilter, defaultFilter + }) { const id = open ? 'simple-popper' : undefined; const handleSelectFilter = (filterFn) => { @@ -10,13 +21,14 @@ function FilterBox({anchorEl , open = false, handleClose = () => {} , columnFilt return (
- + {columnFilterModeOptions.map((option, index) => ( - handleSelectFilter(option)} selected={option === defaultFilter} sx={{ cursor: 'pointer' }}> - + handleSelectFilter(option)} + selected={option === defaultFilter} sx={{cursor: 'pointer'}}> + ))} diff --git a/src/core/components/DataTable/head/TableHeadRow.js b/src/core/components/DataTable/head/TableHeadRow.js index 8c2202a..33a23e2 100644 --- a/src/core/components/DataTable/head/TableHeadRow.js +++ b/src/core/components/DataTable/head/TableHeadRow.js @@ -19,7 +19,7 @@ const DataTable_TableHeadRow = ({ const {virtualColumns, virtualPaddingLeft, virtualPaddingRight} = columnVirtualizer ?? {}; - const backgroundColor = index % 2 === 0 ? '#2070af' : '#ff5c0f'; + const backgroundColor = index % 2 === 0 ? '#015688' : '#ff5c0f'; const tableRowProps = { ...parseFromValuesOrFunc(muiTableHeadRowProps, { diff --git a/src/core/components/DataTable/refactor/RefactorTable.jsx b/src/core/components/DataTable/refactor/RefactorTable.jsx new file mode 100644 index 0000000..06f75c1 --- /dev/null +++ b/src/core/components/DataTable/refactor/RefactorTable.jsx @@ -0,0 +1,28 @@ +"use client" +import {IconButton, Tooltip} from '@mui/material'; +import RestartAltIcon from '@mui/icons-material/RestartAlt'; +import useTableSetting from "@/lib/hooks/useTableSetting"; +import {useState} from "react"; + +function RefactorTable() { + const {refactorAction} = useTableSetting(); + const [userId, setUserId] = useState(2); + const [pageName, setPageName] = useState('loan'); + const [tableName, setTableName] = useState('loan_table'); + + const refactor = () => { + refactorAction(userId, pageName, tableName); + }; + + return ( + + + + + + ); +} + +export default RefactorTable; + + diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 46bae3e..2b9641c 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -4,6 +4,7 @@ import DataTable_LinearProgressBar from "./LinearProgressBar"; import DataTable_TablePagination from "./TablePagination"; import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import FilterColumn from "@/core/components/DataTable/filter/FilterColumn"; +import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; const DataTable_TopToolbar = ({table, columns}) => { const { @@ -71,6 +72,7 @@ const DataTable_TopToolbar = ({table, columns}) => { justifyContent: 'flex-end', }} > + diff --git a/src/lib/contexts/tableSetting.jsx b/src/lib/contexts/tableSetting.jsx index 0c2262d..abc2ad7 100644 --- a/src/lib/contexts/tableSetting.jsx +++ b/src/lib/contexts/tableSetting.jsx @@ -1,6 +1,5 @@ 'use client' import {createContext, useCallback, useEffect, useState} from "react"; -import {flattenArrayOfObjects} from "@/core/utils/flattenArrayOfObjects"; export const TableSettingContext = createContext(); export const TableSettingProvider = ({children}) => { @@ -53,7 +52,23 @@ export const TableSettingProvider = ({children}) => { localStorage.setItem("_setting-app", JSON.stringify(updatedLocalStorage)); setSettingStore(updatedLocalStorage); } - + const refactorAction = (user_id, page_name, table_name) => { + const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; + const userSettings = prevLocalStorage[user_id] || {}; + const pageSettings = userSettings[page_name] || {}; + const refactorData = { + ...prevLocalStorage, + [user_id]: { + ...userSettings, + [page_name]: { + ...pageSettings, + [table_name]: {}, + }, + }, + }; + localStorage.setItem("_setting-app", JSON.stringify(refactorData)); + setSettingStore(refactorData); + } const SummaryTextMessage = (values, columns) => { let SummaryText = ""; let HideText = ""; @@ -122,7 +137,7 @@ export const TableSettingProvider = ({children}) => { return ( + value={{settingStore, hideAction, sortAction, filterAction, refactorAction}}> {children} ); diff --git a/src/lib/hooks/useTableSetting.jsx b/src/lib/hooks/useTableSetting.jsx index 14d9d4e..7617655 100644 --- a/src/lib/hooks/useTableSetting.jsx +++ b/src/lib/hooks/useTableSetting.jsx @@ -1,10 +1,10 @@ -import { useContext } from "react"; -import { TableSettingContext } from "../contexts/tableSetting"; +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, refactorAction} = + useContext(TableSettingContext); + return {settingStore, hideAction, sortAction, filterAction, refactorAction}; }; export default useTableSetting; From d3a932ef27fcd18e485861b9bceed836dca76fae Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 6 May 2024 18:09:02 +0330 Subject: [PATCH 04/28] start working on filter bugs --- src/components/home/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index f919b3d..4efdf85 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -30,7 +30,7 @@ function HomeComponent() { id: "lastName", enableColumnFilter: true, datatype: "text", - filterFn: "contains", + filterFn: "equals", columnFilterModeOptions: [ "equals", "notEquals", @@ -40,7 +40,7 @@ function HomeComponent() { ], enableColumnFilter: true, datatype: "text", - filterFn: "contains", + filterFn: "notEquals", columnFilterModeOptions: [ "equals", "notEquals", From dbb02648581ed3aef3ea45b1c2480e7d108492b4 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 18 May 2024 10:07:24 +0330 Subject: [PATCH 05/28] debug filter --- src/components/home/index.jsx | 63 +++++++--------- .../DataTable/filter/FilterColumn.jsx | 20 +++--- .../filter/TextFieldWithFnBox/FilterBox.jsx | 6 +- src/core/components/DataTable/index.js | 72 ++++++++++++------- 4 files changed, 87 insertions(+), 74 deletions(-) diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 4efdf85..2682b64 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -17,6 +17,7 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "contains", + inputType: "textField", enableClickToCopy: true, columnFilterModeOptions: [ "equals", @@ -31,6 +32,7 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "equals", + inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -38,14 +40,6 @@ function HomeComponent() { ], }, ], - enableColumnFilter: true, - datatype: "text", - filterFn: "notEquals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], }, { accessorKey: 'address', @@ -53,7 +47,8 @@ function HomeComponent() { id: "address", enableColumnFilter: true, datatype: "text", - filterFn: "contains", + filterFn: "notEquals", + inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -66,13 +61,15 @@ function HomeComponent() { id: "city", enableColumnFilter: true, datatype: "text", - filterFn: "contains", + filterFn: "equals", + inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", "contains", "lessThan", "greaterThan", + "fuzzy" ], }, @@ -80,10 +77,10 @@ function HomeComponent() { accessorKey: 'state', header: 'وضعیت', id: "state", - text: 'نام', enableColumnFilter: true, datatype: "text", filterFn: "contains", + inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -91,46 +88,40 @@ function HomeComponent() { ], }, { - accessorKey: 'state', + accessorKey: 'price', header: 'محدوده', - id: "betweenNum", - text: 'محدوده', + id: "price", enableColumnFilter: true, - datatype: "text", - filterFn: "betweenNum", - columnFilterModeOptions: [], + datatype: "nemeric", + filterFn: "between", + inputType: "betweenNum", }, { - accessorKey: 'state', - header: 'تاریخ', - id: "betweenDate", - text: 'تاریخ', + accessorKey: 'updated_at', + header: 'تاریخ بروزرسانی', + id: "updated_at", enableColumnFilter: true, - datatype: "text", - filterFn: "betweenDate", - columnFilterModeOptions: [], + datatype: "date", + filterFn: "between", + inputType: "betweenDate", }, { - accessorKey: 'state', - header: 'شلکت', - id: "select2", - text: 'تاریخ', - type: 'select2', + accessorKey: 'company', + header: 'نام شرکت', + id: "company", enableColumnFilter: true, datatype: "text", filterFn: "equals", - columnFilterModeOptions: [], + inputType: "select2", }, { - accessorKey: 'state', - header: 'سلکت', - id: "select", - text: 'تنتنت', - type: 'select', + accessorKey: 'area', + header: 'منطقه', + id: "area", enableColumnFilter: true, datatype: "text", filterFn: "equals", - columnFilterModeOptions: [], + inputType: "select", }, ], [], diff --git a/src/core/components/DataTable/filter/FilterColumn.jsx b/src/core/components/DataTable/filter/FilterColumn.jsx index 1daa295..efe809b 100644 --- a/src/core/components/DataTable/filter/FilterColumn.jsx +++ b/src/core/components/DataTable/filter/FilterColumn.jsx @@ -1,7 +1,6 @@ "use client" import {Box, Button, Divider, Drawer, FormControl, IconButton, styled, Tooltip, Typography} from '@mui/material'; import {useFormik} from 'formik'; -import TextFieldWithFnBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox"; import {useEffect, useState} from "react"; import useTableSetting from "@/lib/hooks/useTableSetting"; import BetweenNumberFilter from "@/core/components/DataTable/filter/BetweenNumberFilter"; @@ -10,6 +9,7 @@ import SelectBoxMultiple from "@/core/components/DataTable/filter/SelectBoxMulti import SelectBox from "@/core/components/DataTable/filter/SelectBox"; import FilterAltIcon from '@mui/icons-material/FilterAlt'; import CloseIcon from '@mui/icons-material/Close'; +import TextFieldWithFnBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox"; function FilterColumn({columns}) { const [open, setOpen] = useState(false); @@ -34,11 +34,13 @@ function FilterColumn({columns}) { useEffect(() => { const settingValue = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []; setSelectedFilters(settingValue.length > 0 ? settingValue : []); + if (!settingValue.length > 0) { + formik.resetForm(); + } }, [settingStore]); const handleSelectFilter = (fieldName, filterFn) => { const filterIndex = selectedFilters.findIndex(filter => filter.id === fieldName); - if (filterIndex !== -1) { const updatedFilters = [...selectedFilters]; updatedFilters[filterIndex].fn = filterFn; @@ -139,36 +141,32 @@ function FilterColumn({columns}) { {columns.map((column, index) => ( column.enableColumnFilter && - (column.filterFn === 'betweenDate' ? + (column.inputType === 'betweenDate' ? handleSelectFilter(column.id, filterFn)} defaultValue={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || ''} /> - : column.filterFn === 'betweenNum' ? + : column.inputType === 'betweenNum' ? handleSelectFilter(column.id, filterFn)} defaultValue={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || ["", ""]} /> - : column.type === 'select2' ? + : column.inputType === 'select2' ? handleSelectFilter(column.id, filterFn)} defaultValue={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || []} /> - : column.type === 'select' ? + : column.inputType === 'select' ? handleSelectFilter(column.id, filterFn)} defaultValue={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || ''} /> : @@ -177,7 +175,7 @@ function FilterColumn({columns}) { id={column.id} header={column.header} formik={formik} - defaultFilter={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.fn || column.filterFn} + defaultFilter={(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.fn || column._filterFn} columnFilterModeOptions={column.columnFilterModeOptions} onSelectFilter={(filterFn) => handleSelectFilter(column.id, filterFn)} defaultValue={formik.values[column.id] || (settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || ''} diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx index 25f10c6..3bba610 100644 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx +++ b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx @@ -1,4 +1,5 @@ import {ClickAwayListener, List, ListItem, ListItemText, Paper, Popper} from '@mui/material'; +import {useState} from "react"; const columnFilterModeOptionFa = { equals: "برابر", @@ -6,15 +7,18 @@ const columnFilterModeOptionFa = { contains: "شامل", lessThan: "کوچکتر", greaterThan: "بزرگتر", + fuzzy: "فازی", } function FilterBox({ anchorEl, open = false, handleClose = () => { }, columnFilterModeOptions, onSelectFilter, defaultFilter }) { + const [selectedFilter, setSelectedFilter] = useState(defaultFilter); const id = open ? 'simple-popper' : undefined; const handleSelectFilter = (filterFn) => { + setSelectedFilter(filterFn); onSelectFilter(filterFn); handleClose(); }; @@ -27,7 +31,7 @@ function FilterBox({ {columnFilterModeOptions.map((option, index) => ( handleSelectFilter(option)} - selected={option === defaultFilter} sx={{cursor: 'pointer'}}> + selected={option === selectedFilter} sx={{cursor: 'pointer'}}> ))} diff --git a/src/core/components/DataTable/index.js b/src/core/components/DataTable/index.js index 408994a..aba1d1c 100644 --- a/src/core/components/DataTable/index.js +++ b/src/core/components/DataTable/index.js @@ -8,48 +8,68 @@ import Toolbar from "@/components/home/Toolbar"; const data = [ { name: { - firstName: 'John', - lastName: 'Doe', + firstName: 'امین', + lastName: 'قاسمپور', }, - address: '261 Erdman Ford', - city: 'East Daphne', - state: 'Kentucky', + address: 'فلان جا', + city: 'تهران', + state: 'بررسی شده', + price: '20', + updated_at: '2024/05/02', + company: 'همراه اول', + area: 'منطقه 5', }, { name: { - firstName: 'Jane', - lastName: 'Doe', + firstName: 'امیر حسین', + lastName: 'محمودی', }, - address: '769 Dominic Grove', - city: 'Columbus', - state: 'Ohio', + address: 'فلان جا', + city: 'تهران', + state: 'تکمیل شده', + price: '27', + updated_at: '2024/05/02', + company: 'وایتل', + area: 'منطقه 27', }, { name: { - firstName: 'Joe', - lastName: 'Doe', + firstName: 'یاسمن', + lastName: 'علی اکبری', }, - address: '566 Brakus Inlet', - city: 'South Linda', - state: 'West Virginia', + address: 'فلان جا', + city: 'شیراز', + state: 'بررسی شده', + price: '32', + updated_at: '2024/05/02', + company: 'ایرانسل', + area: 'منطقه 23', }, { name: { - firstName: 'Kevin', - lastName: 'Vandy', + firstName: 'حمیدرضا', + lastName: 'رنجبرپور', }, - address: '722 Emie Stream', - city: 'Lincoln', - state: 'Nebraska', + address: 'فلان جا', + city: 'اصفهان', + state: 'بررسی شده', + price: '45', + updated_at: '2024/05/02', + company: 'ایرانول', + area: 'منطقه 21', }, { name: { - firstName: 'Joshua', - lastName: 'Rolluffs', + firstName: 'محمد', + lastName: 'جلالی', }, - address: '32188 Larkin Turnpike', - city: 'Charleston', - state: 'South Carolina', + address: 'فلان جا', + city: 'رشت', + state: 'درحال بررسی', + price: '8', + updated_at: '2024/05/02', + company: 'فیلیمو', + area: 'منطقه 8', }, ]; @@ -116,7 +136,7 @@ const DataTable = (props) => { ...props }) - return ; + return ; }; export default DataTable; From 6184cbc2e0beb11bef0c9d31c54a9f58ec897df2 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 18 May 2024 10:40:32 +0330 Subject: [PATCH 06/28] finish filter bug --- .../filter/TextFieldWithFnBox/FilterBox.jsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx index 3bba610..92c39e8 100644 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx +++ b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx @@ -1,4 +1,4 @@ -import {ClickAwayListener, List, ListItem, ListItemText, Paper, Popper} from '@mui/material'; +import {ClickAwayListener, List, ListItem, ListItemIcon, ListItemText, Paper, Popper} from '@mui/material'; import {useState} from "react"; const columnFilterModeOptionFa = { @@ -10,6 +10,15 @@ const columnFilterModeOptionFa = { fuzzy: "فازی", } +const columnFilterModeOptionSymbol = { + equals: "=", + notEquals: "≠", + contains: "*", + lessThan: "<", + greaterThan: ">", + fuzzy: "≈", +} + function FilterBox({ anchorEl, open = false, handleClose = () => { }, columnFilterModeOptions, onSelectFilter, defaultFilter @@ -33,6 +42,7 @@ function FilterBox({ handleSelectFilter(option)} selected={option === selectedFilter} sx={{cursor: 'pointer'}}> + {option === columnFilterModeOptionSymbol} ))} From ef551d0cf3fb39b2946867b10f3491d43db0d344 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Sat, 18 May 2024 10:41:54 +0330 Subject: [PATCH 07/28] for deploy --- .env.local.example | 0 .gitignore | 2 +- next.config.mjs | 6 +++++- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .env.local.example diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore index 2d5bbdd..19f7fa0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,7 @@ node_modules cypress/videos cypress/screenshots .next -.env* +.env.local .env .idea package-lock.json diff --git a/next.config.mjs b/next.config.mjs index 4678774..bb49d74 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,8 @@ +const isProd = process.env.NODE_ENV === 'production' + /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + assetPrefix: isProd ? '/v3' : undefined, +}; export default nextConfig; From 0111ad5db3d7f684d26f95f17a6f9b0050380e9b Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 18 May 2024 15:29:35 +0330 Subject: [PATCH 08/28] remove symbol --- .../components/DataTable/filter/FilterColumn.jsx | 8 ++++---- .../filter/TextFieldWithFnBox/FilterBox.jsx | 12 +----------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/core/components/DataTable/filter/FilterColumn.jsx b/src/core/components/DataTable/filter/FilterColumn.jsx index efe809b..3c0a16c 100644 --- a/src/core/components/DataTable/filter/FilterColumn.jsx +++ b/src/core/components/DataTable/filter/FilterColumn.jsx @@ -14,9 +14,9 @@ import TextFieldWithFnBox from "@/core/components/DataTable/filter/TextFieldWith function FilterColumn({columns}) { const [open, setOpen] = useState(false); const [selectedFilters, setSelectedFilters] = useState([]); - const [userId, setUserId] = useState(2); - const [pageName, setPageName] = useState('loan'); - const [tableName, setTableName] = useState('loan_table'); + const [userId, setUserId] = useState(0); + const [pageName, setPageName] = useState('testPage'); + const [tableName, setTableName] = useState('testTable'); const {settingStore, hideAction, filterAction, sortAction,} = useTableSetting(); const DrawerHeader = styled('div')(({theme}) => ({ @@ -100,7 +100,7 @@ function FilterColumn({columns}) { } }); - + console.log(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']) return ( <> diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx index 92c39e8..3bba610 100644 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx +++ b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx @@ -1,4 +1,4 @@ -import {ClickAwayListener, List, ListItem, ListItemIcon, ListItemText, Paper, Popper} from '@mui/material'; +import {ClickAwayListener, List, ListItem, ListItemText, Paper, Popper} from '@mui/material'; import {useState} from "react"; const columnFilterModeOptionFa = { @@ -10,15 +10,6 @@ const columnFilterModeOptionFa = { fuzzy: "فازی", } -const columnFilterModeOptionSymbol = { - equals: "=", - notEquals: "≠", - contains: "*", - lessThan: "<", - greaterThan: ">", - fuzzy: "≈", -} - function FilterBox({ anchorEl, open = false, handleClose = () => { }, columnFilterModeOptions, onSelectFilter, defaultFilter @@ -42,7 +33,6 @@ function FilterBox({ handleSelectFilter(option)} selected={option === selectedFilter} sx={{cursor: 'pointer'}}> - {option === columnFilterModeOptionSymbol} ))} From 23f1b9a4b14e28030c4223746758372228ff355b Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 18 May 2024 18:00:02 +0330 Subject: [PATCH 09/28] start refactor --- .../DataTable/filter/BetweenNumberFilter.jsx | 58 ----- .../filter/DatePicker/BetweenDateFilter.jsx | 35 --- .../filter/DatePicker/MuiDatePicker.jsx | 67 ------ .../DataTable/filter/FilterBody.jsx | 58 +++++ .../DataTable/filter/FilterBodyField.jsx | 9 + .../DataTable/filter/FilterButton.jsx | 17 ++ .../DataTable/filter/FilterColumn.jsx | 201 ------------------ .../components/DataTable/filter/SelectBox.jsx | 53 ----- .../DataTable/filter/SelectBoxMultiple.jsx | 116 ---------- .../filter/TextFieldWithFnBox/FilterBox.jsx | 46 ---- .../TextFieldWithFnBox/TextFieldWithFnBox.jsx | 61 ------ .../components/DataTable/filter/index.jsx | 18 ++ .../DataTable/refactor/RefactorTable.jsx | 6 +- .../DataTable/toolbar/TopToolbar.js | 2 +- 14 files changed, 106 insertions(+), 641 deletions(-) delete mode 100644 src/core/components/DataTable/filter/BetweenNumberFilter.jsx delete mode 100644 src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx delete mode 100644 src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx create mode 100644 src/core/components/DataTable/filter/FilterBody.jsx create mode 100644 src/core/components/DataTable/filter/FilterBodyField.jsx create mode 100644 src/core/components/DataTable/filter/FilterButton.jsx delete mode 100644 src/core/components/DataTable/filter/FilterColumn.jsx delete mode 100644 src/core/components/DataTable/filter/SelectBox.jsx delete mode 100644 src/core/components/DataTable/filter/SelectBoxMultiple.jsx delete mode 100644 src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx delete mode 100644 src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx create mode 100644 src/core/components/DataTable/filter/index.jsx diff --git a/src/core/components/DataTable/filter/BetweenNumberFilter.jsx b/src/core/components/DataTable/filter/BetweenNumberFilter.jsx deleted file mode 100644 index 0b3512a..0000000 --- a/src/core/components/DataTable/filter/BetweenNumberFilter.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import {Grid, TextField} from '@mui/material'; -import {useEffect} from "react"; - -const BetweenNumberFilter = ({formik, id , defaultValue}) => { - - useEffect(() => { - formik.setFieldValue(`${id}[0]`, defaultValue?.[0] || ''); - formik.setFieldValue(`${id}[1]`, defaultValue?.[1] || ''); - }, []); - const handleBlur = (index) => () => { - const minValue = formik.values[id][0]; - const maxValue = formik.values[id][1]; - - if (index === 0 && minValue !== '' && maxValue !== '' && parseInt(minValue) > parseInt(maxValue)) { - formik.setFieldValue(`${id}[0]`, maxValue); - } - - if (index === 1 && minValue !== '' && maxValue !== '' && parseInt(maxValue) < parseInt(minValue)) { - formik.setFieldValue(`${id}[1]`, minValue); - } - }; - return ( - - - - - - - - - ); -}; - -export default BetweenNumberFilter; diff --git a/src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx b/src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx deleted file mode 100644 index 0e4a325..0000000 --- a/src/core/components/DataTable/filter/DatePicker/BetweenDateFilter.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import {Grid} from '@mui/material'; -import MuiDatePicker from "@/core/components/DataTable/filter/DatePicker/MuiDatePicker"; -import {useEffect, useState} from "react"; - -const BetWeenDateFilter = ({formik, id, defaultValue}) => { - useEffect(() => { - formik.setFieldValue(`${id}[0]`, defaultValue?.[0] || ''); - formik.setFieldValue(`${id}[1]`, defaultValue?.[1] || ''); - }, []); - - const [dateRange, setDateRange] = useState(defaultValue); - - const handleDateChange = (index, value) => { - const newRange = [...dateRange]; - newRange[index] = value; - setDateRange(newRange); - }; - - return ( - - - handleDateChange(0, value)}/> - - - handleDateChange(1, value)}/> - - - ); -}; - -export default BetWeenDateFilter; diff --git a/src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx b/src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx deleted file mode 100644 index f2b0876..0000000 --- a/src/core/components/DataTable/filter/DatePicker/MuiDatePicker.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import { LocalizationProvider, MobileDateTimePicker } from "@mui/x-date-pickers"; -import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; -import moment from "jalali-moment"; -import { faIR } from "@mui/x-date-pickers/locales"; -import { Box, IconButton, InputAdornment, TextField } from "@mui/material"; -import ClearIcon from "@mui/icons-material/Clear"; -import { useState } from "react"; - -export default function MuiDatePicker({label, name, formik, defaultValue, minDate, maxDate, onDateChange }) { - const [pickerValue, setPickerValue] = useState(defaultValue ? new Date(defaultValue) : null); - - return ( - - - { - const date = new Date(newValue); - const formattedDate = moment(date) - .locale("en") - .format("YYYY-MM-DD HH:mm"); - formik.setFieldValue(name, formattedDate); - onDateChange(formattedDate); - setPickerValue(newValue); - }} - slotProps={{ - textField: { - placeholder: "تاریخ خود را وارد کنید", - helperText: label, - InputProps: { - endAdornment: ( - - { - event.stopPropagation(); - formik.setFieldValue(name, ""); - setPickerValue(null); - }} - sx={{ - color: "#bfbfbf", - '&:hover': { - backgroundColor: 'rgba(189, 189, 189, 0.1)', - }, - }} - > - - - - ), - }, - }, - }} - value={pickerValue} - minDate={minDate ? new Date(minDate) : null} - maxDate={maxDate ? new Date(maxDate) : null} - /> - - - ); -} diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx new file mode 100644 index 0000000..b87f980 --- /dev/null +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -0,0 +1,58 @@ +'use client' + +import {Box, Drawer, IconButton, Typography} from "@mui/material"; +import CancelIcon from '@mui/icons-material/Cancel'; +import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField"; + +function FilterBody({columns, drawerState, setDrawerState}) { + // const initialValues = columns.reduce((acc, column) => { + // if (column.enableColumnFilter) { + // const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); + // if (column.filterFn === 'betweenNum' || column.filterFn === 'betweenDate') { + // acc[column.id] = filter?.value || ["", ""]; + // } else if (column.type === 'select2') { + // acc[column.id] = filter?.value || []; + // } else { + // acc[column.id] = filter?.value || ''; + // } + // } + // return acc; + // }, {}); + // const initialValues = {}; + return ( + { + setDrawerState(false) + }}> + + فیلتر + { + setDrawerState(false) + }}> + + + + + {/**/} + {columns.map((column) => { + + })} + {/**/} + + + ); +} + +export default FilterBody; diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx new file mode 100644 index 0000000..e78697e --- /dev/null +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -0,0 +1,9 @@ +'use client' + +function FilterBodyField({column}) { + return ( + asdasdasd + ); +} + +export default FilterBodyField; diff --git a/src/core/components/DataTable/filter/FilterButton.jsx b/src/core/components/DataTable/filter/FilterButton.jsx new file mode 100644 index 0000000..ec444bb --- /dev/null +++ b/src/core/components/DataTable/filter/FilterButton.jsx @@ -0,0 +1,17 @@ +'use client' +import FilterAltIcon from '@mui/icons-material/FilterAlt'; +import {IconButton, Tooltip} from "@mui/material"; + +function FilterButton({drawerState, setDrawerState}) { + return ( + + { + setDrawerState(!drawerState) + }} aria-label="filter table"> + + + + ); +} + +export default FilterButton; diff --git a/src/core/components/DataTable/filter/FilterColumn.jsx b/src/core/components/DataTable/filter/FilterColumn.jsx deleted file mode 100644 index 3c0a16c..0000000 --- a/src/core/components/DataTable/filter/FilterColumn.jsx +++ /dev/null @@ -1,201 +0,0 @@ -"use client" -import {Box, Button, Divider, Drawer, FormControl, IconButton, styled, Tooltip, Typography} from '@mui/material'; -import {useFormik} from 'formik'; -import {useEffect, useState} from "react"; -import useTableSetting from "@/lib/hooks/useTableSetting"; -import BetweenNumberFilter from "@/core/components/DataTable/filter/BetweenNumberFilter"; -import BetWeenDateFilter from "@/core/components/DataTable/filter/DatePicker/BetweenDateFilter"; -import SelectBoxMultiple from "@/core/components/DataTable/filter/SelectBoxMultiple"; -import SelectBox from "@/core/components/DataTable/filter/SelectBox"; -import FilterAltIcon from '@mui/icons-material/FilterAlt'; -import CloseIcon from '@mui/icons-material/Close'; -import TextFieldWithFnBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox"; - -function FilterColumn({columns}) { - const [open, setOpen] = useState(false); - const [selectedFilters, setSelectedFilters] = useState([]); - const [userId, setUserId] = useState(0); - const [pageName, setPageName] = useState('testPage'); - const [tableName, setTableName] = useState('testTable'); - const {settingStore, hideAction, filterAction, sortAction,} = useTableSetting(); - - const DrawerHeader = styled('div')(({theme}) => ({ - display: 'flex', - alignItems: 'center', - padding: theme.spacing(0, 1), - justifyContent: 'space-between', - })); - const toggleDrawer = (newOpen) => () => { - setOpen(newOpen); - }; - const handleDrawerClose = () => { - setOpen(false); - }; - useEffect(() => { - const settingValue = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []; - setSelectedFilters(settingValue.length > 0 ? settingValue : []); - if (!settingValue.length > 0) { - formik.resetForm(); - } - }, [settingStore]); - - const handleSelectFilter = (fieldName, filterFn) => { - const filterIndex = selectedFilters.findIndex(filter => filter.id === fieldName); - if (filterIndex !== -1) { - const updatedFilters = [...selectedFilters]; - updatedFilters[filterIndex].fn = filterFn; - setSelectedFilters(updatedFilters); - } else { - const newFilter = {id: fieldName, fn: filterFn}; - const updatedFilters = [...selectedFilters, newFilter]; - setSelectedFilters(updatedFilters); - } - }; - - const initialValues = columns.reduce((acc, column) => { - if (column.enableColumnFilter) { - const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); - if (column.filterFn === 'betweenNum' || column.filterFn === 'betweenDate') { - acc[column.id] = filter?.value || ["", ""]; - } else if (column.type === 'select2') { - acc[column.id] = filter?.value || []; - } else { - acc[column.id] = filter?.value || ''; - } - } - return acc; - }, {}); - - const formik = useFormik({ - initialValues, - onSubmit: (values) => { - const updatedFilters = selectedFilters.map(filter => { - const value = values[filter.id]; - if (value !== undefined) { - return {...filter, value}; - } - return filter; - }); - Object.entries(values).forEach(([fieldName, value]) => { - const filterIndex = updatedFilters.findIndex(filter => filter.id === fieldName); - if (filterIndex === -1 && value !== '' && value !== null && value !== undefined) { - const column = columns.find(col => col.id === fieldName); - updatedFilters.push({id: fieldName, value, fn: column.filterFn, datatype: column.datatype}); - } - }); - - const newArrayFilter = updatedFilters.filter((filter) => { - const value = values[filter.id]; - - return ( - value !== '' && - value !== null && - value !== undefined && - !(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value.every((v) => v === '')))) - ); - }); - - setSelectedFilters(newArrayFilter); - filterAction(userId, pageName, tableName, newArrayFilter, columns); - } - - }); - console.log(settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']) - return ( - <> - - - - - - - - فیلتر - - - - - - - {columns.map((column, index) => ( - column.enableColumnFilter && - (column.inputType === 'betweenDate' ? - filter.id === column.id)?.value || ''} - /> - : column.inputType === 'betweenNum' ? - filter.id === column.id)?.value || ["", ""]} - /> - : column.inputType === 'select2' ? - filter.id === column.id)?.value || []} - /> - : column.inputType === 'select' ? - filter.id === column.id)?.value || ''} - /> - : - filter.id === column.id)?.fn || column._filterFn} - columnFilterModeOptions={column.columnFilterModeOptions} - onSelectFilter={(filterFn) => handleSelectFilter(column.id, filterFn)} - defaultValue={formik.values[column.id] || (settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.value || ''} - /> - ) - ))} - - - - - - - - - - - ); -} - -export default FilterColumn; - - diff --git a/src/core/components/DataTable/filter/SelectBox.jsx b/src/core/components/DataTable/filter/SelectBox.jsx deleted file mode 100644 index 88cce6e..0000000 --- a/src/core/components/DataTable/filter/SelectBox.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import FormControl from '@mui/material/FormControl'; -import Select from '@mui/material/Select'; -import {useEffect, useState} from "react"; -const names = [ - 'Oliver Hansen', - 'Van Henry', - 'April Tucker', - 'Ralph Hubbard', - 'Omar Alexander', - 'Carlos Abbott', - 'Miriam Wagner', - 'Bradley Wilkerson', - 'Virginia Andrews', - 'Kelly Snyder', -]; -const SelectBox = ({ formik, id, defaultValue }) => { - - useEffect(() => { - formik.setFieldValue(id, defaultValue || ''); - }, []); - - const [selectedValue, setSelectedValue] = useState(defaultValue || ''); - - const handleChange = (event) => { - const { value } = event.target; - setSelectedValue(value); - formik.setFieldValue(id, value); - }; - - return ( - <> - - انتخاب - - - - ); -}; - -export default SelectBox; diff --git a/src/core/components/DataTable/filter/SelectBoxMultiple.jsx b/src/core/components/DataTable/filter/SelectBoxMultiple.jsx deleted file mode 100644 index 4355c72..0000000 --- a/src/core/components/DataTable/filter/SelectBoxMultiple.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import {useTheme} from '@mui/material/styles'; -import Box from '@mui/material/Box'; -import OutlinedInput from '@mui/material/OutlinedInput'; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import FormControl from '@mui/material/FormControl'; -import Select from '@mui/material/Select'; -import Chip from '@mui/material/Chip'; -import {useEffect, useState} from "react"; - -const ITEM_HEIGHT = 48; -const ITEM_PADDING_TOP = 8; -const MenuProps = { - PaperProps: { - style: { - maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, - width: 250, - }, - }, -}; - -const names = [ - 'Oliver Hansen', - 'Van Henry', - 'April Tucker', - 'Ralph Hubbard', - 'Omar Alexander', - 'Carlos Abbott', - 'Miriam Wagner', - 'Bradley Wilkerson', - 'Virginia Andrews', - 'Kelly Snyder', -]; - -function getStyles(name, personName, theme) { - return { - fontWeight: - personName.indexOf(name) === -1 - ? theme.typography.fontWeightRegular - : theme.typography.fontWeightMedium, - }; -} - -const SelectBoxMultiple = ({formik, id, defaultValue}) => { - const theme = useTheme(); - const [personName, setPersonName] = useState(defaultValue || []); - - useEffect(() => { - defaultValue.forEach((value, index) => { - formik.setFieldValue(`${id}[${index}]`, value || ''); - }); - - }, []); - - const handleChange = (event) => { - const { - target: {value}, - } = event; - - const selectedValues = typeof value === 'string' ? value.split(',').filter(item => item.trim() !== '') : value; - - formik.setFieldValue(id, []); - - if (selectedValues.length === 0) { - setPersonName([]); - formik.setFieldValue(id, []); - } else { - setPersonName(selectedValues); - selectedValues.forEach((selectedValue, index) => { - formik.setFieldValue(`${id}[${index}]`, selectedValue); - }); - } - }; - - return ( - <> - - انتخاب - - - - ); -}; - -export default SelectBoxMultiple; diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx deleted file mode 100644 index 3bba610..0000000 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import {ClickAwayListener, List, ListItem, ListItemText, Paper, Popper} from '@mui/material'; -import {useState} from "react"; - -const columnFilterModeOptionFa = { - equals: "برابر", - notEquals: "نابرابر", - contains: "شامل", - lessThan: "کوچکتر", - greaterThan: "بزرگتر", - fuzzy: "فازی", -} - -function FilterBox({ - anchorEl, open = false, handleClose = () => { - }, columnFilterModeOptions, onSelectFilter, defaultFilter - }) { - const [selectedFilter, setSelectedFilter] = useState(defaultFilter); - - const id = open ? 'simple-popper' : undefined; - const handleSelectFilter = (filterFn) => { - setSelectedFilter(filterFn); - onSelectFilter(filterFn); - handleClose(); - }; - - return ( -
- - - - - {columnFilterModeOptions.map((option, index) => ( - handleSelectFilter(option)} - selected={option === selectedFilter} sx={{cursor: 'pointer'}}> - - - ))} - - - - -
- ); -} - -export default FilterBox; diff --git a/src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx b/src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx deleted file mode 100644 index 18600dc..0000000 --- a/src/core/components/DataTable/filter/TextFieldWithFnBox/TextFieldWithFnBox.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import {IconButton, TextField} from '@mui/material'; -import ArtTrackIcon from '@mui/icons-material/ArtTrack'; -import {useEffect, useState} from "react"; -import FilterBox from "@/core/components/DataTable/filter/TextFieldWithFnBox/FilterBox"; - -const TextFieldWithFnBox = ({ - formik, - id, - header, - defaultValue, - defaultFilter, - columnFilterModeOptions, - onSelectFilter - }) => { - - const [anchorEl, setAnchorEl] = useState(null); - const [open, setOpen] = useState(false); - - useEffect(() => { - formik.setFieldValue(id, defaultValue || ''); - }, []); - - const handleClick = (event) => { - setOpen((prevOpen) => !prevOpen); - setAnchorEl(anchorEl ? null : event.currentTarget); - }; - - const handleClose = () => { - setOpen(false); - setAnchorEl(null); - }; - - return ( - <> - - - - ) - }} - sx={{ - position: 'relative' - }} - /> - - - ); -}; - -export default TextFieldWithFnBox; diff --git a/src/core/components/DataTable/filter/index.jsx b/src/core/components/DataTable/filter/index.jsx new file mode 100644 index 0000000..b8872bf --- /dev/null +++ b/src/core/components/DataTable/filter/index.jsx @@ -0,0 +1,18 @@ +'use client' + +import {useState} from "react"; +import FilterButton from "@/core/components/DataTable/filter/FilterButton"; +import FilterBody from "@/core/components/DataTable/filter/FilterBody"; + +function FilterColumn({columns}) { + const [open, setOpen] = useState(false); + + return ( + <> + + + + ); +} + +export default FilterColumn; diff --git a/src/core/components/DataTable/refactor/RefactorTable.jsx b/src/core/components/DataTable/refactor/RefactorTable.jsx index 06f75c1..71e302c 100644 --- a/src/core/components/DataTable/refactor/RefactorTable.jsx +++ b/src/core/components/DataTable/refactor/RefactorTable.jsx @@ -6,9 +6,9 @@ import {useState} from "react"; function RefactorTable() { const {refactorAction} = useTableSetting(); - const [userId, setUserId] = useState(2); - const [pageName, setPageName] = useState('loan'); - const [tableName, setTableName] = useState('loan_table'); + const [userId, setUserId] = useState(0); + const [pageName, setPageName] = useState('testPage'); + const [tableName, setTableName] = useState('testTable'); const refactor = () => { refactorAction(userId, pageName, tableName); diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 2b9641c..53c65da 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -3,7 +3,7 @@ import {Box, 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/FilterColumn"; +import FilterColumn from "@/core/components/DataTable/filter"; import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; const DataTable_TopToolbar = ({table, columns}) => { From fddf62921472fadc8a509308588ae1f29baff7d5 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 25 May 2024 17:32:26 +0330 Subject: [PATCH 10/28] design filter part and do step1 (default value for filterFn) --- src/components/home/index.jsx | 33 +++-- .../DataTable/filter/FilterBody.jsx | 139 ++++++++++++------ .../DataTable/filter/FilterBodyField.jsx | 59 +++++++- .../DataTable/filter/FilterHeader.jsx | 32 ++++ .../DataTable/filter/FilterOptionList.jsx | 29 ++++ 5 files changed, 232 insertions(+), 60 deletions(-) create mode 100644 src/core/components/DataTable/filter/FilterHeader.jsx create mode 100644 src/core/components/DataTable/filter/FilterOptionList.jsx diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 2682b64..f8a3d65 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -14,10 +14,9 @@ function HomeComponent() { accessorKey: 'name.firstName', header: 'نام', id: "firstName", - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", - inputType: "textField", enableClickToCopy: true, columnFilterModeOptions: [ "equals", @@ -32,7 +31,6 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "equals", - inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -48,7 +46,6 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "notEquals", - inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -62,7 +59,6 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "equals", - inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -80,7 +76,6 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "contains", - inputType: "textField", columnFilterModeOptions: [ "equals", "notEquals", @@ -94,7 +89,11 @@ function HomeComponent() { enableColumnFilter: true, datatype: "nemeric", filterFn: "between", - inputType: "betweenNum", + columnFilterModeOptions: [ + "equals", + "notEquals", + "between" + ], }, { accessorKey: 'updated_at', @@ -103,16 +102,24 @@ function HomeComponent() { enableColumnFilter: true, datatype: "date", filterFn: "between", - inputType: "betweenDate", + columnFilterModeOptions: [ + "equals", + "notEquals", + "between" + ], }, { accessorKey: 'company', header: 'نام شرکت', id: "company", enableColumnFilter: true, - datatype: "text", + datatype: "select2", filterFn: "equals", - inputType: "select2", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains" + ], }, { accessorKey: 'area', @@ -121,7 +128,11 @@ function HomeComponent() { enableColumnFilter: true, datatype: "text", filterFn: "equals", - inputType: "select", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains" + ], }, ], [], diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx index b87f980..42e826b 100644 --- a/src/core/components/DataTable/filter/FilterBody.jsx +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -1,58 +1,103 @@ 'use client' -import {Box, Drawer, IconButton, Typography} from "@mui/material"; -import CancelIcon from '@mui/icons-material/Cancel'; +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 FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField"; +import FilterHeader from "@/core/components/DataTable/filter/FilterHeader"; + +const ScrollBox = styled(Box)({ + flexGrow: 1, + padding: '16px', + overflowY: 'scroll', + maxWidth: "450px", + '::-webkit-scrollbar': { + width: '5px', + }, + '::-webkit-scrollbar-track': { + boxShadow: 'inset 0 0 5px #fff', + borderRadius: '5px', + }, + '::-webkit-scrollbar-thumb': { + background: '#16534a', + borderRadius: '0px', + }, + '::-webkit-scrollbar-thumb:hover': { + background: '#ffffff', + }, +}); function FilterBody({columns, drawerState, setDrawerState}) { - // const initialValues = columns.reduce((acc, column) => { - // if (column.enableColumnFilter) { - // const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); - // if (column.filterFn === 'betweenNum' || column.filterFn === 'betweenDate') { - // acc[column.id] = filter?.value || ["", ""]; - // } else if (column.type === 'select2') { - // acc[column.id] = filter?.value || []; - // } else { - // acc[column.id] = filter?.value || ''; - // } - // } - // return acc; - // }, {}); - // const initialValues = {}; + const [userId, setUserId] = useState(0); + const [pageName, setPageName] = useState('testPage'); + const [tableName, setTableName] = useState('testTable'); + const {settingStore, filterAction} = useTableSetting(); + + const [initialValues, setInitialValues] = useState({}); + + useEffect(() => { + const values = columns.reduce((acc, column) => { + if (!column.enableColumnFilter) return acc; + const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); + if (column.datatype === 'select2') { + acc[column.id] = filter?.value || []; + } else { + acc[column.id] = filter?.value || ''; + } + return acc; + }, {}); + setInitialValues(values); + }, [columns, settingStore, userId, pageName, tableName]); + + const handleSubmit = (values) => { + console.log("Form values:", values); + }; + return ( - { - setDrawerState(false) - }}> - - فیلتر - { - setDrawerState(false) - }}> - - - - - {/**/} - {columns.map((column) => { - - })} - {/**/} + setDrawerState(false)} + sx={{overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%"}}> + + + {Object.keys(initialValues).length > 0 && ( + + {({values, handleChange, handleBlur}) => ( +
+ {columns.map((column) => ( + column.enableColumnFilter && ( + + ) + ))} + + )} +
+ )} +
+ +
); } -export default FilterBody; +export default FilterBody; \ No newline at end of file diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index e78697e..9d20133 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -1,8 +1,63 @@ 'use client' -function FilterBodyField({column}) { +import {InputAdornment, TextField, Typography} from "@mui/material"; +import FilterListIcon from '@mui/icons-material/FilterList'; +import {useState} from "react"; +import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList"; +import useTableSetting from "@/lib/hooks/useTableSetting"; + +const columnFilterModeOptionFa = { + equals: "برابر", + notEquals: "نابرابر", + contains: "شامل", + lessThan: "کوچکتر", + greaterThan: "بزرگتر", + fuzzy: "فازی", + between: "مابین" +} + +function FilterBodyField({column, value}) { + const [anchorEl, setAnchorEl] = useState(null); + const [userId, setUserId] = useState(0); + const [pageName, setPageName] = useState('testPage'); + const [tableName, setTableName] = useState('testTable'); + const {settingStore} = useTableSetting(); + const defaultFilter = (settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.fn || column._filterFn; + const defaultFilterTranslation = columnFilterModeOptionFa[defaultFilter] || defaultFilter; + + const HandleOpenFilterBox = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleCloseFilterBox = () => { + setAnchorEl(null); + }; + return ( - asdasdasd + <> + + نوع فیلتر: {defaultFilterTranslation} + } + variant="outlined" + size="normal" + sx={{marginY: 1}} + InputProps={{ + endAdornment: ( + + + + ), + }} + /> + + ); } diff --git a/src/core/components/DataTable/filter/FilterHeader.jsx b/src/core/components/DataTable/filter/FilterHeader.jsx new file mode 100644 index 0000000..015801d --- /dev/null +++ b/src/core/components/DataTable/filter/FilterHeader.jsx @@ -0,0 +1,32 @@ +'use client' + +import {Box, IconButton, Typography} from "@mui/material"; +import CancelIcon from '@mui/icons-material/Cancel'; +import FilterAltIcon from '@mui/icons-material/FilterAlt'; + +function FilterHeader({setDrawerState}) { + return ( + + + + فیلتر + + setDrawerState(false)}> + + + + ); +} + +export default FilterHeader; \ No newline at end of file diff --git a/src/core/components/DataTable/filter/FilterOptionList.jsx b/src/core/components/DataTable/filter/FilterOptionList.jsx new file mode 100644 index 0000000..fb4fc46 --- /dev/null +++ b/src/core/components/DataTable/filter/FilterOptionList.jsx @@ -0,0 +1,29 @@ +'use client' + +import {ListItem, Menu} from "@mui/material"; +import {useState} from "react"; + +function FilterOptionList({defaultFilter, filterOption, handleCloseFilterBox, anchorEl, columnFilterModeOptionFa}) { + + const [selectedFilter, setSelectedFilter] = useState(defaultFilter); + + return ( + + {filterOption.map((option, index) => ( + + {columnFilterModeOptionFa[option]} + + ))} + + ); +} + +export default FilterOptionList; From 474e6f3e8dfe864f4a953c2c18b40f0e306d7eb8 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 1 Jun 2024 17:19:56 +0330 Subject: [PATCH 11/28] create custom components for fileds and start to get hand dirty on datepicker (step2) --- src/components/home/index.jsx | 30 +++---- .../DataTable/filter/FilterBodyField.jsx | 88 +++++++++++++------ .../filter/fieldsType/CustomDatePicker.jsx | 30 +++++++ .../fieldsType/CustomDatePickerRange.jsx | 30 +++++++ .../filter/fieldsType/CustomSelect.jsx | 44 ++++++++++ .../fieldsType/CustomSelectMultiple.jsx | 36 ++++++++ .../filter/fieldsType/CustomTextField.jsx | 30 +++++++ .../fieldsType/CustomTextFieldRange.jsx | 45 ++++++++++ 8 files changed, 287 insertions(+), 46 deletions(-) create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index f8a3d65..ae8a116 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -14,7 +14,7 @@ function HomeComponent() { accessorKey: 'name.firstName', header: 'نام', id: "firstName", - enableColumnFilter: false, + enableColumnFilter: true, datatype: "text", filterFn: "contains", enableClickToCopy: true, @@ -67,7 +67,6 @@ function HomeComponent() { "greaterThan", "fuzzy" ], - }, { accessorKey: 'state', @@ -87,7 +86,7 @@ function HomeComponent() { header: 'محدوده', id: "price", enableColumnFilter: true, - datatype: "nemeric", + datatype: "numeric", filterFn: "between", columnFilterModeOptions: [ "equals", @@ -102,23 +101,18 @@ function HomeComponent() { enableColumnFilter: true, datatype: "date", filterFn: "between", - columnFilterModeOptions: [ - "equals", - "notEquals", - "between" - ], }, { accessorKey: 'company', header: 'نام شرکت', id: "company", enableColumnFilter: true, - datatype: "select2", + datatype: "numeric", filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" + columnSelectOption: [ + {value: 1, label: "وایتل"}, + {value: 2, label: "اسنپ"}, + {value: 3, label: "تپسی"} ], }, { @@ -126,12 +120,12 @@ function HomeComponent() { header: 'منطقه', id: "area", enableColumnFilter: true, - datatype: "text", + datatype: "numeric", filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" + columnSelectOption: [ + {value: 1, label: "وایتل"}, + {value: 2, label: "اسنپ"}, + {value: 3, label: "تپسی"} ], }, ], diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index 9d20133..f60f9df 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -1,10 +1,14 @@ 'use client' -import {InputAdornment, TextField, Typography} from "@mui/material"; -import FilterListIcon from '@mui/icons-material/FilterList'; import {useState} from "react"; import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList"; import useTableSetting from "@/lib/hooks/useTableSetting"; +import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect"; +import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField"; +import CustomTextFieldRange from "@/core/components/DataTable/filter/fieldsType/CustomTextFieldRange"; +import CustomDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDatePicker"; +import CustomSelectMultiple from "@/core/components/DataTable/filter/fieldsType/CustomSelectMultiple"; +import CustomDatePickerRange from "@/core/components/DataTable/filter/fieldsType/CustomDatePickerRange"; const columnFilterModeOptionFa = { equals: "برابر", @@ -25,40 +29,68 @@ function FilterBodyField({column, value}) { const defaultFilter = (settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.fn || column._filterFn; const defaultFilterTranslation = columnFilterModeOptionFa[defaultFilter] || defaultFilter; - const HandleOpenFilterBox = (event) => { + const handleOpenFilterBox = (event) => { setAnchorEl(event.currentTarget); }; const handleCloseFilterBox = () => { setAnchorEl(null); }; - return ( <> - - نوع فیلتر: {defaultFilterTranslation} - } - variant="outlined" - size="normal" - sx={{marginY: 1}} - InputProps={{ - endAdornment: ( - - - - ), - }} - /> - + {column.datatype === "numeric" && column._filterFn === "between" ? ( + + ) : column.datatype === "numeric" && column._filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( + + ) : column.datatype === "date" && column._filterFn === "equals" ? ( + + ) : column.datatype === "date" && column._filterFn === "between" ? ( + + ) : column.datatype === "array" && column._filterFn === "equals" ? ( + + ) : ( + + )} + {Array.isArray(column.columnFilterModeOptions) && anchorEl !== null && ( + + )} ); } -export default FilterBodyField; +export default FilterBodyField; \ No newline at end of file diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx new file mode 100644 index 0000000..5e600f0 --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx @@ -0,0 +1,30 @@ +'use client' + +import {InputAdornment, TextField, Typography} from "@mui/material"; +import FilterListIcon from '@mui/icons-material/FilterList'; + +function CustomDatePicker({column, value, defaultFilterTranslation, handleOpenFilterBox}) { + return ( + + نوع فیلتر: {defaultFilterTranslation} + } + variant="outlined" + size="normal" + sx={{marginY: 1}} + InputProps={{ + endAdornment: ( + + + + ), + }} + /> + ); +} + +export default CustomDatePicker; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx new file mode 100644 index 0000000..ace1e3f --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx @@ -0,0 +1,30 @@ +'use client' + +import {InputAdornment, TextField, Typography} from "@mui/material"; +import FilterListIcon from '@mui/icons-material/FilterList'; + +function CustomDatePickerRange({column, value, defaultFilterTranslation, handleOpenFilterBox}) { + return ( + + نوع فیلتر: {defaultFilterTranslation} + } + variant="outlined" + size="normal" + sx={{marginY: 1}} + InputProps={{ + endAdornment: ( + + + + ), + }} + /> + ); +} + +export default CustomDatePickerRange; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx new file mode 100644 index 0000000..4c44a5f --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx @@ -0,0 +1,44 @@ +'use client' + +import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; +import {useState} from "react"; + +function CustomSelect({column, value, defaultFilterTranslation}) { + const [fieldValue, setFieldValue] = useState(value); + const columnSelectOption = column.columnSelectOption; + + const handleChange = (event) => { + setFieldValue(event.target.value); + }; + + return ( + + {column.header} + + + + نوع فیلتر: {defaultFilterTranslation} + + + + ); +} + +export default CustomSelect; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx new file mode 100644 index 0000000..af5200e --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx @@ -0,0 +1,36 @@ +'use client' + +import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; + +function CustomSelectMultiple({column, value, defaultFilterTranslation}) { + const columnSelectOption = column.columnSelectOption; + return ( + + {column.header} + + + + نوع فیلتر: {defaultFilterTranslation} + + + + ); +} + +export default CustomSelectMultiple; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx new file mode 100644 index 0000000..c760de2 --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx @@ -0,0 +1,30 @@ +'use client' + +import {InputAdornment, TextField, Typography} from "@mui/material"; +import FilterListIcon from '@mui/icons-material/FilterList'; + +function CustomTextField({column, value, defaultFilterTranslation, handleOpenFilterBox}) { + return ( + + نوع فیلتر: {defaultFilterTranslation} + } + variant="outlined" + size="normal" + sx={{marginY: 1}} + InputProps={{ + endAdornment: ( + + + + ), + }} + /> + ); +} + +export default CustomTextField; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx new file mode 100644 index 0000000..1fbbd40 --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx @@ -0,0 +1,45 @@ +'use client' + +import {Box, InputAdornment, TextField, Typography} from "@mui/material"; +import FilterListIcon from '@mui/icons-material/FilterList'; + +function CustomTextFieldRange({column, value, defaultFilterTranslation, handleOpenFilterBox}) { + return ( + + + از {column.header} + } + value={value} + fullWidth + helperText={ + نوع فیلتر: {defaultFilterTranslation} + } + variant="outlined" + size="normal" + sx={{marginY: 1, marginRight: 1}} + /> + + تا {column.header} + } + value={value} + fullWidth + variant="outlined" + size="normal" + sx={{marginY: 1}} + InputProps={{ + endAdornment: ( + + + + ), + }} + /> + + ); +} + +export default CustomTextFieldRange; From 3f896ef5e91868bf257d54b366d8305a30a7ffc5 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sun, 9 Jun 2024 16:43:53 +0330 Subject: [PATCH 12/28] working on datepickerrange problems --- package.json | 5 +- src/components/home/index.jsx | 12 ++- .../DataTable/filter/FilterBody.jsx | 99 +++++++++++++------ .../DataTable/filter/FilterBodyField.jsx | 16 ++- .../CustomDate/CustomDatePicker.jsx | 15 +++ .../CustomDate/CustomDatePickerRange.jsx | 25 +++++ .../fieldsType/CustomDate/DatePicker.jsx | 66 +++++++++++++ .../filter/fieldsType/CustomDatePicker.jsx | 30 ------ .../fieldsType/CustomDatePickerRange.jsx | 30 ------ .../filter/fieldsType/CustomSelect.jsx | 17 ++-- .../fieldsType/CustomSelectMultiple.jsx | 32 +++++- .../filter/fieldsType/CustomTextField.jsx | 5 +- .../fieldsType/CustomTextFieldRange.jsx | 44 +++++---- 13 files changed, 264 insertions(+), 132 deletions(-) create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx create mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker.jsx delete mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx delete mode 100644 src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx diff --git a/package.json b/package.json index 3e7a01c..0290200 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,13 @@ "formik": "^2.4.5", "jalali-moment": "^3.3.11", "material-react-table": "^2.11.2", - "next": "14.1.0", + "next": "^14.2.3", "react": "^18", "react-dom": "^18", "sass": "^1.75.0", "stylis": "^4.3.1", - "stylis-plugin-rtl": "^2.1.1" + "stylis-plugin-rtl": "^2.1.1", + "yup": "^1.4.0" }, "devDependencies": { "eslint": "^8", diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index ae8a116..359e13e 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -94,13 +94,21 @@ function HomeComponent() { "between" ], }, + { + accessorKey: 'created_at', + header: 'تاریخ ساخت', + id: "created_at", + enableColumnFilter: true, + datatype: "date", + filterFn: "between", + }, { accessorKey: 'updated_at', header: 'تاریخ بروزرسانی', id: "updated_at", enableColumnFilter: true, datatype: "date", - filterFn: "between", + filterFn: "equals", }, { accessorKey: 'company', @@ -120,7 +128,7 @@ function HomeComponent() { header: 'منطقه', id: "area", enableColumnFilter: true, - datatype: "numeric", + datatype: "array", filterFn: "equals", columnSelectOption: [ {value: 1, label: "وایتل"}, diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx index 42e826b..fb6dcea 100644 --- a/src/core/components/DataTable/filter/FilterBody.jsx +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -6,10 +6,10 @@ import useTableSetting from "@/lib/hooks/useTableSetting"; import {useEffect, useState} from "react"; import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField"; import FilterHeader from "@/core/components/DataTable/filter/FilterHeader"; +import * as Yup from "yup"; const ScrollBox = styled(Box)({ flexGrow: 1, - padding: '16px', overflowY: 'scroll', maxWidth: "450px", '::-webkit-scrollbar': { @@ -40,8 +40,10 @@ function FilterBody({columns, drawerState, setDrawerState}) { const values = columns.reduce((acc, column) => { if (!column.enableColumnFilter) return acc; const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); - if (column.datatype === 'select2') { + if (column.datatype === 'array') { acc[column.id] = filter?.value || []; + } else if (column._filterFn === "between") { + acc[column.id] = filter?.value || ["", ""]; } else { acc[column.id] = filter?.value || ''; } @@ -50,6 +52,33 @@ function FilterBody({columns, drawerState, setDrawerState}) { setInitialValues(values); }, [columns, settingStore, userId, pageName, tableName]); + console.log("initialValues", initialValues) + + const validationSchema = Yup.object().shape( + columns.reduce((acc, column) => { + if (column._filterFn === "between") { + acc[column.id] = Yup.array().of(Yup.string()).test({ + test(value, ctx) { + const [start, end] = value || ["", ""]; + const startInt = parseInt(start, 10); + const endInt = parseInt(end, 10); + if (start && end && endInt <= startInt) { + return ctx.createError({ + message: `مقدار وارده باید بیشتر از (${start}) باشد` + }); + } else if (start && !end) { + return ctx.createError({ + message: "این بخش را پر نمایید" + }); + } + return true; + } + }); + } + return acc; + }, {}) + ); + const handleSubmit = (values) => { console.log("Form values:", values); }; @@ -58,44 +87,50 @@ function FilterBody({columns, drawerState, setDrawerState}) { setDrawerState(false)} sx={{overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%"}}> - - {Object.keys(initialValues).length > 0 && ( + {Object.keys(initialValues).length > 0 && ( + - {({values, handleChange, handleBlur}) => ( + {({values, handleChange, handleBlur, setFieldValue, errors, touched}) => (
- {columns.map((column) => ( - column.enableColumnFilter && ( - - ) - ))} + + {columns.map((column) => ( + column.enableColumnFilter && ( + + ) + ))} + + + + )}
- )} -
- - - +
+ )}
); } diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index f60f9df..879a5e0 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -6,9 +6,9 @@ import useTableSetting from "@/lib/hooks/useTableSetting"; import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect"; import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField"; import CustomTextFieldRange from "@/core/components/DataTable/filter/fieldsType/CustomTextFieldRange"; -import CustomDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDatePicker"; +import CustomDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker"; import CustomSelectMultiple from "@/core/components/DataTable/filter/fieldsType/CustomSelectMultiple"; -import CustomDatePickerRange from "@/core/components/DataTable/filter/fieldsType/CustomDatePickerRange"; +import CustomDatePickerRange from "@/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange"; const columnFilterModeOptionFa = { equals: "برابر", @@ -20,7 +20,7 @@ const columnFilterModeOptionFa = { between: "مابین" } -function FilterBodyField({column, value}) { +function FilterBodyField({column, value, handleChange, handleBlur, setFieldValue, errors, touched}) { const [anchorEl, setAnchorEl] = useState(null); const [userId, setUserId] = useState(0); const [pageName, setPageName] = useState('testPage'); @@ -28,7 +28,6 @@ function FilterBodyField({column, value}) { const {settingStore} = useTableSetting(); const defaultFilter = (settingStore?.[userId]?.[pageName]?.[tableName]?.['filters'] || []).find(filter => filter.id === column.id)?.fn || column._filterFn; const defaultFilterTranslation = columnFilterModeOptionFa[defaultFilter] || defaultFilter; - const handleOpenFilterBox = (event) => { setAnchorEl(event.currentTarget); }; @@ -43,11 +42,16 @@ function FilterBodyField({column, value}) { value={value} defaultFilterTranslation={defaultFilterTranslation} handleOpenFilterBox={handleOpenFilterBox} + handleBlur={handleBlur} + handleChange={handleChange} + errors={errors} + touched={touched} /> ) : column.datatype === "numeric" && column._filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( @@ -55,6 +59,7 @@ function FilterBodyField({column, value}) { @@ -69,6 +74,7 @@ function FilterBodyField({column, value}) { @@ -78,6 +84,8 @@ function FilterBodyField({column, value}) { value={value} defaultFilterTranslation={defaultFilterTranslation} handleOpenFilterBox={handleOpenFilterBox} + handleBlur={handleBlur} + handleChange={handleChange} /> )} {Array.isArray(column.columnFilterModeOptions) && anchorEl !== null && ( diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx new file mode 100644 index 0000000..ec57e2f --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import DatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker"; + +function CustomDatePicker({column, value, defaultFilterTranslation, setFieldValue}) { + return ( + + ); +} + +export default CustomDatePicker; \ No newline at end of file diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx new file mode 100644 index 0000000..847c16f --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx @@ -0,0 +1,25 @@ +'use client' + +import DatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker"; +import React from "react"; + +function CustomDatePickerRange({column, value, defaultFilterTranslation, setFieldValue}) { + return ( + <> + + + + ); +} + +export default CustomDatePickerRange; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker.jsx new file mode 100644 index 0000000..19ffb3d --- /dev/null +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/DatePicker.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers"; +import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import {faIR} from "@mui/x-date-pickers/locales"; +import {IconButton, InputAdornment, Typography} from "@mui/material"; +import ClearIcon from "@mui/icons-material/Clear"; +import moment from "jalali-moment"; + +function DatePicker({column, value, defaultFilterTranslation, setFieldValue}) { + return ( + + { + const date = new Date(value); + const formattedDate = moment(date) + .locale("en") + .format("YYYY-MM-DD"); + setFieldValue(column.id, formattedDate); + }} + slotProps={{ + textField: { + placeholder: "تاریخ خود را وارد کنید", + helperText: ( + + نوع فیلتر: {defaultFilterTranslation} (تاریخ) + + ), + InputProps: { + endAdornment: ( + + { + event.stopPropagation(); + setFieldValue(column.id, ""); + }} + sx={{ + color: "#bfbfbf", + '&:hover': { + backgroundColor: 'rgba(189, 189, 189, 0.1)', + color: "#363434" + }, + }} + > + + + + ), + }, + }, + }} + /> + + ); +} + +export default DatePicker; \ No newline at end of file diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx deleted file mode 100644 index 5e600f0..0000000 --- a/src/core/components/DataTable/filter/fieldsType/CustomDatePicker.jsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client' - -import {InputAdornment, TextField, Typography} from "@mui/material"; -import FilterListIcon from '@mui/icons-material/FilterList'; - -function CustomDatePicker({column, value, defaultFilterTranslation, handleOpenFilterBox}) { - return ( - - نوع فیلتر: {defaultFilterTranslation} - } - variant="outlined" - size="normal" - sx={{marginY: 1}} - InputProps={{ - endAdornment: ( - - - - ), - }} - /> - ); -} - -export default CustomDatePicker; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx deleted file mode 100644 index ace1e3f..0000000 --- a/src/core/components/DataTable/filter/fieldsType/CustomDatePickerRange.jsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client' - -import {InputAdornment, TextField, Typography} from "@mui/material"; -import FilterListIcon from '@mui/icons-material/FilterList'; - -function CustomDatePickerRange({column, value, defaultFilterTranslation, handleOpenFilterBox}) { - return ( - - نوع فیلتر: {defaultFilterTranslation} - } - variant="outlined" - size="normal" - sx={{marginY: 1}} - InputProps={{ - endAdornment: ( - - - - ), - }} - /> - ); -} - -export default CustomDatePickerRange; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx index 4c44a5f..ad21280 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx @@ -1,27 +1,22 @@ 'use client' import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; -import {useState} from "react"; -function CustomSelect({column, value, defaultFilterTranslation}) { - const [fieldValue, setFieldValue] = useState(value); +function CustomSelect({column, value, defaultFilterTranslation, setFieldValue}) { const columnSelectOption = column.columnSelectOption; - const handleChange = (event) => { - setFieldValue(event.target.value); - }; - return ( - {column.header} + {column.header} } onChange={(e) => { - setFieldValue(column.id, e.target.value) + setFieldValue(`${column.id}.value`, e.target.value) }} > {columnSelectOption.map((option) => ( diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx index d6a62eb..502eefd 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx @@ -12,7 +12,7 @@ import { Typography } from "@mui/material"; -function CustomSelectMultiple({column, value, defaultFilterTranslation, setFieldValue}) { +function CustomSelectMultiple({column, filterParameters, defaultFilterTranslation, setFieldValue}) { const columnSelectOption = column.columnSelectOption; const getLabelForValue = (value) => { @@ -27,10 +27,10 @@ function CustomSelectMultiple({column, value, defaultFilterTranslation, setField - + نوع فیلتر: {defaultFilterTranslation} diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx index 502eefd..ae027fe 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx @@ -51,7 +51,7 @@ function CustomSelectMultiple({column, filterParameters, defaultFilterTranslatio ))} - + نوع فیلتر: {defaultFilterTranslation} diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx index c5c35d8..91f9226 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx @@ -18,7 +18,7 @@ function CustomTextField({ onChange={handleChange} onBlur={handleBlur} fullWidth - helperText={ + helperText={ نوع فیلتر: {defaultFilterTranslation} } variant="outlined" diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx index 9d4da31..35c9358 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx @@ -22,7 +22,7 @@ function CustomTextFieldRange({ value={filterParameters.value[0]} fullWidth error={touched?.[`${column.id}`]?.value && Boolean(errors?.[`${column.id}`]?.value)} - helperText={نوع + helperText={نوع فیلتر: {defaultFilterTranslation}} variant="outlined" size="normal" diff --git a/src/core/components/DataTable/filter/index.jsx b/src/core/components/DataTable/filter/index.jsx index b8872bf..faa01c9 100644 --- a/src/core/components/DataTable/filter/index.jsx +++ b/src/core/components/DataTable/filter/index.jsx @@ -4,13 +4,14 @@ import {useState} from "react"; import FilterButton from "@/core/components/DataTable/filter/FilterButton"; import FilterBody from "@/core/components/DataTable/filter/FilterBody"; -function FilterColumn({columns}) { +function FilterColumn({columns, userid, pagename, tablename}) { const [open, setOpen] = useState(false); return ( <> - + ); } diff --git a/src/core/components/DataTable/index.js b/src/core/components/DataTable/index.js index aba1d1c..df0e109 100644 --- a/src/core/components/DataTable/index.js +++ b/src/core/components/DataTable/index.js @@ -1,142 +1,9 @@ -import {useMaterialReactTable} from "material-react-table"; import DataTable_Main from "./Main"; -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"; - -const data = [ - { - name: { - firstName: 'امین', - lastName: 'قاسمپور', - }, - address: 'فلان جا', - city: 'تهران', - state: 'بررسی شده', - price: '20', - updated_at: '2024/05/02', - company: 'همراه اول', - area: 'منطقه 5', - }, - { - name: { - firstName: 'امیر حسین', - lastName: 'محمودی', - }, - address: 'فلان جا', - city: 'تهران', - state: 'تکمیل شده', - price: '27', - updated_at: '2024/05/02', - company: 'وایتل', - area: 'منطقه 27', - }, - { - name: { - firstName: 'یاسمن', - lastName: 'علی اکبری', - }, - address: 'فلان جا', - city: 'شیراز', - state: 'بررسی شده', - price: '32', - updated_at: '2024/05/02', - company: 'ایرانسل', - area: 'منطقه 23', - }, - { - name: { - firstName: 'حمیدرضا', - lastName: 'رنجبرپور', - }, - address: 'فلان جا', - city: 'اصفهان', - state: 'بررسی شده', - price: '45', - updated_at: '2024/05/02', - company: 'ایرانول', - area: 'منطقه 21', - }, - { - name: { - firstName: 'محمد', - lastName: 'جلالی', - }, - address: 'فلان جا', - city: 'رشت', - state: 'درحال بررسی', - price: '8', - updated_at: '2024/05/02', - company: 'فیلیمو', - area: 'منطقه 8', - }, -]; const DataTable = (props) => { - const {userId, pageName, tableName, columns, initialStateProps} = props - const {settingStore, hideAction, sortAction} = useTableSetting(); - const flatColumns = flattenArrayOfObjects(columns, 'columns') - - const onColumnVisibilityChange = (event) => { - const settingValue = event(); - hideAction(userId, pageName, tableName, settingValue, flatColumns); - }; - const onSortingChange = (event) => { - const settingValue = event(settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || []); - sortAction(userId, pageName, tableName, settingValue, flatColumns); - } - - - const table = useMaterialReactTable({ - localization: FA_DATATABLE_LOCALIZATION, - columns, - data: data, - // manualSorting: true, - renderTopToolbarCustomActions: ({table}) => (<> - - ), - initialState: { - density: 'compact', - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [], - ...initialStateProps - }, - state: { - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] - }, - muiTableHeadProps: { - sx: { - borderTop: "1px solid #e1e1e1", - borderBottom: "2px solid #e1e1e1", - } - }, - muiTableHeadCellProps: { - sx: { - color: "primary.main", - borderLeft: "1px solid #e1e1e1", - "&:first-of-type": { - borderLeft: "unset" - } - }, - }, - muiTableBodyCellProps: { - sx: { - borderLeft: "1px solid #e1e1e1", - "&:first-of-type": { - borderLeft: "unset" - } - }, - }, - onColumnVisibilityChange: onColumnVisibilityChange, - onSortingChange: onSortingChange, - ...props - }) - - return ; + return ( + + ); }; -export default DataTable; +export default DataTable; \ 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 ede47c1..7380cf0 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -65,7 +65,9 @@ const DataTable_Paper = ({table, ...rest}) => { > {enableTopToolbar && (parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( - + ))} {enableBottomToolbar && diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 53c65da..1adf4d3 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -6,7 +6,7 @@ import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import FilterColumn from "@/core/components/DataTable/filter"; import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; -const DataTable_TopToolbar = ({table, columns}) => { +const DataTable_TopToolbar = ({table, columns, userid, pagename, tablename}) => { const { getState, options: { @@ -73,7 +73,7 @@ const DataTable_TopToolbar = ({table, columns}) => { }} > - +
)} diff --git a/src/core/components/NotificationDesign/AskForKeep.jsx b/src/core/components/NotificationDesign/AskForKeep.jsx index 1d688a9..7a68d2f 100644 --- a/src/core/components/NotificationDesign/AskForKeep.jsx +++ b/src/core/components/NotificationDesign/AskForKeep.jsx @@ -1,6 +1,6 @@ 'use client' -import BeenhereIcon from '@mui/icons-material/Beenhere'; +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"; @@ -14,10 +14,10 @@ function AskForKeep({onSaveFilter}) { return ( - + ذخیره سازی اطلاعات - + @@ -34,8 +34,8 @@ function AskForKeep({onSaveFilter}) { From acc13ef1d50ef93365fb421e1ab78d6206b0831a Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sun, 23 Jun 2024 09:45:25 +0330 Subject: [PATCH 18/28] complete making needed data for keeping in local storage --- src/app/(withAuth)/dashboard/template.js | 2 - src/components/home/index.jsx | 3 +- src/core/components/DataTable/Main.js | 2 + .../DataTable/filter/FilterBody.jsx | 87 ++++++++++++------- .../DataTable/filter/FilterBodyField.jsx | 10 +-- .../filter/fieldsType/CustomTextField.jsx | 1 + src/core/components/DataTable/index.js | 5 +- src/lib/contexts/DataTable.jsx | 15 ++++ src/lib/hooks/useDataTable.jsx | 9 ++ 9 files changed, 94 insertions(+), 40 deletions(-) create mode 100644 src/lib/contexts/DataTable.jsx create mode 100644 src/lib/hooks/useDataTable.jsx 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; From 2777cdba08b990efa4b8160b105c0533b03d02a8 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 24 Jun 2024 14:49:41 +0330 Subject: [PATCH 19/28] complete filter part of datatable --- src/core/components/DataTable/filter/FilterBody.jsx | 3 ++- .../components/DataTable/filter/fieldsType/CustomSelect.jsx | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx index 17f830c..6d020a2 100644 --- a/src/core/components/DataTable/filter/FilterBody.jsx +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -187,10 +187,11 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab size="large" disabled={isSubmitting || !isValid || !dirty} sx={{ + px: 8, boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px", backgroundColor: "#155175", ':hover': { backgroundColor: "#155175", - }, width: "50%" + } }}> اعمال فیلتر diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx index 6fa20e4..44f0599 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx @@ -18,6 +18,7 @@ function CustomSelect({column, filterParameters, defaultFilterTranslation, setFi setFieldValue(`${column.id}.value`, e.target.value) }} > + {column.header} {columnSelectOption.map((option) => ( Date: Wed, 26 Jun 2024 10:25:22 +0330 Subject: [PATCH 20/28] debug name props problems --- src/components/home/index.jsx | 2 +- src/core/components/DataTable/Main.js | 20 +++++++++---------- .../DataTable/filter/FilterBody.jsx | 15 +++++++------- .../components/DataTable/filter/index.jsx | 6 +++--- src/core/components/DataTable/table/Paper.js | 6 +++--- .../DataTable/toolbar/TopToolbar.js | 5 +++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 659d11f..7af2edf 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -141,7 +141,7 @@ function HomeComponent() { return ( <> - + ); diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index 09300df..2110b34 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -76,18 +76,18 @@ const data = [ const DataTable_Main = (props) => { const {filterData} = useDataTable(); - const {userId, pageName, tableName, columns, initialStateProps} = props + const {user_id, page_name, table_name, columns, initialStateProps} = props const flatColumns = flattenArrayOfObjects(columns, 'columns') const {settingStore, hideAction, sortAction} = useTableSetting(); const onColumnVisibilityChange = (event) => { const settingValue = event(); - hideAction(userId, pageName, tableName, settingValue, flatColumns); + hideAction(user_id, page_name, table_name, settingValue, flatColumns); }; const onSortingChange = (event) => { - const settingValue = event(settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || []); - sortAction(userId, pageName, tableName, settingValue, flatColumns); + const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || []); + sortAction(user_id, page_name, table_name, settingValue, flatColumns); } const table = useMaterialReactTable({ @@ -102,13 +102,13 @@ const DataTable_Main = (props) => { ), initialState: { density: 'compact', - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [], + columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], + sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], ...initialStateProps }, state: { - columnVisibility: settingStore?.[userId]?.[pageName]?.[tableName]?.['hides'], - sorting: settingStore?.[userId]?.[pageName]?.[tableName]?.['sorts'] || [] + columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], + sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [] }, muiTableHeadProps: { sx: { @@ -141,8 +141,8 @@ const DataTable_Main = (props) => { ...props }) - return ; + return ; }; export default DataTable_Main; diff --git a/src/core/components/DataTable/filter/FilterBody.jsx b/src/core/components/DataTable/filter/FilterBody.jsx index 6d020a2..385981b 100644 --- a/src/core/components/DataTable/filter/FilterBody.jsx +++ b/src/core/components/DataTable/filter/FilterBody.jsx @@ -28,21 +28,20 @@ const ScrollBox = styled(Box)({ } }); -function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tableName}) { +function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, table_name}) { 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 - + const filterDataRef = useRef(filterData); useEffect(() => { - filterDataRef.current = filterData; // Update ref whenever filterData changes + filterDataRef.current = filterData; }, [filterData]); useEffect(() => { const values = columns.reduce((acc, column) => { if (!column.enableColumnFilter) return acc; - const filter = settingStore?.[userId]?.[pageName]?.[tableName]?.['filters']?.find((filter) => filter.id === column.id); + 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, @@ -68,7 +67,7 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab return acc; }, {}); setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values); - }, [columns, settingStore, userId, pageName, tableName, filterData]); + }, [columns, settingStore, user_id, page_name, table_name, filterData]); useEffect(() => { @@ -119,7 +118,7 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab }; const onSaveFilter = () => { - const currentFilterData = filterDataRef.current; // Use the ref to get the latest filterData + const currentFilterData = filterDataRef.current; const arrayOfObjects = Object.keys(currentFilterData).map(key => { const value = currentFilterData[key].value; if (value !== "" && @@ -127,7 +126,7 @@ function FilterBody({columns, drawerState, setDrawerState, userId, pageName, tab return currentFilterData[key]; } }).filter(Boolean); - console.log("arrayOfObjects", arrayOfObjects); + filterAction(user_id, page_name, table_name, arrayOfObjects, columns) toast.dismiss({containerId: "filtering"}); }; diff --git a/src/core/components/DataTable/filter/index.jsx b/src/core/components/DataTable/filter/index.jsx index faa01c9..65a93d2 100644 --- a/src/core/components/DataTable/filter/index.jsx +++ b/src/core/components/DataTable/filter/index.jsx @@ -4,14 +4,14 @@ import {useState} from "react"; import FilterButton from "@/core/components/DataTable/filter/FilterButton"; import FilterBody from "@/core/components/DataTable/filter/FilterBody"; -function FilterColumn({columns, userid, pagename, tablename}) { +function FilterColumn({columns, user_id, page_name, table_name}) { const [open, setOpen] = useState(false); return ( <> - + ); } diff --git a/src/core/components/DataTable/table/Paper.js b/src/core/components/DataTable/table/Paper.js index 7380cf0..d5431b7 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -65,9 +65,9 @@ const DataTable_Paper = ({table, ...rest}) => { > {enableTopToolbar && (parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( - + ))} {enableBottomToolbar && diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 1adf4d3..eabe836 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -6,7 +6,7 @@ import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import FilterColumn from "@/core/components/DataTable/filter"; import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; -const DataTable_TopToolbar = ({table, columns, userid, pagename, tablename}) => { +const DataTable_TopToolbar = ({table, columns, user_id, page_name, table_name}) => { const { getState, options: { @@ -73,7 +73,8 @@ const DataTable_TopToolbar = ({table, columns, userid, pagename, tablename}) => }} > - + )} From fa8caad7ef729c58873f5d813990cd921ee6e70f Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 29 Jun 2024 10:12:16 +0330 Subject: [PATCH 21/28] complete making fetchURL for swr request complete filter/sort/pagination/pagesie (all data that have been needed for Datatable) --- package.json | 1 + src/components/home/index.jsx | 2 +- src/core/components/DataTable/Main.js | 29 +++++++++++++++++-- src/core/components/DataTable/table/Paper.js | 7 +++-- .../DataTable/toolbar/TopToolbar.js | 4 +-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 8c05f3c..b4ddfd0 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "sass": "^1.75.0", "stylis": "^4.3.1", "stylis-plugin-rtl": "^2.1.1", + "swr": "^2.2.5", "yup": "^1.4.0" }, "devDependencies": { diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 7af2edf..090a572 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -141,7 +141,7 @@ function HomeComponent() { return ( <> - + ); diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index 2110b34..ec33f55 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -5,6 +5,7 @@ import useTableSetting from "@/lib/hooks/useTableSetting"; import {flattenArrayOfObjects} from "@/core/utils/flattenArrayOfObjects"; import Toolbar from "@/components/home/Toolbar"; import useDataTable from "@/lib/hooks/useDataTable"; +import {useMemo, useState} from "react"; const data = [ { @@ -76,10 +77,30 @@ const data = [ const DataTable_Main = (props) => { const {filterData} = useDataTable(); - const {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 {settingStore, hideAction, sortAction} = useTableSetting(); + 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 settingValue = event(); @@ -108,7 +129,8 @@ const DataTable_Main = (props) => { }, state: { columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], - sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [] + sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], + pagination }, muiTableHeadProps: { sx: { @@ -135,6 +157,7 @@ const DataTable_Main = (props) => { }, manualFiltering: true, manualPagination: true, + onPaginationChange: setPagination, manualSorting: true, onColumnVisibilityChange: onColumnVisibilityChange, onSortingChange: onSortingChange, diff --git a/src/core/components/DataTable/table/Paper.js b/src/core/components/DataTable/table/Paper.js index d5431b7..9a3be31 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -65,9 +65,10 @@ const DataTable_Paper = ({table, ...rest}) => { > {enableTopToolbar && (parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( - + ))} {enableBottomToolbar && diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index eabe836..7a321e2 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -6,7 +6,7 @@ import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import FilterColumn from "@/core/components/DataTable/filter"; import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; -const DataTable_TopToolbar = ({table, columns, user_id, page_name, table_name}) => { +const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, table_name}) => { const { getState, options: { @@ -73,7 +73,7 @@ const DataTable_TopToolbar = ({table, columns, user_id, page_name, table_name}) }} > - From 6288ac926c6f6f5ad9c89e87f18420e0df8ab02c Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Mon, 8 Jul 2024 15:45:39 +0330 Subject: [PATCH 22/28] update --- public/images/headerLogo.png | Bin 0 -> 12522 bytes public/images/rmsLogo.svg | 1 + src/app/default.js | 3 + src/app/page.js | 8 +- .../headerWithLogo/HaederBottom/index.jsx | 40 ++ .../headerWithLogo/HaederTop/index.jsx | 17 + .../dashboard/headerWithLogo/index.jsx | 18 +- .../headerWithSidebar/HeaderMenu/index.jsx | 4 + .../dashboard/headerWithSidebar/index.jsx | 186 +++++---- src/core/components/SidebarListItems.jsx | 119 ++++-- src/core/components/SidebarMenu.jsx | 315 ++++++-------- src/core/components/SidebarSubitems.jsx | 147 +++---- src/core/utils/pageMenu.js | 386 ++++++++++++++++++ src/core/utils/theme.js | 12 +- 14 files changed, 853 insertions(+), 403 deletions(-) create mode 100644 public/images/headerLogo.png create mode 100644 public/images/rmsLogo.svg create mode 100644 src/app/default.js create mode 100644 src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx create mode 100644 src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx create mode 100644 src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx create mode 100644 src/core/utils/pageMenu.js diff --git a/public/images/headerLogo.png b/public/images/headerLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..86dbfcdec68e82cd257652da38e41f13e4464345 GIT binary patch literal 12522 zcmaKSRajijmUcJp?jD>Fq;VQ|2<{NHai@XCJrLa8gF6HX7Bsj!1WRxW4hb$l-?W#yM6*){aGBf}HfTgsG|>tG20c&+4Wdg>+L5Q(neSYqo)E}hq>I|Ku0>8eqNar6suk^qoU96a%X zPZ4N31cbOb^4k3$7trK$BewFHTdgIcB0fZG8w#9Kua!0V`<$JeJp6d**w5L2ob;Z; z4#LG_Ox!E90|;t-5(Y0($E(Wsk8}pX5z22M(BSNi^;#ni008Ik-d+K)I~7}!vw&E_{@%{!p4Gm? z*`I;JXZv$!TG2Nb>(3oAa0mb#m8r88lil4#c<2zY&b`~d!T_+M1F%`YGvZ!F&HsQl z?Q<9HE$}E#l~H#kyG}XbA<>O{;;(YxM62RQwz%vX!f)XQ{lH~Q0bcCTINDQOkL*9TR zaLwYDXeUvKGvg3wA@V#)LB%wO5d`YA1H-Pxa21kviAM5tmu#*Cg0Y6;_X(@RG+a@S zQ5|xil;8$+_<1;Y@wRemvZ%p)w;31@woy=8q5TZmS1OU9=EAZW#RGR3z&|R^JZJ`l zWfijwF^mb9F^$wCV;mwf-__&QiRU$^)Z_OcB=50FwO&)_W6BfQnvOGQ3 zNYai9+8c%hE(LT2d-+v)wqng<(ODeZ93{r11jmtIJ17l7)imjeEeY5Os!0zceLF1# z;DLxOCDcNCjp7u%_q>*3y9gzpxg<05E7d0|^5#)0Bfy_OC^+VOsBvh9SK#xwXE97< z6G@E~vlT5&XW3fY-q>&)!oH#Y455-qpH82(KR`a*KMeWfiGdl088Req#!PBY>PuQi z(n89SsZ@$Mm!3JS#rcDaJkvS@JHuI9@9p(lKf=UOyi{o?8?mvi1vzL~_F^ksu*6Jx7iw5zeI38>*;@mc9wF*|WRAv!r)Idg~Ris!z|{R?&k z-?*cGsqC>up{yVo|GVX9}}wo?n)0_QDV| zTdvjO{^Eh1E|!TD`z)((GhgRmqJ7jo?LAYIEHtBJ=R=alU>vAk?pun zutgBhGRyK;(`f~C{CJFZoOO(JB6tnCX1I2|o}wJ5z@uCgf(iM#!raF_9H1RX#hW~R z75x=`hq~6})&*|4SG>ffiV0(Q=^p9CnvP{rWlo=c#!`35PQT4I&HXLPZqHt;S$3TN zIW98bU-h8Oo=rYt)F*N#@#p+TZ_8zTJGU&mtoJHmpTpS0Sl{@elS;KQhcR!F({XsU z-(aJ2%-0kwDq?v*c?d5$C<^!4=W}>hX&3FfNEcneVnAj9@?+kE(EZp`{B8H9_a)JV z3Zg0SJ8&1+8B7-32yYKhjgW~@g3OB;i`b6DfgwsLiGhl#PwkrQ+(UdxerL|TX8kT} zhHw-mm+%AmJ?A*164fGZT-X%KI!=Id>7CNycr!}GhMYr0E43|YCh?s=0n1yiO7`FC zUo~Mau$y;_)jRqR)}3(|@f9&`LaTPot{&Fab`Ba2=EvEsL9Lao!Cv9FG8gH1FnoH{ zlgOR^rGAmfZ8x}mhb-=#oh+?1n0f8)T45XU-r?j}o~N)ruYQ7`z^4qn^aior5E@A} z4ieSfGACt9{L9enPpUFqg|UU|^)0RMg_HJjbyBYdehT?Z-P?qz%DNA7qpE7KdMA=5 zwb5NE>qsyDs-9YQS!NSV$w|p6(!jJ$`^x%*vxT`u)ryrh8FR;b&vBGIIeheHhwjep zYL(F8lhRDlSB+XVEFvY2a#k+`5(BSR`A+!{^W5uJ&%f{J&_5FSbtcrQwbnH*wR-7a zY|wVgv=h-qYZ801gN!u3S$Nr=&-#zqj5VY^scq?LXkXfSuU*Dzgv^$dNU?s@nb z85wh`{qv#CoDh;~p?zkTzF?pe_?9@;q#9aXUVB?7+q$=_^r|KL1?l12u3o(? z;48ZJ$qh6b(|M|?YUx^LTv_b?>FIlg6+%fU^y@6;xTA^HOV_?r#{aL=?CHm!@nmM? z-@5k#ezwYast)AE`jh~iOgrNdEY2KX4)I68+BSsP34IZ!%mf2 zOm0T5e(lE_op(V0(B7D>GPEexh}4S61wfxR<-Zs>A6edvo#+bJ!u}{93C*0%1>W2B zEV%u+{lRYZ*}L;>@R+>CiSZ{zE5op8;KqpHV8=p%}O^!*{d1*13yjj*zhCekL zp!4E=^*@ddw@|7qr+rTG^L%wB}{zm(EbR-=(}cD1D8W#?lv2k{8d@C&ko z_;@(E`QFiRae@RnI0ZOB+-#g6Fee|Fm!Ia}5ACZoR|_k!hP3RzWxdu!Xl-CHD42u8 z)6jctM~XAa+g;*MHIcW8Z&J%F6#Y!qM@+ zsoh{2mj7S*|CPU+mN(RrL&MU|+1=IrHHubr|3lROE$AP@f7<|7hPc{WzD7|N;^1ca zuMf(~VAWUUZJi(v($41Yj+Ra^1!)o5R|va>tp%8qOMnvu;^*Py=i=lO0D%OgB_(Bf zIXO8&(tKQ!0-*o!_}{QnTrx6zASpfpSw3kHNJc_HP(o5tKw4HtT1tu^#3k_`tb&sp z4B}*N`5(EquX6v5<^4agU@2Ei2+Y}4%h}oCKMAE~;|z0lvvG#fyl$pm6Ns0cmxfu_ z*2%)z(~aeyn7>-~YO}PZtF4Eng{-TyBhA0u54QbZw6L(S;N-O6;bh~r5P-0m^YECn z32;NK*m%vjIR&|R`MIn(Up??&c#Hqxz5h!3*OpgHp#M<_46zb0v*O~iV&muI<7ESZ zECt!jIQh)jAm$dl0{kEW2#AN9mg7}Lj(_s-f8^zVnqHIrpW=V_ve(Lg_ft!!*RZ<2 z_QD&@HhKVn)>J`SLd$FA*a+1Ne_4~CAxuG zakQ)AEA&hCb2<_3JoP*gqJ?d}wgfbUXxR|0xgkW4EZ;#UcsebuborTkjuafjZ9B^d zwCEDOqR$<7-5bCAb=9@LYyng@r&)$~9`A7#jI`+DX-h%G8{72bS6qIR*$<_(BnPTJ24PuI;WG|$Nv|PWh z7HbT=p8oy_kEN!*NtJvPn6)A|Lfk@`8Khui!>sb;^P4)EQTfsJ`gnP6DnrTcg9;*Z z?wYyc*eDJGiF^owFFQoCg`X&ADfZ`?ZB}u{iCVi{*yn1hbd8Ssv*6i_L%3u2-=i%Uxi+^clzaAc)Hxj{ie8(UjjvbtZ49i<$9 z)EY%IzkO>5z1mYI6;ze&S{>q!eN`g+88;FI zJUU+Y8^4Hg<28_AO#&ke@Xu}>G93}$+)kxvg+N>)on{qG%E-o1m# z=ewQ#D7}c`mT|ex&dB0TbZIDlAb`ch!2eie4ojc(Q#Gr#x43-w1N|&$ielh$eMkqD z`DC?aC=8SQ;@ZF&GE*osEI)PN_qcTN$LH_wu8Je7rkG(WMR^C1e?0Rl?z^d;>#3nc=E8?JOR92aU{5CT5uyVO;!C>peLxqd zNSW+S>0t)jcg6hS!F(=~wB+4SOGK+a>ASMe4-;LiYvI&rfju$o+!9OhVAw%Wx=8@y zYO|w^+1A$n9AC*mo{(GG^(vK!ubF}dUY^$$>iyc;7r$^v>lTP>*@z9%Y)+ayU%PUb z)6+LTtZYi!~V6*1FS%<>PE*sp#7_JIV(I?a=rfhQy6{8jV41kpVuo1#LKc<{rhM%K(ufeVH?D%E%GqJ>E+1Y8 z{|X(RcmC!hJ#AO}0hJmR;6&x9!`qQ0Ql#WDH)*HE@y z40GO?ZKg<0TuglQi_lKBADEt3xAYuA94~of*q5IzWk-yYJPL_uu!EvZ2TL2Nw=HHA z-bKFeotwBff9~-9a~^)O>S@}4jvEnI`ws7c{p|Zu_)9cpy5}^cARoXh$0B&>FJ&HX zHZV$PGo24SMo@eE%M1RR*Pe!z{W`;addQ?3Ykx4dTweJTuN5bpu|J}t@6F&nCi!%U zz3w~1I>3?Whq6W;J$^Q$Z?JqNMj=)Z<$9J5Jr&NBfNCxBM#5NoEo=Cw=Nr0N(r`s9 zQT@7#NpC#C$qG+k-5rk8#fa!vjZlFd*JqKRjh}A}&VMsY#2BbtgU19qkPxwM;o-{GE{AfX})=|+>BlRx4!zTz?y9i%AV^d}j`P@h?w#KdvI*BXrgwgbC z;dSx5r>6&ucW}G7g}B87R(Ygfj{T74j)y-4)To58GXiNwCA6orEI(LbEoD?C68Z24 z&GZ17JF`_Phyj380`jJj2Uz0%tS<@E_FnhQgy$aR1_WBfuFhyVNuJ?mgB5l{6{T1r zea*bHWYCKI)GTNIz5a*#R%_HZ1SkOoLV*va&|8Xw#ZK~HOs3+oeU-PTLV6L8iIl98u-Nw7L{gPy!yFm7 z?o2(l^J-^@Cj#Ga-&Kht;$Gw7ZS)WAbD1tthUhj}n+?}W+-|O5qo9{R8V#2dRewS! zlB`X2_H-s5%6nWk|(3Y`KNSNUSm5Z>R`=BXp#WMI2r^>1sAH%0j_3vAZTV zHqeNwKrYg_%k6z&SBcr|*_@XyW|o|AaaK`-B;0z3t&&%NJoROJj@e2rez+#*Nbq*E zg(4KkN>k3=7Zw80q{U;CS5Q^lq)~CoQ>53cKmh-WXX-~iE<=OTU-`Os8YO3b%%#UOhp>gTIiX?C^I$y8a1GTN z_+aKRgd{piD$iGIMVpJp3YSgdx$H^jNkxN*RVNTOT{I+b=3Voqav%A*r|>y?iyvv* z=KBp6Do4*wvA}f!cMLhCqyfo14YL}0FIUve-(V7RRucz0&FXY=W_@9ps<9-X!p|yY z4@yb8zqp$Pd4GJ;q;D(#uCLG!c8iK$5%}c7`3Bh($P_0S=3cGm#YZm@T`4M~Knud7 zOy2XF1o<#dkit!lH$T&Rt2bnjjF7M-d@;M3j|^&3dv@El>M^1y+S}>(T>~K_0>;wk zW{19b9N@fN{8H3Ch(V=v!&C_73b+^`?i*omdi4n+r51iNXH*@4jgECmlzWDPX-5dk z-Y@jC9-a{2?vO%u5IBLMXW0foT?}qhnK+Y6?n``EPm9s_lc%vd1S}c_B!7eB=C1l| zs;hhVc^DEo(;8n2YkIz=JAb+f=;mP9rm$b^HC77(7Zi{vWMEl-cK%t}?YjG3QNh@I ziiaXx87C1Vk~U~_v`wFBF}h!}b(UTI^*GNgrAX&TI3rM-&9tpUFJZdAZ9(82>%x`* zh`c}`xqa_<9t+h@AkyiaHkU&--<@zAot?LLozptjK`k;x01vX=lBHJHHT_I#5H z@4#z)i?j?vsS#btsM{#-=;YB?&`=4{cL?tn;1CXJ_qS>2@XIN?xmgr3+I@NAcjn=B z?d*VCYX4zAUBF=2Xaz$S7Zf5W409ODQ$g8Us)vcU6DR7K1U~UzQwvNR{1Zxi4y2yz zk;wh|6&KO`eTR-WeTqSJ%TG@8YeU^Tz;q5@3<0k{>IlwLp}%WdHr1HzQZe?QpP)Hn z@n8t#U^qJ zdJ(vxSec%N-6r_FBs@KA>eB9Jn_oH4!fw|}+^@dqgmtnalh9ZKG`@DSyXV!@;DsbFZ5sK@~WG0$b{$a(`~6C2l0!Qdlvu1&usz zsEa03AB%3j+2A}GZ|7J>DqA^=K5H_Aucr>}249*OEHXJ6iB4Pm zC|WvB$d71wq3k$LUI_g)n$o&hh!xnJNj2YAao|sd@!{1KO)!=a4Twma@?go9v9;5S z7cV;DI2e#iC4!SxPs+fSWx7?ni2xOqwZRe5qqIZhUHU^*N|o_GBMxJm5!A!&j<(~` zjsSKd5waz;6l`_-7G|j87y6SaIL;!_E-WNZB(iu^-1h1|qs|vWW2)p$43L5kk3ea< zpcnG}>oMxr59C5FaES_7de)QW>M{Eg@RarS!i;fiX39yrNl$ISGF9r(YE>EatJhgT zmbQi_H;)Sbb~~dMAPA&d0^JQM1cd;mb`%n3KzX(azANDCpkNg|WIZ#|iUCSvoUuAe z?$d5dWBTNA#~v5aXW~$YwFq*yUXaU;9ym<1ENkHtJnDH0xF+LzTMInMZMEe!On|0W zs#J-)?X4yro}{*BX>2AFq`)=u+<{T%Y!X`PB&oj5*$Xu;E|bQ@tjOl#&ne=jU5 zc(xG z0Mg$1rWi+Gpf9f|Om2;U=+;ciO;cr+D1r(Ljm`Q+qcMs!a!S~U{~0^&$3Rl8;xy^v%p&eel+`TT2h`KMLlMc#t@K%zm zSwhtBmJ-nSGZYZfE_k#kGrc!eKtUF*UB=RrDZP_{Sg?jDh#E1BlARQ3xQ%@Sa|=2Q zfdiAp6*a1S9=?mstziG58q{|k5ogg8mphbhB>LlBTb6|<$;G};a8G>_UBpjO5++s^ ziKl0>VPh|#3O2`XIdxpmyjD4qNJuJ^j_GKyLIP_wPm$|62jkWAS_n4UK^-VrdXi~( zqrPMPX@)#AmR!9jDYBA~eyJ^hq35F8ve52s$Cua>g=QWzKWJY7LmwnyCW89cw<>7= zvnRP1#pWi;hZfvQApH4tWDDn08EL|ZBTB+|^Yd@(5@n@har6Cn>P=~yVC>LG7W*ZD zD?xDq@v~{VSuDb_#kG$L=^tzFKQSeoJ#HPh#261A%veH~xJgPu)_Q+?q=0cg{%=#@ z@6GS(ExrDh>4$DE;n3euZ_FdXzQTdr74L%97S=Sq9VO(|+f z-cEMCKjPnc68a4LEuDxagTCoL{HRZ5Z!xb|fj_`>(K}fn@X-zB&W6sSFD&w7c#*LP zg8x_GCGhEduf8NBRR|r8wxWDyM@6j6$XKdu;ybm0QIh=|ObpM>&diKk1%cC39F)$_ zq-kN^x`I?Y?YO^AR5nhIw9~sk5L*WM-?ZhNA*~_H*4%q(6@0sDZvuHnyuVf4quBXc?UKAR;y zEJCR^a(^=ogy$Pw3b~XVHGdw2F8X1r%mJN-r8jNR1v?cTQuN5MyitBDVI z{Z{MIbVaLQ$C8LUL73NyVPZtOuH!`bqOS@+`BCcX;_UNFthlyixYWLppRA`uIA)hD zH?L$8K(m6S$x1&$Oi#|yUbmC@tLQ_HgK^eVN*D~uf>!+rua9g^utHy%zI9UO-d`X0 z5Fw9YEad7nhNuQEv!cxAS*4aL`k1xq%Q?@AE>x7;BZ-+f4FPn$9;d-u)bOCQ4a0Zf zuQ(EKnM9Naej-r3nN}e3vUSiBTN#L+*3yKwJ>X?}eQeHxD-F4^&s~|X9l_8XzQH@U zxMRi?q^0SB%NSIoDvRr^ASUHQQe!8jP4(TZ{ zx=sg09bwMAR@huVl@cYeQz3}SjX6$WviDk#e|+MJpNP_U2X|xG(lr#>W`or$>FS^b z=OorTL%EhbuHQ4kZ*3XeQwtmUh;7dp?BhfVs_I_WN{(hXnCgNSHTr-n&26 zI9}_uY21sKZwXKR2gJF?LVVG+&5r*z(Q2&VhaK5sFm;AuoMSK6n-6`im`d(`{Me9f zX+ye#ck)4o0FAfuzHBNgxl@@y~hDH=VPXZa!&7$+0lbN(1oZ{w2&>1Pq-|W zFOvuG-m z7=FU29k#6MPxW|bZP)?BeVd5~pFI$imsg6E8_ZIn9saw`&=28kx27;;5RG3D-Mt+R zd78bNawXK}5SZJAK-s*m9EHAYLBMiL25dGX0G1*E!{@Hz6fEp^-)SL=a2pB~3Q0g5 z+0Y{gF*Em$zG|f-rR`=I=A6Z?K{CTK-HdCaANQ%M_5q1;ji1|fTC0w14LK><^X

mm31Bcz$^icoAM}HQMpQ)JAmuRf&zW6Hkj0eypKH=VDQnQ%`abFjBST>n z`+Qt4a_x7oqrhym|CAL_!D&xB&5)=!mb}5C6TGp*C2+mmY9v#*IS^oki;HXhaB~zG zwCF$`h(Uhg^L_=x77|nf7r+~}JCBX=-L1xNRas$D!nFWSu`@;S?>l2-Y0wn;g!u=nU{A*l5QmdYnP+02 zl1dg{hObYPHY*Ly#-Ny)nJC@o+pRGU7n*%>OU$`n5re<)nd=v0PQ2{?Xch1F)aexA z=rhgk=NDC#UPF8xv!vr@(C2x;VNruuXhH^c8Ui#7*LZGKE(D$rK6NyD*==So`k}>Eq=e`qh{}E5V)7X7))Y8On=3 z`5|>>1R{w$7^ z(kke~kIB71A{%S;)s@}{QW>)lv=rA86LC3as~%6oda}2QJ07^N&T`$QrsOojv@Tj>6?*`2AlHg~&P*U)9$gmn*{%0_3V zAs}x0Z;#8f;a&?yqL-=r)X;n3(>v0fuNmr11nQ#Uq?hfu#pmK<$vWL+`g(dxCF(`S zekMgTOP&tvah~h`>A%Fpt!1k}Y6V-84(>$8IS4E-MqrGF_C4cY2XTkL*7yCRJi3Quc=%Xt^Pj-TNx z7a3F-2LHAez@#38*iaqK7T-n@Mvrg$-cXS2WbkT!g;~eEaru0ld#aj>*KVHOZvFA@ zDzS+h{Y@oK$LfRs0r`zgqKs)RImdv@C`!396NdGCABT2B$PPh9bd(3Sej}L0w8R7WCS~I%TLQ8A5^9|lL#2u*77Tji_>mA$Yuq{ z)%(1|p>HsMPLS8@^sivCxTN2aX6$eC^)(uC|H<)WO9|9xf4aNhhxEH|Tw@_+`r?d1PU%X`wv*QP~Od4Ega&MeFlATQ^B zhm1vX*XvpZF|>+kf%|o2wFQjVn|lv;+UH%O&nFSA3RRmGcQ*VcvNffc9zY8jr6lL6?->n8-lyY@ozLa}6pTsQi?8Rj?lll$eY1^dAk`}MAa;Y2!45)7Vg^$~5oe1p&l zRsXQ`l^9tgZxMo2Ab<6r$HNv0IjE>bgZ?mxKSH`)VzQzPV<^-EzpmsgZ8fOTXM!w- ziW|wQk<`w;PW5x9BUk($p&_?i^esKL0AFP7`aUSifG6^`s6Y z{z(Rt+uW5@$`mHu9*Q4os?t6D^hlv~9${u0dMJR(;L6pbU8HPUK3hwhxv#&usjEiLiF=sD|@&$rQV36Gk(Qfr$I}1twGD_Nt68# zkD_ZiY3UxDn7&q!`3z4X3td$Xr@@4Prh}w}0uarauy9;Q_JybzMLKz-)P`^ouja_E zK;8DO?n^P+J}>ty_iR0EIa?q%J-nw!{A*my*BsC;airV^X|S z!<*_0ZGH(E56);DWxd(%d$KjK$jV`hukBCP(+!ajWY}_yuXXUZ_EVHVS6`aT^rR0u zy*LzDLtO*W_(kpRXH+kn$kZLuJ31k+2XAJ(?X0-?_#qPT$OY!%ST?h*sIb392g>8s zM69nTz@cu4h)Z4mLbG#XgB6-(2kR?M_PRXQlQ}oJD)Xe)6#T(a92M~JhwE@Je>uJg zYs$+nNc!EN9h~o1rc&rOApb%+P}^{0n4AVV#&o+Q;s zOjc@m-|n)FB-z({twJIO;ehbRKl!|M?wQOLLOx#UtZHWwGtpOrPM+8=IIB^s3SU?R zd^LXI1%72SYIk4t2cPkDqLfcqp%;mA7`Fz2iiU2Hn)*W%(Mth zG0;NpW!0_C_r9_c6IpBisY<5Ynd;)=f*X!aJ!{nARliz~&$MFP?W6thu&{oVnwBP5 zp{ELk)>TV*JsG?yD6npao#w0;T8{O(A1#Wc$Tu9-oe9Hu&r#aeTpXhr&F?ww6x(K&vh{c85QYTNz;%257u#B AtN;K2 literal 0 HcmV?d00001 diff --git a/public/images/rmsLogo.svg b/public/images/rmsLogo.svg new file mode 100644 index 0000000..5c47991 --- /dev/null +++ b/public/images/rmsLogo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/default.js b/src/app/default.js new file mode 100644 index 0000000..73d13c1 --- /dev/null +++ b/src/app/default.js @@ -0,0 +1,3 @@ +export default function Default() { + return null +} \ No newline at end of file diff --git a/src/app/page.js b/src/app/page.js index 9d660d7..3fab3b7 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,8 +1,8 @@ -'use client' -import HomeComponent from "@/components/home"; +import { redirect } from "next/navigation" function Page() { - return ; + redirect('/dashboard', 'replace') + return null } -export default Page; +export default Page \ No newline at end of file diff --git a/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx new file mode 100644 index 0000000..501dadc --- /dev/null +++ b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx @@ -0,0 +1,40 @@ +"use client"; +import { Stack, Typography } from "@mui/material"; +import Image from "next/image"; + +const HeaderBottom = () => { + return ( + theme.palette.primary2.main, + }} + spacing={4} + alignItems={"center"} + direction={"row"} + > + + + theme.palette.primary2.contrastText }} + > + سامانه جامع راهداری + + theme.palette.primary2.contrastText }} + > + rms.rmto.ir + + + + ); +}; +export default HeaderBottom; diff --git a/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx b/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx new file mode 100644 index 0000000..27cd26a --- /dev/null +++ b/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx @@ -0,0 +1,17 @@ +import { Stack } from "@mui/material"; +import Image from "next/image"; + +const HeaderTop = () => { + return ( + + + + ); +}; +export default HeaderTop; diff --git a/src/components/layouts/dashboard/headerWithLogo/index.jsx b/src/components/layouts/dashboard/headerWithLogo/index.jsx index f16f58c..f628e49 100644 --- a/src/components/layouts/dashboard/headerWithLogo/index.jsx +++ b/src/components/layouts/dashboard/headerWithLogo/index.jsx @@ -1,9 +1,13 @@ -import {Box, Stack} from "@mui/material"; +import { Box, Stack } from "@mui/material"; +import HeaderTop from "./HaederTop"; +import HeaderBottom from "./HaederBottom"; const HeaderWithLogo = () => { - return ( - header1 - header2 - ) -} -export default HeaderWithLogo \ No newline at end of file + return ( + + + + + ); +}; +export default HeaderWithLogo; diff --git a/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx new file mode 100644 index 0000000..01fd681 --- /dev/null +++ b/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx @@ -0,0 +1,4 @@ +const HeaderMenu = () => { + return <>منو; +}; +export default HeaderMenu; diff --git a/src/components/layouts/dashboard/headerWithSidebar/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/index.jsx index eeb88a3..be0a284 100644 --- a/src/components/layouts/dashboard/headerWithSidebar/index.jsx +++ b/src/components/layouts/dashboard/headerWithSidebar/index.jsx @@ -1,94 +1,116 @@ -'use client' -import {useState} from "react"; -import {Box, Drawer, IconButton, Paper, styled, Toolbar, Typography} from "@mui/material"; -import MuiAppBar from '@mui/material/AppBar'; -import MenuIcon from '@mui/icons-material/Menu'; -import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +"use client"; import SidebarMenu from "@/core/components/SidebarMenu"; +import ChevronRightIcon from "@mui/icons-material/ChevronRight"; +import MenuIcon from "@mui/icons-material/Menu"; +import { Box, Drawer, IconButton, Paper, styled, Toolbar } from "@mui/material"; +import MuiAppBar from "@mui/material/AppBar"; +import { useState } from "react"; +import HeaderMenu from "./HeaderMenu"; -const drawerWidth = 260; +const drawerWidth = 300; -const Main = styled(Paper, {shouldForwardProp: (prop) => prop !== 'open'})(({theme, open}) => ({ - flexGrow: 1, transition: theme.transitions.create('margin', { - easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, - }), marginLeft: `-${drawerWidth}px`, ...(open && { - transition: theme.transitions.create('margin', { - easing: theme.transitions.easing.easeOut, duration: theme.transitions.duration.enteringScreen, - }), marginLeft: 0, +const Main = styled(Paper, { shouldForwardProp: (prop) => prop !== "open" })( + ({ theme, open }) => ({ + flexGrow: 1, + transition: theme.transitions.create("margin", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, }), -}),); + marginLeft: `-${drawerWidth}px`, + ...(open && { + transition: theme.transitions.create("margin", { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + marginLeft: 0, + }), + }) +); const AppBar = styled(MuiAppBar, { - shouldForwardProp: (prop) => prop !== 'open', -})(({theme, open}) => ({ - transition: theme.transitions.create(['margin', 'width'], { - easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, - }), ...(open && { - width: `calc(100% - ${drawerWidth}px)`, - marginLeft: `${drawerWidth}px`, - transition: theme.transitions.create(['margin', 'width'], { - easing: theme.transitions.easing.easeOut, duration: theme.transitions.duration.enteringScreen, - }), + shouldForwardProp: (prop) => prop !== "open", +})(({ theme, open }) => ({ + transition: theme.transitions.create(["margin", "width"], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + ...(open && { + width: `calc(100% - ${drawerWidth}px)`, + marginLeft: `${drawerWidth}px`, + transition: theme.transitions.create(["margin", "width"], { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, }), + }), })); -const DrawerHeader = styled('div')(({theme}) => ({ - display: 'flex', alignItems: 'center', padding: theme.spacing(0, 1), // necessary for content to be below app bar - ...theme.mixins.toolbar, justifyContent: 'flex-end', +const DrawerHeader = styled("div")(({ theme }) => ({ + display: "flex", + alignItems: "center", + padding: theme.spacing(0, 1), + ...theme.mixins.toolbar, + justifyContent: "flex-end", })); -const HeaderWithSidebar = ({children}) => { - const [open, setOpen] = useState(false); +const HeaderWithSidebar = ({ children }) => { + const [open, setOpen] = useState(true); - const handleDrawerOpen = () => { - setOpen(true); - }; - - const handleDrawerClose = () => { - setOpen(false); - }; - return ( - - - - - - - menu - - - - - - - - - - - -
- - {children} -
-
) -} -export default HeaderWithSidebar \ No newline at end of file + const handleDrawerOpen = () => { + setOpen(true); + }; + const handleDrawerClose = () => { + setOpen(false); + }; + return ( + + + + + + + + + + + + + + + + + + + +
+ + {children} +
+
+ ); +}; +export default HeaderWithSidebar; diff --git a/src/core/components/SidebarListItems.jsx b/src/core/components/SidebarListItems.jsx index 9ffcac2..d300d7f 100644 --- a/src/core/components/SidebarListItems.jsx +++ b/src/core/components/SidebarListItems.jsx @@ -1,46 +1,77 @@ -import {Collapse, ListItem, ListItemButton, ListItemIcon, ListItemText} from "@mui/material"; -import { ExpandLess, ExpandMore } from '@mui/icons-material'; -import WifiIcon from '@mui/icons-material/Wifi'; import SidebarSubitems from "@/core/components/SidebarSubitems"; +import { ExpandLess, ExpandMore } from "@mui/icons-material"; +import { + Collapse, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import Link from "next/link"; -const SidebarListItems = ({menuItem, dispatch}) => { - return( - <> - - { - dispatch({type: "COLLAPSE_MENU", id: menuItem.id}) - }}> - - {menuItem.icon} - - - {menuItem.hasSubitems ? (menuItem.showSubitems ? : ) : null } - - - - { - menuItem.hasSubitems ? (menuItem.Subitems.map((subitem,index)=>{ - return( - - ) - })) : null - } - - - - ) -} -export default SidebarListItems \ No newline at end of file +const SidebarListItems = ({ menuItem, dispatch }) => { + return ( + <> + + { + dispatch({ type: "COLLAPSE_MENU", id: menuItem.id }); + }} + > + + {menuItem.icon} + + + {menuItem.hasSubitems ? ( + menuItem.showSubitems ? ( + + ) : ( + + ) + ) : null} + + + + {menuItem.hasSubitems ? ( + + {menuItem.Subitems.map((subitem, index) => { + return ( + + ); + })} + + ) : null} + + + ); +}; +export default SidebarListItems; diff --git a/src/core/components/SidebarMenu.jsx b/src/core/components/SidebarMenu.jsx index f7589c3..c9f6a73 100644 --- a/src/core/components/SidebarMenu.jsx +++ b/src/core/components/SidebarMenu.jsx @@ -1,201 +1,132 @@ -"use client" -import {List} from "@mui/material"; +"use client"; import SidebarListItems from "@/core/components/SidebarListItems"; -import {useEffect, useReducer, useState} from "react"; -import {usePathname} from 'next/navigation' -import SecurityIcon from '@mui/icons-material/Security'; -import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard"; -import AssessmentIcon from '@mui/icons-material/Assessment'; -import AirlineSeatReclineNormalIcon from "@mui/icons-material/AirlineSeatReclineNormal"; -import RepartitionIcon from '@mui/icons-material/Repartition'; - -const data = [ - { - id: "hello", - type: "menu", - route: "/hello", - icon: , - selected: false, - Subitems: [ - { - id: "amin", - route: "/s", - icon: , - firstName: "amin", - lastName: "ali", - Subitems: [ - { - id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: - }, - { - id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: - } - ], - hasSubitems: true, - showSubitems: false, - type: "menu", - selected: false, - }, - { - id: "amir", - route: "/dashboarsad", - icon: , - firstName: "amir", - lastName: "akbar", - hasSubitems: false, - showSubitems: false, - selected: false, - type: "page", - }, - ], - hasSubitems: true, - showSubitems: false - }, - { - id: "hi", - type: "menu", - icon: , - route: "/hi", - selected: false, - Subitems: [ - { - id: "ali", - route: "/dashboardss", - firstName: "ali", - lastName: "ali", - icon: , - hasSubitems: false, - showSubitems: false, - type: "page", - selected: false, - }, - { - id: "akbar", - route: "/akbar", - firstName: "akbar", - icon: , - lastName: "akbar", - hasSubitems: false, - showSubitems: false, - type: "page", - selected: false, - }, - ], - hasSubitems: true, - showSubitems: false - }, - { - id: "hoo", - type: "page", - route: "/dashboard", - icon: , - selected: false, - hasSubitems: false, - showSubitems: false - } -] +import { List } from "@mui/material"; +import { usePathname } from "next/navigation"; +import { useEffect, useReducer, useState } from "react"; +import { pageMenu } from "../utils/pageMenu"; function reducer(state, action) { - switch (action.type) { - case "COLLAPSE_MENU": - return state.map((item) => action.id == item.id ? { - ...item, showSubitems: !item.showSubitems - } : item) - case "COLLAPSE_SUB_ITEMS" : - return state.map((item) => { - return item.hasSubitems ? { - ...item, Subitems: item.Subitems.map((subitem) => action.id === subitem.id ? { - ...subitem, showSubitems: !subitem.showSubitems - } : subitem) - } : item - }) - case "COLLAPSE_SUB_SECOND_ITEMS" : - return state.map((item) => { - return item.hasSubitems ? { - ...item, Subitems: item.Subitems.map((subitem) => { - return subitem.hasSubitems ? { - ...subitem, - Subitems: subitem.Subitems.map((secondSubitem) => action.id === secondSubitem.id ? { - ...secondSubitem, showSubitems: !secondSubitem.showSubitems - } : secondSubitem) - } : subitem - }) - } : item - }) - case "SELECTED": - return state.map((item) => { - return item.type === "page" ? { - ...item, selected: action.route === item.route,showSubitems: item.route === action.route - } : item.Subitems && Array.isArray(item.Subitems) ? { - ...item, Subitems: item.Subitems.map((subitem) => { - return subitem.type === "page" ? { - ...subitem, selected: action.route === subitem.route,showSubitems: subitem.route === action.route - } : subitem.Subitems && Array.isArray(subitem.Subitems) ? { - ...subitem, Subitems: subitem.Subitems.map((secondSubItem) => ({ - ...secondSubItem, selected: secondSubItem.route === action.route - })),showSubitems: subitem.Subitems.some((secondSubItem) => secondSubItem.route === action.route), - } : subitem - }),showSubitems: item.Subitems.some((subitem) => subitem.showSubitems), - } : item - }); - // case "SELECTED": - // return state.map((item) => { - // return item.type === "page" ? { - // ...item, - // selected: action.route === item.route - // } : item.Subitems && Array.isArray(item.Subitems) ? { - // ...item, - // Subitems: item.Subitems.map((subitem) => { - // const updatedSubitem = subitem.type === "page" ? { - // ...subitem, - // selected: action.route === subitem.route - // } : subitem.Subitems && Array.isArray(subitem.Subitems) ? { - // ...subitem, - // Subitems: subitem.Subitems.map((secondSubItem) => ({ - // ...secondSubItem, - // selected: secondSubItem.route === action.route - // })), - // showSubitems: subitem.Subitems.some((secondSubItem) => secondSubItem.route === action.route), - // } : subitem; - // - // console.log("Updated subitem:", updatedSubitem); // Log the updated subitem - // return updatedSubitem; - // }), - // showSubitems: item.Subitems.some((subitem) => subitem.showSubitems), - // } : item - // }); + switch (action.type) { + case "COLLAPSE_MENU": + return state.map((item) => + action.id == item.id + ? { + ...item, + showSubitems: !item.showSubitems, + } + : item + ); + case "COLLAPSE_SUB_ITEMS": + return state.map((item) => { + return item.hasSubitems + ? { + ...item, + Subitems: item.Subitems.map((subitem) => + action.id === subitem.id + ? { + ...subitem, + showSubitems: !subitem.showSubitems, + } + : subitem + ), + } + : item; + }); + case "COLLAPSE_SUB_SECOND_ITEMS": + return state.map((item) => { + return item.hasSubitems + ? { + ...item, + Subitems: item.Subitems.map((subitem) => { + return subitem.hasSubitems + ? { + ...subitem, + Subitems: subitem.Subitems.map((secondSubitem) => + action.id === secondSubitem.id + ? { + ...secondSubitem, + showSubitems: !secondSubitem.showSubitems, + } + : secondSubitem + ), + } + : subitem; + }), + } + : item; + }); + case "SELECTED": + return state.map((item) => { + return item.type === "page" + ? { + ...item, + selected: action.route === item.route, + showSubitems: item.route === action.route, + } + : item.Subitems && Array.isArray(item.Subitems) + ? { + ...item, + Subitems: item.Subitems.map((subitem) => { + return subitem.type === "page" + ? { + ...subitem, + selected: action.route === subitem.route, + showSubitems: subitem.route === action.route, + } + : subitem.Subitems && Array.isArray(subitem.Subitems) + ? { + ...subitem, + Subitems: subitem.Subitems.map((secondSubItem) => ({ + ...secondSubItem, + selected: secondSubItem.route === action.route, + })), + showSubitems: subitem.Subitems.some( + (secondSubItem) => secondSubItem.route === action.route + ), + } + : subitem; + }), + showSubitems: item.Subitems.some( + (subitem) => subitem.showSubitems + ), + } + : item; + }); - - default: - throw new Error(); - } + default: + throw new Error(); + } } const SidebarMenu = () => { - const [menuItems, dispatch] = useReducer(reducer, data); - const pathname = usePathname() - const [selectedKey, setSelectedKey] = useState(null); - useEffect(() => { - dispatch({type: "SELECTED", route: pathname}); - setSelectedKey(pathname); - }, [pathname]); + const [menuItems, dispatch] = useReducer(reducer, pageMenu); + const pathname = usePathname(); + const [selectedKey, setSelectedKey] = useState(null); + useEffect(() => { + dispatch({ type: "SELECTED", route: pathname }); + setSelectedKey(pathname); + }, [pathname]); - useEffect(() => { - selectedKey && document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({ - behavior: "smooth", block: "center" - }); - }, [selectedKey]); + useEffect(() => { + selectedKey && + document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + }, [selectedKey]); - return ( - - { - menuItems.map((menuItem) => { - return ( - - ) - }) - } - - ) -} -export default SidebarMenu \ No newline at end of file + return ( + + {menuItems.map((menuItem) => { + return ( + + ); + })} + + ); +}; +export default SidebarMenu; diff --git a/src/core/components/SidebarSubitems.jsx b/src/core/components/SidebarSubitems.jsx index 275befb..b54d3a9 100644 --- a/src/core/components/SidebarSubitems.jsx +++ b/src/core/components/SidebarSubitems.jsx @@ -1,74 +1,75 @@ -import {Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText} from "@mui/material"; -import {ExpandLess, ExpandMore} from "@mui/icons-material"; +import { ExpandLess, ExpandMore } from "@mui/icons-material"; +import { + Collapse, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import Link from "next/link"; -const SidebarSubitems = ({subitem, dispatch}) => { - return ( - <> - - - { - dispatch({type: "COLLAPSE_SUB_ITEMS", id: subitem.id}) - }}> - - {subitem.icon} - - - {subitem.hasSubitems ? (subitem.showSubitems ? : ) : null - } - - - - { - subitem.hasSubitems ? (subitem.Subitems.map((subSubitem, index) => { - return ( - - - - { - dispatch({type: "COLLAPSE_SUB_SECOND_ITEMS", id: subSubitem.id}) - }} - selected={subSubitem.selected} - sx={{ - '&.Mui-selected': { - backgroundColor: 'rgba(0, 0, 0, 0.05)', - }, - }} - > - - {subSubitem.icon} - - - - - - - ) - })) : null - } - - ) -} -export default SidebarSubitems \ No newline at end of file +const SidebarSubitems = ({ subitem, dispatch }) => { + return ( + <> + + { + dispatch({ type: "COLLAPSE_SUB_ITEMS", id: subitem.id }); + }} + > + + {subitem.icon} + + + {subitem.hasSubitems ? ( + subitem.showSubitems ? ( + + ) : ( + + ) + ) : null} + + + + {subitem.hasSubitems ? ( + + {subitem.Subitems.map((subSubitem, index) => { + return ( + + ); + })} + + ) : null} + + + ); +}; +export default SidebarSubitems; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js new file mode 100644 index 0000000..b97199a --- /dev/null +++ b/src/core/utils/pageMenu.js @@ -0,0 +1,386 @@ +import { AirlineSeatReclineNormal, Assessment, Repartition, Security, SpaceDashboard } from "@mui/icons-material"; + +export const pageMenu = [ + { + id: 'dashboard', + label: 'پیشخوان', + type: "page", + route: "/dashboard", + icon: , + }, + { + id: 'userManagement', + label: 'مدیریت کاربران', + type: "page", + route: "./v2/user_management", + icon: , + }, + { + id: 'projectsManagment', + label: 'پروژه های راهداری', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'projectsManagmentFinance', + label: 'ثبت قرارداد و پروژه', + type: "page", + route: "./v2/rahdari_projects/finance", + icon: , + }, + { + id: 'projectsManagmentList', + label: 'لیست پروژه ها', + type: "page", + route: "./v2/rahdari_projects/projects_list", + icon: , + }, + { + id: 'projectsManagmentProposal', + label: 'پروژه های پیشنهادی', + type: "page", + route: "./v2/rahdari_projects/proposal", + icon: , + }, + { + id: 'projectsManagmentLawmaker', + label: 'درخواست نمایندگان', + type: "page", + route: "./v2/rahdari_projects/lawmakers", + icon: , + }, + { + id: 'projectsManagmentMap', + label: 'پراکندگی بر روی نقشه', + type: "page", + route: "./v2/map?type=rahdari_projects", + icon: , + }, + ] + }, + { + id: 'roadItemManagment', + label: 'فعالیت های روزانه', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadItemManagmentSupervisor', + label: 'ارزیابی', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadItemManagmentSupervisorCartable', + label: 'کارتابل', + type: "page", + route: "./v2/road_items/supervisor/cartable", + }, + ] + }, + { + id: 'roadItemManagmentOparation', + label: 'عملیات', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadItemManagmentOparationCreate', + label: 'ثبت فعالیت', + type: "page", + route: "./v2/road_items/operator/create", + }, + { + id: 'roadItemManagmentOparationCartable', + label: 'کارتابل', + type: "page", + route: "./v2/road_items/operator/cartable", + }, + ] + }, + { + id: 'roadItemManagmentMap', + label: 'پراکندگی بر روی نقشه', + type: "page", + route: "./v2/map?type=road_items", + icon: , + }, + { + id: 'roadItemManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/road_items/report", + icon: , + }, + ] + }, + { + id: 'roadPatrolManagment', + label: 'گشت راهداری و ترابری', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadPatrolManagmentSupervisor', + label: 'ارزیابی', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadPatrolManagmentSupervisorCartable', + label: 'کارتابل', + type: "page", + route: "./road_patrols/supervisor/cartable", + }, + ] + }, + { + id: 'roadPatrolManagmentOparation', + label: 'عملیات', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadPatrolManagmentOparationCreate', + label: 'ثبت اقدام', + type: "page", + route: "./v2/road_patrols/operator/create", + }, + { + id: 'roadPatrolManagmentOparationCartable', + label: 'کارتابل', + type: "page", + route: "./v2/road_patrols/operator/cartable", + }, + ] + }, + { + id: 'roadPatrolManagmentMap', + label: 'پراکندگی بر روی نقشه', + type: "page", + route: "./v2/map?type=road_patrols", + icon: , + }, + { + id: 'roadPatrolManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/road_patrols/report", + icon: , + }, + ] + }, + { + id: 'safetyAndPrivacyManagment', + label: 'نگهداری حریم راه', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'safetyAndPrivacyManagmentOparation', + label: 'عملیات', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'safetyAndPrivacyManagmentOparationCreate', + label: 'ثبت فعالیت', + type: "page", + route: "./safety_and_privacy/operator/first_step", + }, + { + id: 'safetyAndPrivacyManagmentOparationCartable', + label: 'کارتابل', + type: "page", + route: "./v2/safety_and_privacy/operator/cartable", + }, + ] + }, + { + id: 'safetyAndPrivacyManagmentMap', + label: 'پراکندگی بر روی نقشه', + type: "page", + route: "./v2/map?type=safety_and_privacy", + icon: , + }, + { + id: 'safetyAndPrivacyManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/safety_and_privacy/report", + icon: , + }, + ] + }, + { + id: 'roadObservationsManagment', + label: 'واکنش سریع', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadObservationsManagmentSupervisor', + label: 'ارزیابی', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadObservationsManagmentSupervisorCartable', + label: 'کارتابل', + type: "page", + route: "./v2/road_observations/supervisor/cartable", + }, + ] + }, + { + id: 'roadObservationsManagmentList', + label: 'رسیدگی به شکایات', + type: "page", + route: "./v2/road_observations", + icon: , + }, + { + id: 'roadObservationsManagmentOparation', + label: 'عملیات', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'roadObservationsManagmentOparationCartable', + label: 'کارتابل', + type: "page", + route: "./v2/road_observations/operator/cartable", + }, + ] + }, + { + id: 'roadObservationsManagmentMap', + label: 'پراکندگی بر روی نقشه', + type: "page", + route: "./v2/map?type=road_observations", + icon: , + }, + { + id: 'roadObservationsManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/road_observations/report/index", + icon: , + }, + ] + }, + { + id: 'winterCampManagment', + label: 'قرارگاه زمستانی', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'winterCampManagmentBlocking', + label: 'محور های انسدادی', + type: "page", + route: "./v2/winter_camp", + icon: , + }, + { + id: 'winterCampManagmentFirstRing', + label: 'محور های حلقه اول', + type: "page", + route: "./v2/map?type=camp", + icon: , + }, + { + id: 'winterCampManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/map?type=campNew", + icon: , + }, + ] + }, + { + id: 'receiptManagment', + label: 'خسارات وارده بر ابنیه فنی و تاسیسات راه', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'receiptManagmentOparation', + label: 'عملیات', + type: "menu", + icon: , + hasSubitems: true, + Subitems: [ + { + id: 'receiptManagmentOparationCartable', + label: 'کارتابل', + type: "page", + route: "./v2/receipt", + }, + ] + }, + { + id: 'receiptManagmentReport', + label: 'گزارش ها', + type: "page", + route: "./v2/receipt/report", + icon: , + }, + ] + } + // { + // id: "hello", + // type: "menu", + // route: "/hello", + // icon: , + // selected: false, + // Subitems: [ + // { + // id: "amin", + // route: "/s", + // icon: , + // firstName: "amin", + // lastName: "ali", + // Subitems: [ + // { + // id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: + // }, + // { + // id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: + // } + // ], + // hasSubitems: true, + // showSubitems: false, + // type: "menu", + // selected: false, + // }, + // { + // id: "amir", + // route: "/dashboarsad", + // icon: , + // firstName: "amir", + // lastName: "akbar", + // hasSubitems: false, + // showSubitems: false, + // selected: false, + // type: "page", + // }, + // ], + // hasSubitems: true, + // showSubitems: false + // }, +] \ No newline at end of file diff --git a/src/core/utils/theme.js b/src/core/utils/theme.js index d96fc53..581e23e 100644 --- a/src/core/utils/theme.js +++ b/src/core/utils/theme.js @@ -1,5 +1,5 @@ 'use client' -import {createTheme} from "@mui/material"; +import { createTheme } from "@mui/material"; const theme = createTheme({ direction: 'rtl', @@ -7,6 +7,16 @@ const theme = createTheme({ fontFamily: `IRANSansFaNum, sans-serif`, fontSize: 12 }, + palette: { + primary: { + main: '#2070af', + contrastText: '#fff' + }, + primary2: { + main: '#015688', + contrastText: '#fff' + }, + } }); export default theme \ No newline at end of file From 863bdaca95bbf5087777a0e9f8c5c9453a6d5ace Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Tue, 9 Jul 2024 11:28:59 +0330 Subject: [PATCH 23/28] add auth and base functions and fixed bug --- .env.local.example | 1 + package.json | 1 + public/global.scss | 6 +- src/app/(withAuth)/dashboard/layout.js | 11 - src/app/(withAuth)/dashboard/page.js | 24 ++- src/app/(withAuth)/dashboard/template.js | 22 +- src/app/(withAuth)/layout.js | 14 ++ src/app/layout.js | 14 +- src/app/lfwd/page.js | 51 +++++ src/app/template.js | 16 +- src/core/components/Toasts/error.jsx | 191 ++++++++++++++++++ src/core/components/Toasts/success.jsx | 35 ++++ src/core/middlewares/withAuth.js | 22 ++ src/core/utils/errorResponse.js | 61 ++++++ src/core/utils/pageMenu.js | 60 +++--- src/core/utils/routes.js | 4 + src/core/utils/successRequest.js | 10 + .../contexts/{DataTable.jsx => DataTable.js} | 0 src/lib/contexts/auth.js | 76 +++++++ .../{tableSetting.jsx => tableSetting.js} | 0 .../{useDataTable.jsx => useDataTable.js} | 0 src/lib/hooks/useRequest.js | 42 ++++ ...useTableSetting.jsx => useTableSetting.js} | 0 23 files changed, 592 insertions(+), 69 deletions(-) delete mode 100644 src/app/(withAuth)/dashboard/layout.js create mode 100644 src/app/(withAuth)/layout.js create mode 100644 src/app/lfwd/page.js create mode 100644 src/core/components/Toasts/error.jsx create mode 100644 src/core/components/Toasts/success.jsx create mode 100644 src/core/middlewares/withAuth.js create mode 100644 src/core/utils/errorResponse.js create mode 100644 src/core/utils/routes.js create mode 100644 src/core/utils/successRequest.js rename src/lib/contexts/{DataTable.jsx => DataTable.js} (100%) create mode 100644 src/lib/contexts/auth.js rename src/lib/contexts/{tableSetting.jsx => tableSetting.js} (100%) rename src/lib/hooks/{useDataTable.jsx => useDataTable.js} (100%) create mode 100644 src/lib/hooks/useRequest.js rename src/lib/hooks/{useTableSetting.jsx => useTableSetting.js} (100%) diff --git a/.env.local.example b/.env.local.example index e69de29..05bae5f 100644 --- a/.env.local.example +++ b/.env.local.example @@ -0,0 +1 @@ +NEXT_PUBLIC_API_URL="https://rms.witel.ir" \ No newline at end of file diff --git a/package.json b/package.json index b4ddfd0..4beef0b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@mui/material": "^5.15.6", "@mui/material-nextjs": "^5.15.6", "@mui/x-date-pickers": "^6.19.5", + "axios": "^1.7.2", "date-fns": "^3.3.1", "date-fns-jalali": "^2.13.0-0", "dayjs": "^1.11.10", diff --git a/public/global.scss b/public/global.scss index a383b5f..1af3ae3 100644 --- a/public/global.scss +++ b/public/global.scss @@ -1,7 +1,9 @@ @import "fontiran"; +@import "react-toastify/dist/ReactToastify.css"; .filter-toast { - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, + rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; background-color: #d0dfe8; border: 1px dashed #095b8c; -} \ No newline at end of file +} diff --git a/src/app/(withAuth)/dashboard/layout.js b/src/app/(withAuth)/dashboard/layout.js deleted file mode 100644 index 213bb0a..0000000 --- a/src/app/(withAuth)/dashboard/layout.js +++ /dev/null @@ -1,11 +0,0 @@ -import 'react-toastify/dist/ReactToastify.css'; - -const Layout = ({children}) => { - return ( - <> - {children} - - ) -} - -export default Layout \ No newline at end of file diff --git a/src/app/(withAuth)/dashboard/page.js b/src/app/(withAuth)/dashboard/page.js index f0731fe..915b3de 100644 --- a/src/app/(withAuth)/dashboard/page.js +++ b/src/app/(withAuth)/dashboard/page.js @@ -1,6 +1,28 @@ +'use client' +import { Button } from "@mui/material" +import axios from "axios" + const Page = () => { + const handler = () => { + try { + axios.get('https://rms.witel.ir/test_login?username=witel', { withCredentials: true }) + } catch (error) { + console.log(error); + } + } + const handler2 = () => { + try { + const res = axios.get('https://rms.witel.ir/webapi/user/get-permission', { withCredentials: true }) + console.log(res); + } catch (error) { + console.log(error); + } + } return ( -
dashboard
+ <> + + + ) } diff --git a/src/app/(withAuth)/dashboard/template.js b/src/app/(withAuth)/dashboard/template.js index 62759c6..eb7d2ef 100644 --- a/src/app/(withAuth)/dashboard/template.js +++ b/src/app/(withAuth)/dashboard/template.js @@ -1,17 +1,19 @@ -import {Box, Stack} from "@mui/material"; +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'; -const Template = ({children}) => { - return ( - - - - {children} - - - ) +const Template = ({ children }) => { + return ( + + + + + {children} + + + + ) } export default Template \ No newline at end of file diff --git a/src/app/(withAuth)/layout.js b/src/app/(withAuth)/layout.js new file mode 100644 index 0000000..5a5cca8 --- /dev/null +++ b/src/app/(withAuth)/layout.js @@ -0,0 +1,14 @@ +import WithAuthMiddleware from "@/core/middlewares/withAuth" +import { AuthProvider } from "@/lib/contexts/auth" + +const Layout = ({ children }) => { + return ( + + + {children} + + + ) +} + +export default Layout \ No newline at end of file diff --git a/src/app/layout.js b/src/app/layout.js index c23a7ec..1d4819e 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -1,17 +1,17 @@ -import {TableSettingProvider} from "@/lib/contexts/tableSetting"; +import { TableSettingProvider } from "@/lib/contexts/tableSetting"; export const metadata = { title: 'سامانه جامع راهداری', } -export default function RootLayout({children}) { +export default function RootLayout({ children }) { return ( - - - {children} - - + + + {children} + + ) } diff --git a/src/app/lfwd/page.js b/src/app/lfwd/page.js new file mode 100644 index 0000000..55eca31 --- /dev/null +++ b/src/app/lfwd/page.js @@ -0,0 +1,51 @@ +'use client' + +import { GET_LOGIN_ROUTE } from "@/core/utils/routes" +import useRequest from "@/lib/hooks/useRequest" +import { Button, Stack, Typography, Zoom } from "@mui/material" +import Link from "next/link" +import { useEffect, useState } from "react" + +const Page = () => { + const [login, setLogin] = useState(0) + const request = useRequest() + + useEffect(() => { + const login = async () => { + try { + const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) + setLogin(1) + } catch (error) { + setLogin(2) + } + } + + login() + }, []) + + const retry = async () => { + setLogin(0) + try { + const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) + setLogin(1) + } catch (error) { + setLogin(2) + } + } + + + return ( + + + {login === 0 ? 'درحال دریافت مجوز برای ارتباط با سرور...' : login === 1 ? 'ارتباط با سرور برقرار شد.' : 'ارتباط با سرور برقرار نشد. مشکلی وجود دارد.'} + + + + + + + + + ) +} +export default Page \ No newline at end of file diff --git a/src/app/template.js b/src/app/template.js index 14f15b6..71830af 100644 --- a/src/app/template.js +++ b/src/app/template.js @@ -1,18 +1,18 @@ import cacheProviderRtl from "@/core/utils/cacheRtl"; -import {CssBaseline, ThemeProvider} from "@mui/material"; +import { CssBaseline, ThemeProvider } from "@mui/material"; import theme from "@/core/utils/theme"; -import {AppRouterCacheProvider} from "@mui/material-nextjs/v14-appRouter"; -import 'react-toastify/dist/ReactToastify.css'; +import { AppRouterCacheProvider } from "@mui/material-nextjs/v14-appRouter"; import "^/global.scss"; -import {ToastContainer} from "react-toastify"; +import { ToastContainer } from "react-toastify"; -const Template = ({children}) => { +const Template = ({ children }) => { return ( - + - + {children} - + + ) diff --git a/src/core/components/Toasts/error.jsx b/src/core/components/Toasts/error.jsx new file mode 100644 index 0000000..d0d9760 --- /dev/null +++ b/src/core/components/Toasts/error.jsx @@ -0,0 +1,191 @@ +import { toast } from "react-toastify"; +import { Box, Typography } from "@mui/material"; +import { Dangerous } from "@mui/icons-material"; + +export const errorServerToast = (toastContainer) => + toast.error( + () => ( + + + + + + {"The request failed due to an internal error."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 5000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); + +export const errorUnauthorizedToast = (toastContainer) => + toast.error( + () => ( + + + + + + {"The user is not authorized to make the request."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); + +export const errorLogicToast = (message, toastContainer) => + toast.error( + () => ( + + + + + + {message || + "The request was well-formed but was unable to be followed due to semantic errors."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); + +export const errorValidationToast = (message, toastContainer) => + toast.error( + () => ( + + + + + + {message || + "The request was well-formed but was unable to be followed due to semantic errors."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); + +export const errorTooManyToast = (toastContainer) => + toast.error( + () => ( + + + + + + {"Too many requests have been sent within a given time span."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); + +export const errorClientToast = (toastContainer) => + toast.error( + () => ( + + + + + + { + "The API request is invalid or improperly formed. Consequently, the API server could not understand the request." + } + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); diff --git a/src/core/components/Toasts/success.jsx b/src/core/components/Toasts/success.jsx new file mode 100644 index 0000000..b405a04 --- /dev/null +++ b/src/core/components/Toasts/success.jsx @@ -0,0 +1,35 @@ +import { toast } from "react-toastify"; +import { Box, Typography } from "@mui/material"; +import { Beenhere } from "@mui/icons-material"; + +export const successToast = (toastContainer) => + toast.success( + () => ( + + + + + + {"Your operation was successful"} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); diff --git a/src/core/middlewares/withAuth.js b/src/core/middlewares/withAuth.js new file mode 100644 index 0000000..1b93025 --- /dev/null +++ b/src/core/middlewares/withAuth.js @@ -0,0 +1,22 @@ +'use client' +import { useAuth } from "@/lib/contexts/auth"; +import { usePathname, useRouter } from "next/navigation"; +import { useEffect } from "react"; + +function WithAuthMiddleware({ children }) { + const router = useRouter() + const pathName = usePathname() + const { isAuth, initAuthState } = useAuth(); + + useEffect(() => { + if (!initAuthState) return + if (!isAuth) { + router.replace(`${process.env.NEXT_PUBLIC_API_URL}/login?_back=${encodeURIComponent(pathName)}`) + } + }, [isAuth, initAuthState]) + + if (!initAuthState || !isAuth) return null; + return <>{children} +} + +export default WithAuthMiddleware \ No newline at end of file diff --git a/src/core/utils/errorResponse.js b/src/core/utils/errorResponse.js new file mode 100644 index 0000000..3accb8f --- /dev/null +++ b/src/core/utils/errorResponse.js @@ -0,0 +1,61 @@ +'use client' +import { toast } from "react-toastify"; +import { + errorClientToast, + errorLogicToast, + errorServerToast, + errorTooManyToast, + errorUnauthorizedToast, + errorValidationToast +} from "@/core/components/toasts/error"; + +const isServerError = status => status >= 500 && status <= 599; +const isClientError = status => status >= 400 && status <= 499; + +const errorServer = (response, notification, toastContainer) => { + if (notification) errorServerToast(toastContainer) +} + +const errorClient = (response, notification, toastContainer) => { + switch (response.status) { + case 401: + if (notification) errorUnauthorizedToast(toastContainer) + break; + case 422: + if ('type' in response.data) { + if (Array.isArray(response.data.message)) { + response.data.message.map((item) => { + if (notification) errorLogicToast(item, toastContainer) + }) + } else { + if (notification) errorLogicToast(response.data.message, toastContainer) + } + break; + } + if (notification) { + const errorsMap = Object.keys(response.data.errors) + const errorsArray = response.data.errors + + errorsMap.map((item, index) => { + errorValidationToast(errorsArray[item][0], toastContainer); + }) + + } + break; + case 429: + if (notification) errorTooManyToast(toastContainer) + break + default: + if (notification) errorClientToast(toastContainer) + break + } +} + +export const errorResponse = (response, notification, toastContainer) => { + if (notification) toast.dismiss({ container: toastContainer }) + if (isServerError(response.status)) { + errorServer(response, notification, toastContainer) + } else if (isClientError(response.status)) { + errorClient(response, notification, toastContainer) + } +} diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index b97199a..81cb873 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -12,7 +12,7 @@ export const pageMenu = [ id: 'userManagement', label: 'مدیریت کاربران', type: "page", - route: "./v2/user_management", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", icon: , }, { @@ -26,35 +26,35 @@ export const pageMenu = [ id: 'projectsManagmentFinance', label: 'ثبت قرارداد و پروژه', type: "page", - route: "./v2/rahdari_projects/finance", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", icon: , }, { id: 'projectsManagmentList', label: 'لیست پروژه ها', type: "page", - route: "./v2/rahdari_projects/projects_list", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", icon: , }, { id: 'projectsManagmentProposal', label: 'پروژه های پیشنهادی', type: "page", - route: "./v2/rahdari_projects/proposal", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", icon: , }, { id: 'projectsManagmentLawmaker', label: 'درخواست نمایندگان', type: "page", - route: "./v2/rahdari_projects/lawmakers", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", icon: , }, { id: 'projectsManagmentMap', label: 'پراکندگی بر روی نقشه', type: "page", - route: "./v2/map?type=rahdari_projects", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", icon: , }, ] @@ -77,7 +77,7 @@ export const pageMenu = [ id: 'roadItemManagmentSupervisorCartable', label: 'کارتابل', type: "page", - route: "./v2/road_items/supervisor/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable", }, ] }, @@ -92,13 +92,13 @@ export const pageMenu = [ id: 'roadItemManagmentOparationCreate', label: 'ثبت فعالیت', type: "page", - route: "./v2/road_items/operator/create", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create", }, { id: 'roadItemManagmentOparationCartable', label: 'کارتابل', type: "page", - route: "./v2/road_items/operator/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable", }, ] }, @@ -106,14 +106,14 @@ export const pageMenu = [ id: 'roadItemManagmentMap', label: 'پراکندگی بر روی نقشه', type: "page", - route: "./v2/map?type=road_items", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", icon: , }, { id: 'roadItemManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/road_items/report", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", icon: , }, ] @@ -136,7 +136,7 @@ export const pageMenu = [ id: 'roadPatrolManagmentSupervisorCartable', label: 'کارتابل', type: "page", - route: "./road_patrols/supervisor/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable", }, ] }, @@ -151,13 +151,13 @@ export const pageMenu = [ id: 'roadPatrolManagmentOparationCreate', label: 'ثبت اقدام', type: "page", - route: "./v2/road_patrols/operator/create", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", }, { id: 'roadPatrolManagmentOparationCartable', label: 'کارتابل', type: "page", - route: "./v2/road_patrols/operator/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", }, ] }, @@ -165,14 +165,14 @@ export const pageMenu = [ id: 'roadPatrolManagmentMap', label: 'پراکندگی بر روی نقشه', type: "page", - route: "./v2/map?type=road_patrols", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", icon: , }, { id: 'roadPatrolManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/road_patrols/report", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", icon: , }, ] @@ -195,13 +195,13 @@ export const pageMenu = [ id: 'safetyAndPrivacyManagmentOparationCreate', label: 'ثبت فعالیت', type: "page", - route: "./safety_and_privacy/operator/first_step", + route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step", }, { id: 'safetyAndPrivacyManagmentOparationCartable', label: 'کارتابل', type: "page", - route: "./v2/safety_and_privacy/operator/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", }, ] }, @@ -209,14 +209,14 @@ export const pageMenu = [ id: 'safetyAndPrivacyManagmentMap', label: 'پراکندگی بر روی نقشه', type: "page", - route: "./v2/map?type=safety_and_privacy", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", icon: , }, { id: 'safetyAndPrivacyManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/safety_and_privacy/report", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", icon: , }, ] @@ -239,7 +239,7 @@ export const pageMenu = [ id: 'roadObservationsManagmentSupervisorCartable', label: 'کارتابل', type: "page", - route: "./v2/road_observations/supervisor/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable", }, ] }, @@ -247,7 +247,7 @@ export const pageMenu = [ id: 'roadObservationsManagmentList', label: 'رسیدگی به شکایات', type: "page", - route: "./v2/road_observations", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", icon: , }, { @@ -261,7 +261,7 @@ export const pageMenu = [ id: 'roadObservationsManagmentOparationCartable', label: 'کارتابل', type: "page", - route: "./v2/road_observations/operator/cartable", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable", }, ] }, @@ -269,14 +269,14 @@ export const pageMenu = [ id: 'roadObservationsManagmentMap', label: 'پراکندگی بر روی نقشه', type: "page", - route: "./v2/map?type=road_observations", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", icon: , }, { id: 'roadObservationsManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/road_observations/report/index", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", icon: , }, ] @@ -292,21 +292,21 @@ export const pageMenu = [ id: 'winterCampManagmentBlocking', label: 'محور های انسدادی', type: "page", - route: "./v2/winter_camp", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", icon: , }, { id: 'winterCampManagmentFirstRing', label: 'محور های حلقه اول', type: "page", - route: "./v2/map?type=camp", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", icon: , }, { id: 'winterCampManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/map?type=campNew", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", icon: , }, ] @@ -329,7 +329,7 @@ export const pageMenu = [ id: 'receiptManagmentOparationCartable', label: 'کارتابل', type: "page", - route: "./v2/receipt", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt", }, ] }, @@ -337,7 +337,7 @@ export const pageMenu = [ id: 'receiptManagmentReport', label: 'گزارش ها', type: "page", - route: "./v2/receipt/report", + route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", icon: , }, ] diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js new file mode 100644 index 0000000..39b6b09 --- /dev/null +++ b/src/core/utils/routes.js @@ -0,0 +1,4 @@ +const api = process.env.NEXT_PUBLIC_API_URL + +export const GET_USER_ROUTE = api + '/webapi/user/get-permission' +export const GET_LOGIN_ROUTE = api + '/test_login' \ No newline at end of file diff --git a/src/core/utils/successRequest.js b/src/core/utils/successRequest.js new file mode 100644 index 0000000..5138d7a --- /dev/null +++ b/src/core/utils/successRequest.js @@ -0,0 +1,10 @@ +'use client' +import { toast } from "react-toastify"; +import { successToast } from "@/core/components/toasts/success"; + +export const successRequest = (notification, toastContainer) => { + if (notification) { + toast.dismiss({ container: toastContainer }) + successToast(toastContainer) + } +} \ No newline at end of file diff --git a/src/lib/contexts/DataTable.jsx b/src/lib/contexts/DataTable.js similarity index 100% rename from src/lib/contexts/DataTable.jsx rename to src/lib/contexts/DataTable.js diff --git a/src/lib/contexts/auth.js b/src/lib/contexts/auth.js new file mode 100644 index 0000000..e60f413 --- /dev/null +++ b/src/lib/contexts/auth.js @@ -0,0 +1,76 @@ +'use client' +import { createContext, useCallback, useContext, useEffect, useReducer } from 'react'; +import useRequest from '../hooks/useRequest'; +import { GET_USER_ROUTE } from '@/core/utils/routes'; + +const initAuth = { + initAuthState: false, + isAuth: false, + user: {} +}; + +const authReducer = (state, action) => { + switch (action.type) { + case "CLEAR_USER": + return { ...state, user: {} }; + case "CHANGE_USER": + return { ...state, user: action.user }; + case "CHANGE_AUTH_STATE": + return { ...state, isAuth: action.isAuth }; + case "CHANGE_INIT_AUTH": + return { ...state, initAuthState: action.initAuthState }; + default: + return state; + } +}; + +const AuthContext = createContext(); + +export const AuthProvider = ({ children }) => { + const [state, dispatch] = useReducer(authReducer, initAuth); + const request = useRequest() + + const clearUser = useCallback(() => { + dispatch({ type: "CLEAR_USER" }); + }, []); + + const changeUser = useCallback((user) => { + dispatch({ type: "CHANGE_USER", user }); + }, []); + + const changeAuthState = useCallback((isAuth) => { + dispatch({ type: "CHANGE_AUTH_STATE", isAuth }); + }, []); + + const changeInitAuth = useCallback((initAuthState) => { + dispatch({ type: "CHANGE_INIT_AUTH", initAuthState }); + }, []); + + const getUser = useCallback(async () => { + try { + const { data } = await request(GET_USER_ROUTE, 'get') + changeUser(data); + changeAuthState(true); + changeInitAuth(true); + } catch (error) { + if (error.response && error.response.status === 401) { + clearUser(); + changeAuthState(false); + changeInitAuth(true); + } + } + }, [clearUser, changeUser, changeAuthState, changeInitAuth]); + + useEffect(() => { + getUser() + }, []) + + return {children}; +}; + +export const useAuth = () => useContext(AuthContext); \ No newline at end of file diff --git a/src/lib/contexts/tableSetting.jsx b/src/lib/contexts/tableSetting.js similarity index 100% rename from src/lib/contexts/tableSetting.jsx rename to src/lib/contexts/tableSetting.js diff --git a/src/lib/hooks/useDataTable.jsx b/src/lib/hooks/useDataTable.js similarity index 100% rename from src/lib/hooks/useDataTable.jsx rename to src/lib/hooks/useDataTable.js diff --git a/src/lib/hooks/useRequest.js b/src/lib/hooks/useRequest.js new file mode 100644 index 0000000..8beee2e --- /dev/null +++ b/src/lib/hooks/useRequest.js @@ -0,0 +1,42 @@ +import { errorResponse } from "@/core/utils/errorResponse"; +import { successRequest } from "@/core/utils/successRequest"; +import axios from "axios"; + +const defaultOptions = { + data: {}, + requestOptions: { + headers: {} + }, + notification: { + show: true, + success: false, + failed: true + }, +} + +const useRequest = (initOptions) => { + const _options = Object.assign({}, defaultOptions, initOptions); + + return async (url = '', method = 'get', options) => { + const mergedOptions = Object.assign({}, _options, options); + + try { + const response = await axios({ + url, + method, + data: method === 'get' ? null : mergedOptions.data, + withCredentials: true, + ...mergedOptions.requestOptions + }); + successRequest(mergedOptions.notification.show && mergedOptions.notification.success, 'request_data'); + return response; + } catch (error) { + if (error.response) { + errorResponse(error.response, mergedOptions.notification.show && mergedOptions.notification.failed, 'request_data'); + } + throw error; + } + } +} + +export default useRequest \ No newline at end of file diff --git a/src/lib/hooks/useTableSetting.jsx b/src/lib/hooks/useTableSetting.js similarity index 100% rename from src/lib/hooks/useTableSetting.jsx rename to src/lib/hooks/useTableSetting.js From bc73725138b24a732d9f58561ee4a5e29cdb5c1e Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Tue, 9 Jul 2024 13:58:13 +0330 Subject: [PATCH 24/28] formatted --- .eslintrc.json | 2 +- .prettierrc | 12 + editorconfig | 485 ------------------ package.json | 7 +- src/app/(withAuth)/dashboard/page.js | 24 +- src/app/(withAuth)/dashboard/template.js | 12 +- src/app/(withAuth)/layout.js | 14 +- src/app/default.js | 4 +- src/app/layout.js | 14 +- src/app/lfwd/page.js | 60 ++- src/app/page.js | 8 +- src/app/template.js | 6 +- src/components/home/Toolbar.jsx | 22 +- src/components/home/index.jsx | 109 ++-- .../headerWithLogo/HaederBottom/index.jsx | 51 +- .../headerWithLogo/HaederTop/index.jsx | 16 +- .../dashboard/headerWithLogo/index.jsx | 12 +- .../headerWithSidebar/HeaderMenu/index.jsx | 2 +- .../dashboard/headerWithSidebar/index.jsx | 164 +++--- src/core/components/DataTable/Main.js | 177 ++++--- .../components/DataTable/body/TableBody.js | 160 +++--- .../DataTable/body/TableBodyCell.js | 173 +++---- .../DataTable/body/TableBodyCellValue.js | 189 ++++--- .../components/DataTable/body/TableBodyRow.js | 179 +++---- .../DataTable/body/TableDetailPanel.js | 32 +- .../DataTable/buttons/CopyButton.js | 41 +- .../DataTable/buttons/GrabHandleButton.js | 36 +- .../buttons/ShowHideColumnsButton.js | 19 +- .../DataTable/buttons/ToggleFiltersButton.js | 6 +- .../DataTable/filter/FilterBody.jsx | 225 ++++---- .../DataTable/filter/FilterBodyField.jsx | 28 +- .../DataTable/filter/FilterButton.jsx | 19 +- .../DataTable/filter/FilterHeader.jsx | 26 +- .../DataTable/filter/FilterOptionList.jsx | 49 +- .../CustomDate/CustomDatePicker.jsx | 10 +- .../CustomDate/CustomDatePickerRange.jsx | 10 +- .../fieldsType/CustomDate/MuiDatePicker.jsx | 38 +- .../filter/fieldsType/CustomSelect.jsx | 19 +- .../fieldsType/CustomSelectMultiple.jsx | 30 +- .../filter/fieldsType/CustomTextField.jsx | 35 +- .../fieldsType/CustomTextFieldRange.jsx | 41 +- .../components/DataTable/filter/index.jsx | 18 +- .../components/DataTable/head/TableHead.js | 57 +- .../DataTable/head/TableHeadCell.js | 239 ++++----- .../components/DataTable/head/TableHeadRow.js | 44 +- src/core/components/DataTable/index.js | 4 +- .../DataTable/localization/fa/datatable.js | 5 +- .../DataTable/menus/ActionMenuItem.js | 32 +- .../DataTable/menus/CellActionMenu.js | 26 +- .../DataTable/menus/ShowHideColumnsMenu.js | 52 +- .../menus/ShowHideColumnsMenuItems.js | 42 +- .../DataTable/refactor/RefactorTable.jsx | 18 +- src/core/components/DataTable/table/Paper.js | 68 +-- src/core/components/DataTable/table/Table.js | 20 +- .../DataTable/table/TableContainer.js | 53 +- .../DataTable/table/TableLoadingOverlay.js | 22 +- .../DataTable/toolbar/BottomToolbar.js | 60 +-- .../DataTable/toolbar/LinearProgressBar.js | 16 +- .../DataTable/toolbar/TablePagination.js | 79 +-- .../toolbar/ToolbarInternalButtons.js | 31 +- .../DataTable/toolbar/TopToolbar.js | 83 +-- .../NotificationDesign/AskForKeep.jsx | 78 +-- src/core/components/SidebarListItems.jsx | 116 ++--- src/core/components/SidebarMenu.jsx | 224 ++++---- src/core/components/SidebarSubitems.jsx | 114 ++-- src/core/components/Toasts/error.jsx | 348 +++++++------ src/core/components/Toasts/success.jsx | 58 +-- src/core/middlewares/withAuth.js | 16 +- src/core/utils/cacheRtl.js | 12 +- src/core/utils/errorResponse.js | 47 +- src/core/utils/flattenArrayOfObjects.js | 2 +- src/core/utils/pageMenu.js | 288 +++++------ src/core/utils/routes.js | 6 +- src/core/utils/successRequest.js | 8 +- src/core/utils/theme.js | 18 +- src/core/utils/utils.js | 240 ++++----- src/lib/contexts/DataTable.js | 12 +- src/lib/contexts/auth.js | 38 +- src/lib/contexts/tableSetting.js | 85 +-- src/lib/hooks/useDataTable.js | 8 +- src/lib/hooks/useRequest.js | 26 +- src/lib/hooks/useTableSetting.js | 9 +- 82 files changed, 2206 insertions(+), 3082 deletions(-) create mode 100644 .prettierrc delete mode 100644 editorconfig diff --git a/.eslintrc.json b/.eslintrc.json index bffb357..121cefd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals","prettier"] } diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7eeebb6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "es5", + "bracketSpacing": true, + "jsxBracketSameLine": false, + "arrowParens": "always", + "endOfLine": "crlf" +} \ No newline at end of file diff --git a/editorconfig b/editorconfig deleted file mode 100644 index 05e5a39..0000000 --- a/editorconfig +++ /dev/null @@ -1,485 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = crlf -indent_size = 4 -indent_style = space -insert_final_newline = false -max_line_length = 120 -tab_width = 4 -ij_continuation_indent_size = 4 -ij_formatter_off_tag = @formatter:off -ij_formatter_on_tag = @formatter:on -ij_formatter_tags_enabled = true -ij_smart_tabs = false -ij_visual_guides = none -ij_wrap_on_typing = false - -[*.css] -ij_css_align_closing_brace_with_properties = false -ij_css_blank_lines_around_nested_selector = 1 -ij_css_blank_lines_between_blocks = 1 -ij_css_block_comment_add_space = false -ij_css_brace_placement = end_of_line -ij_css_enforce_quotes_on_format = false -ij_css_hex_color_long_format = false -ij_css_hex_color_lower_case = false -ij_css_hex_color_short_format = false -ij_css_hex_color_upper_case = false -ij_css_keep_blank_lines_in_code = 2 -ij_css_keep_indents_on_empty_lines = false -ij_css_keep_single_line_blocks = false -ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow -ij_css_space_after_colon = true -ij_css_space_before_opening_brace = true -ij_css_use_double_quotes = true -ij_css_value_alignment = do_not_align - -[*.sass] -indent_size = 2 -ij_sass_align_closing_brace_with_properties = false -ij_sass_blank_lines_around_nested_selector = 1 -ij_sass_blank_lines_between_blocks = 1 -ij_sass_brace_placement = 0 -ij_sass_enforce_quotes_on_format = false -ij_sass_hex_color_long_format = false -ij_sass_hex_color_lower_case = false -ij_sass_hex_color_short_format = false -ij_sass_hex_color_upper_case = false -ij_sass_keep_blank_lines_in_code = 2 -ij_sass_keep_indents_on_empty_lines = false -ij_sass_keep_single_line_blocks = false -ij_sass_line_comment_add_space = false -ij_sass_line_comment_at_first_column = false -ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow -ij_sass_space_after_colon = true -ij_sass_space_before_opening_brace = true -ij_sass_use_double_quotes = true -ij_sass_value_alignment = 0 - -[*.scss] -indent_size = 2 -ij_scss_align_closing_brace_with_properties = false -ij_scss_blank_lines_around_nested_selector = 1 -ij_scss_blank_lines_between_blocks = 1 -ij_scss_block_comment_add_space = false -ij_scss_brace_placement = 0 -ij_scss_enforce_quotes_on_format = false -ij_scss_hex_color_long_format = false -ij_scss_hex_color_lower_case = false -ij_scss_hex_color_short_format = false -ij_scss_hex_color_upper_case = false -ij_scss_keep_blank_lines_in_code = 2 -ij_scss_keep_indents_on_empty_lines = false -ij_scss_keep_single_line_blocks = false -ij_scss_line_comment_add_space = false -ij_scss_line_comment_at_first_column = false -ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow -ij_scss_space_after_colon = true -ij_scss_space_before_opening_brace = true -ij_scss_use_double_quotes = true -ij_scss_value_alignment = 0 - -[{*.ats,*.cts,*.mts,*.ts}] -ij_continuation_indent_size = 4 -ij_typescript_align_imports = false -ij_typescript_align_multiline_array_initializer_expression = false -ij_typescript_align_multiline_binary_operation = false -ij_typescript_align_multiline_chained_methods = false -ij_typescript_align_multiline_extends_list = false -ij_typescript_align_multiline_for = true -ij_typescript_align_multiline_parameters = true -ij_typescript_align_multiline_parameters_in_calls = false -ij_typescript_align_multiline_ternary_operation = false -ij_typescript_align_object_properties = 0 -ij_typescript_align_union_types = false -ij_typescript_align_var_statements = 0 -ij_typescript_array_initializer_new_line_after_left_brace = false -ij_typescript_array_initializer_right_brace_on_new_line = false -ij_typescript_array_initializer_wrap = off -ij_typescript_assignment_wrap = off -ij_typescript_binary_operation_sign_on_next_line = false -ij_typescript_binary_operation_wrap = off -ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** -ij_typescript_blank_lines_after_imports = 1 -ij_typescript_blank_lines_around_class = 1 -ij_typescript_blank_lines_around_field = 0 -ij_typescript_blank_lines_around_field_in_interface = 0 -ij_typescript_blank_lines_around_function = 1 -ij_typescript_blank_lines_around_method = 1 -ij_typescript_blank_lines_around_method_in_interface = 1 -ij_typescript_block_brace_style = end_of_line -ij_typescript_block_comment_add_space = false -ij_typescript_block_comment_at_first_column = true -ij_typescript_call_parameters_new_line_after_left_paren = false -ij_typescript_call_parameters_right_paren_on_new_line = false -ij_typescript_call_parameters_wrap = off -ij_typescript_catch_on_new_line = false -ij_typescript_chained_call_dot_on_new_line = true -ij_typescript_class_brace_style = end_of_line -ij_typescript_comma_on_new_line = false -ij_typescript_do_while_brace_force = never -ij_typescript_else_on_new_line = false -ij_typescript_enforce_trailing_comma = keep -ij_typescript_enum_constants_wrap = on_every_item -ij_typescript_extends_keyword_wrap = off -ij_typescript_extends_list_wrap = off -ij_typescript_field_prefix = _ -ij_typescript_file_name_style = relaxed -ij_typescript_finally_on_new_line = false -ij_typescript_for_brace_force = never -ij_typescript_for_statement_new_line_after_left_paren = false -ij_typescript_for_statement_right_paren_on_new_line = false -ij_typescript_for_statement_wrap = off -ij_typescript_force_quote_style = false -ij_typescript_force_semicolon_style = false -ij_typescript_function_expression_brace_style = end_of_line -ij_typescript_if_brace_force = never -ij_typescript_import_merge_members = global -ij_typescript_import_prefer_absolute_path = global -ij_typescript_import_sort_members = true -ij_typescript_import_sort_module_name = false -ij_typescript_import_use_node_resolution = true -ij_typescript_imports_wrap = on_every_item -ij_typescript_indent_case_from_switch = true -ij_typescript_indent_chained_calls = true -ij_typescript_indent_package_children = 0 -ij_typescript_jsdoc_include_types = false -ij_typescript_jsx_attribute_value = braces -ij_typescript_keep_blank_lines_in_code = 2 -ij_typescript_keep_first_column_comment = true -ij_typescript_keep_indents_on_empty_lines = false -ij_typescript_keep_line_breaks = true -ij_typescript_keep_simple_blocks_in_one_line = false -ij_typescript_keep_simple_methods_in_one_line = false -ij_typescript_line_comment_add_space = true -ij_typescript_line_comment_at_first_column = false -ij_typescript_method_brace_style = end_of_line -ij_typescript_method_call_chain_wrap = off -ij_typescript_method_parameters_new_line_after_left_paren = false -ij_typescript_method_parameters_right_paren_on_new_line = false -ij_typescript_method_parameters_wrap = off -ij_typescript_object_literal_wrap = on_every_item -ij_typescript_object_types_wrap = on_every_item -ij_typescript_parentheses_expression_new_line_after_left_paren = false -ij_typescript_parentheses_expression_right_paren_on_new_line = false -ij_typescript_place_assignment_sign_on_next_line = false -ij_typescript_prefer_as_type_cast = false -ij_typescript_prefer_explicit_types_function_expression_returns = false -ij_typescript_prefer_explicit_types_function_returns = false -ij_typescript_prefer_explicit_types_vars_fields = false -ij_typescript_prefer_parameters_wrap = false -ij_typescript_reformat_c_style_comments = false -ij_typescript_space_after_colon = true -ij_typescript_space_after_comma = true -ij_typescript_space_after_dots_in_rest_parameter = false -ij_typescript_space_after_generator_mult = true -ij_typescript_space_after_property_colon = true -ij_typescript_space_after_quest = true -ij_typescript_space_after_type_colon = true -ij_typescript_space_after_unary_not = false -ij_typescript_space_before_async_arrow_lparen = true -ij_typescript_space_before_catch_keyword = true -ij_typescript_space_before_catch_left_brace = true -ij_typescript_space_before_catch_parentheses = true -ij_typescript_space_before_class_lbrace = true -ij_typescript_space_before_class_left_brace = true -ij_typescript_space_before_colon = true -ij_typescript_space_before_comma = false -ij_typescript_space_before_do_left_brace = true -ij_typescript_space_before_else_keyword = true -ij_typescript_space_before_else_left_brace = true -ij_typescript_space_before_finally_keyword = true -ij_typescript_space_before_finally_left_brace = true -ij_typescript_space_before_for_left_brace = true -ij_typescript_space_before_for_parentheses = true -ij_typescript_space_before_for_semicolon = false -ij_typescript_space_before_function_left_parenth = true -ij_typescript_space_before_generator_mult = false -ij_typescript_space_before_if_left_brace = true -ij_typescript_space_before_if_parentheses = true -ij_typescript_space_before_method_call_parentheses = false -ij_typescript_space_before_method_left_brace = true -ij_typescript_space_before_method_parentheses = false -ij_typescript_space_before_property_colon = false -ij_typescript_space_before_quest = true -ij_typescript_space_before_switch_left_brace = true -ij_typescript_space_before_switch_parentheses = true -ij_typescript_space_before_try_left_brace = true -ij_typescript_space_before_type_colon = false -ij_typescript_space_before_unary_not = false -ij_typescript_space_before_while_keyword = true -ij_typescript_space_before_while_left_brace = true -ij_typescript_space_before_while_parentheses = true -ij_typescript_spaces_around_additive_operators = true -ij_typescript_spaces_around_arrow_function_operator = true -ij_typescript_spaces_around_assignment_operators = true -ij_typescript_spaces_around_bitwise_operators = true -ij_typescript_spaces_around_equality_operators = true -ij_typescript_spaces_around_logical_operators = true -ij_typescript_spaces_around_multiplicative_operators = true -ij_typescript_spaces_around_relational_operators = true -ij_typescript_spaces_around_shift_operators = true -ij_typescript_spaces_around_unary_operator = false -ij_typescript_spaces_within_array_initializer_brackets = false -ij_typescript_spaces_within_brackets = false -ij_typescript_spaces_within_catch_parentheses = false -ij_typescript_spaces_within_for_parentheses = false -ij_typescript_spaces_within_if_parentheses = false -ij_typescript_spaces_within_imports = false -ij_typescript_spaces_within_interpolation_expressions = false -ij_typescript_spaces_within_method_call_parentheses = false -ij_typescript_spaces_within_method_parentheses = false -ij_typescript_spaces_within_object_literal_braces = false -ij_typescript_spaces_within_object_type_braces = true -ij_typescript_spaces_within_parentheses = false -ij_typescript_spaces_within_switch_parentheses = false -ij_typescript_spaces_within_type_assertion = false -ij_typescript_spaces_within_union_types = true -ij_typescript_spaces_within_while_parentheses = false -ij_typescript_special_else_if_treatment = true -ij_typescript_ternary_operation_signs_on_next_line = false -ij_typescript_ternary_operation_wrap = off -ij_typescript_union_types_wrap = on_every_item -ij_typescript_use_chained_calls_group_indents = false -ij_typescript_use_double_quotes = true -ij_typescript_use_explicit_js_extension = auto -ij_typescript_use_path_mapping = always -ij_typescript_use_public_modifier = false -ij_typescript_use_semicolon_after_statement = true -ij_typescript_var_declaration_wrap = normal -ij_typescript_while_brace_force = never -ij_typescript_while_on_new_line = false -ij_typescript_wrap_comments = false - -[{*.cjs,*.js}] -ij_continuation_indent_size = 4 -ij_javascript_align_imports = false -ij_javascript_align_multiline_array_initializer_expression = false -ij_javascript_align_multiline_binary_operation = false -ij_javascript_align_multiline_chained_methods = false -ij_javascript_align_multiline_extends_list = false -ij_javascript_align_multiline_for = true -ij_javascript_align_multiline_parameters = true -ij_javascript_align_multiline_parameters_in_calls = false -ij_javascript_align_multiline_ternary_operation = false -ij_javascript_align_object_properties = 0 -ij_javascript_align_union_types = false -ij_javascript_align_var_statements = 0 -ij_javascript_array_initializer_new_line_after_left_brace = false -ij_javascript_array_initializer_right_brace_on_new_line = false -ij_javascript_array_initializer_wrap = off -ij_javascript_assignment_wrap = off -ij_javascript_binary_operation_sign_on_next_line = false -ij_javascript_binary_operation_wrap = off -ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** -ij_javascript_blank_lines_after_imports = 1 -ij_javascript_blank_lines_around_class = 1 -ij_javascript_blank_lines_around_field = 0 -ij_javascript_blank_lines_around_function = 1 -ij_javascript_blank_lines_around_method = 1 -ij_javascript_block_brace_style = end_of_line -ij_javascript_block_comment_add_space = false -ij_javascript_block_comment_at_first_column = true -ij_javascript_call_parameters_new_line_after_left_paren = false -ij_javascript_call_parameters_right_paren_on_new_line = false -ij_javascript_call_parameters_wrap = off -ij_javascript_catch_on_new_line = false -ij_javascript_chained_call_dot_on_new_line = true -ij_javascript_class_brace_style = end_of_line -ij_javascript_comma_on_new_line = false -ij_javascript_do_while_brace_force = never -ij_javascript_else_on_new_line = false -ij_javascript_enforce_trailing_comma = keep -ij_javascript_extends_keyword_wrap = off -ij_javascript_extends_list_wrap = off -ij_javascript_field_prefix = _ -ij_javascript_file_name_style = relaxed -ij_javascript_finally_on_new_line = false -ij_javascript_for_brace_force = never -ij_javascript_for_statement_new_line_after_left_paren = false -ij_javascript_for_statement_right_paren_on_new_line = false -ij_javascript_for_statement_wrap = off -ij_javascript_force_quote_style = false -ij_javascript_force_semicolon_style = false -ij_javascript_function_expression_brace_style = end_of_line -ij_javascript_if_brace_force = never -ij_javascript_import_merge_members = global -ij_javascript_import_prefer_absolute_path = global -ij_javascript_import_sort_members = true -ij_javascript_import_sort_module_name = false -ij_javascript_import_use_node_resolution = true -ij_javascript_imports_wrap = on_every_item -ij_javascript_indent_case_from_switch = true -ij_javascript_indent_chained_calls = true -ij_javascript_indent_package_children = 0 -ij_javascript_jsx_attribute_value = braces -ij_javascript_keep_blank_lines_in_code = 2 -ij_javascript_keep_first_column_comment = true -ij_javascript_keep_indents_on_empty_lines = false -ij_javascript_keep_line_breaks = true -ij_javascript_keep_simple_blocks_in_one_line = false -ij_javascript_keep_simple_methods_in_one_line = false -ij_javascript_line_comment_add_space = true -ij_javascript_line_comment_at_first_column = false -ij_javascript_method_brace_style = end_of_line -ij_javascript_method_call_chain_wrap = off -ij_javascript_method_parameters_new_line_after_left_paren = false -ij_javascript_method_parameters_right_paren_on_new_line = false -ij_javascript_method_parameters_wrap = off -ij_javascript_object_literal_wrap = on_every_item -ij_javascript_object_types_wrap = on_every_item -ij_javascript_parentheses_expression_new_line_after_left_paren = false -ij_javascript_parentheses_expression_right_paren_on_new_line = false -ij_javascript_place_assignment_sign_on_next_line = false -ij_javascript_prefer_as_type_cast = false -ij_javascript_prefer_explicit_types_function_expression_returns = false -ij_javascript_prefer_explicit_types_function_returns = false -ij_javascript_prefer_explicit_types_vars_fields = false -ij_javascript_prefer_parameters_wrap = false -ij_javascript_reformat_c_style_comments = false -ij_javascript_space_after_colon = true -ij_javascript_space_after_comma = true -ij_javascript_space_after_dots_in_rest_parameter = false -ij_javascript_space_after_generator_mult = true -ij_javascript_space_after_property_colon = true -ij_javascript_space_after_quest = true -ij_javascript_space_after_type_colon = true -ij_javascript_space_after_unary_not = false -ij_javascript_space_before_async_arrow_lparen = true -ij_javascript_space_before_catch_keyword = true -ij_javascript_space_before_catch_left_brace = true -ij_javascript_space_before_catch_parentheses = true -ij_javascript_space_before_class_lbrace = true -ij_javascript_space_before_class_left_brace = true -ij_javascript_space_before_colon = true -ij_javascript_space_before_comma = false -ij_javascript_space_before_do_left_brace = true -ij_javascript_space_before_else_keyword = true -ij_javascript_space_before_else_left_brace = true -ij_javascript_space_before_finally_keyword = true -ij_javascript_space_before_finally_left_brace = true -ij_javascript_space_before_for_left_brace = true -ij_javascript_space_before_for_parentheses = true -ij_javascript_space_before_for_semicolon = false -ij_javascript_space_before_function_left_parenth = true -ij_javascript_space_before_generator_mult = false -ij_javascript_space_before_if_left_brace = true -ij_javascript_space_before_if_parentheses = true -ij_javascript_space_before_method_call_parentheses = false -ij_javascript_space_before_method_left_brace = true -ij_javascript_space_before_method_parentheses = false -ij_javascript_space_before_property_colon = false -ij_javascript_space_before_quest = true -ij_javascript_space_before_switch_left_brace = true -ij_javascript_space_before_switch_parentheses = true -ij_javascript_space_before_try_left_brace = true -ij_javascript_space_before_type_colon = false -ij_javascript_space_before_unary_not = false -ij_javascript_space_before_while_keyword = true -ij_javascript_space_before_while_left_brace = true -ij_javascript_space_before_while_parentheses = true -ij_javascript_spaces_around_additive_operators = true -ij_javascript_spaces_around_arrow_function_operator = true -ij_javascript_spaces_around_assignment_operators = true -ij_javascript_spaces_around_bitwise_operators = true -ij_javascript_spaces_around_equality_operators = true -ij_javascript_spaces_around_logical_operators = true -ij_javascript_spaces_around_multiplicative_operators = true -ij_javascript_spaces_around_relational_operators = true -ij_javascript_spaces_around_shift_operators = true -ij_javascript_spaces_around_unary_operator = false -ij_javascript_spaces_within_array_initializer_brackets = false -ij_javascript_spaces_within_brackets = false -ij_javascript_spaces_within_catch_parentheses = false -ij_javascript_spaces_within_for_parentheses = false -ij_javascript_spaces_within_if_parentheses = false -ij_javascript_spaces_within_imports = false -ij_javascript_spaces_within_interpolation_expressions = false -ij_javascript_spaces_within_method_call_parentheses = false -ij_javascript_spaces_within_method_parentheses = false -ij_javascript_spaces_within_object_literal_braces = false -ij_javascript_spaces_within_object_type_braces = true -ij_javascript_spaces_within_parentheses = false -ij_javascript_spaces_within_switch_parentheses = false -ij_javascript_spaces_within_type_assertion = false -ij_javascript_spaces_within_union_types = true -ij_javascript_spaces_within_while_parentheses = false -ij_javascript_special_else_if_treatment = true -ij_javascript_ternary_operation_signs_on_next_line = false -ij_javascript_ternary_operation_wrap = off -ij_javascript_union_types_wrap = on_every_item -ij_javascript_use_chained_calls_group_indents = false -ij_javascript_use_double_quotes = true -ij_javascript_use_explicit_js_extension = auto -ij_javascript_use_path_mapping = always -ij_javascript_use_public_modifier = false -ij_javascript_use_semicolon_after_statement = true -ij_javascript_var_declaration_wrap = normal -ij_javascript_while_brace_force = never -ij_javascript_while_on_new_line = false -ij_javascript_wrap_comments = false - -[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}] -indent_size = 2 -ij_json_array_wrapping = split_into_lines -ij_json_keep_blank_lines_in_code = 0 -ij_json_keep_indents_on_empty_lines = false -ij_json_keep_line_breaks = true -ij_json_keep_trailing_comma = false -ij_json_object_wrapping = split_into_lines -ij_json_property_alignment = do_not_align -ij_json_space_after_colon = true -ij_json_space_after_comma = true -ij_json_space_before_colon = false -ij_json_space_before_comma = false -ij_json_spaces_within_braces = false -ij_json_spaces_within_brackets = false -ij_json_wrap_long_lines = false - -[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] -ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 -ij_html_align_attributes = true -ij_html_align_text = false -ij_html_attribute_wrap = normal -ij_html_block_comment_add_space = false -ij_html_block_comment_at_first_column = true -ij_html_do_not_align_children_of_min_lines = 0 -ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p -ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot -ij_html_enforce_quotes = false -ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var -ij_html_keep_blank_lines = 2 -ij_html_keep_indents_on_empty_lines = false -ij_html_keep_line_breaks = true -ij_html_keep_line_breaks_in_text = true -ij_html_keep_whitespaces = false -ij_html_keep_whitespaces_inside = span, pre, textarea -ij_html_line_comment_at_first_column = true -ij_html_new_line_after_last_attribute = never -ij_html_new_line_before_first_attribute = never -ij_html_quote_style = double -ij_html_remove_new_line_before_tags = br -ij_html_space_after_tag_name = false -ij_html_space_around_equality_in_attribute = false -ij_html_space_inside_empty_tag = false -ij_html_text_wrap = normal - -[{*.markdown,*.md}] -ij_markdown_force_one_space_after_blockquote_symbol = true -ij_markdown_force_one_space_after_header_symbol = true -ij_markdown_force_one_space_after_list_bullet = true -ij_markdown_force_one_space_between_words = true -ij_markdown_format_tables = true -ij_markdown_insert_quote_arrows_on_wrap = true -ij_markdown_keep_indents_on_empty_lines = false -ij_markdown_keep_line_breaks_inside_text_blocks = true -ij_markdown_max_lines_around_block_elements = 1 -ij_markdown_max_lines_around_header = 1 -ij_markdown_max_lines_between_paragraphs = 1 -ij_markdown_min_lines_around_block_elements = 1 -ij_markdown_min_lines_around_header = 1 -ij_markdown_min_lines_between_paragraphs = 1 -ij_markdown_wrap_text_if_long = true -ij_markdown_wrap_text_inside_blockquotes = true diff --git a/package.json b/package.json index 4beef0b..b7f9320 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,html,css,scss}\"" }, "dependencies": { "@emotion/cache": "^11.11.0", @@ -35,6 +36,8 @@ }, "devDependencies": { "eslint": "^8", - "eslint-config-next": "14.1.0" + "eslint-config-next": "14.1.0", + "eslint-config-prettier": "^9.1.0", + "prettier": "^3.3.2" } } diff --git a/src/app/(withAuth)/dashboard/page.js b/src/app/(withAuth)/dashboard/page.js index 915b3de..c06d81d 100644 --- a/src/app/(withAuth)/dashboard/page.js +++ b/src/app/(withAuth)/dashboard/page.js @@ -1,29 +1,33 @@ -'use client' -import { Button } from "@mui/material" -import axios from "axios" +"use client"; +import { Button } from "@mui/material"; +import axios from "axios"; const Page = () => { const handler = () => { try { - axios.get('https://rms.witel.ir/test_login?username=witel', { withCredentials: true }) + axios.get("https://rms.witel.ir/test_login?username=witel", { + withCredentials: true, + }); } catch (error) { console.log(error); } - } + }; const handler2 = () => { try { - const res = axios.get('https://rms.witel.ir/webapi/user/get-permission', { withCredentials: true }) + const res = axios.get("https://rms.witel.ir/webapi/user/get-permission", { + withCredentials: true, + }); console.log(res); } catch (error) { console.log(error); } - } + }; return ( <> - ) -} + ); +}; -export default Page \ No newline at end of file +export default Page; diff --git a/src/app/(withAuth)/dashboard/template.js b/src/app/(withAuth)/dashboard/template.js index eb7d2ef..28b4ea0 100644 --- a/src/app/(withAuth)/dashboard/template.js +++ b/src/app/(withAuth)/dashboard/template.js @@ -1,19 +1,17 @@ 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 "react-toastify/dist/ReactToastify.css"; const Template = ({ children }) => { return ( - - {children} - + {children} - ) -} + ); +}; -export default Template \ No newline at end of file +export default Template; diff --git a/src/app/(withAuth)/layout.js b/src/app/(withAuth)/layout.js index 5a5cca8..400bbc9 100644 --- a/src/app/(withAuth)/layout.js +++ b/src/app/(withAuth)/layout.js @@ -1,14 +1,12 @@ -import WithAuthMiddleware from "@/core/middlewares/withAuth" -import { AuthProvider } from "@/lib/contexts/auth" +import WithAuthMiddleware from "@/core/middlewares/withAuth"; +import { AuthProvider } from "@/lib/contexts/auth"; const Layout = ({ children }) => { return ( - - {children} - + {children} - ) -} + ); +}; -export default Layout \ No newline at end of file +export default Layout; diff --git a/src/app/default.js b/src/app/default.js index 73d13c1..d157a71 100644 --- a/src/app/default.js +++ b/src/app/default.js @@ -1,3 +1,3 @@ export default function Default() { - return null -} \ No newline at end of file + return null; +} diff --git a/src/app/layout.js b/src/app/layout.js index 1d4819e..64aea89 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -1,17 +1,15 @@ import { TableSettingProvider } from "@/lib/contexts/tableSetting"; export const metadata = { - title: 'سامانه جامع راهداری', -} + title: "سامانه جامع راهداری", +}; export default function RootLayout({ children }) { return ( - - - - {children} - + + + {children} - ) + ); } diff --git a/src/app/lfwd/page.js b/src/app/lfwd/page.js index 55eca31..b3456a3 100644 --- a/src/app/lfwd/page.js +++ b/src/app/lfwd/page.js @@ -1,51 +1,57 @@ -'use client' +"use client"; -import { GET_LOGIN_ROUTE } from "@/core/utils/routes" -import useRequest from "@/lib/hooks/useRequest" -import { Button, Stack, Typography, Zoom } from "@mui/material" -import Link from "next/link" -import { useEffect, useState } from "react" +import { GET_LOGIN_ROUTE } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { Button, Stack, Typography, Zoom } from "@mui/material"; +import Link from "next/link"; +import { useEffect, useState } from "react"; -const Page = () => { - const [login, setLogin] = useState(0) - const request = useRequest() +const Page = ({ searchParams }) => { + const { username } = searchParams; + const [login, setLogin] = useState(0); + const request = useRequest(); useEffect(() => { const login = async () => { try { - const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) - setLogin(1) + await request(`${GET_LOGIN_ROUTE}?username=${username}`); + setLogin(1); } catch (error) { - setLogin(2) + setLogin(2); } - } + }; - login() - }, []) + login(); + }, []); const retry = async () => { - setLogin(0) + setLogin(0); try { - const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) - setLogin(1) + await request(`${GET_LOGIN_ROUTE}?username=${username}`); + setLogin(1); } catch (error) { - setLogin(2) + setLogin(2); } - } - + }; return ( - + - {login === 0 ? 'درحال دریافت مجوز برای ارتباط با سرور...' : login === 1 ? 'ارتباط با سرور برقرار شد.' : 'ارتباط با سرور برقرار نشد. مشکلی وجود دارد.'} + {login === 0 + ? "درحال دریافت مجوز برای ارتباط با سرور..." + : login === 1 + ? "ارتباط با سرور برقرار شد." + : "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."} - + - ) -} -export default Page \ No newline at end of file + ); +}; +export default Page; diff --git a/src/app/page.js b/src/app/page.js index 3fab3b7..2997c35 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,8 +1,8 @@ -import { redirect } from "next/navigation" +import { redirect } from "next/navigation"; function Page() { - redirect('/dashboard', 'replace') - return null + redirect("/dashboard", "replace"); + return null; } -export default Page \ No newline at end of file +export default Page; diff --git a/src/app/template.js b/src/app/template.js index 71830af..3ffc656 100644 --- a/src/app/template.js +++ b/src/app/template.js @@ -15,7 +15,7 @@ const Template = ({ children }) => { - ) -} + ); +}; -export default Template \ No newline at end of file +export default Template; diff --git a/src/components/home/Toolbar.jsx b/src/components/home/Toolbar.jsx index 1270b92..82f2646 100644 --- a/src/components/home/Toolbar.jsx +++ b/src/components/home/Toolbar.jsx @@ -1,22 +1,10 @@ -import {Button} from "@mui/material"; +import { Button } from "@mui/material"; -const Toolbar = ({columns}) => { +const Toolbar = ({ columns }) => { return ( <> - ) -} -export default Toolbar - - - - - - - - - - - - + ); +}; +export default Toolbar; diff --git a/src/components/home/index.jsx b/src/components/home/index.jsx index 090a572..7344232 100644 --- a/src/components/home/index.jsx +++ b/src/components/home/index.jsx @@ -1,149 +1,128 @@ -'use client' +"use client"; import DataTable from "@/core/components/DataTable"; -import {useMemo} from "react"; +import { useMemo } from "react"; function HomeComponent() { const columns = useMemo( () => [ { - accessorKey: 'fullname', - header: 'نام کامل', + accessorKey: "fullname", + header: "نام کامل", id: "fullname", columns: [ { - accessorKey: 'name.firstName', - header: 'نام', + accessorKey: "name.firstName", + header: "نام", id: "firstName", enableColumnFilter: true, datatype: "text", filterFn: "contains", enableClickToCopy: true, - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], + columnFilterModeOptions: ["equals", "notEquals", "contains"], }, { - accessorKey: 'name.lastName', - header: 'نام خانوادگی', + accessorKey: "name.lastName", + header: "نام خانوادگی", id: "lastName", enableColumnFilter: true, datatype: "text", filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], + columnFilterModeOptions: ["equals", "notEquals", "contains"], }, ], }, { - accessorKey: 'address', - header: 'آدرس', + accessorKey: "address", + header: "آدرس", id: "address", enableColumnFilter: true, datatype: "text", filterFn: "notEquals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], + columnFilterModeOptions: ["equals", "notEquals", "contains"], }, { - accessorKey: 'city', - header: 'شهر', + accessorKey: "city", + header: "شهر", id: "city", enableColumnFilter: true, datatype: "text", filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains", - "lessThan", - "greaterThan", - "fuzzy" - ], + columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "fuzzy"], }, { - accessorKey: 'state', - header: 'وضعیت', + accessorKey: "state", + header: "وضعیت", id: "state", enableColumnFilter: true, datatype: "text", filterFn: "contains", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains" - ], + columnFilterModeOptions: ["equals", "notEquals", "contains"], }, { - accessorKey: 'price', - header: 'محدوده', + accessorKey: "price", + header: "محدوده", id: "price", enableColumnFilter: true, datatype: "numeric", filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - ], + columnFilterModeOptions: ["equals", "notEquals"], }, { - accessorKey: 'created_at', - header: 'تاریخ ساخت', + accessorKey: "created_at", + header: "تاریخ ساخت", id: "created_at", enableColumnFilter: true, datatype: "date", filterFn: "between", }, { - accessorKey: 'updated_at', - header: 'تاریخ بروزرسانی', + accessorKey: "updated_at", + header: "تاریخ بروزرسانی", id: "updated_at", enableColumnFilter: true, datatype: "date", filterFn: "equals", }, { - accessorKey: 'company', - header: 'نام شرکت', + accessorKey: "company", + header: "نام شرکت", id: "company", enableColumnFilter: true, datatype: "numeric", filterFn: "equals", columnSelectOption: [ - {value: 1, label: "وایتل"}, - {value: 2, label: "اسنپ"}, - {value: 3, label: "تپسی"} + { value: 1, label: "وایتل" }, + { value: 2, label: "اسنپ" }, + { value: 3, label: "تپسی" }, ], }, { - accessorKey: 'area', - header: 'منطقه', + accessorKey: "area", + header: "منطقه", id: "area", enableColumnFilter: true, datatype: "array", filterFn: "equals", columnSelectOption: [ - {value: 1, label: "وایتل"}, - {value: 2, label: "اسنپ"}, - {value: 3, label: "تپسی"} + { value: 1, label: "وایتل" }, + { value: 2, label: "اسنپ" }, + { value: 3, label: "تپسی" }, ], }, ], - [], + [] ); return ( <> - + - ); } diff --git a/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx index 501dadc..62ec234 100644 --- a/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx +++ b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx @@ -3,38 +3,25 @@ import { Stack, Typography } from "@mui/material"; import Image from "next/image"; const HeaderBottom = () => { - return ( - theme.palette.primary2.main, - }} - spacing={4} - alignItems={"center"} - direction={"row"} - > - - - theme.palette.primary2.contrastText }} + return ( + theme.palette.primary2.main, + }} + spacing={4} + alignItems={"center"} + direction={"row"} > - سامانه جامع راهداری - - theme.palette.primary2.contrastText }} - > - rms.rmto.ir - - - - ); + + + theme.palette.primary2.contrastText }}> + سامانه جامع راهداری + + theme.palette.primary2.contrastText }}>rms.rmto.ir + + + ); }; export default HeaderBottom; diff --git a/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx b/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx index 27cd26a..6899881 100644 --- a/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx +++ b/src/components/layouts/dashboard/headerWithLogo/HaederTop/index.jsx @@ -2,16 +2,10 @@ import { Stack } from "@mui/material"; import Image from "next/image"; const HeaderTop = () => { - return ( - - - - ); + return ( + + + + ); }; export default HeaderTop; diff --git a/src/components/layouts/dashboard/headerWithLogo/index.jsx b/src/components/layouts/dashboard/headerWithLogo/index.jsx index f628e49..16ef4b2 100644 --- a/src/components/layouts/dashboard/headerWithLogo/index.jsx +++ b/src/components/layouts/dashboard/headerWithLogo/index.jsx @@ -3,11 +3,11 @@ import HeaderTop from "./HaederTop"; import HeaderBottom from "./HaederBottom"; const HeaderWithLogo = () => { - return ( - - - - - ); + return ( + + + + + ); }; export default HeaderWithLogo; diff --git a/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx index 01fd681..c705242 100644 --- a/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx +++ b/src/components/layouts/dashboard/headerWithSidebar/HeaderMenu/index.jsx @@ -1,4 +1,4 @@ const HeaderMenu = () => { - return <>منو; + return <>منو; }; export default HeaderMenu; diff --git a/src/components/layouts/dashboard/headerWithSidebar/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/index.jsx index be0a284..c8febb6 100644 --- a/src/components/layouts/dashboard/headerWithSidebar/index.jsx +++ b/src/components/layouts/dashboard/headerWithSidebar/index.jsx @@ -9,108 +9,102 @@ import HeaderMenu from "./HeaderMenu"; const drawerWidth = 300; -const Main = styled(Paper, { shouldForwardProp: (prop) => prop !== "open" })( - ({ theme, open }) => ({ +const Main = styled(Paper, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({ flexGrow: 1, transition: theme.transitions.create("margin", { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, }), marginLeft: `-${drawerWidth}px`, ...(open && { - transition: theme.transitions.create("margin", { - easing: theme.transitions.easing.easeOut, - duration: theme.transitions.duration.enteringScreen, - }), - marginLeft: 0, + transition: theme.transitions.create("margin", { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + marginLeft: 0, }), - }) -); +})); const AppBar = styled(MuiAppBar, { - shouldForwardProp: (prop) => prop !== "open", + shouldForwardProp: (prop) => prop !== "open", })(({ theme, open }) => ({ - transition: theme.transitions.create(["margin", "width"], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - ...(open && { - width: `calc(100% - ${drawerWidth}px)`, - marginLeft: `${drawerWidth}px`, transition: theme.transitions.create(["margin", "width"], { - easing: theme.transitions.easing.easeOut, - duration: theme.transitions.duration.enteringScreen, + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + ...(open && { + width: `calc(100% - ${drawerWidth}px)`, + marginLeft: `${drawerWidth}px`, + transition: theme.transitions.create(["margin", "width"], { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), }), - }), })); const DrawerHeader = styled("div")(({ theme }) => ({ - display: "flex", - alignItems: "center", - padding: theme.spacing(0, 1), - ...theme.mixins.toolbar, - justifyContent: "flex-end", + display: "flex", + alignItems: "center", + padding: theme.spacing(0, 1), + ...theme.mixins.toolbar, + justifyContent: "flex-end", })); const HeaderWithSidebar = ({ children }) => { - const [open, setOpen] = useState(true); + const [open, setOpen] = useState(true); - const handleDrawerOpen = () => { - setOpen(true); - }; - const handleDrawerClose = () => { - setOpen(false); - }; - return ( - - - - - - - - - - - - - - - - - - - -
- - {children} -
-
- ); + const handleDrawerOpen = () => { + setOpen(true); + }; + const handleDrawerClose = () => { + setOpen(false); + }; + return ( + + + + + + + + + + + + + + + + + + + +
+ + {children} +
+
+ ); }; export default HeaderWithSidebar; diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index ec33f55..db8aebd 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -1,91 +1,96 @@ import DataTable_Paper from "./table/Paper"; -import {useMaterialReactTable} from "material-react-table"; -import {FA_DATATABLE_LOCALIZATION} from "./localization/fa/datatable"; +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 { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects"; import Toolbar from "@/components/home/Toolbar"; import useDataTable from "@/lib/hooks/useDataTable"; -import {useMemo, useState} from "react"; +import { useMemo, useState } from "react"; const data = [ { name: { - firstName: 'امین', - lastName: 'قاسمپور', + firstName: "امین", + lastName: "قاسمپور", }, - address: 'فلان جا', - city: 'تهران', - state: 'بررسی شده', - price: '20', - updated_at: '2024/05/02', - company: 'همراه اول', - area: 'منطقه 5', + address: "فلان جا", + city: "تهران", + state: "بررسی شده", + price: "20", + updated_at: "2024/05/02", + company: "همراه اول", + area: "منطقه 5", }, { name: { - firstName: 'امیر حسین', - lastName: 'محمودی', + firstName: "امیر حسین", + lastName: "محمودی", }, - address: 'فلان جا', - city: 'تهران', - state: 'تکمیل شده', - price: '27', - updated_at: '2024/05/02', - company: 'وایتل', - area: 'منطقه 27', + address: "فلان جا", + city: "تهران", + state: "تکمیل شده", + price: "27", + updated_at: "2024/05/02", + company: "وایتل", + area: "منطقه 27", }, { name: { - firstName: 'یاسمن', - lastName: 'علی اکبری', + firstName: "یاسمن", + lastName: "علی اکبری", }, - address: 'فلان جا', - city: 'شیراز', - state: 'بررسی شده', - price: '32', - updated_at: '2024/05/02', - company: 'ایرانسل', - area: 'منطقه 23', + address: "فلان جا", + city: "شیراز", + state: "بررسی شده", + price: "32", + updated_at: "2024/05/02", + company: "ایرانسل", + area: "منطقه 23", }, { name: { - firstName: 'حمیدرضا', - lastName: 'رنجبرپور', + firstName: "حمیدرضا", + lastName: "رنجبرپور", }, - address: 'فلان جا', - city: 'اصفهان', - state: 'بررسی شده', - price: '45', - updated_at: '2024/05/02', - company: 'ایرانول', - area: 'منطقه 21', + address: "فلان جا", + city: "اصفهان", + state: "بررسی شده", + price: "45", + updated_at: "2024/05/02", + company: "ایرانول", + area: "منطقه 21", }, { name: { - firstName: 'محمد', - lastName: 'جلالی', + firstName: "محمد", + lastName: "جلالی", }, - address: 'فلان جا', - city: 'رشت', - state: 'درحال بررسی', - price: '8', - updated_at: '2024/05/02', - company: 'فیلیمو', - area: 'منطقه 8', + address: "فلان جا", + city: "رشت", + state: "درحال بررسی", + price: "8", + updated_at: "2024/05/02", + company: "فیلیمو", + area: "منطقه 8", }, ]; const DataTable_Main = (props) => { - const {filterData} = useDataTable(); - const {table_url, user_id, page_name, table_name, columns, initialStateProps} = props - const flatColumns = flattenArrayOfObjects(columns, 'columns') - const {settingStore, hideAction, sortAction} = useTableSetting(); - const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 10}); + const { filterData } = useDataTable(); + const { table_url, user_id, page_name, table_name, columns, initialStateProps } = props; + const flatColumns = flattenArrayOfObjects(columns, "columns"); + const { settingStore, hideAction, sortAction } = useTableSetting(); + const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); const filters = Object.keys(filterData) - .map(key => { + .map((key) => { const value = filterData[key].value; - if (value !== "" && - !(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) { + if ( + value !== "" && + !( + Array.isArray(value) && + (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")) + ) + ) { return filterData[key]; } }) @@ -98,7 +103,7 @@ const DataTable_Main = (props) => { 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'] ?? [])); + params.set("sorting", JSON.stringify(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ?? [])); return `${table_url}?${params}`; }, [table_url, finalFilters, pagination, columns]); @@ -107,52 +112,52 @@ const DataTable_Main = (props) => { hideAction(user_id, page_name, table_name, settingValue, flatColumns); }; const onSortingChange = (event) => { - const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || []); + const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []); sortAction(user_id, page_name, table_name, settingValue, flatColumns); - } + }; const table = useMaterialReactTable({ localization: FA_DATATABLE_LOCALIZATION, columns, data: data, // manualSorting: true, - renderTopToolbarCustomActions: ({table}) => (<> - - ), + renderTopToolbarCustomActions: ({ table }) => ( + <> + + + ), initialState: { - density: 'compact', - columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], - sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], - ...initialStateProps + density: "compact", + columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"], + sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [], + ...initialStateProps, }, state: { - columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], - sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], - pagination + columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"], + sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [], + pagination, }, muiTableHeadProps: { sx: { borderTop: "1px solid #e1e1e1", borderBottom: "2px solid #e1e1e1", - } + }, }, muiTableHeadCellProps: { sx: { color: "primary.main", borderLeft: "1px solid #e1e1e1", "&:first-of-type": { - borderLeft: "unset" - } + borderLeft: "unset", + }, }, }, muiTableBodyCellProps: { sx: { borderLeft: "1px solid #e1e1e1", "&:first-of-type": { - borderLeft: "unset" - } + borderLeft: "unset", + }, }, }, manualFiltering: true, @@ -161,14 +166,18 @@ const DataTable_Main = (props) => { manualSorting: true, onColumnVisibilityChange: onColumnVisibilityChange, onSortingChange: onSortingChange, - ...props - }) + ...props, + }); - return ; + return ( + + ); }; export default DataTable_Main; - - - diff --git a/src/core/components/DataTable/body/TableBody.js b/src/core/components/DataTable/body/TableBody.js index e1620a3..b0750be 100644 --- a/src/core/components/DataTable/body/TableBody.js +++ b/src/core/components/DataTable/body/TableBody.js @@ -4,11 +4,7 @@ import { useMRT_RowVirtualizer, useMRT_Rows } from "material-react-table"; import { memo, useMemo } from "react"; import DataTable_TableBodyRow, { Memo_DataTable_TableBodyRow } from "./TableBodyRow"; -const DataTable_TableBody = ({ - columnVirtualizer, - table, - ...rest -}) => { +const DataTable_TableBody = ({ columnVirtualizer, table, ...rest }) => { const { getBottomRows, getIsSomeRowsPinned, @@ -35,12 +31,8 @@ const DataTable_TableBody = ({ ...rest, }; - const tableHeadHeight = - ((enableStickyHeader || isFullScreen) && - tableHeadRef.current?.clientHeight) || - 0; - const tableFooterHeight = - (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0; + const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0; + const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0; const pinnedRowIds = useMemo(() => { if (!rowPinning.bottom?.length && !rowPinning.top?.length) return []; @@ -63,67 +55,63 @@ const DataTable_TableBody = ({ return ( <> - {!rowPinningDisplayMode?.includes('sticky') && - getIsSomeRowsPinned('top') && ( - ({ - display: layoutMode?.startsWith('grid') ? 'grid' : undefined, - position: 'sticky', - top: tableHeadHeight - 1, - zIndex: 1, - ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)), - })} - > - {getTopRows().map((row, staticRowIndex) => { - const props = { - ...commonRowProps, - row, - staticRowIndex, - }; - return memoMode === 'rows' ? ( - - ) : ( - - ); - })} - - )} + {!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("top") && ( + ({ + display: layoutMode?.startsWith("grid") ? "grid" : undefined, + position: "sticky", + top: tableHeadHeight - 1, + zIndex: 1, + ...parseFromValuesOrFunc(tableBodyProps?.sx, theme), + })} + > + {getTopRows().map((row, staticRowIndex) => { + const props = { + ...commonRowProps, + row, + staticRowIndex, + }; + return memoMode === "rows" ? ( + + ) : ( + + ); + })} + + )} ({ - display: layoutMode?.startsWith('grid') ? 'grid' : undefined, - height: rowVirtualizer - ? `${rowVirtualizer.getTotalSize()}px` - : undefined, - minHeight: !rows.length ? '100px' : undefined, - position: 'relative', - ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)), + display: layoutMode?.startsWith("grid") ? "grid" : undefined, + height: rowVirtualizer ? `${rowVirtualizer.getTotalSize()}px` : undefined, + minHeight: !rows.length ? "100px" : undefined, + position: "relative", + ...parseFromValuesOrFunc(tableBodyProps?.sx, theme), })} > {tableBodyProps?.children ?? (!rows.length ? ( {renderEmptyRowsFallback?.({ table }) ?? ( {globalFilter || columnFilters.length @@ -155,12 +143,10 @@ const DataTable_TableBody = ({ row, rowVirtualizer, staticRowIndex, - virtualRow: rowVirtualizer - ? (rowOrVirtualRow) - : undefined, + virtualRow: rowVirtualizer ? rowOrVirtualRow : undefined, }; const key = `${row.id}-${row.index}`; - return memoMode === 'rows' ? ( + return memoMode === "rows" ? ( ) : ( @@ -169,39 +155,37 @@ const DataTable_TableBody = ({ ))} - {!rowPinningDisplayMode?.includes('sticky') && - getIsSomeRowsPinned('bottom') && ( - ({ - bottom: tableFooterHeight - 1, - display: layoutMode?.startsWith('grid') ? 'grid' : undefined, - position: 'sticky', - zIndex: 1, - ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)), - })} - > - {getBottomRows().map((row, staticRowIndex) => { - const props = { - ...commonRowProps, - row, - staticRowIndex, - }; - return memoMode === 'rows' ? ( - - ) : ( - - ); - })} - - )} + {!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("bottom") && ( + ({ + bottom: tableFooterHeight - 1, + display: layoutMode?.startsWith("grid") ? "grid" : undefined, + position: "sticky", + zIndex: 1, + ...parseFromValuesOrFunc(tableBodyProps?.sx, theme), + })} + > + {getBottomRows().map((row, staticRowIndex) => { + const props = { + ...commonRowProps, + row, + staticRowIndex, + }; + return memoMode === "rows" ? ( + + ) : ( + + ); + })} + + )} ); - -} -export default DataTable_TableBody +}; +export default DataTable_TableBody; export const Memo_DataTable_TableBody = memo( DataTable_TableBody, - (prev, next) => prev.table.options.data === next.table.options.data, -); \ No newline at end of file + (prev, next) => prev.table.options.data === next.table.options.data +); diff --git a/src/core/components/DataTable/body/TableBodyCell.js b/src/core/components/DataTable/body/TableBodyCell.js index 9ef022d..4c1804b 100644 --- a/src/core/components/DataTable/body/TableBodyCell.js +++ b/src/core/components/DataTable/body/TableBodyCell.js @@ -7,15 +7,7 @@ const { useState, useEffect, useMemo, memo } = require("react"); const { default: DataTable_CopyButton } = require("../buttons/CopyButton"); const { default: DataTable_TableBodyCellValue } = require("./TableBodyCellValue"); -const DataTable_TableBodyCell = ({ - cell, - numRows, - rowRef, - staticColumnIndex, - staticRowIndex, - table, - ...rest -}) => { +const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, staticRowIndex, table, ...rest }) => { const theme = useTheme(); const { getState, @@ -73,9 +65,7 @@ const DataTable_TableBodyCell = ({ if ((!isLoading && !showSkeletons) || skeletonWidth !== 100) return; const size = column.getSize(); setSkeletonWidth( - columnDefType === 'display' - ? size / 2 - : Math.round(Math.random() * (size - size / 3) + size / 3), + columnDefType === "display" ? size / 2 : Math.round(Math.random() * (size - size / 3) + size / 3) ); }, [isLoading, showSkeletons]); @@ -88,77 +78,55 @@ const DataTable_TableBodyCell = ({ const isLastColumn = column.getIsLastColumn(); const isLastRow = numRows && staticRowIndex === numRows - 1; const isResizingColumn = columnSizingInfo.isResizingColumn === column.id; - const showResizeBorder = - isResizingColumn && columnResizeMode === 'onChange'; + const showResizeBorder = isResizingColumn && columnResizeMode === "onChange"; const borderStyle = showResizeBorder ? `2px solid ${draggingBorderColor} !important` : isDraggingColumn || isDraggingRow - ? `1px dashed ${theme.palette.grey[500]} !important` - : isHoveredColumn || isHoveredRow || isResizingColumn - ? `2px dashed ${draggingBorderColor} !important` - : undefined; + ? `1px dashed ${theme.palette.grey[500]} !important` + : isHoveredColumn || isHoveredRow || isResizingColumn + ? `2px dashed ${draggingBorderColor} !important` + : undefined; if (showResizeBorder) { - return columnResizeDirection === 'ltr' - ? { borderRight: borderStyle } - : { borderLeft: borderStyle }; + return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle }; } return borderStyle ? { - borderBottom: - isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) - ? borderStyle - : undefined, - borderLeft: - isDraggingColumn || - isHoveredColumn || - ((isDraggingRow || isHoveredRow) && isFirstColumn) - ? borderStyle - : undefined, - borderRight: - isDraggingColumn || - isHoveredColumn || - ((isDraggingRow || isHoveredRow) && isLastColumn) - ? borderStyle - : undefined, - borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined, - } + borderBottom: + isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) ? borderStyle : undefined, + borderLeft: + isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isFirstColumn) + ? borderStyle + : undefined, + borderRight: + isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isLastColumn) + ? borderStyle + : undefined, + borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined, + } : undefined; - }, [ - columnSizingInfo.isResizingColumn, - draggingColumn, - draggingRow, - hoveredColumn, - hoveredRow, - staticRowIndex, - ]); + }, [columnSizingInfo.isResizingColumn, draggingColumn, draggingRow, hoveredColumn, hoveredRow, staticRowIndex]); - const isColumnPinned = - enableColumnPinning && - columnDef.columnDefType !== 'group' && - column.getIsPinned(); + const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned(); const isEditable = isCellEditable({ cell, table }); const isEditing = isEditable && - !['custom', 'modal'].includes(editDisplayMode) && - (editDisplayMode === 'table' || - editingRow?.id === row.id || - editingCell?.id === cell.id) && + !["custom", "modal"].includes(editDisplayMode) && + (editDisplayMode === "table" || editingRow?.id === row.id || editingCell?.id === cell.id) && !row.getIsGrouped(); - const isCreating = - isEditable && createDisplayMode === 'row' && creatingRow?.id === row.id; + const isCreating = isEditable && createDisplayMode === "row" && creatingRow?.id === row.id; const showClickToCopyButton = (parseFromValuesOrFunc(enableClickToCopy, cell) === true || parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === true) && - !['context-menu', false].includes( + !["context-menu", false].includes( // @ts-ignore - parseFromValuesOrFunc(columnDef.enableClickToCopy, cell), + parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) ); const isRightClickable = parseFromValuesOrFunc(enableCellActions, cell); @@ -175,13 +143,11 @@ const DataTable_TableBodyCell = ({ const handleDragEnter = (e) => { tableCellProps?.onDragEnter?.(e); - if (enableGrouping && hoveredColumn?.id === 'drop-zone') { + if (enableGrouping && hoveredColumn?.id === "drop-zone") { setHoveredColumn(null); } if (enableColumnOrdering && draggingColumn) { - setHoveredColumn( - columnDef.enableColumnOrdering !== false ? column : null, - ); + setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null); } }; @@ -210,43 +176,39 @@ const DataTable_TableBodyCell = ({ onDragEnter={handleDragEnter} onDragOver={handleDragOver} sx={(theme) => ({ - '&:hover': { + "&:hover": { outline: actionCell?.id === cell.id || - (editDisplayMode === 'cell' && isEditable) || - (editDisplayMode === 'table' && (isCreating || isEditing)) + (editDisplayMode === "cell" && isEditable) || + (editDisplayMode === "table" && (isCreating || isEditing)) ? `1px solid ${theme.palette.grey[500]}` : undefined, - textOverflow: 'clip', + textOverflow: "clip", }, - alignItems: layoutMode?.startsWith('grid') ? 'center' : undefined, + alignItems: layoutMode?.startsWith("grid") ? "center" : undefined, cursor: isRightClickable - ? 'context-menu' - : isEditable && editDisplayMode === 'cell' - ? 'pointer' - : 'inherit', - outline: - actionCell?.id === cell.id - ? `1px solid ${theme.palette.grey[500]}` - : undefined, - outlineOffset: '-1px', - overflow: 'hidden', + ? "context-menu" + : isEditable && editDisplayMode === "cell" + ? "pointer" + : "inherit", + outline: actionCell?.id === cell.id ? `1px solid ${theme.palette.grey[500]}` : undefined, + outlineOffset: "-1px", + overflow: "hidden", p: - density === 'compact' - ? columnDefType === 'display' - ? '0 0.5rem' - : '0.5rem' - : density === 'comfortable' - ? columnDefType === 'display' - ? '0.5rem 0.75rem' - : '1rem' - : columnDefType === 'display' - ? '1rem 1.25rem' - : '1.5rem', + density === "compact" + ? columnDefType === "display" + ? "0 0.5rem" + : "0.5rem" + : density === "comfortable" + ? columnDefType === "display" + ? "0.5rem 0.75rem" + : "1rem" + : columnDefType === "display" + ? "1rem 1.25rem" + : "1.5rem", - textOverflow: columnDefType !== 'display' ? 'ellipsis' : undefined, - whiteSpace: - row.getIsPinned() || density === 'compact' ? 'nowrap' : 'normal', + textOverflow: columnDefType !== "display" ? "ellipsis" : undefined, + whiteSpace: row.getIsPinned() || density === "compact" ? "nowrap" : "normal", ...getCommonMRTCellStyles({ column, table, @@ -261,17 +223,10 @@ const DataTable_TableBodyCell = ({ {cell.getIsPlaceholder() ? ( columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null ) : showSkeletons !== false && (isLoading || showSkeletons) ? ( - - ) : columnDefType === 'display' && - (['mrt-row-expand', 'mrt-row-numbers', 'mrt-row-select'].includes( - column.id, - ) || - !row.getIsGrouped()) ? ( + + ) : columnDefType === "display" && + (["mrt-row-expand", "mrt-row-numbers", "mrt-row-select"].includes(column.id) || + !row.getIsGrouped()) ? ( columnDef.Cell?.({ cell, column, @@ -289,18 +244,12 @@ const DataTable_TableBodyCell = ({ ) : ( )} - {cell.getIsGrouped() && !columnDef.GroupedCell && ( - <> ({row.subRows?.length}) - )} + {cell.getIsGrouped() && !columnDef.GroupedCell && <> ({row.subRows?.length})} )} ); - -} +}; export default DataTable_TableBodyCell; -export const Memo_DataTable_TableBodyCell = memo( - DataTable_TableBodyCell, - (prev, next) => next.cell === prev.cell, -); \ No newline at end of file +export const Memo_DataTable_TableBodyCell = memo(DataTable_TableBodyCell, (prev, next) => next.cell === prev.cell); diff --git a/src/core/components/DataTable/body/TableBodyCellValue.js b/src/core/components/DataTable/body/TableBodyCellValue.js index 6d4f05f..aea105f 100644 --- a/src/core/components/DataTable/body/TableBodyCellValue.js +++ b/src/core/components/DataTable/body/TableBodyCellValue.js @@ -2,111 +2,102 @@ import { Box } from "@mui/material"; const allowedTypes = ["string", "number"]; -const DataTable_TableBodyCellValue = ({ - cell, - rowRef, - staticColumnIndex, - staticRowIndex, - table, -}) => { - const { - getState, - options: { - enableFilterMatchHighlighting, - mrtTheme: { matchHighlightColor }, - }, - } = table; - const { column, row } = cell; - const { columnDef } = column; - const { globalFilter, globalFilterFn } = getState(); - const filterValue = column.getFilterValue(); +const DataTable_TableBodyCellValue = ({ cell, rowRef, staticColumnIndex, staticRowIndex, table }) => { + const { + getState, + options: { + enableFilterMatchHighlighting, + mrtTheme: { matchHighlightColor }, + }, + } = table; + const { column, row } = cell; + const { columnDef } = column; + const { globalFilter, globalFilterFn } = getState(); + const filterValue = column.getFilterValue(); - let renderedCellValue = - cell.getIsAggregated() && columnDef.AggregatedCell - ? columnDef.AggregatedCell({ - cell, - column, - row, - table, - }) - : row.getIsGrouped() && !cell.getIsGrouped() - ? null - : cell.getIsGrouped() && columnDef.GroupedCell - ? columnDef.GroupedCell({ + let renderedCellValue = + cell.getIsAggregated() && columnDef.AggregatedCell + ? columnDef.AggregatedCell({ + cell, + column, + row, + table, + }) + : row.getIsGrouped() && !cell.getIsGrouped() + ? null + : cell.getIsGrouped() && columnDef.GroupedCell + ? columnDef.GroupedCell({ + cell, + column, + row, + table, + }) + : undefined; + + const isGroupedValue = renderedCellValue !== undefined; + + if (!isGroupedValue) { + renderedCellValue = cell.renderValue(); + } + + if ( + enableFilterMatchHighlighting && + columnDef.enableFilterMatchHighlighting !== false && + String(renderedCellValue) && + allowedTypes.includes(typeof renderedCellValue) && + ((filterValue && + allowedTypes.includes(typeof filterValue) && + ["autocomplete", "text"].includes(columnDef.filterVariant)) || + (globalFilter && allowedTypes.includes(typeof globalFilter) && column.getCanGlobalFilter())) + ) { + const chunks = highlightWords?.({ + matchExactly: (filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy", + query: (filterValue ?? globalFilter ?? "").toString(), + text: renderedCellValue?.toString(), + }); + if (chunks?.length > 1 || chunks?.[0]?.match) { + renderedCellValue = ( + + {chunks?.map(({ key, match, text }) => ( + + )) ?? renderedCellValue} + + ); + } + } + + if (columnDef.Cell && !isGroupedValue) { + renderedCellValue = columnDef.Cell({ cell, column, + renderedCellValue, row, + rowRef, + staticColumnIndex, + staticRowIndex, table, - }) - : undefined; - - const isGroupedValue = renderedCellValue !== undefined; - - if (!isGroupedValue) { - renderedCellValue = cell.renderValue(); - } - - if ( - enableFilterMatchHighlighting && - columnDef.enableFilterMatchHighlighting !== false && - String(renderedCellValue) && - allowedTypes.includes(typeof renderedCellValue) && - ((filterValue && - allowedTypes.includes(typeof filterValue) && - ["autocomplete", "text"].includes(columnDef.filterVariant)) || - (globalFilter && - allowedTypes.includes(typeof globalFilter) && - column.getCanGlobalFilter())) - ) { - const chunks = highlightWords?.({ - matchExactly: - (filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy", - query: (filterValue ?? globalFilter ?? "").toString(), - text: renderedCellValue?.toString(), - }); - if (chunks?.length > 1 || chunks?.[0]?.match) { - renderedCellValue = ( - - {chunks?.map(({ key, match, text }) => ( - - )) ?? renderedCellValue} - - ); + }); } - } - if (columnDef.Cell && !isGroupedValue) { - renderedCellValue = columnDef.Cell({ - cell, - column, - renderedCellValue, - row, - rowRef, - staticColumnIndex, - staticRowIndex, - table, - }); - } - - return renderedCellValue; + return renderedCellValue; }; export default DataTable_TableBodyCellValue; diff --git a/src/core/components/DataTable/body/TableBodyRow.js b/src/core/components/DataTable/body/TableBodyRow.js index e500eb0..a041d66 100644 --- a/src/core/components/DataTable/body/TableBodyRow.js +++ b/src/core/components/DataTable/body/TableBodyRow.js @@ -28,11 +28,7 @@ const DataTable_TableBodyRow = ({ enableStickyHeader, layoutMode, memoMode, - mrtTheme: { - baseBackgroundColor, - pinnedRowBackgroundColor, - selectedRowBackgroundColor, - }, + mrtTheme: { baseBackgroundColor, pinnedRowBackgroundColor, selectedRowBackgroundColor }, muiTableBodyRowProps, renderDetailPanel, rowPinningDisplayMode, @@ -40,21 +36,12 @@ const DataTable_TableBodyRow = ({ refs: { tableFooterRef, tableHeadRef }, setHoveredRow, } = table; - const { - density, - draggingColumn, - draggingRow, - editingCell, - editingRow, - hoveredRow, - isFullScreen, - rowPinning, - } = getState(); + const { density, draggingColumn, draggingRow, editingCell, editingRow, hoveredRow, isFullScreen, rowPinning } = + getState(); const visibleCells = row.getVisibleCells(); - const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = - columnVirtualizer ?? {}; + const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {}; const isRowSelected = getIsRowSelected({ row, table }); const isRowPinned = enableRowPinning && row.getIsPinned(); @@ -71,30 +58,17 @@ const DataTable_TableBodyRow = ({ }; const [bottomPinnedIndex, topPinnedIndex] = useMemo(() => { - if ( - !enableRowPinning || - !rowPinningDisplayMode?.includes('sticky') || - !pinnedRowIds || - !row.getIsPinned() - ) + if (!enableRowPinning || !rowPinningDisplayMode?.includes("sticky") || !pinnedRowIds || !row.getIsPinned()) return []; - return [ - [...pinnedRowIds].reverse().indexOf(row.id), - pinnedRowIds.indexOf(row.id), - ]; + return [[...pinnedRowIds].reverse().indexOf(row.id), pinnedRowIds.indexOf(row.id)]; }, [pinnedRowIds, rowPinning]); - const tableHeadHeight = - ((enableStickyHeader || isFullScreen) && - tableHeadRef.current?.clientHeight) || - 0; - const tableFooterHeight = - (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0; + const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0; + const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0; const sx = parseFromValuesOrFunc(tableRowProps?.sx, theme); - const defaultRowHeight = - density === 'compact' ? 37 : density === 'comfortable' ? 53 : 69; + const defaultRowHeight = density === "compact" ? 37 : density === "comfortable" ? 53 : 69; const customRowHeight = // @ts-ignore @@ -117,16 +91,16 @@ const DataTable_TableBodyRow = ({ const cellHighlightColor = isRowSelected ? selectedRowBackgroundColor : isRowPinned - ? pinnedRowBackgroundColor - : undefined; + ? pinnedRowBackgroundColor + : undefined; const cellHighlightColorHover = tableRowProps?.hover !== false ? isRowSelected ? cellHighlightColor - : theme.palette.mode === 'dark' - ? `${lighten(baseBackgroundColor, 0.3)}` - : `${darken(baseBackgroundColor, 0.3)}` + : theme.palette.mode === "dark" + ? `${lighten(baseBackgroundColor, 0.3)}` + : `${darken(baseBackgroundColor, 0.3)}` : undefined; return ( @@ -146,91 +120,81 @@ const DataTable_TableBodyRow = ({ selected={isRowSelected} {...tableRowProps} style={{ - transform: virtualRow - ? `translateY(${virtualRow.start}px)` - : undefined, + transform: virtualRow ? `translateY(${virtualRow.start}px)` : undefined, ...tableRowProps?.style, }} sx={(theme) => ({ - '&:hover td:after': cellHighlightColorHover + "&:hover td:after": cellHighlightColorHover ? { - backgroundColor: alpha(cellHighlightColorHover, 0.3), - ...commonCellBeforeAfterStyles, - } + backgroundColor: alpha(cellHighlightColorHover, 0.3), + ...commonCellBeforeAfterStyles, + } : undefined, backgroundColor: `${baseBackgroundColor} !important`, bottom: !virtualRow && bottomPinnedIndex !== undefined && isRowPinned - ? `${bottomPinnedIndex * rowHeight + - (enableStickyFooter ? tableFooterHeight - 1 : 0) - }px` + ? `${bottomPinnedIndex * rowHeight + (enableStickyFooter ? tableFooterHeight - 1 : 0)}px` : undefined, - boxSizing: 'border-box', - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, + boxSizing: "border-box", + display: layoutMode?.startsWith("grid") ? "flex" : undefined, opacity: isRowPinned ? 0.97 : isDraggingRow || isHoveredRow ? 0.5 : 1, position: virtualRow - ? 'absolute' - : rowPinningDisplayMode?.includes('sticky') && isRowPinned - ? 'sticky' - : 'relative', + ? "absolute" + : rowPinningDisplayMode?.includes("sticky") && isRowPinned + ? "sticky" + : "relative", td: { ...getCommonPinnedCellStyles({ table, theme }), }, - 'td:after': cellHighlightColor + "td:after": cellHighlightColor ? { - backgroundColor: cellHighlightColor, - ...commonCellBeforeAfterStyles, - } + backgroundColor: cellHighlightColor, + ...commonCellBeforeAfterStyles, + } : undefined, top: virtualRow ? 0 : topPinnedIndex !== undefined && isRowPinned - ? `${topPinnedIndex * rowHeight + - (enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0) + ? `${ + topPinnedIndex * rowHeight + + (enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0) }px` - : undefined, - transition: virtualRow ? 'none' : 'all 150ms ease-in-out', - width: '100%', - zIndex: - rowPinningDisplayMode?.includes('sticky') && isRowPinned ? 2 : 0, - ...(sx), + : undefined, + transition: virtualRow ? "none" : "all 150ms ease-in-out", + width: "100%", + zIndex: rowPinningDisplayMode?.includes("sticky") && isRowPinned ? 2 : 0, + ...sx, })} > - {virtualPaddingLeft ? ( - - ) : null} - {(virtualColumns ?? visibleCells).map( - (cellOrVirtualCell, staticColumnIndex) => { - let cell = cellOrVirtualCell; - if (columnVirtualizer) { - staticColumnIndex = (cellOrVirtualCell).index; - cell = visibleCells[staticColumnIndex]; - } - const props = { - cell, - numRows, - rowRef, - staticColumnIndex, - staticRowIndex, - table, - }; - return cell ? ( - memoMode === 'cells' && - cell.column.columnDef.columnDefType === 'data' && - !draggingColumn && - !draggingRow && - editingCell?.id !== cell.id && - editingRow?.id !== row.id ? ( - - ) : ( - - ) - ) : null; - }, - )} - {virtualPaddingRight ? ( - - ) : null} + {virtualPaddingLeft ? : null} + {(virtualColumns ?? visibleCells).map((cellOrVirtualCell, staticColumnIndex) => { + let cell = cellOrVirtualCell; + if (columnVirtualizer) { + staticColumnIndex = cellOrVirtualCell.index; + cell = visibleCells[staticColumnIndex]; + } + const props = { + cell, + numRows, + rowRef, + staticColumnIndex, + staticRowIndex, + table, + }; + return cell ? ( + memoMode === "cells" && + cell.column.columnDef.columnDefType === "data" && + !draggingColumn && + !draggingRow && + editingCell?.id !== cell.id && + editingRow?.id !== row.id ? ( + + ) : ( + + ) + ) : null; + })} + {virtualPaddingRight ? : null} {renderDetailPanel && !row.getIsGrouped() && ( ); -} -export default DataTable_TableBodyRow +}; +export default DataTable_TableBodyRow; export const Memo_DataTable_TableBodyRow = memo( DataTable_TableBodyRow, - (prev, next) => - prev.row === next.row && prev.staticRowIndex === next.staticRowIndex, -); \ No newline at end of file + (prev, next) => prev.row === next.row && prev.staticRowIndex === next.staticRowIndex +); diff --git a/src/core/components/DataTable/body/TableDetailPanel.js b/src/core/components/DataTable/body/TableDetailPanel.js index 0c9f8a9..853aab5 100644 --- a/src/core/components/DataTable/body/TableDetailPanel.js +++ b/src/core/components/DataTable/body/TableDetailPanel.js @@ -23,7 +23,6 @@ const DataTable_TableDetailPanel = ({ } = table; const { isLoading } = getState(); - const tableRowProps = parseFromValuesOrFunc(muiTableBodyRowProps, { isDetailPanel: true, row, @@ -52,16 +51,12 @@ const DataTable_TableDetailPanel = ({ }} {...tableRowProps} sx={(theme) => ({ - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, - position: virtualRow ? 'absolute' : undefined, - top: virtualRow - ? `${parentRowRef.current?.getBoundingClientRect()?.height}px` - : undefined, - transform: virtualRow - ? `translateY(${virtualRow?.start}px)` - : undefined, - width: '100%', - ...(parseFromValuesOrFunc(tableRowProps?.sx, theme)), + display: layoutMode?.startsWith("grid") ? "flex" : undefined, + position: virtualRow ? "absolute" : undefined, + top: virtualRow ? `${parentRowRef.current?.getBoundingClientRect()?.height}px` : undefined, + transform: virtualRow ? `translateY(${virtualRow?.start}px)` : undefined, + width: "100%", + ...parseFromValuesOrFunc(tableRowProps?.sx, theme), })} > ({ backgroundColor: virtualRow ? baseBackgroundColor : undefined, - borderBottom: !row.getIsExpanded() ? 'none' : undefined, - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, - py: !!DetailPanel && row.getIsExpanded() ? '1rem' : 0, - transition: !virtualRow ? 'all 150ms ease-in-out' : undefined, + borderBottom: !row.getIsExpanded() ? "none" : undefined, + display: layoutMode?.startsWith("grid") ? "flex" : undefined, + py: !!DetailPanel && row.getIsExpanded() ? "1rem" : 0, + transition: !virtualRow ? "all 150ms ease-in-out" : undefined, width: `100%`, - ...(parseFromValuesOrFunc(tableCellProps?.sx, theme)), + ...parseFromValuesOrFunc(tableCellProps?.sx, theme), })} > {virtualRow ? ( @@ -88,6 +83,5 @@ const DataTable_TableDetailPanel = ({ ); - -} -export default DataTable_TableDetailPanel \ No newline at end of file +}; +export default DataTable_TableDetailPanel; diff --git a/src/core/components/DataTable/buttons/CopyButton.js b/src/core/components/DataTable/buttons/CopyButton.js index c8878e0..c4dfe4b 100644 --- a/src/core/components/DataTable/buttons/CopyButton.js +++ b/src/core/components/DataTable/buttons/CopyButton.js @@ -2,11 +2,7 @@ import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils import { Button, Tooltip } from "@mui/material"; import { useState } from "react"; -const DataTable_CopyButton = ({ - cell, - table, - ...rest -}) => { +const DataTable_CopyButton = ({ cell, table, ...rest }) => { const { options: { localization, muiCopyButtonProps }, } = table; @@ -40,11 +36,8 @@ const DataTable_CopyButton = ({ return ( - - - )} + + {({ + values, + handleChange, + handleBlur, + setFieldValue, + errors, + touched, + isSubmitting, + isValid, + dirty, + resetForm, + }) => ( +
+ + {columns.map( + (column) => + column.enableColumnFilter && ( + + ) + )} + + + + +
+ )}
)} @@ -204,4 +221,4 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t ); } -export default FilterBody; \ No newline at end of file +export default FilterBody; diff --git a/src/core/components/DataTable/filter/FilterBodyField.jsx b/src/core/components/DataTable/filter/FilterBodyField.jsx index b12e770..a9bef12 100644 --- a/src/core/components/DataTable/filter/FilterBodyField.jsx +++ b/src/core/components/DataTable/filter/FilterBodyField.jsx @@ -1,4 +1,4 @@ -import {useState} from "react"; +import { useState } from "react"; import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList"; import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect"; import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField"; @@ -14,19 +14,19 @@ const columnFilterModeOptionFa = { lessThan: "کوچکتر", greaterThan: "بزرگتر", fuzzy: "فازی", - between: "مابین" + between: "مابین", }; 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; @@ -47,7 +47,9 @@ function FilterBodyField({ errors={errors} touched={touched} /> - ) : filterParameters.datatype === "numeric" && filterParameters.filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( + ) : filterParameters.datatype === "numeric" && + filterParameters.filterFn === "equals" && + Array.isArray(column.columnSelectOption) ? ( - { - setDrawerState(!drawerState) - }} aria-label="filter table"> - + { + setDrawerState(!drawerState); + }} + aria-label="filter table" + > +
); diff --git a/src/core/components/DataTable/filter/FilterHeader.jsx b/src/core/components/DataTable/filter/FilterHeader.jsx index 2acd0b7..76980ce 100644 --- a/src/core/components/DataTable/filter/FilterHeader.jsx +++ b/src/core/components/DataTable/filter/FilterHeader.jsx @@ -1,10 +1,10 @@ -'use client' +"use client"; -import {Box, IconButton, Typography} from "@mui/material"; -import CancelIcon from '@mui/icons-material/Cancel'; -import FilterAltIcon from '@mui/icons-material/FilterAlt'; +import { Box, IconButton, Typography } from "@mui/material"; +import CancelIcon from "@mui/icons-material/Cancel"; +import FilterAltIcon from "@mui/icons-material/FilterAlt"; -function FilterHeader({setDrawerState}) { +function FilterHeader({ setDrawerState }) { return ( - - - فیلتر + + + + فیلتر + - setDrawerState(false)}> - + setDrawerState(false)}> + ); } -export default FilterHeader; \ No newline at end of file +export default FilterHeader; diff --git a/src/core/components/DataTable/filter/FilterOptionList.jsx b/src/core/components/DataTable/filter/FilterOptionList.jsx index ce02c23..e088832 100644 --- a/src/core/components/DataTable/filter/FilterOptionList.jsx +++ b/src/core/components/DataTable/filter/FilterOptionList.jsx @@ -1,17 +1,17 @@ -'use client' +"use client"; -import {ListItem, Menu} from "@mui/material"; -import {useState} from "react"; +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) => { @@ -19,25 +19,26 @@ function FilterOptionList({ setFieldValue(`${column.id}.filterFn`, filterOption[index]); setSelectedFilter(filterOption[index]); setAnchorEl(null); - } + }; const handleCloseFilterBox = () => { setAnchorEl(null); }; return ( - + {filterOption.map((option, index) => ( - handleChangeItem(event, index)} - selected={option === selectedFilter} - sx={{cursor: 'pointer', width: "100px", display: "flex", justifyContent: "center"}}> + handleChangeItem(event, index)} + selected={option === selectedFilter} + sx={{ + cursor: "pointer", + width: "100px", + display: "flex", + justifyContent: "center", + }} + > {columnFilterModeOptionFa[option]} ))} @@ -45,4 +46,4 @@ function FilterOptionList({ ); } -export default FilterOptionList; \ No newline at end of file +export default FilterOptionList; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx index e92a426..fe5d2e0 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePicker.jsx @@ -1,8 +1,8 @@ -import React from 'react'; +import React from "react"; import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker"; -import {Typography} from "@mui/material"; +import { Typography } from "@mui/material"; -function CustomDatePicker({column, filterParameters, defaultFilterTranslation, setFieldValue}) { +function CustomDatePicker({ column, filterParameters, defaultFilterTranslation, setFieldValue }) { return ( + نوع فیلتر: {defaultFilterTranslation} (تاریخ) } @@ -18,4 +18,4 @@ function CustomDatePicker({column, filterParameters, defaultFilterTranslation, s ); } -export default CustomDatePicker; \ No newline at end of file +export default CustomDatePicker; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx index b870061..116af77 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/CustomDatePickerRange.jsx @@ -1,12 +1,12 @@ -'use client' +"use client"; import React from "react"; -import {Box, Typography} from "@mui/material"; +import { Box, Typography } from "@mui/material"; import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker"; -function CustomDatePickerRange({column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched}) { +function CustomDatePickerRange({ column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched }) { return ( - + + نوع فیلتر: {defaultFilterTranslation} (تاریخ) } diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx index 5031372..d715192 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx @@ -1,33 +1,31 @@ -import React from 'react'; -import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers"; -import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali"; -import {faIR} from "@mui/x-date-pickers/locales"; -import {Box, FormHelperText, IconButton, InputAdornment} from "@mui/material"; +import React from "react"; +import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers"; +import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import { faIR } from "@mui/x-date-pickers/locales"; +import { Box, FormHelperText, IconButton, InputAdornment } from "@mui/material"; import ClearIcon from "@mui/icons-material/Clear"; 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 }) { // console.log("error", error); // // console.log("helperText", helperText) return ( - - + { const date = new Date(value); - const formattedDate = moment(date) - .locale("en") - .format("YYYY-MM-DD"); + const formattedDate = moment(date).locale("en").format("YYYY-MM-DD"); setFieldValue(name, formattedDate); }} minDate={minDate ? new Date(minDate) : null} @@ -47,13 +45,13 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText }} sx={{ color: "#bfbfbf", - '&:hover': { - backgroundColor: 'rgba(189, 189, 189, 0.1)', - color: "#363434" + "&:hover": { + backgroundColor: "rgba(189, 189, 189, 0.1)", + color: "#363434", }, }} > - + ), @@ -61,7 +59,7 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText }, }} /> - + {helperText ? helperText : ""} @@ -69,4 +67,4 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText ); } -export default MuiDatePicker; \ No newline at end of file +export default MuiDatePicker; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx index 44f0599..bd038e2 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelect.jsx @@ -1,35 +1,32 @@ -'use client' +"use client"; -import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; +import { FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography } from "@mui/material"; -function CustomSelect({column, filterParameters, defaultFilterTranslation, setFieldValue}) { +function CustomSelect({ column, filterParameters, defaultFilterTranslation, setFieldValue }) { const columnSelectOption = column.columnSelectOption; return ( - + {column.header} - + نوع فیلتر: {defaultFilterTranslation} diff --git a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx index ae027fe..130f98f 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomSelectMultiple.jsx @@ -1,4 +1,4 @@ -'use client' +"use client"; import { Box, @@ -9,49 +9,47 @@ import { MenuItem, OutlinedInput, Select, - Typography + Typography, } from "@mui/material"; -function CustomSelectMultiple({column, filterParameters, defaultFilterTranslation, setFieldValue}) { +function CustomSelectMultiple({ column, filterParameters, defaultFilterTranslation, setFieldValue }) { const columnSelectOption = column.columnSelectOption; const getLabelForValue = (value) => { - const option = columnSelectOption.find(opt => opt.value === value); + const option = columnSelectOption.find((opt) => opt.value === value); return option ? option.label : value; }; return ( - - {column.header} + + + {column.header} + - + نوع فیلتر: {defaultFilterTranslation} diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx index eacd820..05b44ce 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextField.jsx @@ -1,15 +1,14 @@ -import {InputAdornment, TextField, Typography} from "@mui/material"; -import FilterListIcon from '@mui/icons-material/FilterList'; +import { InputAdornment, TextField, Typography } from "@mui/material"; +import FilterListIcon from "@mui/icons-material/FilterList"; function CustomTextField({ - column, - filterParameters, - defaultFilterTranslation, - handleOpenFilterBox, - handleChange, - handleBlur - }) { - + column, + filterParameters, + defaultFilterTranslation, + handleOpenFilterBox, + handleChange, + handleBlur, +}) { return ( - نوع فیلتر: {defaultFilterTranslation} - } + helperText={ + + نوع فیلتر: {defaultFilterTranslation} + + } variant="outlined" size="normal" - sx={{marginY: 1}} + sx={{ marginY: 1 }} InputProps={{ endAdornment: ( - - + + ), }} @@ -36,4 +37,4 @@ function CustomTextField({ ); } -export default CustomTextField; \ No newline at end of file +export default CustomTextField; diff --git a/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx index 35c9358..fea4169 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomTextFieldRange.jsx @@ -1,18 +1,18 @@ -import {Box, InputAdornment, TextField, Typography} from "@mui/material"; -import FilterListIcon from '@mui/icons-material/FilterList'; +import { Box, InputAdornment, TextField, Typography } from "@mui/material"; +import FilterListIcon from "@mui/icons-material/FilterList"; function CustomTextFieldRange({ - column, - filterParameters, - defaultFilterTranslation, - handleOpenFilterBox, - handleChange, - handleBlur, - errors, - touched - }) { + column, + filterParameters, + defaultFilterTranslation, + handleOpenFilterBox, + handleChange, + handleBlur, + errors, + touched, +}) { return ( - + نوع - فیلتر: {defaultFilterTranslation}} + helperText={ + + نوع فیلتر: {defaultFilterTranslation} + + } variant="outlined" size="normal" - sx={{marginY: 1, marginRight: 1}} + sx={{ marginY: 1, marginRight: 1 }} /> - + + ), }} @@ -53,4 +56,4 @@ function CustomTextFieldRange({ ); } -export default CustomTextFieldRange; \ No newline at end of file +export default CustomTextFieldRange; diff --git a/src/core/components/DataTable/filter/index.jsx b/src/core/components/DataTable/filter/index.jsx index 65a93d2..8d26594 100644 --- a/src/core/components/DataTable/filter/index.jsx +++ b/src/core/components/DataTable/filter/index.jsx @@ -1,17 +1,23 @@ -'use client' +"use client"; -import {useState} from "react"; +import { useState } from "react"; import FilterButton from "@/core/components/DataTable/filter/FilterButton"; import FilterBody from "@/core/components/DataTable/filter/FilterBody"; -function FilterColumn({columns, user_id, page_name, table_name}) { +function FilterColumn({ columns, user_id, page_name, table_name }) { const [open, setOpen] = useState(false); return ( <> - - + + ); } diff --git a/src/core/components/DataTable/head/TableHead.js b/src/core/components/DataTable/head/TableHead.js index 5e5dd99..39ee214 100644 --- a/src/core/components/DataTable/head/TableHead.js +++ b/src/core/components/DataTable/head/TableHead.js @@ -1,26 +1,17 @@ -import {parseFromValuesOrFunc} from "@/core/utils/utils"; -import {TableHead} from "@mui/material"; +import { parseFromValuesOrFunc } from "@/core/utils/utils"; +import { TableHead } from "@mui/material"; import DataTable_TableHeadRow from "./TableHeadRow"; -const DataTable_TableHead = ({ - columnVirtualizer, - table, - ...rest - }) => { +const DataTable_TableHead = ({ columnVirtualizer, table, ...rest }) => { const { getState, - options: { - enableStickyHeader, - layoutMode, - muiTableHeadProps, - positionToolbarAlertBanner, - }, - refs: {tableHeadRef}, + options: { enableStickyHeader, layoutMode, muiTableHeadProps, positionToolbarAlertBanner }, + refs: { tableHeadRef }, } = table; - const {isFullScreen, showAlertBanner} = getState(); + const { isFullScreen, showAlertBanner } = getState(); const tableHeadProps = { - ...parseFromValuesOrFunc(muiTableHeadProps, {table}), + ...parseFromValuesOrFunc(muiTableHeadProps, { table }), ...rest, }; @@ -37,28 +28,24 @@ const DataTable_TableHead = ({ } }} sx={(theme) => ({ - display: layoutMode?.startsWith('grid') ? 'grid' : undefined, + display: layoutMode?.startsWith("grid") ? "grid" : undefined, opacity: 0.97, - position: stickyHeader ? 'sticky' : 'relative', - top: stickyHeader && layoutMode?.startsWith('grid') ? 0 : undefined, + position: stickyHeader ? "sticky" : "relative", + top: stickyHeader && layoutMode?.startsWith("grid") ? 0 : undefined, zIndex: stickyHeader ? 2 : undefined, - ...(parseFromValuesOrFunc(tableHeadProps?.sx, theme)), + ...parseFromValuesOrFunc(tableHeadProps?.sx, theme), })} > - {table - .getHeaderGroups() - .map((headerGroup, index) => ( - - )) - } + {table.getHeaderGroups().map((headerGroup, index) => ( + + ))} ); - -} -export default DataTable_TableHead \ No newline at end of file +}; +export default DataTable_TableHead; diff --git a/src/core/components/DataTable/head/TableHeadCell.js b/src/core/components/DataTable/head/TableHeadCell.js index 6248d63..a0b8fc5 100644 --- a/src/core/components/DataTable/head/TableHeadCell.js +++ b/src/core/components/DataTable/head/TableHeadCell.js @@ -1,16 +1,10 @@ -import {getCommonMRTCellStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; -import {useTheme} from "@emotion/react"; -import {Box, TableCell} from "@mui/material"; -import {MRT_TableHeadCellSortLabel} from "material-react-table"; -import {useMemo} from "react"; +import { getCommonMRTCellStyles, parseFromValuesOrFunc } from "@/core/utils/utils"; +import { useTheme } from "@emotion/react"; +import { Box, TableCell } from "@mui/material"; +import { MRT_TableHeadCellSortLabel } from "material-react-table"; +import { useMemo } from "react"; -const DataTable_TableHeadCell = ({ - columnVirtualizer, - header, - staticColumnIndex, - table, - ...rest - }) => { +const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, table, ...rest }) => { const theme = useTheme(); const { getState, @@ -24,26 +18,19 @@ const DataTable_TableHeadCell = ({ enableGrouping, enableMultiSort, layoutMode, - mrtTheme: {draggingBorderColor}, + mrtTheme: { draggingBorderColor }, muiTableHeadCellProps, }, - refs: {tableHeadCellRefs}, + refs: { tableHeadCellRefs }, setHoveredColumn, } = table; - const { - columnSizingInfo, - density, - draggingColumn, - grouping, - hoveredColumn, - showColumnFilters, - } = getState(); - const {column} = header; - const {columnDef} = column; - const {columnDefType} = columnDef; + const { columnSizingInfo, density, draggingColumn, grouping, hoveredColumn, showColumnFilters } = getState(); + const { column } = header; + const { columnDef } = column; + const { columnDefType } = columnDef; const tableCellProps = { - ...parseFromValuesOrFunc(muiTableHeadCellProps, {column, table}), + ...parseFromValuesOrFunc(muiTableHeadCellProps, { column, table }), ...parseFromValuesOrFunc(columnDef.muiTableHeadCellProps, { column, table, @@ -51,23 +38,17 @@ const DataTable_TableHeadCell = ({ ...rest, }; - const isColumnPinned = - enableColumnPinning && - columnDef.columnDefType !== 'group' && - column.getIsPinned(); + const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned(); const showColumnActions = - (enableColumnActions || columnDef.enableColumnActions) && - columnDef.enableColumnActions !== false; + (enableColumnActions || columnDef.enableColumnActions) && columnDef.enableColumnActions !== false; const showDragHandle = enableColumnDragging !== false && columnDef.enableColumnDragging !== false && (enableColumnDragging || (enableColumnOrdering && columnDef.enableColumnOrdering !== false) || - (enableGrouping && - columnDef.enableGrouping !== false && - !grouping.includes(column.id))); + (enableGrouping && columnDef.enableGrouping !== false && !grouping.includes(column.id))); const headerPL = useMemo(() => { let pl = 0; @@ -80,41 +61,37 @@ const DataTable_TableHeadCell = ({ const draggingBorders = useMemo(() => { const showResizeBorder = columnSizingInfo.isResizingColumn === column.id && - columnResizeMode === 'onChange' && + columnResizeMode === "onChange" && !header.subHeaders.length; const borderStyle = showResizeBorder ? `2px solid ${draggingBorderColor} !important` : draggingColumn?.id === column.id - ? `1px dashed ${theme.palette.grey[500]}` - : hoveredColumn?.id === column.id - ? `2px dashed ${draggingBorderColor}` - : undefined; + ? `1px dashed ${theme.palette.grey[500]}` + : hoveredColumn?.id === column.id + ? `2px dashed ${draggingBorderColor}` + : undefined; if (showResizeBorder) { - return columnResizeDirection === 'ltr' - ? {borderRight: borderStyle} - : {borderLeft: borderStyle}; + return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle }; } const draggingBorders = borderStyle ? { - borderLeft: borderStyle, - borderRight: borderStyle, - borderTop: borderStyle, - } + borderLeft: borderStyle, + borderRight: borderStyle, + borderTop: borderStyle, + } : undefined; return draggingBorders; }, [draggingColumn, hoveredColumn, columnSizingInfo.isResizingColumn]); const handleDragEnter = (_e) => { - if (enableGrouping && hoveredColumn?.id === 'drop-zone') { + if (enableGrouping && hoveredColumn?.id === "drop-zone") { setHoveredColumn(null); } - if (enableColumnOrdering && draggingColumn && columnDefType !== 'group') { - setHoveredColumn( - columnDef.enableColumnOrdering !== false ? column : null, - ); + if (enableColumnOrdering && draggingColumn && columnDefType !== "group") { + setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null); } }; @@ -124,7 +101,6 @@ const DataTable_TableHeadCell = ({ } }; - const HeaderElement = parseFromValuesOrFunc(columnDef.Header, { column, @@ -132,12 +108,9 @@ const DataTable_TableHeadCell = ({ table, }) ?? columnDef.header; - const columnRelativeDepth = header.depth - column.depth; - if ( - columnRelativeDepth > 1 - ) { + if (columnRelativeDepth > 1) { return null; } @@ -149,13 +122,7 @@ const DataTable_TableHeadCell = ({ return ( { if (node) { tableHeadCellRefs.current[column.id] = node; - if (columnDefType !== 'group') { + if (columnDefType !== "group") { columnVirtualizer?.measureElement?.(node); } } }} {...tableCellProps} sx={(theme) => ({ - '& :hover': { - '.MuiButtonBase-root': { - opacity: 1, - }, + "& :hover": { + ".MuiButtonBase-root": { + opacity: 1, }, - flexDirection: layoutMode?.startsWith('grid') ? 'column' : undefined, - fontWeight: 'bold', - overflow: 'visible', - p: - density === 'compact' - ? '0.5rem' - : density === 'comfortable' - ? columnDefType === 'display' - ? '0.75rem' - : '1rem' - : columnDefType === 'display' - ? '1rem 1.25rem' - : '1.5rem', - pb: - columnDefType === 'display' - ? 0 - : showColumnFilters || density === 'compact' - ? '0.4rem' - : '0.6rem', - pt: - columnDefType === 'group' || density === 'compact' - ? '0.25rem' - : density === 'comfortable' - ? '.75rem' - : '1.25rem', - userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined, - verticalAlign: 'middle', - ...getCommonMRTCellStyles({ - column, - header, - table, - tableCellProps, - theme, - }), - ...draggingBorders, - } - )} + }, + flexDirection: layoutMode?.startsWith("grid") ? "column" : undefined, + fontWeight: "bold", + overflow: "visible", + p: + density === "compact" + ? "0.5rem" + : density === "comfortable" + ? columnDefType === "display" + ? "0.75rem" + : "1rem" + : columnDefType === "display" + ? "1rem 1.25rem" + : "1.5rem", + pb: columnDefType === "display" ? 0 : showColumnFilters || density === "compact" ? "0.4rem" : "0.6rem", + pt: + columnDefType === "group" || density === "compact" + ? "0.25rem" + : density === "comfortable" + ? ".75rem" + : "1.25rem", + userSelect: enableMultiSort && column.getCanSort() ? "none" : undefined, + verticalAlign: "middle", + ...getCommonMRTCellStyles({ + column, + header, + table, + tableCellProps, + theme, + }), + ...draggingBorders, + })} > {tableCellProps.children ?? ( {HeaderElement} - {(column.getCanSort() && columnDefType !== 'group') && ( - + {column.getCanSort() && columnDefType !== "group" && ( + )} )} ); - -} -export default DataTable_TableHeadCell; \ No newline at end of file +}; +export default DataTable_TableHeadCell; diff --git a/src/core/components/DataTable/head/TableHeadRow.js b/src/core/components/DataTable/head/TableHeadRow.js index 33a23e2..512147a 100644 --- a/src/core/components/DataTable/head/TableHeadRow.js +++ b/src/core/components/DataTable/head/TableHeadRow.js @@ -1,25 +1,20 @@ -import {parseFromValuesOrFunc} from "@/core/utils/utils"; -import {TableRow} from "@mui/material"; +import { parseFromValuesOrFunc } from "@/core/utils/utils"; +import { TableRow } from "@mui/material"; import DataTable_TableHeadCell from "./TableHeadCell"; const DataTable_TableHeadRow = ({ - columnVirtualizer, - headerGroup, - table, - index, // Add index prop - ...rest - }) => { + columnVirtualizer, + headerGroup, + table, + index, // Add index prop + ...rest +}) => { const { - options: { - enableStickyHeader, - layoutMode, - muiTableHeadRowProps, - }, + options: { enableStickyHeader, layoutMode, muiTableHeadRowProps }, } = table; - const {virtualColumns, virtualPaddingLeft, virtualPaddingRight} = - columnVirtualizer ?? {}; + const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {}; - const backgroundColor = index % 2 === 0 ? '#015688' : '#ff5c0f'; + const backgroundColor = index % 2 === 0 ? "#015688" : "#ff5c0f"; const tableRowProps = { ...parseFromValuesOrFunc(muiTableHeadRowProps, { @@ -27,20 +22,23 @@ const DataTable_TableHeadRow = ({ table, }), ...rest, - sx: (theme) => ({ // Access theme from the sx function + sx: (theme) => ({ + // Access theme from the sx function ...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}), backgroundColor, // Apply background color - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, - position: enableStickyHeader && layoutMode === 'semantic' ? 'sticky' : 'relative', + display: layoutMode?.startsWith("grid") ? "flex" : undefined, + position: enableStickyHeader && layoutMode === "semantic" ? "sticky" : "relative", top: 0, }), }; return ( - {virtualPaddingLeft && } + {virtualPaddingLeft && } {(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader, staticColumnIndex) => { - const header = columnVirtualizer ? headerGroup.headers[headerOrVirtualHeader.index] : headerOrVirtualHeader; + const header = columnVirtualizer + ? headerGroup.headers[headerOrVirtualHeader.index] + : headerOrVirtualHeader; return header ? ( ) : null; })} - {virtualPaddingRight && } + {virtualPaddingRight && } ); }; -export default DataTable_TableHeadRow; \ No newline at end of file +export default DataTable_TableHeadRow; diff --git a/src/core/components/DataTable/index.js b/src/core/components/DataTable/index.js index e440895..f387d06 100644 --- a/src/core/components/DataTable/index.js +++ b/src/core/components/DataTable/index.js @@ -4,9 +4,9 @@ import DataTableProvider from "@/lib/contexts/DataTable"; const DataTable = (props) => { return ( - + ); }; -export default DataTable; \ No newline at end of file +export default DataTable; diff --git a/src/core/components/DataTable/localization/fa/datatable.js b/src/core/components/DataTable/localization/fa/datatable.js index f80b7e0..e36f366 100644 --- a/src/core/components/DataTable/localization/fa/datatable.js +++ b/src/core/components/DataTable/localization/fa/datatable.js @@ -67,8 +67,7 @@ export const FA_DATATABLE_LOCALIZATION = { rowsPerPage: "ردیف در هر صفحه", save: "ذخیره", search: "جستجو", - selectedCountOfRowCountRowsSelected: - "{selectedCount} از {rowCount} ردیف انتخاب شده", + selectedCountOfRowCountRowsSelected: "{selectedCount} از {rowCount} ردیف انتخاب شده", select: "انتخاب", showAll: "نمایش همه", showAllColumns: "نمایش همه ستون‌ها", @@ -89,4 +88,4 @@ export const FA_DATATABLE_LOCALIZATION = { unpin: "رها کردن", unpinAll: "رها کردن همه", unsorted: "بدون مرتب سازی", -}; \ No newline at end of file +}; diff --git a/src/core/components/DataTable/menus/ActionMenuItem.js b/src/core/components/DataTable/menus/ActionMenuItem.js index 2b208b9..012fcc5 100644 --- a/src/core/components/DataTable/menus/ActionMenuItem.js +++ b/src/core/components/DataTable/menus/ActionMenuItem.js @@ -1,12 +1,6 @@ import { Box, IconButton, ListItemIcon, MenuItem } from "@mui/material"; -const DataTable_ActionMenuItem = ({ - icon, - label, - onOpenSubMenu, - table, - ...rest -}) => { +const DataTable_ActionMenuItem = ({ icon, label, onOpenSubMenu, table, ...rest }) => { const { options: { icons: { ArrowRightIcon }, @@ -16,35 +10,29 @@ const DataTable_ActionMenuItem = ({ return ( {icon} {label} {onOpenSubMenu && ( - + )} ); - -} -export default DataTable_ActionMenuItem \ No newline at end of file +}; +export default DataTable_ActionMenuItem; diff --git a/src/core/components/DataTable/menus/CellActionMenu.js b/src/core/components/DataTable/menus/CellActionMenu.js index 36638e0..5b27ca9 100644 --- a/src/core/components/DataTable/menus/CellActionMenu.js +++ b/src/core/components/DataTable/menus/CellActionMenu.js @@ -2,10 +2,7 @@ import { parseFromValuesOrFunc } from "@/core/utils/utils"; import { Menu } from "@mui/material"; import DataTable_ActionMenuItem from "./ActionMenuItem"; -const DataTable_CellActionMenu = ({ - table, - ...rest -}) => { +const DataTable_CellActionMenu = ({ table, ...rest }) => { const { getState, options: { @@ -32,12 +29,11 @@ const DataTable_CellActionMenu = ({ }; const internalMenuItems = [ - (parseFromValuesOrFunc(enableClickToCopy, cell) === 'context-menu' || - parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === - 'context-menu') && ( + (parseFromValuesOrFunc(enableClickToCopy, cell) === "context-menu" || + parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === "context-menu") && ( } - key={'mrt-copy'} + key={"mrt-copy"} label={localization.copy} onClick={(event) => { event.stopPropagation(); @@ -47,10 +43,10 @@ const DataTable_CellActionMenu = ({ table={table} /> ), - parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === 'cell' && ( + parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === "cell" && ( } - key={'mrt-edit'} + key={"mrt-edit"} label={localization.edit} onClick={() => { openEditingCell({ cell, table }); @@ -71,14 +67,13 @@ const DataTable_CellActionMenu = ({ }; const menuItems = - columnDef.renderCellActionMenuItems?.(renderActionProps) ?? - renderCellActionMenuItems?.(renderActionProps); + columnDef.renderCellActionMenuItems?.(renderActionProps) ?? renderCellActionMenuItems?.(renderActionProps); return ( (!!menuItems?.length || !!internalMenuItems?.length) && ( ) ); - -} -export default DataTable_CellActionMenu \ No newline at end of file +}; +export default DataTable_CellActionMenu; diff --git a/src/core/components/DataTable/menus/ShowHideColumnsMenu.js b/src/core/components/DataTable/menus/ShowHideColumnsMenu.js index 12efae8..cb0423c 100644 --- a/src/core/components/DataTable/menus/ShowHideColumnsMenu.js +++ b/src/core/components/DataTable/menus/ShowHideColumnsMenu.js @@ -2,11 +2,7 @@ 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 DataTable_ShowHideColumnsMenu = ({ anchorEl, setAnchorEl, table, ...rest }) => { const { getAllColumns, getAllLeafColumns, @@ -36,14 +32,11 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl, const allColumns = useMemo(() => { const columns = getAllColumns(); - if ( - columnOrder.length > 0 && - !columns.some((col) => col.columnDef.columnDefType === 'group') - ) { + 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), + getCenterLeafColumns().find((col) => col?.id === colId) ), ...getRightLeafColumns(), ].filter(Boolean); @@ -58,16 +51,14 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl, getRightLeafColumns(), ]); - const isNestedColumns = allColumns.some( - (col) => col.columnDef.columnDefType === 'group', - ); + const isNestedColumns = allColumns.some((col) => col.columnDef.columnDefType === "group"); const [hoveredColumn, setHoveredColumn] = useState(null); return ( {enableHiding && ( - )} {enableColumnOrdering && ( - )} {enableColumnPinning && ( - )} {enableHiding && ( - )} @@ -136,5 +112,5 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl, ))} ); -} -export default DataTable_ShowHideColumnsMenu \ No newline at end of file +}; +export default DataTable_ShowHideColumnsMenu; diff --git a/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js b/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js index 58425d9..97c2e5d 100644 --- a/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js +++ b/src/core/components/DataTable/menus/ShowHideColumnsMenuItems.js @@ -30,7 +30,7 @@ const DataTable_ShowHideColumnsMenuItems = ({ const switchChecked = column.getIsVisible(); const handleToggleColumnHidden = (column) => { - if (columnDefType === 'group') { + if (columnDefType === "group") { column?.columns?.forEach?.((childColumn) => { childColumn.toggleVisibility(!switchChecked); }); @@ -78,29 +78,29 @@ const DataTable_ShowHideColumnsMenuItems = ({ ref={menuItemRef} {...rest} sx={(theme) => ({ - alignItems: 'center', - justifyContent: 'flex-start', + 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', + ? `2px dashed ${draggingBorderColor}` + : "none", + outlineOffset: "-2px", pl: `${(column.depth + 0.5) * 2}rem`, - py: '6px', - ...(parseFromValuesOrFunc(rest?.sx, theme)), + py: "6px", + ...parseFromValuesOrFunc(rest?.sx, theme), })} > - {columnDefType !== 'group' && + {columnDefType !== "group" && enableColumnOrdering && !isNestedColumns && (columnDef.enableColumnOrdering !== false ? ( @@ -110,7 +110,7 @@ const DataTable_ShowHideColumnsMenuItems = ({ table={table} /> ) : ( - + ))} {enableHiding ? ( + } @@ -136,9 +133,7 @@ const DataTable_ShowHideColumnsMenuItems = ({ onChange={() => handleToggleColumnHidden(column)} /> ) : ( - - {columnDef.header} - + {columnDef.header} )} @@ -155,6 +150,5 @@ const DataTable_ShowHideColumnsMenuItems = ({ ))} ); - -} -export default DataTable_ShowHideColumnsMenuItems; \ No newline at end of file +}; +export default DataTable_ShowHideColumnsMenuItems; diff --git a/src/core/components/DataTable/refactor/RefactorTable.jsx b/src/core/components/DataTable/refactor/RefactorTable.jsx index 71e302c..49217a0 100644 --- a/src/core/components/DataTable/refactor/RefactorTable.jsx +++ b/src/core/components/DataTable/refactor/RefactorTable.jsx @@ -1,14 +1,14 @@ -"use client" -import {IconButton, Tooltip} from '@mui/material'; -import RestartAltIcon from '@mui/icons-material/RestartAlt'; +"use client"; +import { IconButton, Tooltip } from "@mui/material"; +import RestartAltIcon from "@mui/icons-material/RestartAlt"; import useTableSetting from "@/lib/hooks/useTableSetting"; -import {useState} from "react"; +import { useState } from "react"; function RefactorTable() { - const {refactorAction} = useTableSetting(); + const { refactorAction } = useTableSetting(); const [userId, setUserId] = useState(0); - const [pageName, setPageName] = useState('testPage'); - const [tableName, setTableName] = useState('testTable'); + const [pageName, setPageName] = useState("testPage"); + const [tableName, setTableName] = useState("testTable"); const refactor = () => { refactorAction(userId, pageName, tableName); @@ -17,12 +17,10 @@ function RefactorTable() { return ( - + ); } export default RefactorTable; - - diff --git a/src/core/components/DataTable/table/Paper.js b/src/core/components/DataTable/table/Paper.js index 9a3be31..ede80b3 100644 --- a/src/core/components/DataTable/table/Paper.js +++ b/src/core/components/DataTable/table/Paper.js @@ -1,27 +1,27 @@ -import {parseFromValuesOrFunc} from "@/core/utils/utils"; -import {Paper} from "@mui/material"; +import { parseFromValuesOrFunc } from "@/core/utils/utils"; +import { Paper } from "@mui/material"; import DataTable_BottomToolbar from "../toolbar/BottomToolbar"; import DataTable_TopToolbar from "../toolbar/TopToolbar"; import DataTable_TableContainer from "./TableContainer"; -const DataTable_Paper = ({table, ...rest}) => { +const DataTable_Paper = ({ table, ...rest }) => { const { getState, options: { enableBottomToolbar, enableTopToolbar, - mrtTheme: {baseBackgroundColor}, + mrtTheme: { baseBackgroundColor }, muiTablePaperProps, renderBottomToolbar, renderTopToolbar, }, - refs: {tablePaperRef}, + refs: { tablePaperRef }, } = table; - const {isFullScreen} = getState(); + const { isFullScreen } = getState(); const paperProps = { - ...parseFromValuesOrFunc(muiTablePaperProps, {table}), + ...parseFromValuesOrFunc(muiTablePaperProps, { table }), ...rest, }; @@ -39,42 +39,44 @@ const DataTable_Paper = ({table, ...rest}) => { 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, }} sx={(theme) => ({ backgroundColor: baseBackgroundColor, - backgroundImage: 'unset', - overflow: 'hidden', - transition: 'all 100ms ease-in-out', - ...(parseFromValuesOrFunc(paperProps?.sx, theme)), + backgroundImage: "unset", + overflow: "hidden", + transition: "all 100ms ease-in-out", + ...parseFromValuesOrFunc(paperProps?.sx, theme), })} > {enableTopToolbar && - (parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( - + (parseFromValuesOrFunc(renderTopToolbar, { table }) ?? ( + ))} - + {enableBottomToolbar && - (parseFromValuesOrFunc(renderBottomToolbar, {table}) ?? ( - - ))} + (parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? )} ); }; diff --git a/src/core/components/DataTable/table/Table.js b/src/core/components/DataTable/table/Table.js index ca49d0c..1bf6b69 100644 --- a/src/core/components/DataTable/table/Table.js +++ b/src/core/components/DataTable/table/Table.js @@ -5,10 +5,7 @@ import { useMemo } from "react"; import DataTable_TableBody, { Memo_DataTable_TableBody } from "../body/TableBody"; import DataTable_TableHead from "../head/TableHead"; -const DataTable_Table = ({ - table, - ...rest -}) => { +const DataTable_Table = ({ table, ...rest }) => { const { getFlatHeaders, getState, @@ -23,8 +20,7 @@ const DataTable_Table = ({ renderCaption, }, } = table; - const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } = - getState(); + const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } = getState(); const tableProps = { ...parseFromValuesOrFunc(muiTableProps, { table }), @@ -58,14 +54,14 @@ const DataTable_Table = ({ {...tableProps} style={{ ...columnSizeVars, ...tableProps?.style }} sx={(theme) => ({ - display: layoutMode?.startsWith('grid') ? 'grid' : undefined, - position: 'relative', - ...(parseFromValuesOrFunc(tableProps?.sx, theme)), + display: layoutMode?.startsWith("grid") ? "grid" : undefined, + position: "relative", + ...parseFromValuesOrFunc(tableProps?.sx, theme), })} > {!!Caption && {Caption}} {enableTableHead && } - {memoMode === 'table-body' || columnSizingInfo.isResizingColumn ? ( + {memoMode === "table-body" || columnSizingInfo.isResizingColumn ? ( ) : ( @@ -73,5 +69,5 @@ const DataTable_Table = ({ {/* {enableTableFooter && } */} ); -} -export default DataTable_Table \ No newline at end of file +}; +export default DataTable_Table; diff --git a/src/core/components/DataTable/table/TableContainer.js b/src/core/components/DataTable/table/TableContainer.js index aa4b625..bc1d80c 100644 --- a/src/core/components/DataTable/table/TableContainer.js +++ b/src/core/components/DataTable/table/TableContainer.js @@ -5,31 +5,17 @@ import DataTable_CellActionMenu from "../menus/CellActionMenu"; import DataTable_Table from "./Table"; import DataTable_TableLoadingOverlay from "./TableLoadingOverlay"; -const useIsomorphicLayoutEffect = - typeof window !== 'undefined' ? useLayoutEffect : useEffect; +const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect; -const DataTable_TableContainer = ({ - table, - ...rest -}) => { +const DataTable_TableContainer = ({ table, ...rest }) => { const { getState, - options: { - enableCellActions, - enableStickyHeader, - muiTableContainerProps, - }, + options: { enableCellActions, enableStickyHeader, muiTableContainerProps }, refs: { bottomToolbarRef, tableContainerRef, topToolbarRef }, } = table; - const { - actionCell, - isFullScreen, - isLoading, - showLoadingOverlay, - } = getState(); + const { actionCell, isFullScreen, isLoading, showLoadingOverlay } = getState(); - const loading = - showLoadingOverlay !== false && (isLoading || showLoadingOverlay); + const loading = showLoadingOverlay !== false && (isLoading || showLoadingOverlay); const [totalToolbarHeight, setTotalToolbarHeight] = useState(0); @@ -41,15 +27,9 @@ const DataTable_TableContainer = ({ }; useIsomorphicLayoutEffect(() => { - const topToolbarHeight = - typeof document !== 'undefined' - ? topToolbarRef.current?.offsetHeight ?? 0 - : 0; + const topToolbarHeight = typeof document !== "undefined" ? topToolbarRef.current?.offsetHeight ?? 0 : 0; - const bottomToolbarHeight = - typeof document !== 'undefined' - ? bottomToolbarRef?.current?.offsetHeight ?? 0 - : 0; + const bottomToolbarHeight = typeof document !== "undefined" ? bottomToolbarRef?.current?.offsetHeight ?? 0 : 0; setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight); }); @@ -57,7 +37,7 @@ const DataTable_TableContainer = ({ return ( { if (node) { @@ -69,19 +49,17 @@ const DataTable_TableContainer = ({ } }} style={{ - maxHeight: isFullScreen - ? `calc(100vh - ${totalToolbarHeight}px)` - : undefined, + maxHeight: isFullScreen ? `calc(100vh - ${totalToolbarHeight}px)` : undefined, ...tableContainerProps?.style, }} sx={(theme) => ({ maxHeight: enableStickyHeader ? `clamp(350px, calc(100vh - ${totalToolbarHeight}px), 9999px)` : undefined, - maxWidth: '100%', - overflow: 'auto', - position: 'relative', - ...(parseFromValuesOrFunc(tableContainerProps?.sx, theme)), + maxWidth: "100%", + overflow: "auto", + position: "relative", + ...parseFromValuesOrFunc(tableContainerProps?.sx, theme), })} > {loading ? : null} @@ -89,6 +67,5 @@ const DataTable_TableContainer = ({ {enableCellActions && actionCell && } ); - -} -export default DataTable_TableContainer \ No newline at end of file +}; +export default DataTable_TableContainer; diff --git a/src/core/components/DataTable/table/TableLoadingOverlay.js b/src/core/components/DataTable/table/TableLoadingOverlay.js index 55e4ae5..0c417dd 100644 --- a/src/core/components/DataTable/table/TableLoadingOverlay.js +++ b/src/core/components/DataTable/table/TableLoadingOverlay.js @@ -1,9 +1,6 @@ import { Box, CircularProgress } from "@mui/material"; -const DataTable_TableLoadingOverlay = ({ - table, - ...rest -}) => { +const DataTable_TableLoadingOverlay = ({ table, ...rest }) => { const { options: { localization, @@ -20,17 +17,17 @@ const DataTable_TableLoadingOverlay = ({ return ( @@ -43,6 +40,5 @@ const DataTable_TableLoadingOverlay = ({ )} ); - -} -export default DataTable_TableLoadingOverlay \ No newline at end of file +}; +export default DataTable_TableLoadingOverlay; diff --git a/src/core/components/DataTable/toolbar/BottomToolbar.js b/src/core/components/DataTable/toolbar/BottomToolbar.js index 15e7f5a..ced2c06 100644 --- a/src/core/components/DataTable/toolbar/BottomToolbar.js +++ b/src/core/components/DataTable/toolbar/BottomToolbar.js @@ -3,23 +3,15 @@ import { Box, alpha, useMediaQuery } from "@mui/material"; import DataTable_LinearProgressBar from "./LinearProgressBar"; import DataTable_TablePagination from "./TablePagination"; -const DataTable_BottomToolbar = ({ - table, - ...rest -}) => { +const DataTable_BottomToolbar = ({ table, ...rest }) => { const { getState, - options: { - enablePagination, - muiBottomToolbarProps, - positionPagination, - renderBottomToolbarCustomActions, - }, + options: { enablePagination, muiBottomToolbarProps, positionPagination, renderBottomToolbarCustomActions }, refs: { bottomToolbarRef }, } = table; const { isFullScreen } = getState(); - const isMobile = useMediaQuery('(max-width:720px)'); + const isMobile = useMediaQuery("(max-width:720px)"); const toolbarProps = { ...parseFromValuesOrFunc(muiBottomToolbarProps, { table }), ...rest, @@ -40,49 +32,41 @@ const DataTable_BottomToolbar = ({ }} sx={(theme) => ({ ...getCommonToolbarStyles({ table, theme }), - bottom: isFullScreen ? '0' : undefined, - boxShadow: `0 1px 2px -1px ${alpha( - theme.palette.grey[700], - 0.5, - )} inset`, + bottom: isFullScreen ? "0" : undefined, + boxShadow: `0 1px 2px -1px ${alpha(theme.palette.grey[700], 0.5)} inset`, left: 0, - position: isFullScreen ? 'fixed' : 'relative', + position: isFullScreen ? "fixed" : "relative", right: 0, - ...(parseFromValuesOrFunc(toolbarProps?.sx, theme)), + ...parseFromValuesOrFunc(toolbarProps?.sx, theme), })} > - {renderBottomToolbarCustomActions ? ( - renderBottomToolbarCustomActions({ table }) - ) : ( - - )} + {renderBottomToolbarCustomActions ? renderBottomToolbarCustomActions({ table }) : } - {enablePagination && - ['both', 'bottom'].includes(positionPagination ?? '') && ( - - )} + {enablePagination && ["both", "bottom"].includes(positionPagination ?? "") && ( + + )} ); -} -export default DataTable_BottomToolbar \ No newline at end of file +}; +export default DataTable_BottomToolbar; diff --git a/src/core/components/DataTable/toolbar/LinearProgressBar.js b/src/core/components/DataTable/toolbar/LinearProgressBar.js index cdcbc0a..74c465f 100644 --- a/src/core/components/DataTable/toolbar/LinearProgressBar.js +++ b/src/core/components/DataTable/toolbar/LinearProgressBar.js @@ -1,11 +1,7 @@ import { parseFromValuesOrFunc } from "@/core/utils/utils"; import { Collapse, LinearProgress } from "@mui/material"; -const DataTable_LinearProgressBar = ({ - isTopToolbar, - table, - ...rest -}) => { +const DataTable_LinearProgressBar = ({ isTopToolbar, table, ...rest }) => { const { getState, options: { muiLinearProgressProps }, @@ -26,19 +22,19 @@ const DataTable_LinearProgressBar = ({ mountOnEnter sx={{ bottom: isTopToolbar ? 0 : undefined, - position: 'absolute', + position: "absolute", top: !isTopToolbar ? 0 : undefined, - width: '100%', + width: "100%", }} unmountOnExit > ); -} -export default DataTable_LinearProgressBar \ No newline at end of file +}; +export default DataTable_LinearProgressBar; diff --git a/src/core/components/DataTable/toolbar/TablePagination.js b/src/core/components/DataTable/toolbar/TablePagination.js index cd70fda..6492b41 100644 --- a/src/core/components/DataTable/toolbar/TablePagination.js +++ b/src/core/components/DataTable/toolbar/TablePagination.js @@ -1,16 +1,23 @@ import { flipIconStyles, getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils"; import { useTheme } from "@emotion/react"; -import { Box, IconButton, InputLabel, MenuItem, Pagination, PaginationItem, Select, Tooltip, Typography, useMediaQuery } from "@mui/material"; +import { + Box, + IconButton, + InputLabel, + MenuItem, + Pagination, + PaginationItem, + Select, + Tooltip, + Typography, + useMediaQuery, +} from "@mui/material"; const defaultRowsPerPage = [5, 10, 15, 20, 25, 30, 50, 100]; -const DataTable_TablePagination = ({ - position = 'bottom', - table, - ...rest -}) => { +const DataTable_TablePagination = ({ position = "bottom", table, ...rest }) => { const theme = useTheme(); - const isMobile = useMediaQuery('(max-width: 720px)'); + const isMobile = useMediaQuery("(max-width: 720px)"); const { getState, @@ -64,26 +71,21 @@ const DataTable_TablePagination = ({ {showRowsPerPage && ( - + {localization.rowsPerPage} @@ -92,22 +94,19 @@ const DataTable_TablePagination = ({ disableUnderline disabled={disabled} inputProps={{ - 'aria-label': localization.rowsPerPage, - id: 'mrt-rows-per-page', + "aria-label": localization.rowsPerPage, + id: "mrt-rows-per-page", }} label={localization.rowsPerPage} - onChange={(event) => - table.setPageSize(+(event.target.value)) - } + onChange={(event) => table.setPageSize(+event.target.value)} sx={{ mb: 0 }} value={pageSize} variant="standard" {...SelectProps} > {rowsPerPageOptions.map((option) => { - const value = typeof option !== 'number' ? option.value : option; - const label = - typeof option !== 'number' ? option.label : `${option}`; + const value = typeof option !== "number" ? option.value : option; + const label = typeof option !== "number" ? option.label : `${option}`; return ( SelectProps?.children ?? (SelectProps?.native ? ( @@ -124,7 +123,7 @@ const DataTable_TablePagination = ({ )} - {paginationDisplayMode === 'pages' ? ( + {paginationDisplayMode === "pages" ? ( - ) : paginationDisplayMode === 'default' ? ( + ) : paginationDisplayMode === "default" ? ( <> {`${lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString() - }-${lastRowIndex.toLocaleString()} ${localization.of - } ${totalRowCount.toLocaleString()}`} + >{`${ + lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString() + }-${lastRowIndex.toLocaleString()} ${ + localization.of + } ${totalRowCount.toLocaleString()}`} {showFirstButton && ( @@ -213,5 +214,5 @@ const DataTable_TablePagination = ({ ) : null} ); -} -export default DataTable_TablePagination \ No newline at end of file +}; +export default DataTable_TablePagination; diff --git a/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js b/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js index 606add0..9250b89 100644 --- a/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js +++ b/src/core/components/DataTable/toolbar/ToolbarInternalButtons.js @@ -16,32 +16,29 @@ const DataTable_ToolbarInternalButtons = ({ table, ...rest }) => { }, } = table; - return ( ({ - alignItems: 'center', - display: 'flex', + alignItems: "center", + display: "flex", zIndex: 3, - ...(parseFromValuesOrFunc(rest?.sx, theme)), + ...parseFromValuesOrFunc(rest?.sx, theme), })} > {renderToolbarInternalActions?.({ table, }) ?? ( - <> - {enableFilters && - enableColumnFilters && - columnFilterDisplayMode !== 'popover' && ( - - )} - {(enableHiding || enableColumnOrdering || enableColumnPinning) && ( - - )} - - )} + <> + {enableFilters && enableColumnFilters && columnFilterDisplayMode !== "popover" && ( + + )} + {(enableHiding || enableColumnOrdering || enableColumnPinning) && ( + + )} + + )} ); -} -export default DataTable_ToolbarInternalButtons \ No newline at end of file +}; +export default DataTable_ToolbarInternalButtons; diff --git a/src/core/components/DataTable/toolbar/TopToolbar.js b/src/core/components/DataTable/toolbar/TopToolbar.js index 7a321e2..b0e5297 100644 --- a/src/core/components/DataTable/toolbar/TopToolbar.js +++ b/src/core/components/DataTable/toolbar/TopToolbar.js @@ -1,12 +1,12 @@ -import {getCommonToolbarStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; -import {Box, useMediaQuery} from "@mui/material"; +import { getCommonToolbarStyles, parseFromValuesOrFunc } from "@/core/utils/utils"; +import { Box, 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"; -const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, table_name}) => { +const DataTable_TopToolbar = ({ table, columns, table_url, user_id, page_name, table_name }) => { const { getState, options: { @@ -16,19 +16,16 @@ const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, ta positionPagination, renderTopToolbarCustomActions, }, - refs: {topToolbarRef}, + refs: { topToolbarRef }, } = table; - const {isFullScreen, showGlobalFilter} = getState(); + const { isFullScreen, showGlobalFilter } = getState(); - const isMobile = useMediaQuery('(max-width:720px)'); - const isTablet = useMediaQuery('(max-width:1024px)'); + const isMobile = useMediaQuery("(max-width:720px)"); + const isTablet = useMediaQuery("(max-width:1024px)"); - const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, {table}); + const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, { table }); - const stackAlertBanner = - isMobile || - !!renderTopToolbarCustomActions || - (showGlobalFilter && isTablet); + const stackAlertBanner = isMobile || !!renderTopToolbarCustomActions || (showGlobalFilter && isTablet); return ( ({ - ...getCommonToolbarStyles({table, theme}), - position: isFullScreen ? 'sticky' : 'relative', - top: isFullScreen ? '0' : undefined, - ...(parseFromValuesOrFunc(toolbarProps?.sx, theme)), + ...getCommonToolbarStyles({ table, theme }), + position: isFullScreen ? "sticky" : "relative", + top: isFullScreen ? "0" : undefined, + ...parseFromValuesOrFunc(toolbarProps?.sx, theme), })} > - {renderTopToolbarCustomActions?.({table}) ?? } + {renderTopToolbarCustomActions?.({ table }) ?? } {enableToolbarInternalActions && ( - - - + + + )} - {enablePagination && - ['both', 'top'].includes(positionPagination ?? '') && ( - - )} - + {enablePagination && ["both", "top"].includes(positionPagination ?? "") && ( + + )} + ); -} +}; -export default DataTable_TopToolbar \ No newline at end of file +export default DataTable_TopToolbar; diff --git a/src/core/components/NotificationDesign/AskForKeep.jsx b/src/core/components/NotificationDesign/AskForKeep.jsx index 7a68d2f..d4721bb 100644 --- a/src/core/components/NotificationDesign/AskForKeep.jsx +++ b/src/core/components/NotificationDesign/AskForKeep.jsx @@ -1,47 +1,61 @@ -'use client' +"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}) { +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"}); + toast.dismiss({ containerId: "filtering" }); }; return ( - - - + + + ذخیره سازی اطلاعات - + - - - آیا مایل به ذخیره فیلتر های اعمال شده برای دفعات بعد هستید؟ - + + آیا مایل به ذخیره فیلتر های اعمال شده برای دفعات بعد هستید؟ - - - + + + ); } -export default AskForKeep; \ No newline at end of file +export default AskForKeep; diff --git a/src/core/components/SidebarListItems.jsx b/src/core/components/SidebarListItems.jsx index d300d7f..050d9a6 100644 --- a/src/core/components/SidebarListItems.jsx +++ b/src/core/components/SidebarListItems.jsx @@ -1,77 +1,53 @@ import SidebarSubitems from "@/core/components/SidebarSubitems"; import { ExpandLess, ExpandMore } from "@mui/icons-material"; -import { - Collapse, - List, - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, -} from "@mui/material"; +import { Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from "@mui/material"; import Link from "next/link"; const SidebarListItems = ({ menuItem, dispatch }) => { - return ( - <> - - { - dispatch({ type: "COLLAPSE_MENU", id: menuItem.id }); - }} - > - - {menuItem.icon} - - - {menuItem.hasSubitems ? ( - menuItem.showSubitems ? ( - - ) : ( - - ) - ) : null} - - - - {menuItem.hasSubitems ? ( - - {menuItem.Subitems.map((subitem, index) => { - return ( - - ); - })} - - ) : null} - - - ); + return ( + <> + + { + dispatch({ type: "COLLAPSE_MENU", id: menuItem.id }); + }} + > + + {menuItem.icon} + + + {menuItem.hasSubitems ? menuItem.showSubitems ? : : null} + + + + {menuItem.hasSubitems ? ( + + {menuItem.Subitems.map((subitem, index) => { + return ; + })} + + ) : null} + + + ); }; export default SidebarListItems; diff --git a/src/core/components/SidebarMenu.jsx b/src/core/components/SidebarMenu.jsx index c9f6a73..0ad01dc 100644 --- a/src/core/components/SidebarMenu.jsx +++ b/src/core/components/SidebarMenu.jsx @@ -6,127 +6,119 @@ import { useEffect, useReducer, useState } from "react"; import { pageMenu } from "../utils/pageMenu"; function reducer(state, action) { - switch (action.type) { - case "COLLAPSE_MENU": - return state.map((item) => - action.id == item.id - ? { - ...item, - showSubitems: !item.showSubitems, - } - : item - ); - case "COLLAPSE_SUB_ITEMS": - return state.map((item) => { - return item.hasSubitems - ? { - ...item, - Subitems: item.Subitems.map((subitem) => - action.id === subitem.id - ? { - ...subitem, - showSubitems: !subitem.showSubitems, - } - : subitem - ), - } - : item; - }); - case "COLLAPSE_SUB_SECOND_ITEMS": - return state.map((item) => { - return item.hasSubitems - ? { - ...item, - Subitems: item.Subitems.map((subitem) => { - return subitem.hasSubitems - ? { - ...subitem, - Subitems: subitem.Subitems.map((secondSubitem) => - action.id === secondSubitem.id - ? { - ...secondSubitem, - showSubitems: !secondSubitem.showSubitems, - } - : secondSubitem - ), - } - : subitem; - }), - } - : item; - }); - case "SELECTED": - return state.map((item) => { - return item.type === "page" - ? { - ...item, - selected: action.route === item.route, - showSubitems: item.route === action.route, - } - : item.Subitems && Array.isArray(item.Subitems) - ? { - ...item, - Subitems: item.Subitems.map((subitem) => { - return subitem.type === "page" - ? { - ...subitem, - selected: action.route === subitem.route, - showSubitems: subitem.route === action.route, - } - : subitem.Subitems && Array.isArray(subitem.Subitems) - ? { - ...subitem, - Subitems: subitem.Subitems.map((secondSubItem) => ({ - ...secondSubItem, - selected: secondSubItem.route === action.route, - })), - showSubitems: subitem.Subitems.some( - (secondSubItem) => secondSubItem.route === action.route - ), - } - : subitem; - }), - showSubitems: item.Subitems.some( - (subitem) => subitem.showSubitems - ), - } - : item; - }); + switch (action.type) { + case "COLLAPSE_MENU": + return state.map((item) => + action.id == item.id + ? { + ...item, + showSubitems: !item.showSubitems, + } + : item + ); + case "COLLAPSE_SUB_ITEMS": + return state.map((item) => { + return item.hasSubitems + ? { + ...item, + Subitems: item.Subitems.map((subitem) => + action.id === subitem.id + ? { + ...subitem, + showSubitems: !subitem.showSubitems, + } + : subitem + ), + } + : item; + }); + case "COLLAPSE_SUB_SECOND_ITEMS": + return state.map((item) => { + return item.hasSubitems + ? { + ...item, + Subitems: item.Subitems.map((subitem) => { + return subitem.hasSubitems + ? { + ...subitem, + Subitems: subitem.Subitems.map((secondSubitem) => + action.id === secondSubitem.id + ? { + ...secondSubitem, + showSubitems: !secondSubitem.showSubitems, + } + : secondSubitem + ), + } + : subitem; + }), + } + : item; + }); + case "SELECTED": + return state.map((item) => { + return item.type === "page" + ? { + ...item, + selected: action.route === item.route, + showSubitems: item.route === action.route, + } + : item.Subitems && Array.isArray(item.Subitems) + ? { + ...item, + Subitems: item.Subitems.map((subitem) => { + return subitem.type === "page" + ? { + ...subitem, + selected: action.route === subitem.route, + showSubitems: subitem.route === action.route, + } + : subitem.Subitems && Array.isArray(subitem.Subitems) + ? { + ...subitem, + Subitems: subitem.Subitems.map((secondSubItem) => ({ + ...secondSubItem, + selected: secondSubItem.route === action.route, + })), + showSubitems: subitem.Subitems.some( + (secondSubItem) => secondSubItem.route === action.route + ), + } + : subitem; + }), + showSubitems: item.Subitems.some((subitem) => subitem.showSubitems), + } + : item; + }); - default: - throw new Error(); - } + default: + throw new Error(); + } } const SidebarMenu = () => { - const [menuItems, dispatch] = useReducer(reducer, pageMenu); - const pathname = usePathname(); - const [selectedKey, setSelectedKey] = useState(null); - useEffect(() => { - dispatch({ type: "SELECTED", route: pathname }); - setSelectedKey(pathname); - }, [pathname]); + const [menuItems, dispatch] = useReducer(reducer, pageMenu); + const pathname = usePathname(); + const [selectedKey, setSelectedKey] = useState(null); + useEffect(() => { + dispatch({ type: "SELECTED", route: pathname }); + setSelectedKey(pathname); + }, [pathname]); - useEffect(() => { - selectedKey && - document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({ - behavior: "smooth", - block: "center", - }); - }, [selectedKey]); + useEffect(() => { + selectedKey && + document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + }, [selectedKey]); - return ( - - {menuItems.map((menuItem) => { - return ( - - ); - })} - - ); + return ( + + {menuItems.map((menuItem) => { + return ; + })} + + ); }; export default SidebarMenu; diff --git a/src/core/components/SidebarSubitems.jsx b/src/core/components/SidebarSubitems.jsx index b54d3a9..69418ea 100644 --- a/src/core/components/SidebarSubitems.jsx +++ b/src/core/components/SidebarSubitems.jsx @@ -1,75 +1,51 @@ import { ExpandLess, ExpandMore } from "@mui/icons-material"; -import { - Collapse, - List, - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, -} from "@mui/material"; +import { Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from "@mui/material"; import Link from "next/link"; const SidebarSubitems = ({ subitem, dispatch }) => { - return ( - <> - - { - dispatch({ type: "COLLAPSE_SUB_ITEMS", id: subitem.id }); - }} - > - - {subitem.icon} - - - {subitem.hasSubitems ? ( - subitem.showSubitems ? ( - - ) : ( - - ) - ) : null} - - - - {subitem.hasSubitems ? ( - - {subitem.Subitems.map((subSubitem, index) => { - return ( - - ); - })} - - ) : null} - - - ); + return ( + <> + + { + dispatch({ type: "COLLAPSE_SUB_ITEMS", id: subitem.id }); + }} + > + + {subitem.icon} + + + {subitem.hasSubitems ? subitem.showSubitems ? : : null} + + + + {subitem.hasSubitems ? ( + + {subitem.Subitems.map((subSubitem, index) => { + return ; + })} + + ) : null} + + + ); }; export default SidebarSubitems; diff --git a/src/core/components/Toasts/error.jsx b/src/core/components/Toasts/error.jsx index d0d9760..e93138b 100644 --- a/src/core/components/Toasts/error.jsx +++ b/src/core/components/Toasts/error.jsx @@ -3,189 +3,185 @@ import { Box, Typography } from "@mui/material"; import { Dangerous } from "@mui/icons-material"; export const errorServerToast = (toastContainer) => - toast.error( - () => ( - - - - - - {"The request failed due to an internal error."} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: 5000, - hideProgressBar: true, - pauseOnHover: true, - closeOnClick: false, - draggable: true, - } - ); + toast.error( + () => ( + + + + + {"The request failed due to an internal error."} + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 5000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); export const errorUnauthorizedToast = (toastContainer) => - toast.error( - () => ( - - - - - - {"The user is not authorized to make the request."} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: 3000, - hideProgressBar: true, - pauseOnHover: true, - closeOnClick: false, - draggable: true, - } - ); + toast.error( + () => ( + + + + + {"The user is not authorized to make the request."} + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); export const errorLogicToast = (message, toastContainer) => - toast.error( - () => ( - - - - - - {message || - "The request was well-formed but was unable to be followed due to semantic errors."} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: false, - closeOnClick: false, - draggable: false, - } - ); + toast.error( + () => ( + + + + + + {message || + "The request was well-formed but was unable to be followed due to semantic errors."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); export const errorValidationToast = (message, toastContainer) => - toast.error( - () => ( - - - - - - {message || - "The request was well-formed but was unable to be followed due to semantic errors."} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: false, - closeOnClick: false, - draggable: false, - } - ); + toast.error( + () => ( + + + + + + {message || + "The request was well-formed but was unable to be followed due to semantic errors."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); export const errorTooManyToast = (toastContainer) => - toast.error( - () => ( - - - - - - {"Too many requests have been sent within a given time span."} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: false, - closeOnClick: false, - draggable: false, - } - ); + toast.error( + () => ( + + + + + + {"Too many requests have been sent within a given time span."} + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); export const errorClientToast = (toastContainer) => - toast.error( - () => ( - - - - - - { - "The API request is invalid or improperly formed. Consequently, the API server could not understand the request." - } - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: false, - closeOnClick: false, - draggable: false, - } - ); + toast.error( + () => ( + + + + + + { + "The API request is invalid or improperly formed. Consequently, the API server could not understand the request." + } + + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); diff --git a/src/core/components/Toasts/success.jsx b/src/core/components/Toasts/success.jsx index b405a04..36023c6 100644 --- a/src/core/components/Toasts/success.jsx +++ b/src/core/components/Toasts/success.jsx @@ -3,33 +3,31 @@ import { Box, Typography } from "@mui/material"; import { Beenhere } from "@mui/icons-material"; export const successToast = (toastContainer) => - toast.success( - () => ( - - - - - - {"Your operation was successful"} - - - - - ), - { - icon: false, - containerId: toastContainer, - autoClose: 3000, - hideProgressBar: true, - pauseOnHover: true, - closeOnClick: false, - draggable: true, - } - ); + toast.success( + () => ( + + + + + {"Your operation was successful"} + + + + ), + { + icon: false, + containerId: toastContainer, + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); diff --git a/src/core/middlewares/withAuth.js b/src/core/middlewares/withAuth.js index 1b93025..216b55b 100644 --- a/src/core/middlewares/withAuth.js +++ b/src/core/middlewares/withAuth.js @@ -1,22 +1,22 @@ -'use client' +"use client"; import { useAuth } from "@/lib/contexts/auth"; import { usePathname, useRouter } from "next/navigation"; import { useEffect } from "react"; function WithAuthMiddleware({ children }) { - const router = useRouter() - const pathName = usePathname() + const router = useRouter(); + const pathName = usePathname(); const { isAuth, initAuthState } = useAuth(); useEffect(() => { - if (!initAuthState) return + if (!initAuthState) return; if (!isAuth) { - router.replace(`${process.env.NEXT_PUBLIC_API_URL}/login?_back=${encodeURIComponent(pathName)}`) + router.replace(`${process.env.NEXT_PUBLIC_API_URL}/login?_back=${encodeURIComponent(pathName)}`); } - }, [isAuth, initAuthState]) + }, [isAuth, initAuthState]); if (!initAuthState || !isAuth) return null; - return <>{children} + return <>{children}; } -export default WithAuthMiddleware \ No newline at end of file +export default WithAuthMiddleware; diff --git a/src/core/utils/cacheRtl.js b/src/core/utils/cacheRtl.js index bf8c809..1393e2e 100644 --- a/src/core/utils/cacheRtl.js +++ b/src/core/utils/cacheRtl.js @@ -1,16 +1,16 @@ -'use client' +"use client"; import createCache from "@emotion/cache"; -import {prefixer} from "stylis"; +import { prefixer } from "stylis"; import stylisRTLPlugin from "stylis-plugin-rtl"; -import {CacheProvider} from "@emotion/react"; +import { CacheProvider } from "@emotion/react"; const cache = createCache({ - key: 'mui-rtl', + key: "mui-rtl", stylisPlugins: [prefixer, stylisRTLPlugin], }); const cacheProviderRtl = (props) => { return {props.children}; -} +}; -export default cacheProviderRtl \ No newline at end of file +export default cacheProviderRtl; diff --git a/src/core/utils/errorResponse.js b/src/core/utils/errorResponse.js index 3accb8f..1802581 100644 --- a/src/core/utils/errorResponse.js +++ b/src/core/utils/errorResponse.js @@ -1,4 +1,4 @@ -'use client' +"use client"; import { toast } from "react-toastify"; import { errorClientToast, @@ -6,56 +6,55 @@ import { errorServerToast, errorTooManyToast, errorUnauthorizedToast, - errorValidationToast + errorValidationToast, } from "@/core/components/toasts/error"; -const isServerError = status => status >= 500 && status <= 599; -const isClientError = status => status >= 400 && status <= 499; +const isServerError = (status) => status >= 500 && status <= 599; +const isClientError = (status) => status >= 400 && status <= 499; const errorServer = (response, notification, toastContainer) => { - if (notification) errorServerToast(toastContainer) -} + if (notification) errorServerToast(toastContainer); +}; const errorClient = (response, notification, toastContainer) => { switch (response.status) { case 401: - if (notification) errorUnauthorizedToast(toastContainer) + if (notification) errorUnauthorizedToast(toastContainer); break; case 422: - if ('type' in response.data) { + if ("type" in response.data) { if (Array.isArray(response.data.message)) { response.data.message.map((item) => { - if (notification) errorLogicToast(item, toastContainer) - }) + if (notification) errorLogicToast(item, toastContainer); + }); } else { - if (notification) errorLogicToast(response.data.message, toastContainer) + if (notification) errorLogicToast(response.data.message, toastContainer); } break; } if (notification) { - const errorsMap = Object.keys(response.data.errors) - const errorsArray = response.data.errors + const errorsMap = Object.keys(response.data.errors); + const errorsArray = response.data.errors; errorsMap.map((item, index) => { errorValidationToast(errorsArray[item][0], toastContainer); - }) - + }); } break; case 429: - if (notification) errorTooManyToast(toastContainer) - break + if (notification) errorTooManyToast(toastContainer); + break; default: - if (notification) errorClientToast(toastContainer) - break + if (notification) errorClientToast(toastContainer); + break; } -} +}; export const errorResponse = (response, notification, toastContainer) => { - if (notification) toast.dismiss({ container: toastContainer }) + if (notification) toast.dismiss({ container: toastContainer }); if (isServerError(response.status)) { - errorServer(response, notification, toastContainer) + errorServer(response, notification, toastContainer); } else if (isClientError(response.status)) { - errorClient(response, notification, toastContainer) + errorClient(response, notification, toastContainer); } -} +}; diff --git a/src/core/utils/flattenArrayOfObjects.js b/src/core/utils/flattenArrayOfObjects.js index 4dd4612..5b1564c 100644 --- a/src/core/utils/flattenArrayOfObjects.js +++ b/src/core/utils/flattenArrayOfObjects.js @@ -7,4 +7,4 @@ export const flattenArrayOfObjects = (array, key) => { } return acc; }, []); -}; \ No newline at end of file +}; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 81cb873..6145ffd 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -2,346 +2,346 @@ import { AirlineSeatReclineNormal, Assessment, Repartition, Security, SpaceDashb export const pageMenu = [ { - id: 'dashboard', - label: 'پیشخوان', + id: "dashboard", + label: "پیشخوان", type: "page", route: "/dashboard", - icon: , + icon: , }, { - id: 'userManagement', - label: 'مدیریت کاربران', + id: "userManagement", + label: "مدیریت کاربران", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", - icon: , + icon: , }, { - id: 'projectsManagment', - label: 'پروژه های راهداری', + id: "projectsManagment", + label: "پروژه های راهداری", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'projectsManagmentFinance', - label: 'ثبت قرارداد و پروژه', + id: "projectsManagmentFinance", + label: "ثبت قرارداد و پروژه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", - icon: , + icon: , }, { - id: 'projectsManagmentList', - label: 'لیست پروژه ها', + id: "projectsManagmentList", + label: "لیست پروژه ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", - icon: , + icon: , }, { - id: 'projectsManagmentProposal', - label: 'پروژه های پیشنهادی', + id: "projectsManagmentProposal", + label: "پروژه های پیشنهادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", - icon: , + icon: , }, { - id: 'projectsManagmentLawmaker', - label: 'درخواست نمایندگان', + id: "projectsManagmentLawmaker", + label: "درخواست نمایندگان", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", - icon: , + icon: , }, { - id: 'projectsManagmentMap', - label: 'پراکندگی بر روی نقشه', + id: "projectsManagmentMap", + label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", - icon: , + icon: , }, - ] + ], }, { - id: 'roadItemManagment', - label: 'فعالیت های روزانه', + id: "roadItemManagment", + label: "فعالیت های روزانه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadItemManagmentSupervisor', - label: 'ارزیابی', + id: "roadItemManagmentSupervisor", + label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadItemManagmentSupervisorCartable', - label: 'کارتابل', + id: "roadItemManagmentSupervisorCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable", }, - ] + ], }, { - id: 'roadItemManagmentOparation', - label: 'عملیات', + id: "roadItemManagmentOparation", + label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadItemManagmentOparationCreate', - label: 'ثبت فعالیت', + id: "roadItemManagmentOparationCreate", + label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create", }, { - id: 'roadItemManagmentOparationCartable', - label: 'کارتابل', + id: "roadItemManagmentOparationCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable", }, - ] + ], }, { - id: 'roadItemManagmentMap', - label: 'پراکندگی بر روی نقشه', + id: "roadItemManagmentMap", + label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", - icon: , + icon: , }, { - id: 'roadItemManagmentReport', - label: 'گزارش ها', + id: "roadItemManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", - icon: , + icon: , }, - ] + ], }, { - id: 'roadPatrolManagment', - label: 'گشت راهداری و ترابری', + id: "roadPatrolManagment", + label: "گشت راهداری و ترابری", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadPatrolManagmentSupervisor', - label: 'ارزیابی', + id: "roadPatrolManagmentSupervisor", + label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadPatrolManagmentSupervisorCartable', - label: 'کارتابل', + id: "roadPatrolManagmentSupervisorCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable", }, - ] + ], }, { - id: 'roadPatrolManagmentOparation', - label: 'عملیات', + id: "roadPatrolManagmentOparation", + label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadPatrolManagmentOparationCreate', - label: 'ثبت اقدام', + id: "roadPatrolManagmentOparationCreate", + label: "ثبت اقدام", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", }, { - id: 'roadPatrolManagmentOparationCartable', - label: 'کارتابل', + id: "roadPatrolManagmentOparationCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", }, - ] + ], }, { - id: 'roadPatrolManagmentMap', - label: 'پراکندگی بر روی نقشه', + id: "roadPatrolManagmentMap", + label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", - icon: , + icon: , }, { - id: 'roadPatrolManagmentReport', - label: 'گزارش ها', + id: "roadPatrolManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", - icon: , + icon: , }, - ] + ], }, { - id: 'safetyAndPrivacyManagment', - label: 'نگهداری حریم راه', + id: "safetyAndPrivacyManagment", + label: "نگهداری حریم راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'safetyAndPrivacyManagmentOparation', - label: 'عملیات', + id: "safetyAndPrivacyManagmentOparation", + label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'safetyAndPrivacyManagmentOparationCreate', - label: 'ثبت فعالیت', + id: "safetyAndPrivacyManagmentOparationCreate", + label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step", }, { - id: 'safetyAndPrivacyManagmentOparationCartable', - label: 'کارتابل', + id: "safetyAndPrivacyManagmentOparationCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", }, - ] + ], }, { - id: 'safetyAndPrivacyManagmentMap', - label: 'پراکندگی بر روی نقشه', + id: "safetyAndPrivacyManagmentMap", + label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", - icon: , + icon: , }, { - id: 'safetyAndPrivacyManagmentReport', - label: 'گزارش ها', + id: "safetyAndPrivacyManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", - icon: , + icon: , }, - ] + ], }, { - id: 'roadObservationsManagment', - label: 'واکنش سریع', + id: "roadObservationsManagment", + label: "واکنش سریع", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadObservationsManagmentSupervisor', - label: 'ارزیابی', + id: "roadObservationsManagmentSupervisor", + label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadObservationsManagmentSupervisorCartable', - label: 'کارتابل', + id: "roadObservationsManagmentSupervisorCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable", }, - ] + ], }, { - id: 'roadObservationsManagmentList', - label: 'رسیدگی به شکایات', + id: "roadObservationsManagmentList", + label: "رسیدگی به شکایات", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", - icon: , + icon: , }, { - id: 'roadObservationsManagmentOparation', - label: 'عملیات', + id: "roadObservationsManagmentOparation", + label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'roadObservationsManagmentOparationCartable', - label: 'کارتابل', + id: "roadObservationsManagmentOparationCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable", }, - ] + ], }, { - id: 'roadObservationsManagmentMap', - label: 'پراکندگی بر روی نقشه', + id: "roadObservationsManagmentMap", + label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", - icon: , + icon: , }, { - id: 'roadObservationsManagmentReport', - label: 'گزارش ها', + id: "roadObservationsManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", - icon: , + icon: , }, - ] + ], }, { - id: 'winterCampManagment', - label: 'قرارگاه زمستانی', + id: "winterCampManagment", + label: "قرارگاه زمستانی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'winterCampManagmentBlocking', - label: 'محور های انسدادی', + id: "winterCampManagmentBlocking", + label: "محور های انسدادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", - icon: , + icon: , }, { - id: 'winterCampManagmentFirstRing', - label: 'محور های حلقه اول', + id: "winterCampManagmentFirstRing", + label: "محور های حلقه اول", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", - icon: , + icon: , }, { - id: 'winterCampManagmentReport', - label: 'گزارش ها', + id: "winterCampManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", - icon: , + icon: , }, - ] + ], }, { - id: 'receiptManagment', - label: 'خسارات وارده بر ابنیه فنی و تاسیسات راه', + id: "receiptManagment", + label: "خسارات وارده بر ابنیه فنی و تاسیسات راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'receiptManagmentOparation', - label: 'عملیات', + id: "receiptManagmentOparation", + label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { - id: 'receiptManagmentOparationCartable', - label: 'کارتابل', + id: "receiptManagmentOparationCartable", + label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt", }, - ] + ], }, { - id: 'receiptManagmentReport', - label: 'گزارش ها', + id: "receiptManagmentReport", + label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", - icon: , + icon: , }, - ] - } + ], + }, // { // id: "hello", // type: "menu", @@ -383,4 +383,4 @@ export const pageMenu = [ // hasSubitems: true, // showSubitems: false // }, -] \ No newline at end of file +]; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 39b6b09..8fae96f 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -1,4 +1,4 @@ -const api = process.env.NEXT_PUBLIC_API_URL +const api = process.env.NEXT_PUBLIC_API_URL; -export const GET_USER_ROUTE = api + '/webapi/user/get-permission' -export const GET_LOGIN_ROUTE = api + '/test_login' \ No newline at end of file +export const GET_USER_ROUTE = api + "/webapi/user/get-permission"; +export const GET_LOGIN_ROUTE = api + "/login_dev"; diff --git a/src/core/utils/successRequest.js b/src/core/utils/successRequest.js index 5138d7a..d23776a 100644 --- a/src/core/utils/successRequest.js +++ b/src/core/utils/successRequest.js @@ -1,10 +1,10 @@ -'use client' +"use client"; import { toast } from "react-toastify"; import { successToast } from "@/core/components/toasts/success"; export const successRequest = (notification, toastContainer) => { if (notification) { - toast.dismiss({ container: toastContainer }) - successToast(toastContainer) + toast.dismiss({ container: toastContainer }); + successToast(toastContainer); } -} \ No newline at end of file +}; diff --git a/src/core/utils/theme.js b/src/core/utils/theme.js index 581e23e..f32031b 100644 --- a/src/core/utils/theme.js +++ b/src/core/utils/theme.js @@ -1,22 +1,22 @@ -'use client' +"use client"; import { createTheme } from "@mui/material"; const theme = createTheme({ - direction: 'rtl', + direction: "rtl", typography: { fontFamily: `IRANSansFaNum, sans-serif`, - fontSize: 12 + fontSize: 12, }, palette: { primary: { - main: '#2070af', - contrastText: '#fff' + main: "#2070af", + contrastText: "#fff", }, primary2: { - main: '#015688', - contrastText: '#fff' + main: "#015688", + contrastText: "#fff", }, - } + }, }); -export default theme \ No newline at end of file +export default theme; diff --git a/src/core/utils/utils.js b/src/core/utils/utils.js index 98e0252..a0a320d 100644 --- a/src/core/utils/utils.js +++ b/src/core/utils/utils.js @@ -1,162 +1,120 @@ import { alpha, darken } from "@mui/material"; -export const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, '_'); +export const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, "_"); -export const parseFromValuesOrFunc = ( - fn, - arg -) => (fn instanceof Function ? fn(arg) : fn); +export const parseFromValuesOrFunc = (fn, arg) => (fn instanceof Function ? fn(arg) : fn); -export const getCommonToolbarStyles = ({ - table, -}) => ({ - alignItems: 'flex-start', - backgroundColor: table.options.mrtTheme.baseBackgroundColor, - display: 'grid', - flexWrap: 'wrap-reverse', - minHeight: '3.5rem', - overflow: 'hidden', - position: 'relative', - transition: 'all 150ms ease-in-out', - zIndex: 1, +export const getCommonToolbarStyles = ({ table }) => ({ + alignItems: "flex-start", + backgroundColor: table.options.mrtTheme.baseBackgroundColor, + display: "grid", + flexWrap: "wrap-reverse", + minHeight: "3.5rem", + overflow: "hidden", + position: "relative", + transition: "all 150ms ease-in-out", + zIndex: 1, }); -export const getCommonTooltipProps = ( - placement, -) => ({ - disableInteractive: true, - enterDelay: 500, - enterNextDelay: 500, - placement, +export const getCommonTooltipProps = (placement) => ({ + disableInteractive: true, + enterDelay: 500, + enterNextDelay: 500, + placement, }); export const flipIconStyles = (theme) => - theme.direction === 'rtl' - ? { style: { transform: 'scaleX(-1)' } } - : undefined; + theme.direction === "rtl" ? { style: { transform: "scaleX(-1)" } } : undefined; -export const getCommonPinnedCellStyles = ({ - column, - table, - theme, -}) => { - const { baseBackgroundColor } = table.options.mrtTheme; - const isPinned = column?.getIsPinned(); +export const getCommonPinnedCellStyles = ({ column, table, theme }) => { + const { baseBackgroundColor } = table.options.mrtTheme; + const isPinned = column?.getIsPinned(); - return { - '&[data-pinned="true"]': { - '&:before': { - backgroundColor: alpha( - darken( - baseBackgroundColor, - theme.palette.mode === 'dark' ? 0.05 : 0.01, - ), - 0.97, - ), - boxShadow: column - ? isPinned === 'left' && column.getIsLastColumn(isPinned) - ? `-4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` - : isPinned === 'right' && column.getIsFirstColumn(isPinned) - ? `4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` - : undefined - : undefined, - ...commonCellBeforeAfterStyles, - }, - }, - }; + return { + '&[data-pinned="true"]': { + "&:before": { + backgroundColor: alpha(darken(baseBackgroundColor, theme.palette.mode === "dark" ? 0.05 : 0.01), 0.97), + boxShadow: column + ? isPinned === "left" && column.getIsLastColumn(isPinned) + ? `-4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` + : isPinned === "right" && column.getIsFirstColumn(isPinned) + ? `4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` + : undefined + : undefined, + ...commonCellBeforeAfterStyles, + }, + }, + }; }; -export const getCommonMRTCellStyles = ({ - column, - header, - table, - tableCellProps, - theme, -}) => { - const { - getState, - options: { enableColumnVirtualization, layoutMode }, - } = table; - const { draggingColumn } = getState(); - const { columnDef } = column; - const { columnDefType } = columnDef; +export const getCommonMRTCellStyles = ({ column, header, table, tableCellProps, theme }) => { + const { + getState, + options: { enableColumnVirtualization, layoutMode }, + } = table; + const { draggingColumn } = getState(); + const { columnDef } = column; + const { columnDefType } = columnDef; - const isColumnPinned = - columnDef.columnDefType !== 'group' && column.getIsPinned(); + const isColumnPinned = columnDef.columnDefType !== "group" && column.getIsPinned(); - const widthStyles = { - minWidth: `max(calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId( - header?.id ?? column.id, - )}-size) * 1px), ${columnDef.minSize ?? 30}px)`, - width: `calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId( - header?.id ?? column.id, - )}-size) * 1px)`, - }; + const widthStyles = { + minWidth: `max(calc(var(--${header ? "header" : "col"}-${parseCSSVarId( + header?.id ?? column.id + )}-size) * 1px), ${columnDef.minSize ?? 30}px)`, + width: `calc(var(--${header ? "header" : "col"}-${parseCSSVarId(header?.id ?? column.id)}-size) * 1px)`, + }; - if (layoutMode === 'grid') { - widthStyles.flex = `${[0, false].includes(columnDef.grow) - ? 0 - : `var(--${header ? 'header' : 'col'}-${parseCSSVarId( - header?.id ?? column.id, - )}-size)` - } 0 auto`; - } else if (layoutMode === 'grid-no-grow') { - widthStyles.flex = `${+(columnDef.grow || 0)} 0 auto`; - } - - const pinnedStyles = isColumnPinned - ? { - ...getCommonPinnedCellStyles({ column, table, theme }), - left: - isColumnPinned === 'left' - ? `${column.getStart('left')}px` - : undefined, - opacity: 0.97, - position: 'sticky', - right: - isColumnPinned === 'right' - ? `${column.getAfter('right')}px` - : undefined, + if (layoutMode === "grid") { + widthStyles.flex = `${ + [0, false].includes(columnDef.grow) + ? 0 + : `var(--${header ? "header" : "col"}-${parseCSSVarId(header?.id ?? column.id)}-size)` + } 0 auto`; + } else if (layoutMode === "grid-no-grow") { + widthStyles.flex = `${+(columnDef.grow || 0)} 0 auto`; } - : {}; - return { - backgroundColor: 'inherit', - backgroundImage: 'inherit', - display: layoutMode?.startsWith('grid') ? 'flex' : undefined, - justifyContent: - columnDefType === 'group' - ? 'center' - : layoutMode?.startsWith('grid') - ? tableCellProps.align - : undefined, - opacity: - table.getState().draggingColumn?.id === column.id || - table.getState().hoveredColumn?.id === column.id - ? 0.5 - : 1, - position: 'relative', - transition: enableColumnVirtualization - ? 'none' - : `padding 150ms ease-in-out`, - zIndex: - column.getIsResizing() || draggingColumn?.id === column.id - ? 2 - : columnDefType !== 'group' && isColumnPinned - ? 1 - : 0, - ...pinnedStyles, - ...widthStyles, - ...(parseFromValuesOrFunc(tableCellProps?.sx, theme)), - }; + const pinnedStyles = isColumnPinned + ? { + ...getCommonPinnedCellStyles({ column, table, theme }), + left: isColumnPinned === "left" ? `${column.getStart("left")}px` : undefined, + opacity: 0.97, + position: "sticky", + right: isColumnPinned === "right" ? `${column.getAfter("right")}px` : undefined, + } + : {}; + + return { + backgroundColor: "inherit", + backgroundImage: "inherit", + display: layoutMode?.startsWith("grid") ? "flex" : undefined, + justifyContent: + columnDefType === "group" ? "center" : layoutMode?.startsWith("grid") ? tableCellProps.align : undefined, + opacity: + table.getState().draggingColumn?.id === column.id || table.getState().hoveredColumn?.id === column.id + ? 0.5 + : 1, + position: "relative", + transition: enableColumnVirtualization ? "none" : `padding 150ms ease-in-out`, + zIndex: + column.getIsResizing() || draggingColumn?.id === column.id + ? 2 + : columnDefType !== "group" && isColumnPinned + ? 1 + : 0, + ...pinnedStyles, + ...widthStyles, + ...parseFromValuesOrFunc(tableCellProps?.sx, theme), + }; }; export const commonCellBeforeAfterStyles = { - content: '""', - height: '100%', - left: 0, - position: 'absolute', - top: 0, - width: '100%', - zIndex: -1, -}; \ No newline at end of file + content: '""', + height: "100%", + left: 0, + position: "absolute", + top: 0, + width: "100%", + zIndex: -1, +}; diff --git a/src/lib/contexts/DataTable.js b/src/lib/contexts/DataTable.js index 975b859..fb03fd7 100644 --- a/src/lib/contexts/DataTable.js +++ b/src/lib/contexts/DataTable.js @@ -1,15 +1,11 @@ -import {createContext, useState} from "react"; +import { createContext, useState } from "react"; export const DataTableContext = createContext(); -const DataTableProvider = ({children}) => { +const DataTableProvider = ({ children }) => { const [filterData, setFilterData] = useState({}); - return ( - - {children} - - ); + return {children}; }; -export default DataTableProvider; \ No newline at end of file +export default DataTableProvider; diff --git a/src/lib/contexts/auth.js b/src/lib/contexts/auth.js index e60f413..f2df0e6 100644 --- a/src/lib/contexts/auth.js +++ b/src/lib/contexts/auth.js @@ -1,12 +1,12 @@ -'use client' -import { createContext, useCallback, useContext, useEffect, useReducer } from 'react'; -import useRequest from '../hooks/useRequest'; -import { GET_USER_ROUTE } from '@/core/utils/routes'; +"use client"; +import { createContext, useCallback, useContext, useEffect, useReducer } from "react"; +import useRequest from "../hooks/useRequest"; +import { GET_USER_ROUTE } from "@/core/utils/routes"; const initAuth = { initAuthState: false, isAuth: false, - user: {} + user: {}, }; const authReducer = (state, action) => { @@ -28,7 +28,7 @@ const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [state, dispatch] = useReducer(authReducer, initAuth); - const request = useRequest() + const request = useRequest(); const clearUser = useCallback(() => { dispatch({ type: "CLEAR_USER" }); @@ -48,7 +48,7 @@ export const AuthProvider = ({ children }) => { const getUser = useCallback(async () => { try { - const { data } = await request(GET_USER_ROUTE, 'get') + const { data } = await request(GET_USER_ROUTE, "get"); changeUser(data); changeAuthState(true); changeInitAuth(true); @@ -62,15 +62,21 @@ export const AuthProvider = ({ children }) => { }, [clearUser, changeUser, changeAuthState, changeInitAuth]); useEffect(() => { - getUser() - }, []) + getUser(); + }, []); - return {children}; + return ( + + {children} + + ); }; -export const useAuth = () => useContext(AuthContext); \ No newline at end of file +export const useAuth = () => useContext(AuthContext); diff --git a/src/lib/contexts/tableSetting.js b/src/lib/contexts/tableSetting.js index abc2ad7..3611df9 100644 --- a/src/lib/contexts/tableSetting.js +++ b/src/lib/contexts/tableSetting.js @@ -1,26 +1,26 @@ -'use client' -import {createContext, useCallback, useEffect, useState} from "react"; +"use client"; +import { createContext, useCallback, useEffect, useState } from "react"; export const TableSettingContext = createContext(); -export const TableSettingProvider = ({children}) => { +export const TableSettingProvider = ({ children }) => { const [settingStore, setSettingStore] = useState({}); useEffect(() => { - const _localStorage = localStorage.getItem("_setting-app") + const _localStorage = localStorage.getItem("_setting-app"); if (_localStorage) { - setSettingStore(JSON.parse(_localStorage)) + setSettingStore(JSON.parse(_localStorage)); } }, []); const hideAction = useCallback((user_id, page_name, table_name, settingValue, columns) => { updateSettingStorage(user_id, page_name, table_name, "hides", settingValue, columns); - }, []) + }, []); const sortAction = useCallback((user_id, page_name, table_name, settingValue, columns) => { updateSettingStorage(user_id, page_name, table_name, "sorts", settingValue, columns); - }, []) + }, []); const filterAction = (user_id, page_name, table_name, settingValue, columns) => { updateSettingStorage(user_id, page_name, table_name, "filters", settingValue, columns); - } + }; const updateSettingStorage = (user_id, page_name, table_name, settingType, settingValue, columns) => { const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; const userSettings = prevLocalStorage[user_id] || {}; @@ -30,7 +30,7 @@ export const TableSettingProvider = ({children}) => { if (settingType === "sorts" || settingType === "filters") { newSettings = [...settingValue]; } else { - newSettings = {...tableSettings[settingType] || {}, ...settingValue}; + newSettings = { ...(tableSettings[settingType] || {}), ...settingValue }; } const updatedLocalStorage = { ...prevLocalStorage, @@ -40,18 +40,21 @@ export const TableSettingProvider = ({children}) => { ...pageSettings, [table_name]: { ...tableSettings, - [settingType]: Array.isArray(settingValue) ? [...newSettings] : {...newSettings}, - summary: SummaryTextMessage({ - ...tableSettings, - [settingType]: Array.isArray(settingValue) ? [...newSettings] : {...newSettings}, - }, columns) + [settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings }, + summary: SummaryTextMessage( + { + ...tableSettings, + [settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings }, + }, + columns + ), }, }, }, }; localStorage.setItem("_setting-app", JSON.stringify(updatedLocalStorage)); setSettingStore(updatedLocalStorage); - } + }; const refactorAction = (user_id, page_name, table_name) => { const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; const userSettings = prevLocalStorage[user_id] || {}; @@ -68,7 +71,7 @@ export const TableSettingProvider = ({children}) => { }; localStorage.setItem("_setting-app", JSON.stringify(refactorData)); setSettingStore(refactorData); - } + }; const SummaryTextMessage = (values, columns) => { let SummaryText = ""; let HideText = ""; @@ -76,38 +79,35 @@ export const TableSettingProvider = ({children}) => { let SortText = ""; if (values.sorts && values.sorts.length > 0) { - const _list = [] + const _list = []; for (const sort of values.sorts) { - const _column = columns.find(column => column.id == sort.id) - if (_column) - _list.push(`${_column.header}` + `(${sort.desc ? "نزولی" : "صعودی"})`) + const _column = columns.find((column) => column.id == sort.id); + if (_column) _list.push(`${_column.header}` + `(${sort.desc ? "نزولی" : "صعودی"})`); } - if (_list.length > 0) - SortText = " مرتب شده بر اساس : " + _list.join(", ") + if (_list.length > 0) SortText = " مرتب شده بر اساس : " + _list.join(", "); } if (values.filters && values.filters.length > 0) { - const _list = [] + const _list = []; for (const filter of values.filters) { - const _column = columns.find(column => column.id == filter.id) - if (_column) - _list.push(`${_column.header}`) + const _column = columns.find((column) => column.id == filter.id); + if (_column) _list.push(`${_column.header}`); } - if (_list.length > 0) - FilterText = " فیلتر شده بر اساس : " + _list.join(", ") + if (_list.length > 0) FilterText = " فیلتر شده بر اساس : " + _list.join(", "); } if (values.hides) { - const hidesArray = Object.entries(values.hides).map((e) => ({id: e[0], value: e[1]})) + const hidesArray = Object.entries(values.hides).map((e) => ({ + id: e[0], + value: e[1], + })); if (hidesArray.length > 0) { - const _list = [] + const _list = []; for (const hide of hidesArray) { - if (hide.value) continue - const _column = columns.find(c => c.id == hide.id) - if (_column) - _list.push(_column.header) + if (hide.value) continue; + const _column = columns.find((c) => c.id == hide.id); + if (_column) _list.push(_column.header); } - if (_list.length > 0) - HideText = "ستون های مخفی شده : " + _list.join(", "); + if (_list.length > 0) HideText = "ستون های مخفی شده : " + _list.join(", "); } } @@ -128,7 +128,7 @@ export const TableSettingProvider = ({children}) => { } } if (FilterText) { - SummaryText += FilterText + SummaryText += FilterText; } } @@ -137,8 +137,15 @@ export const TableSettingProvider = ({children}) => { return ( + value={{ + settingStore, + hideAction, + sortAction, + filterAction, + refactorAction, + }} + > {children} ); -}; \ No newline at end of file +}; diff --git a/src/lib/hooks/useDataTable.js b/src/lib/hooks/useDataTable.js index ba7acb5..e396908 100644 --- a/src/lib/hooks/useDataTable.js +++ b/src/lib/hooks/useDataTable.js @@ -1,9 +1,9 @@ -import {useContext} from "react"; -import {DataTableContext} from "@/lib/contexts/DataTable"; +import { useContext } from "react"; +import { DataTableContext } from "@/lib/contexts/DataTable"; const useTableSetting = () => { - const {filterData, setFilterData} = useContext(DataTableContext); - return {filterData, setFilterData}; + const { filterData, setFilterData } = useContext(DataTableContext); + return { filterData, setFilterData }; }; export default useTableSetting; diff --git a/src/lib/hooks/useRequest.js b/src/lib/hooks/useRequest.js index 8beee2e..2e35512 100644 --- a/src/lib/hooks/useRequest.js +++ b/src/lib/hooks/useRequest.js @@ -5,38 +5,42 @@ import axios from "axios"; const defaultOptions = { data: {}, requestOptions: { - headers: {} + headers: {}, }, notification: { show: true, success: false, - failed: true + failed: true, }, -} +}; const useRequest = (initOptions) => { const _options = Object.assign({}, defaultOptions, initOptions); - return async (url = '', method = 'get', options) => { + return async (url = "", method = "get", options) => { const mergedOptions = Object.assign({}, _options, options); try { const response = await axios({ url, method, - data: method === 'get' ? null : mergedOptions.data, + data: method === "get" ? null : mergedOptions.data, withCredentials: true, - ...mergedOptions.requestOptions + ...mergedOptions.requestOptions, }); - successRequest(mergedOptions.notification.show && mergedOptions.notification.success, 'request_data'); + successRequest(mergedOptions.notification.show && mergedOptions.notification.success, "request_data"); return response; } catch (error) { if (error.response) { - errorResponse(error.response, mergedOptions.notification.show && mergedOptions.notification.failed, 'request_data'); + errorResponse( + error.response, + mergedOptions.notification.show && mergedOptions.notification.failed, + "request_data" + ); } throw error; } - } -} + }; +}; -export default useRequest \ No newline at end of file +export default useRequest; diff --git a/src/lib/hooks/useTableSetting.js b/src/lib/hooks/useTableSetting.js index 7617655..6588446 100644 --- a/src/lib/hooks/useTableSetting.js +++ b/src/lib/hooks/useTableSetting.js @@ -1,10 +1,9 @@ -import {useContext} from "react"; -import {TableSettingContext} from "../contexts/tableSetting"; +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}; + const { settingStore, hideAction, sortAction, filterAction, refactorAction } = useContext(TableSettingContext); + return { settingStore, hideAction, sortAction, filterAction, refactorAction }; }; export default useTableSetting; From ad367284113d65dee3336b67936713e853702363 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Tue, 9 Jul 2024 14:11:38 +0330 Subject: [PATCH 25/28] formatted --- src/app/(withAuth)/dashboard/page.js | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/app/(withAuth)/dashboard/page.js b/src/app/(withAuth)/dashboard/page.js index c06d81d..a7efa2a 100644 --- a/src/app/(withAuth)/dashboard/page.js +++ b/src/app/(withAuth)/dashboard/page.js @@ -1,31 +1,9 @@ "use client"; -import { Button } from "@mui/material"; -import axios from "axios"; const Page = () => { - const handler = () => { - try { - axios.get("https://rms.witel.ir/test_login?username=witel", { - withCredentials: true, - }); - } catch (error) { - console.log(error); - } - }; - const handler2 = () => { - try { - const res = axios.get("https://rms.witel.ir/webapi/user/get-permission", { - withCredentials: true, - }); - console.log(res); - } catch (error) { - console.log(error); - } - }; + return ( <> - - ); }; From 6b78309e37ffbcc3caf4f99491263ad9ad404676 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Wed, 10 Jul 2024 11:21:32 +0330 Subject: [PATCH 26/28] permissions for sidebar --- .../fieldsType/CustomDate/MuiDatePicker.jsx | 3 - src/core/components/SidebarMenu.jsx | 96 +++++++++++-------- src/core/utils/filterMenuItems.js | 17 ++++ src/core/utils/pageMenu.js | 74 +++++++------- src/core/utils/routes.js | 2 + src/lib/hooks/usePermissions.js | 18 ++++ 6 files changed, 124 insertions(+), 86 deletions(-) create mode 100644 src/core/utils/filterMenuItems.js create mode 100644 src/lib/hooks/usePermissions.js diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx index d715192..b4da7f5 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx @@ -7,9 +7,6 @@ import ClearIcon from "@mui/icons-material/Clear"; import moment from "jalali-moment"; function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) { - // console.log("error", error); - // - // console.log("helperText", helperText) return ( diff --git a/src/core/components/SidebarMenu.jsx b/src/core/components/SidebarMenu.jsx index 0ad01dc..326dd11 100644 --- a/src/core/components/SidebarMenu.jsx +++ b/src/core/components/SidebarMenu.jsx @@ -1,80 +1,86 @@ "use client"; import SidebarListItems from "@/core/components/SidebarListItems"; +import { usePermissions } from "@/lib/hooks/usePermissions"; import { List } from "@mui/material"; import { usePathname } from "next/navigation"; import { useEffect, useReducer, useState } from "react"; +import { filterMenuItems } from "../utils/filterMenuItems"; import { pageMenu } from "../utils/pageMenu"; function reducer(state, action) { switch (action.type) { + case "UPDATE_MENU": + const _permissions = action.permissions || [] + const filteredPageMenu = filterMenuItems(pageMenu, ['all', ..._permissions]) + return filteredPageMenu case "COLLAPSE_MENU": return state.map((item) => action.id == item.id ? { - ...item, - showSubitems: !item.showSubitems, - } + ...item, + showSubitems: !item.showSubitems, + } : item ); case "COLLAPSE_SUB_ITEMS": return state.map((item) => { return item.hasSubitems ? { - ...item, - Subitems: item.Subitems.map((subitem) => - action.id === subitem.id - ? { - ...subitem, - showSubitems: !subitem.showSubitems, - } - : subitem - ), - } + ...item, + Subitems: item.Subitems.map((subitem) => + action.id === subitem.id + ? { + ...subitem, + showSubitems: !subitem.showSubitems, + } + : subitem + ), + } : item; }); case "COLLAPSE_SUB_SECOND_ITEMS": return state.map((item) => { return item.hasSubitems ? { - ...item, - Subitems: item.Subitems.map((subitem) => { - return subitem.hasSubitems - ? { - ...subitem, - Subitems: subitem.Subitems.map((secondSubitem) => - action.id === secondSubitem.id - ? { - ...secondSubitem, - showSubitems: !secondSubitem.showSubitems, - } - : secondSubitem - ), - } - : subitem; - }), - } + ...item, + Subitems: item.Subitems.map((subitem) => { + return subitem.hasSubitems + ? { + ...subitem, + Subitems: subitem.Subitems.map((secondSubitem) => + action.id === secondSubitem.id + ? { + ...secondSubitem, + showSubitems: !secondSubitem.showSubitems, + } + : secondSubitem + ), + } + : subitem; + }), + } : item; }); case "SELECTED": return state.map((item) => { return item.type === "page" ? { - ...item, - selected: action.route === item.route, - showSubitems: item.route === action.route, - } + ...item, + selected: action.route === item.route, + showSubitems: item.route === action.route, + } : item.Subitems && Array.isArray(item.Subitems) - ? { + ? { ...item, Subitems: item.Subitems.map((subitem) => { return subitem.type === "page" ? { - ...subitem, - selected: action.route === subitem.route, - showSubitems: subitem.route === action.route, - } + ...subitem, + selected: action.route === subitem.route, + showSubitems: subitem.route === action.route, + } : subitem.Subitems && Array.isArray(subitem.Subitems) - ? { + ? { ...subitem, Subitems: subitem.Subitems.map((secondSubItem) => ({ ...secondSubItem, @@ -84,11 +90,11 @@ function reducer(state, action) { (secondSubItem) => secondSubItem.route === action.route ), } - : subitem; + : subitem; }), showSubitems: item.Subitems.some((subitem) => subitem.showSubitems), } - : item; + : item; }); default: @@ -97,9 +103,15 @@ function reducer(state, action) { } const SidebarMenu = () => { + const { data: userPermissions } = usePermissions() const [menuItems, dispatch] = useReducer(reducer, pageMenu); const pathname = usePathname(); const [selectedKey, setSelectedKey] = useState(null); + + useEffect(() => { + dispatch({ type: 'UPDATE_MENU', permissions: userPermissions }); + }, [userPermissions]) + useEffect(() => { dispatch({ type: "SELECTED", route: pathname }); setSelectedKey(pathname); diff --git a/src/core/utils/filterMenuItems.js b/src/core/utils/filterMenuItems.js new file mode 100644 index 0000000..7bceeb5 --- /dev/null +++ b/src/core/utils/filterMenuItems.js @@ -0,0 +1,17 @@ +export function filterMenuItems(items, _permissions = []) { + return items.reduce((acc, item) => { + if (item.permissions) { + if (item.permissions.some(permission => _permissions.includes(permission))) { + acc.push(item); + } + } else if (item.hasSubitems) { + const filteredSubItems = filterMenuItems(item.Subitems, _permissions); + if (filteredSubItems.length > 0) { + acc.push({ ...item, Subitems: filteredSubItems }); + } + } else { + acc.push(item); + } + return acc; + }, []); +} \ No newline at end of file diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 6145ffd..9750e63 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -7,6 +7,7 @@ export const pageMenu = [ type: "page", route: "/dashboard", icon: , + permissions: ["all"] }, { id: "userManagement", @@ -14,6 +15,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", icon: , + permissions: ['full-user-management', 'limited-user-management'] }, { id: "projectsManagment", @@ -28,6 +30,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", icon: , + permissions: ['show-contract', 'show-contract-province'], }, { id: "projectsManagmentList", @@ -35,6 +38,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", icon: , + permissions: ["all"] }, { id: "projectsManagmentProposal", @@ -42,6 +46,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", icon: , + permissions: ['show-proposal', 'show-proposal-province'] }, { id: "projectsManagmentLawmaker", @@ -49,6 +54,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", icon: , + permissions: ['show-lawmaker', 'show-lawmaker-province'] }, { id: "projectsManagmentMap", @@ -56,6 +62,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", icon: , + permissions: ["all"] }, ], }, @@ -78,6 +85,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable", + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province'] }, ], }, @@ -93,12 +101,14 @@ export const pageMenu = [ label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create", + permissions: ['create-road-item'] }, { id: "roadItemManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable", + permissions: ['create-road-item'] }, ], }, @@ -108,6 +118,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", icon: , + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province', 'create-road-item'] }, { id: "roadItemManagmentReport", @@ -115,6 +126,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", icon: , + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province', 'create-road-item'] }, ], }, @@ -137,6 +149,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable", + permissions: ['show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, ], }, @@ -152,12 +165,14 @@ export const pageMenu = [ label: "ثبت اقدام", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", + permissions: ['add-road-patrol'] }, { id: "roadPatrolManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", + permissions: ['add-road-patrol'] }, ], }, @@ -167,6 +182,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", icon: , + permissions: ['add-road-patrol', 'show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, { id: "roadPatrolManagmentReport", @@ -174,6 +190,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", icon: , + permissions: ['add-road-patrol', 'show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, ], }, @@ -196,12 +213,14 @@ export const pageMenu = [ label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step", + permissions: ['add-safety-and-privacy'] }, { id: "safetyAndPrivacyManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', 'show-safety-and-privacy-operator-cartable-edarate-shahri'] }, ], }, @@ -211,6 +230,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", icon: , + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', + 'show-safety-and-privacy-operator-cartable-edarate-shahri', 'add-safety-and-privacy'] }, { id: "safetyAndPrivacyManagmentReport", @@ -218,6 +239,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", icon: , + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', + 'show-safety-and-privacy-operator-cartable-edarate-shahri', 'add-safety-and-privacy'] }, ], }, @@ -240,6 +263,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable", + permissions: ['supervise-fast-react', 'supervise-fast-react-province'] }, ], }, @@ -249,6 +273,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", icon: , + permissions: ['show-fast-react', 'show-fast-react-province', 'show-fast-react-edarate-shahri'] }, { id: "roadObservationsManagmentOparation", @@ -262,6 +287,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable", + permissions: ['show-fast-react', 'show-fast-react-province', 'show-fast-react-edarate-shahri'] }, ], }, @@ -271,6 +297,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", icon: , + permissions: ["all"] }, { id: "roadObservationsManagmentReport", @@ -278,6 +305,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", icon: , + permissions: ["all"] }, ], }, @@ -294,6 +322,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", icon: , + permissions: ['show-camp', 'show-camp-province'] }, { id: "winterCampManagmentFirstRing", @@ -301,6 +330,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", icon: , + permissions: ['show-camp', 'show-camp-province'] }, { id: "winterCampManagmentReport", @@ -308,6 +338,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", icon: , + permissions: ['show-camp', 'show-camp-province'] }, ], }, @@ -330,6 +361,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt", + permissions: ["all"] }, ], }, @@ -339,48 +371,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", icon: , + permissions: ["all"] }, ], }, - // { - // id: "hello", - // type: "menu", - // route: "/hello", - // icon: , - // selected: false, - // Subitems: [ - // { - // id: "amin", - // route: "/s", - // icon: , - // firstName: "amin", - // lastName: "ali", - // Subitems: [ - // { - // id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: - // }, - // { - // id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: - // } - // ], - // hasSubitems: true, - // showSubitems: false, - // type: "menu", - // selected: false, - // }, - // { - // id: "amir", - // route: "/dashboarsad", - // icon: , - // firstName: "amir", - // lastName: "akbar", - // hasSubitems: false, - // showSubitems: false, - // selected: false, - // type: "page", - // }, - // ], - // hasSubitems: true, - // showSubitems: false - // }, ]; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 8fae96f..81ac016 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -2,3 +2,5 @@ const api = process.env.NEXT_PUBLIC_API_URL; export const GET_USER_ROUTE = api + "/webapi/user/get-permission"; export const GET_LOGIN_ROUTE = api + "/login_dev"; + +export const GET_PERMISSIONS_ROUTE = api + "/webapi/user/get-permission"; \ No newline at end of file diff --git a/src/lib/hooks/usePermissions.js b/src/lib/hooks/usePermissions.js new file mode 100644 index 0000000..4f54b41 --- /dev/null +++ b/src/lib/hooks/usePermissions.js @@ -0,0 +1,18 @@ +import { GET_PERMISSIONS_ROUTE } from "@/core/utils/routes"; +import useSWR from "swr"; +import useRequest from "./useRequest"; + +export const usePermissions = () => { + const request = useRequest() + + const fetcher = async (url) => { + try { + const response = await request(url) + return response.data.data + } catch (error) { + throw new Error(); + } + }; + + return useSWR(GET_PERMISSIONS_ROUTE, fetcher, { keepPreviousData: true }); +} \ No newline at end of file From 41181eaadb3b92872bd97ce6e3d6e2c90afde0b6 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Wed, 10 Jul 2024 11:45:30 +0330 Subject: [PATCH 27/28] add build:publish script in package --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b7f9320..4a1bf6b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "next build", "start": "next start", "lint": "next lint", - "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,html,css,scss}\"" + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,html,css,scss}\"", + "build:publish": "npm i && npm run build && pm2 restart ecosystem.config.js" }, "dependencies": { "@emotion/cache": "^11.11.0", @@ -40,4 +41,4 @@ "eslint-config-prettier": "^9.1.0", "prettier": "^3.3.2" } -} +} \ No newline at end of file From bf4c4c4ff294b382bff3b7672e6e4eaa1a717be7 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Wed, 10 Jul 2024 11:57:05 +0330 Subject: [PATCH 28/28] chnage version --- .env.local.example | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.local.example b/.env.local.example index 05bae5f..8d7f889 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1 +1,2 @@ +NEXT_PUBLIC_VERSION="0.1.0" NEXT_PUBLIC_API_URL="https://rms.witel.ir" \ No newline at end of file