LFFE-10 merging from develop on feature
This commit is contained in:
@@ -14,7 +14,6 @@ function DataTable(props) {
|
||||
const [columnFilters, setColumnFilters] = useState([]);
|
||||
const [sorting, setSorting] = useState(props.sorting || []);
|
||||
const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 10});
|
||||
const [rowCount, setRowCount] = useState(0);
|
||||
const [columnFilterFns, setColumnFilterFns] = useState(() => {
|
||||
let output = {};
|
||||
const list = props.columns.map((item) => item.enableColumnFilter ? {[item.id]: item.filterFn} : {[item.id]: ""});
|
||||
@@ -34,8 +33,11 @@ function DataTable(props) {
|
||||
const tableLocalization = useMemo(() => languageList.find((item) => item.key == languageApp).tableLocalization, [languageApp, languageList]);
|
||||
|
||||
const fetchUrl = useMemo(() => {
|
||||
const url = new URL(props.tableUrl);
|
||||
url.searchParams.set("start", `${pagination.pageIndex * pagination.pageSize}`);
|
||||
const params = new URLSearchParams();
|
||||
params.set(
|
||||
"start",
|
||||
`${pagination.pageIndex * pagination.pageSize}`
|
||||
);
|
||||
const filters = columnFilters.map((filter) => {
|
||||
let datatype;
|
||||
for (const i in props.columns) {
|
||||
@@ -47,10 +49,10 @@ function DataTable(props) {
|
||||
...filter, fn: columnFilterFns[filter.id], datatype: datatype,
|
||||
};
|
||||
});
|
||||
url.searchParams.set("size", pagination.pageSize);
|
||||
url.searchParams.set("filters", JSON.stringify(filters ?? []));
|
||||
url.searchParams.set("sorting", JSON.stringify(sorting ?? []));
|
||||
return url;
|
||||
params.set("size", pagination.pageSize);
|
||||
params.set("filters", JSON.stringify(filters ?? []));
|
||||
params.set("sorting", JSON.stringify(sorting ?? []));
|
||||
return `${props.tableUrl}?${params}`;
|
||||
}, [props.tableUrl, columnFilters, columnFilterFns, pagination, sorting, props.columns,]);
|
||||
|
||||
const {data, isValidating, mutate} = useSWR(fetchUrl, (...args) =>
|
||||
@@ -60,7 +62,7 @@ function DataTable(props) {
|
||||
}).then((response) => response.data).catch(() => {
|
||||
})
|
||||
, {
|
||||
revalidateIfStale: false,
|
||||
revalidateIfStale: true,
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: true,
|
||||
keepPreviousData: true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Backdrop, Box, styled} from "@mui/material";
|
||||
import {Backdrop, Box, Stack, styled, Typography} from "@mui/material";
|
||||
import SvgLoading from "@/core/components/svgs/SvgLoading";
|
||||
|
||||
const LoadingImage = styled(Box)({
|
||||
@@ -9,7 +9,7 @@ const LoadingImage = styled(Box)({
|
||||
},
|
||||
"50%": {
|
||||
// opacity: 1,
|
||||
transform: "scale(2)",
|
||||
transform: "scale(.5)",
|
||||
},
|
||||
"100%": {
|
||||
// opacity: 0,
|
||||
@@ -19,20 +19,29 @@ const LoadingImage = styled(Box)({
|
||||
animation: "load 2s infinite",
|
||||
});
|
||||
|
||||
const LoadingHardPage = ({children, loading}) => {
|
||||
const LoadingHardPage = ({children, loading, sx = {}, icon = null, width = 200, height = 200, label = ''}) => {
|
||||
return (
|
||||
<>
|
||||
<Backdrop
|
||||
sx={{bgcolor: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1}}
|
||||
sx={{bgcolor: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1, ...sx}}
|
||||
open={loading}
|
||||
>
|
||||
<LoadingImage
|
||||
width={100}
|
||||
height={100}
|
||||
>
|
||||
<SvgLoading width={100}
|
||||
height={100}/>
|
||||
</LoadingImage>
|
||||
<Stack alignItems={'center'} spacing={2}>
|
||||
<LoadingImage
|
||||
width={width}
|
||||
height={height}
|
||||
>
|
||||
{icon ? (
|
||||
<Box sx={{color: "primary.main", width: width, height: height}}>
|
||||
{icon}
|
||||
</Box>
|
||||
) : (
|
||||
<SvgLoading width={width}
|
||||
height={height}/>
|
||||
)}
|
||||
</LoadingImage>
|
||||
<Typography variant={'body2'} sx={{color: "primary.main"}}>{label}</Typography>
|
||||
</Stack>
|
||||
</Backdrop>
|
||||
{children}
|
||||
</>
|
||||
|
||||
11
src/core/components/LtrTextField.jsx
Normal file
11
src/core/components/LtrTextField.jsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import {styled, TextField} from "@mui/material";
|
||||
|
||||
const LtrTextField = styled(TextField)`
|
||||
.MuiInputBase-input {
|
||||
/* @noflip */
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
`;
|
||||
|
||||
export default LtrTextField
|
||||
@@ -6,13 +6,13 @@ import WifiOffIcon from '@mui/icons-material/WifiOff';
|
||||
import {useTranslations} from "next-intl";
|
||||
|
||||
const NetworkComponent = () => {
|
||||
const toastId = useRef(null);
|
||||
const networkToastId = useRef(null);
|
||||
const network = useNetwork()
|
||||
const t = useTranslations()
|
||||
|
||||
useEffect(() => {
|
||||
if (network.online) {
|
||||
toast.update(toastId.current, {
|
||||
toast.update(networkToastId.current, {
|
||||
type: toast.TYPE.SUCCESS,
|
||||
render: t('online_message'),
|
||||
autoClose: 2000,
|
||||
@@ -22,8 +22,9 @@ const NetworkComponent = () => {
|
||||
});
|
||||
return
|
||||
}
|
||||
toast.dismiss()
|
||||
toastId.current = toast.warn(t('offline_message'), {
|
||||
networkToastId.current = toast.warn(t('offline_message'), {
|
||||
containerId: 'connection',
|
||||
draggable: false,
|
||||
autoClose: false, closeButton: false, closeOnClick: false, icon: <WifiOffIcon/>
|
||||
})
|
||||
}, [network.online]);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {Stack, TextField, Typography} from "@mui/material";
|
||||
import {Stack, Typography} from "@mui/material";
|
||||
import {useTranslations} from "next-intl";
|
||||
import LtrTextField from "@/core/components/LtrTextField";
|
||||
|
||||
const PriceField = (props) => {
|
||||
const t = useTranslations();
|
||||
return (
|
||||
<Stack spacing={1}>
|
||||
<Stack>
|
||||
<TextField
|
||||
<LtrTextField
|
||||
{...props}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
82
src/core/components/PrintablePage.jsx
Normal file
82
src/core/components/PrintablePage.jsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import {Box, Container, Divider, Grid, Paper, Stack, Typography} from '@mui/material';
|
||||
|
||||
const PrintablePage = ({children, header, footer}) => (
|
||||
<>
|
||||
<Box sx={{width: "100%", height: 8, displayPrint: 'none'}}/>
|
||||
<Container
|
||||
sx={{
|
||||
width: '21cm',
|
||||
minHeight: '29.7cm',
|
||||
margin: '0 auto',
|
||||
backgroundColor: 'white',
|
||||
p: '16px !important',
|
||||
pb: footer ? '84px!important' : '',
|
||||
position: 'relative'
|
||||
}}
|
||||
component="article" maxWidth="false">
|
||||
<Grid container columns={5} sx={{pt: 2, px: 4, display: header ? '' : 'none'}}>
|
||||
<Grid item xs={1}>
|
||||
<Box sx={{width: 70}}>
|
||||
<Box component={'img'} sx={{width: '100%', height: '100%', objectFit: 'contain'}}
|
||||
src={'/images/logo.png'}/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={3} sx={{textAlign: 'center'}}>
|
||||
<Typography sx={{fontFamily: 'Bnazanin'}}>باسمه تعالی</Typography>
|
||||
<Typography sx={{fontFamily: 'Bnazanin'}}>جمهوری اسلامی ایران</Typography>
|
||||
<Typography sx={{fontFamily: 'Bnazanin', fontWeight: 'bold'}}>وزارت راه و
|
||||
شهرسازی</Typography>
|
||||
<Typography sx={{fontFamily: 'Bnazanin', fontWeight: 'bold'}}>سازمان
|
||||
راهداری و حمل و نقل جاده
|
||||
ای</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Stack>
|
||||
<Typography sx={{fontFamily: 'Bnazanin'}}>شماره:</Typography>
|
||||
<Typography sx={{fontFamily: 'Bnazanin'}}>تاریخ:</Typography>
|
||||
<Typography sx={{fontFamily: 'Bnazanin'}}>پیوست:</Typography>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Paper elevation={0} sx={{px: 8}}>
|
||||
{children}
|
||||
</Paper>
|
||||
<Box sx={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
px: 4,
|
||||
pb: 2,
|
||||
display: footer ? '' : 'none'
|
||||
}}>
|
||||
<Divider sx={{borderStyle: 'double', borderBottomWidth: 3, borderColor: '#000'}}/>
|
||||
<Stack sx={{my: .5}}>
|
||||
<Box sx={{textAlign: 'center'}}>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 1}}> آدرس: تهران-بلوار
|
||||
کشاورز-خیابان فلسطین جنوبی-خیابان
|
||||
دمشق-پلاک17 </Typography>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 1}}> تلفن: 88-88804379 </Typography>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 1}}> تلفن گویا: 88804400 </Typography>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 1}}> کدپستی: 1416753941 </Typography>
|
||||
</Box>
|
||||
<Box sx={{textAlign: 'center'}}>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 2}}>صندوق پستی: 3773-14155</Typography>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 2}}>پست الکترونیک: info@rmto.ir</Typography>
|
||||
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
|
||||
sx={{fontFamily: 'Bnazanin', px: 2}}>سایت الکترونیک: www.rmto.ir</Typography>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Container>
|
||||
<Box sx={{width: "100%", height: 8, displayPrint: 'none'}}/>
|
||||
</>
|
||||
);
|
||||
|
||||
export default PrintablePage;
|
||||
@@ -10,7 +10,6 @@ const UploadSystem = ({
|
||||
handleUploadChange,
|
||||
fieldname,
|
||||
setFieldValue,
|
||||
imageAlt,
|
||||
imageSize,
|
||||
fileType,
|
||||
fileName,
|
||||
@@ -19,7 +18,6 @@ const UploadSystem = ({
|
||||
}) => {
|
||||
const t = useTranslations();
|
||||
const fileInputRef = useRef(null);
|
||||
|
||||
const handleClick = () => {
|
||||
fileInputRef.current.click();
|
||||
};
|
||||
@@ -69,13 +67,14 @@ const UploadSystem = ({
|
||||
variant="subtitle2"
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
fontSize: "1rem",
|
||||
fontSize: "0.8rem",
|
||||
color: "#a19d9d",
|
||||
mt: 1,
|
||||
}}
|
||||
textAlign="center"
|
||||
>
|
||||
{t("UploadSystem.upload_file")}
|
||||
{t("UploadSystem.upload_file_format")}<br/>
|
||||
{t("UploadSystem.upload_file_unit")}
|
||||
</Typography>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
@@ -2,8 +2,8 @@ import DangerousIcon from "@mui/icons-material/Dangerous";
|
||||
import {Box, Typography} from "@mui/material";
|
||||
import {toast} from "react-toastify";
|
||||
|
||||
const ErrorNotification = (t, status, message) => {
|
||||
toast(
|
||||
const ErrorNotification = (pushToastList, notificationType, t, status, message) => {
|
||||
const toastId = toast(
|
||||
() => (
|
||||
<>
|
||||
<Box
|
||||
@@ -29,11 +29,13 @@ const ErrorNotification = (t, status, message) => {
|
||||
</>
|
||||
),
|
||||
{
|
||||
containerId: 'validation',
|
||||
autoClose: false,
|
||||
closeOnClick: false,
|
||||
draggable: false,
|
||||
}
|
||||
);
|
||||
pushToastList(notificationType, toastId);
|
||||
};
|
||||
|
||||
export default ErrorNotification;
|
||||
export default ErrorNotification;
|
||||
@@ -1,12 +1,14 @@
|
||||
import {toast} from "react-toastify";
|
||||
|
||||
const PendingNotification = (t) => {
|
||||
toast(t("notifications.pending"), {
|
||||
const PendingNotification = (pushToastList, notificationType, t) => {
|
||||
const toastId = toast(t("notifications.pending"), {
|
||||
containerId: 'validation',
|
||||
autoClose: false,
|
||||
closeButton: false,
|
||||
closeOnClick: false,
|
||||
draggable: false,
|
||||
});
|
||||
pushToastList(notificationType, toastId);
|
||||
};
|
||||
|
||||
export default PendingNotification;
|
||||
export default PendingNotification;
|
||||
@@ -2,8 +2,8 @@ import BeenhereIcon from "@mui/icons-material/Beenhere";
|
||||
import {Box, Typography} from "@mui/material";
|
||||
import {toast} from "react-toastify";
|
||||
|
||||
const SuccessNotification = (t, status) => {
|
||||
toast(
|
||||
const SuccessNotification = (pushToastList, notificationType, t, status) => {
|
||||
const toastId = toast(
|
||||
() => (
|
||||
<>
|
||||
<Box
|
||||
@@ -30,6 +30,7 @@ const SuccessNotification = (t, status) => {
|
||||
</>
|
||||
),
|
||||
{
|
||||
containerId: 'validation',
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
pauseOnHover: true,
|
||||
@@ -37,6 +38,7 @@ const SuccessNotification = (t, status) => {
|
||||
draggable: true,
|
||||
}
|
||||
);
|
||||
pushToastList(notificationType, toastId);
|
||||
};
|
||||
|
||||
export default SuccessNotification;
|
||||
export default SuccessNotification;
|
||||
@@ -26,6 +26,8 @@ const UploadFileNotification = (t) => {
|
||||
</>
|
||||
),
|
||||
{
|
||||
containerId: 'validation',
|
||||
toastId: 'upload',
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
pauseOnHover: true,
|
||||
@@ -35,4 +37,4 @@ const UploadFileNotification = (t) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UploadFileNotification;
|
||||
export default UploadFileNotification;
|
||||
@@ -2,8 +2,8 @@ import ReportIcon from "@mui/icons-material/Report";
|
||||
import {Box, Typography} from "@mui/material";
|
||||
import {toast} from "react-toastify";
|
||||
|
||||
const WarningNotification = (t, status) => {
|
||||
toast(
|
||||
const WarningNotification = (pushToastList, notificationType, t, status) => {
|
||||
const toastId = toast(
|
||||
() => (
|
||||
<>
|
||||
<Box
|
||||
@@ -30,11 +30,13 @@ const WarningNotification = (t, status) => {
|
||||
</>
|
||||
),
|
||||
{
|
||||
containerId: 'validation',
|
||||
autoClose: false,
|
||||
closeOnClick: false,
|
||||
draggable: false,
|
||||
}
|
||||
);
|
||||
pushToastList(notificationType, toastId);
|
||||
};
|
||||
|
||||
export default WarningNotification;
|
||||
export default WarningNotification;
|
||||
@@ -1,54 +1,27 @@
|
||||
import {toast} from "react-toastify";
|
||||
import ErrorNotification from "./ErrorNotification";
|
||||
import WarningNotification from "./WarningNotification";
|
||||
import SuccessNotification from "./SuccessNotification";
|
||||
import pendingNotification from "@/core/components/notifications/PendingNotification";
|
||||
import WarningNotification from "@/core/components/notifications/WarningNotification";
|
||||
import ErrorNotification from "@/core/components/notifications/ErrorNotification";
|
||||
import SuccessNotification from "@/core/components/notifications/SuccessNotification";
|
||||
|
||||
const Notifications = async (t, response) => {
|
||||
const {status, data} = response != undefined ? response : ""
|
||||
toast.dismiss();
|
||||
switch (status) {
|
||||
case 200:
|
||||
SuccessNotification(t, status);
|
||||
const Notifications = (pushToastList, notificationType, t, status, message) => {
|
||||
switch (notificationType) {
|
||||
case "pending":
|
||||
pendingNotification(pushToastList, notificationType, t);
|
||||
break;
|
||||
case 400:
|
||||
ErrorNotification(t, status);
|
||||
case "warning":
|
||||
WarningNotification(pushToastList, notificationType, t, status);
|
||||
break;
|
||||
case 401:
|
||||
ErrorNotification(t, status);
|
||||
case "error":
|
||||
if (message) {
|
||||
ErrorNotification(pushToastList, notificationType, t, status, message)
|
||||
} else {
|
||||
ErrorNotification(pushToastList, notificationType, t, status)
|
||||
}
|
||||
break;
|
||||
case 403:
|
||||
ErrorNotification(t, status);
|
||||
break;
|
||||
case 422:
|
||||
ErrorNotification(t, status, data.message);
|
||||
break;
|
||||
case 500:
|
||||
WarningNotification(t, status);
|
||||
break;
|
||||
case 503:
|
||||
WarningNotification(t, status);
|
||||
break;
|
||||
case 504:
|
||||
WarningNotification(t, status);
|
||||
break;
|
||||
default:
|
||||
toast(t("notifications.pending"), {
|
||||
autoClose: false,
|
||||
closeOnClick: false,
|
||||
draggable: false,
|
||||
});
|
||||
case "success":
|
||||
SuccessNotification(pushToastList, notificationType, t, status);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
export default Notifications;
|
||||
|
||||
/*
|
||||
usage document
|
||||
|
||||
** for pending use ( Notifications( t, undefined) ) this before your request.
|
||||
** for success use ( Notifications( t, response) ) this inside .then() of your request.
|
||||
** for Error and Warning use ( Notifications( t, error.response) ) this inside .catche() of your request.
|
||||
|
||||
end usage document
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user