Merge branch 'release/v0.9.5'
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
NEXT_PUBLIC_VERSION="0.9.4"
|
NEXT_PUBLIC_VERSION="0.9.5"
|
||||||
NEXT_PUBLIC_API_URL="https://rms.witel.ir"
|
NEXT_PUBLIC_API_URL="https://rms.witel.ir"
|
||||||
NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map"
|
NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map"
|
||||||
@@ -119,6 +119,19 @@ const AzmayeshList = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "updated_at",
|
||||||
|
header: "تاریخ بروزرسانی",
|
||||||
|
id: "updated_at",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "date",
|
||||||
|
filterFn: "equals",
|
||||||
|
Cell: ({ renderedCellValue }) => (
|
||||||
|
<Typography variant="body2">
|
||||||
|
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
|
||||||
|
</Typography>
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTheme } from "@emotion/react";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
import { object, string } from "yup";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
import { CREATE_AZMAYESH, UPDATE_AZMAYESH } from "@/core/utils/routes";
|
||||||
|
import StyledForm from "@/core/components/StyledForm";
|
||||||
|
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
|
||||||
|
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
|
||||||
|
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
|
||||||
|
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
|
||||||
|
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
|
||||||
|
import BeenhereIcon from "@mui/icons-material/Beenhere";
|
||||||
|
import CandUMapBox from "./CandUMapBox";
|
||||||
|
import CandUCreateTimeLine from "./CandUTimeLine";
|
||||||
|
import CandUGeneralInfo from "./CandUGeneralInfo";
|
||||||
|
|
||||||
|
function TabPanel(props) {
|
||||||
|
const { children, value, index } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div role="tabpanel" hidden={value !== index}>
|
||||||
|
{value === index && <Box>{children}</Box>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const validationSchema = object({
|
||||||
|
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
|
||||||
|
province_id: string().required("استان را وارد کنید!"),
|
||||||
|
project_name: string().required("عنوان پروژه را وارد کنید!"),
|
||||||
|
employer: string().required("کارفرما را وارد کنید!"),
|
||||||
|
consultant: string().required("مشاور را وارد کنید!"),
|
||||||
|
contractor: string().required("پیمانکار را وارد کنید!"),
|
||||||
|
applicant: string().required("متقاضی را وارد کنید!"),
|
||||||
|
work_number: string().required("شماره کار را وارد کنید!"),
|
||||||
|
request_number: string().required("شماره درخواست را وارد کنید!"),
|
||||||
|
request_date: string().required("تاریخ درخواست را وارد کنید!"),
|
||||||
|
report_date: string().required("تاریخ گزارش را وارد کنید!"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const requestServer = useRequest({ auth: true });
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
const [tabState, setTabState] = useState(0);
|
||||||
|
const [mapBoxData, setMapBoxData] = useState(updateInfo ? { lat: updateInfo.lat, lng: updateInfo.lng } : null);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeTab = (event, newValue) => {
|
||||||
|
setTabState(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (tabState === 0) {
|
||||||
|
handleClose();
|
||||||
|
} else {
|
||||||
|
setTabState(tabState - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultValues = {
|
||||||
|
azmayesh_type_id: updateInfo ? updateInfo.azmayesh_type_id : "",
|
||||||
|
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
|
||||||
|
province_id: updateInfo ? updateInfo.province_id : "",
|
||||||
|
province_name: updateInfo ? updateInfo.province_name : "",
|
||||||
|
project_name: updateInfo ? updateInfo.project_name : "",
|
||||||
|
employer: updateInfo ? updateInfo.employer : "",
|
||||||
|
consultant: updateInfo ? updateInfo.consultant : "",
|
||||||
|
contractor: updateInfo ? updateInfo.contractor : "",
|
||||||
|
applicant: updateInfo ? updateInfo.applicant : "",
|
||||||
|
work_number: updateInfo ? updateInfo.work_number : "",
|
||||||
|
request_number: updateInfo ? updateInfo.request_number : "",
|
||||||
|
request_date: updateInfo ? moment(updateInfo.request_date, "YYYY-MM-DD").toDate() : "",
|
||||||
|
report_date: updateInfo ? moment(updateInfo.report_date, "YYYY-MM-DD").toDate() : "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
formState: { isSubmitting, errors, touchedFields },
|
||||||
|
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur" });
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("lat", mapBoxData.lat);
|
||||||
|
formData.append("lng", mapBoxData.lng);
|
||||||
|
formData.append("azmayesh_type_id", data.azmayesh_type_id);
|
||||||
|
formData.append("azmayesh_type_name", data.azmayesh_type_name);
|
||||||
|
formData.append("province_id", data.province_id);
|
||||||
|
formData.append("province_name", data.province_name);
|
||||||
|
formData.append("project_name", data.project_name);
|
||||||
|
formData.append("employer", data.employer);
|
||||||
|
formData.append("consultant", data.consultant);
|
||||||
|
formData.append("contractor", data.contractor);
|
||||||
|
formData.append("applicant", data.applicant);
|
||||||
|
formData.append("work_number", data.work_number);
|
||||||
|
formData.append("request_number", data.request_number);
|
||||||
|
formData.append("request_date", moment(new Date(data.request_date)).format("YYYY-MM-DD"));
|
||||||
|
formData.append("report_date", moment(new Date(data.report_date)).format("YYYY-MM-DD"));
|
||||||
|
|
||||||
|
requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
mutate();
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Tabs
|
||||||
|
allowScrollButtonsMobile
|
||||||
|
value={tabState}
|
||||||
|
onChange={handleChangeTab}
|
||||||
|
variant={`${isMobile ? "scrollable" : "fullWidth"}`}
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "#efefef",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tab icon={<TravelExploreIcon />} label="انتخاب محل آزمایش"></Tab>
|
||||||
|
<Tab disabled={!mapBoxData} icon={<TextSnippetIcon />} label="مشخصات آزمایش"></Tab>
|
||||||
|
</Tabs>
|
||||||
|
<DialogContent dividers sx={{ display: "flex" }}>
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
<TabPanel value={tabState} index={0}>
|
||||||
|
<CandUMapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={tabState} index={1}>
|
||||||
|
<CandUGeneralInfo control={control} register={register} setValue={setValue} errors={errors} />
|
||||||
|
</TabPanel>
|
||||||
|
</Box>
|
||||||
|
{!isMobile && (
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<CandUCreateTimeLine tabState={tabState} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions sx={{ alignItems: "center", justifyContent: "center" }}>
|
||||||
|
<Button
|
||||||
|
onClick={handlePrev}
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
size="large"
|
||||||
|
startIcon={tabState === 0 ? <ExitToAppIcon /> : <KeyboardDoubleArrowRightIcon />}
|
||||||
|
>
|
||||||
|
{tabState === 0 ? "بستن" : "مرحله قبل"}
|
||||||
|
</Button>
|
||||||
|
{tabState === 0 ? (
|
||||||
|
<Button
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
setTabState(tabState + 1);
|
||||||
|
}}
|
||||||
|
variant="contained"
|
||||||
|
size="large"
|
||||||
|
disabled={!mapBoxData}
|
||||||
|
endIcon={<KeyboardDoubleArrowLeftIcon />}
|
||||||
|
>
|
||||||
|
مرحله بعد
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
size="large"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
type={"submit"}
|
||||||
|
endIcon={<BeenhereIcon />}
|
||||||
|
>
|
||||||
|
{updateInfo
|
||||||
|
? isSubmitting
|
||||||
|
? "در حال ویرایش آزمایش"
|
||||||
|
: "ویرایش آزمایش"
|
||||||
|
: isSubmitting
|
||||||
|
? "در حال ثبت آزمایش"
|
||||||
|
: "ثبت آزمایش"}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</DialogActions>
|
||||||
|
</StyledForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CandUAzmayesh;
|
||||||
@@ -1,204 +1,23 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Box, Button, Dialog, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
|
import { Dialog } from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import FormAndRequest from "./FormAndRequest";
|
||||||
import { useTheme } from "@emotion/react";
|
import DialogLoading from "@/core/components/DialogLoading";
|
||||||
import useRequest from "@/lib/hooks/useRequest";
|
|
||||||
import { object, string } from "yup";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
|
||||||
import moment from "jalali-moment";
|
|
||||||
import { CREATE_AZMAYESH, UPDATE_AZMAYESH } from "@/core/utils/routes";
|
|
||||||
import StyledForm from "@/core/components/StyledForm";
|
|
||||||
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
|
|
||||||
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
|
|
||||||
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
|
|
||||||
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
|
|
||||||
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
|
|
||||||
import BeenhereIcon from "@mui/icons-material/Beenhere";
|
|
||||||
import CandUMapBox from "./CandUMapBox";
|
|
||||||
import CandUCreateTimeLine from "./CandUTimeLine";
|
|
||||||
import CandUGeneralInfo from "./CandUGeneralInfo";
|
|
||||||
|
|
||||||
function TabPanel(props) {
|
|
||||||
const { children, value, index } = props;
|
|
||||||
|
|
||||||
|
const CandUAzmayesh = ({ open, setOpen, mutate, updateInfo, rowId, loadingOpen, fromUpdate = false }) => {
|
||||||
|
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
|
||||||
return (
|
return (
|
||||||
<div role="tabpanel" hidden={value !== index}>
|
<Dialog open={open} fullWidth maxWidth="lg">
|
||||||
{value === index && <Box>{children}</Box>}
|
{isUpdateReady ? (
|
||||||
</div>
|
<FormAndRequest
|
||||||
);
|
setOpen={setOpen}
|
||||||
}
|
mutate={mutate}
|
||||||
|
rowId={rowId}
|
||||||
const validationSchema = object({
|
{...(fromUpdate ? { updateInfo } : {})}
|
||||||
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
|
/>
|
||||||
province_id: string().required("استان را وارد کنید!"),
|
) : (
|
||||||
project_name: string().required("عنوان پروژه را وارد کنید!"),
|
<DialogLoading loadingOpen={loadingOpen} />
|
||||||
employer: string().required("کارفرما را وارد کنید!"),
|
)}
|
||||||
consultant: string().required("مشاور را وارد کنید!"),
|
|
||||||
contractor: string().required("پیمانکار را وارد کنید!"),
|
|
||||||
applicant: string().required("متقاضی را وارد کنید!"),
|
|
||||||
work_number: string().required("شماره کار را وارد کنید!"),
|
|
||||||
request_number: string().required("شماره درخواست را وارد کنید!"),
|
|
||||||
request_date: string().required("تاریخ درخواست را وارد کنید!"),
|
|
||||||
report_date: string().required("تاریخ گزارش را وارد کنید!"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const CandUAzmayesh = ({ open, setOpen, mutate, updateInfo, rowId }) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const requestServer = useRequest({ auth: true });
|
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
|
||||||
const [tabState, setTabState] = useState(0);
|
|
||||||
const [mapBoxData, setMapBoxData] = useState(updateInfo ? { lat: updateInfo.lat, lng: updateInfo.lng } : null);
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
setOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeTab = (event, newValue) => {
|
|
||||||
setTabState(newValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePrev = () => {
|
|
||||||
if (tabState === 0) {
|
|
||||||
handleClose();
|
|
||||||
} else {
|
|
||||||
setTabState(tabState - 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultValues = {
|
|
||||||
azmayesh_type_id: updateInfo ? updateInfo.azmayesh_type_id : "",
|
|
||||||
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
|
|
||||||
province_id: updateInfo ? updateInfo.province_id : "",
|
|
||||||
province_name: updateInfo ? updateInfo.province_name : "",
|
|
||||||
project_name: updateInfo ? updateInfo.project_name : "",
|
|
||||||
employer: updateInfo ? updateInfo.employer : "",
|
|
||||||
consultant: updateInfo ? updateInfo.consultant : "",
|
|
||||||
contractor: updateInfo ? updateInfo.contractor : "",
|
|
||||||
applicant: updateInfo ? updateInfo.applicant : "",
|
|
||||||
work_number: updateInfo ? updateInfo.work_number : "",
|
|
||||||
request_number: updateInfo ? updateInfo.request_number : "",
|
|
||||||
request_date: updateInfo ? moment(updateInfo.request_date, "YYYY-MM-DD").toDate() : "",
|
|
||||||
report_date: updateInfo ? moment(updateInfo.report_date, "YYYY-MM-DD").toDate() : "",
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
register,
|
|
||||||
handleSubmit,
|
|
||||||
setValue,
|
|
||||||
formState: { isSubmitting, errors, touchedFields },
|
|
||||||
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur" });
|
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("lat", mapBoxData.lat);
|
|
||||||
formData.append("lng", mapBoxData.lng);
|
|
||||||
formData.append("azmayesh_type_id", data.azmayesh_type_id);
|
|
||||||
formData.append("azmayesh_type_name", data.azmayesh_type_name);
|
|
||||||
formData.append("province_id", data.province_id);
|
|
||||||
formData.append("province_name", data.province_name);
|
|
||||||
formData.append("project_name", data.project_name);
|
|
||||||
formData.append("employer", data.employer);
|
|
||||||
formData.append("consultant", data.consultant);
|
|
||||||
formData.append("contractor", data.contractor);
|
|
||||||
formData.append("applicant", data.applicant);
|
|
||||||
formData.append("work_number", data.work_number);
|
|
||||||
formData.append("request_number", data.request_number);
|
|
||||||
formData.append("request_date", moment(new Date(data.request_date)).format("YYYY-MM-DD"));
|
|
||||||
formData.append("report_date", moment(new Date(data.report_date)).format("YYYY-MM-DD"));
|
|
||||||
|
|
||||||
requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
|
|
||||||
data: formData,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
mutate();
|
|
||||||
handleClose();
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open={open} fullWidth={true} maxWidth={"lg"}>
|
|
||||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
|
||||||
<Tabs
|
|
||||||
allowScrollButtonsMobile
|
|
||||||
value={tabState}
|
|
||||||
onChange={handleChangeTab}
|
|
||||||
variant={`${isMobile ? "scrollable" : "fullWidth"}`}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-around",
|
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "#efefef",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Tab icon={<TravelExploreIcon />} label="انتخاب محل آزمایش"></Tab>
|
|
||||||
<Tab disabled={!mapBoxData} icon={<TextSnippetIcon />} label="مشخصات آزمایش"></Tab>
|
|
||||||
</Tabs>
|
|
||||||
<DialogContent dividers sx={{ display: "flex" }}>
|
|
||||||
<Box sx={{ flex: 1 }}>
|
|
||||||
<TabPanel value={tabState} index={0}>
|
|
||||||
<CandUMapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value={tabState} index={1}>
|
|
||||||
<CandUGeneralInfo
|
|
||||||
control={control}
|
|
||||||
register={register}
|
|
||||||
setValue={setValue}
|
|
||||||
errors={errors}
|
|
||||||
/>
|
|
||||||
</TabPanel>
|
|
||||||
</Box>
|
|
||||||
{!isMobile && (
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
|
||||||
<CandUCreateTimeLine tabState={tabState} />
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions sx={{ alignItems: "center", justifyContent: "center" }}>
|
|
||||||
<Button
|
|
||||||
onClick={handlePrev}
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
size="large"
|
|
||||||
startIcon={tabState === 0 ? <ExitToAppIcon /> : <KeyboardDoubleArrowRightIcon />}
|
|
||||||
>
|
|
||||||
{tabState === 0 ? "بستن" : "مرحله قبل"}
|
|
||||||
</Button>
|
|
||||||
{tabState === 0 ? (
|
|
||||||
<Button
|
|
||||||
onClick={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
setTabState(tabState + 1);
|
|
||||||
}}
|
|
||||||
variant="contained"
|
|
||||||
size="large"
|
|
||||||
disabled={!mapBoxData}
|
|
||||||
endIcon={<KeyboardDoubleArrowLeftIcon />}
|
|
||||||
>
|
|
||||||
مرحله بعد
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
size="large"
|
|
||||||
disabled={isSubmitting}
|
|
||||||
type={"submit"}
|
|
||||||
endIcon={<BeenhereIcon />}
|
|
||||||
>
|
|
||||||
{updateInfo
|
|
||||||
? isSubmitting
|
|
||||||
? "در حال ویرایش آزمایش"
|
|
||||||
: "ویرایش آزمایش"
|
|
||||||
: isSubmitting
|
|
||||||
? "در حال ثبت آزمایش"
|
|
||||||
: "ثبت آزمایش"}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</DialogActions>
|
|
||||||
</StyledForm>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,15 +9,18 @@ const AzmayeshUpdate = ({ rowId, mutate }) => {
|
|||||||
const requestServer = useRequest({ auth: true });
|
const requestServer = useRequest({ auth: true });
|
||||||
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
|
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
|
||||||
const [updateInfo, setUpdateInfo] = useState(null);
|
const [updateInfo, setUpdateInfo] = useState(null);
|
||||||
|
const [loadingOpen, setLoadingOpen] = useState(false);
|
||||||
|
|
||||||
const handleGetInfo = () => {
|
const handleGetInfo = () => {
|
||||||
|
setLoadingOpen(true);
|
||||||
|
setOpenUpdateDialog(true);
|
||||||
requestServer(`${GET_AZMAYESH_LIST}/${rowId}`, "get")
|
requestServer(`${GET_AZMAYESH_LIST}/${rowId}`, "get")
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setUpdateInfo(response.data.data);
|
setUpdateInfo(response.data.data);
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setOpenUpdateDialog(true);
|
setLoadingOpen(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ const AzmayeshUpdate = ({ rowId, mutate }) => {
|
|||||||
mutate={mutate}
|
mutate={mutate}
|
||||||
updateInfo={updateInfo}
|
updateInfo={updateInfo}
|
||||||
rowId={rowId}
|
rowId={rowId}
|
||||||
|
loadingOpen={loadingOpen}
|
||||||
|
fromUpdate={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { Button, DialogActions, DialogContent, DialogTitle } from "@mui/material";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
|
||||||
|
import FormMaker from "@/core/components/FormMaker";
|
||||||
|
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
|
||||||
|
|
||||||
|
const CandUSampleOfAzmayesh = ({
|
||||||
|
sampleInfo,
|
||||||
|
mutate,
|
||||||
|
rowId,
|
||||||
|
setOpenSampleDialog,
|
||||||
|
defaultValues,
|
||||||
|
setDefaultValues,
|
||||||
|
isUpdate,
|
||||||
|
azmayesh_id,
|
||||||
|
}) => {
|
||||||
|
const requestServer = useRequest({ auth: true });
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
const data = {};
|
||||||
|
setIsSubmitting(true);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
|
||||||
|
Object.entries(defaultValues).forEach(([key, value]) => {
|
||||||
|
data[key] = value;
|
||||||
|
});
|
||||||
|
formData.append("data", JSON.stringify(data));
|
||||||
|
requestServer(isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`, "post", {
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
mutate();
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
setOpenSampleDialog(false);
|
||||||
|
setIsSubmitting(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<DialogContent>
|
||||||
|
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
onClick={() => setOpenSampleDialog(false)}
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
بستن
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
|
||||||
|
{isUpdate
|
||||||
|
? isSubmitting
|
||||||
|
? "در حال ویرایش نمونه"
|
||||||
|
: "ویرایش نمونه"
|
||||||
|
: isSubmitting
|
||||||
|
? "در حال ثبت نمونه"
|
||||||
|
: "ثبت نمونه"}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CandUSampleOfAzmayesh;
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Box } from "@mui/material";
|
import { Box, Typography } from "@mui/material";
|
||||||
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
|
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
|
||||||
import { GET_SAMPLE_LIST } from "@/core/utils/routes";
|
import { GET_SAMPLE_LIST } from "@/core/utils/routes";
|
||||||
import RowActions from "./RowActions";
|
import RowActions from "./RowActions";
|
||||||
import AzmayeshInfo from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/AzmayeshInfo";
|
import AzmayeshInfo from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/AzmayeshInfo";
|
||||||
import Toolbar from "./Toolbar";
|
import Toolbar from "./Toolbar";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
|
||||||
const ShowSampleList = ({ sampleInfo, rowData }) => {
|
const ShowSampleList = ({ sampleInfo, rowData }) => {
|
||||||
const parsedData = (data) => {
|
const parsedData = (data) => {
|
||||||
return data.data.map((item) => ({
|
return data.data.map((item) => ({
|
||||||
...JSON.parse(item.data),
|
...JSON.parse(item.data),
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
updated_at: item.updated_at,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,7 +24,6 @@ const ShowSampleList = ({ sampleInfo, rowData }) => {
|
|||||||
id: "id",
|
id: "id",
|
||||||
enableColumnFilter: false,
|
enableColumnFilter: false,
|
||||||
datatype: "text",
|
datatype: "text",
|
||||||
filterFn: "notEquals",
|
|
||||||
},
|
},
|
||||||
...sampleInfo.map((item) => ({
|
...sampleInfo.map((item) => ({
|
||||||
accessorKey: item.id.toString(),
|
accessorKey: item.id.toString(),
|
||||||
@@ -30,8 +31,19 @@ const ShowSampleList = ({ sampleInfo, rowData }) => {
|
|||||||
id: item.id.toString(),
|
id: item.id.toString(),
|
||||||
enableColumnFilter: false,
|
enableColumnFilter: false,
|
||||||
datatype: "text",
|
datatype: "text",
|
||||||
filterFn: "notEquals",
|
|
||||||
})),
|
})),
|
||||||
|
{
|
||||||
|
accessorKey: "updated_at",
|
||||||
|
header: "تاریخ بروزرسانی",
|
||||||
|
id: "updated_at",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "date",
|
||||||
|
Cell: ({ renderedCellValue }) => (
|
||||||
|
<Typography variant="body2">
|
||||||
|
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
|
||||||
|
</Typography>
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
[sampleInfo]
|
[sampleInfo]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ const AzmayeshTypeList = () => {
|
|||||||
filterFn: "notEquals",
|
filterFn: "notEquals",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "created_at",
|
accessorKey: "updated_at",
|
||||||
header: "تاریخ ثبت",
|
header: "تاریخ بروزرسانی",
|
||||||
id: "created_at",
|
id: "updated_at",
|
||||||
enableColumnFilter: false,
|
enableColumnFilter: false,
|
||||||
datatype: "date",
|
datatype: "date",
|
||||||
filterFn: "equals",
|
filterFn: "equals",
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Chip,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
Divider,
|
||||||
|
FormControl,
|
||||||
|
FormHelperText,
|
||||||
|
Grid,
|
||||||
|
InputLabel,
|
||||||
|
List,
|
||||||
|
OutlinedInput,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import StyledForm from "@/core/components/StyledForm";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useFieldArray, useForm } from "react-hook-form";
|
||||||
|
import { array, object, string } from "yup";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
|
||||||
|
import ListItems from "./ListItems";
|
||||||
|
import AzmayeshFields from "./AzmayeshFields";
|
||||||
|
import { ADD_AZMAYESH_TYPE, UPDATE_AZMAYESH_TYPE } from "@/core/utils/routes";
|
||||||
|
|
||||||
|
const validationSchema = object({
|
||||||
|
name: string().required("عنوان نوع آزمایش را مشخص کنید!"),
|
||||||
|
fields: array()
|
||||||
|
.of(
|
||||||
|
object({
|
||||||
|
name: string().required("نام فیلد الزامی است"),
|
||||||
|
type: string().required("نوع فیلد الزامی است"),
|
||||||
|
options: array().when("type", {
|
||||||
|
is: "select",
|
||||||
|
then: (schema) => schema.min(1, "حداقل باید یک آیتم برای نوع انتخابی ایجاد کنید."),
|
||||||
|
otherwise: (schema) => schema.notRequired(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.min(1, "حداقل باید یک فیلد ایجاد نمایید."),
|
||||||
|
});
|
||||||
|
|
||||||
|
const FormAndRequest = ({ setOpen, mutate, rowId, updateInfo }) => {
|
||||||
|
const requestServer = useRequest({ auth: true });
|
||||||
|
const [selectedListItem, setSelectedListItem] = useState(null);
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultValues = {
|
||||||
|
name: updateInfo?.name || "",
|
||||||
|
fields: Array.isArray(updateInfo?.azmayesh_fields)
|
||||||
|
? updateInfo.azmayesh_fields.map((field) => ({
|
||||||
|
name: field.name || "",
|
||||||
|
type: field.type || "",
|
||||||
|
unit: field.unit || "",
|
||||||
|
options: field.option ? field.option : [],
|
||||||
|
}))
|
||||||
|
: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
watch,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur" });
|
||||||
|
|
||||||
|
const { fields, append, remove } = useFieldArray({
|
||||||
|
control,
|
||||||
|
name: "fields",
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleRemove = (index) => {
|
||||||
|
remove(index);
|
||||||
|
if (selectedListItem === index) {
|
||||||
|
setSelectedListItem(null);
|
||||||
|
} else if (selectedListItem > index) {
|
||||||
|
setSelectedListItem((prev) => prev - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddField = () => {
|
||||||
|
append({ name: "", type: "", unit: "", options: [] });
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
setIsSubmitting(true);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("name", data.name);
|
||||||
|
data.fields.map((field, index) => {
|
||||||
|
formData.append(`fields[${index}][name]`, field.name);
|
||||||
|
formData.append(`fields[${index}][unit]`, field.unit);
|
||||||
|
formData.append(`fields[${index}][type]`, field.type);
|
||||||
|
if (field.options.length !== 0) formData.append(`fields[${index}][option]`, JSON.stringify(field.options));
|
||||||
|
});
|
||||||
|
|
||||||
|
requestServer(updateInfo ? `${UPDATE_AZMAYESH_TYPE}/${rowId}` : ADD_AZMAYESH_TYPE, "post", {
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
mutate();
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => setIsSubmitting(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", my: 2 }}>
|
||||||
|
<FormControl error={!!errors.name} size="small" variant="outlined" sx={{ width: "250px" }}>
|
||||||
|
<InputLabel htmlFor="name">عنوان نوع آزمایش</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="name"
|
||||||
|
label={"عنوان نوع آزمایش"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("name")}
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="name">{errors.name ? errors.name.message : null}</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Grid container spacing={2} sx={{ justifyContent: "space-between" }}>
|
||||||
|
<Grid xs={12} md={4} lg={3} sx={{ px: 1 }}>
|
||||||
|
<Divider sx={{ my: 2 }}>
|
||||||
|
<Chip label="لیست فیلد ها" />
|
||||||
|
</Divider>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
fullWidth
|
||||||
|
startIcon={<DataSaverOnIcon />}
|
||||||
|
sx={{ mb: 2 }}
|
||||||
|
onClick={handleAddField}
|
||||||
|
>
|
||||||
|
ایجاد فیلد جدید
|
||||||
|
</Button>
|
||||||
|
<List
|
||||||
|
sx={{
|
||||||
|
border: "1px dashed #e1e1e1",
|
||||||
|
borderRadius: "5px",
|
||||||
|
p: 1,
|
||||||
|
maxHeight: "300px",
|
||||||
|
overflowY: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{fields.length !== 0 ? (
|
||||||
|
fields.map((item, index) => (
|
||||||
|
<ListItems
|
||||||
|
key={index}
|
||||||
|
index={index}
|
||||||
|
selectedListItem={selectedListItem}
|
||||||
|
fields={fields}
|
||||||
|
handleRemove={handleRemove}
|
||||||
|
setSelectedListItem={setSelectedListItem}
|
||||||
|
watch={watch}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
sx={{ color: "#a2a2a2", textAlign: "center", letterSpacing: "1px" }}
|
||||||
|
>
|
||||||
|
فیلدی وجود ندارد
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</List>
|
||||||
|
<Typography variant="caption" color="error">
|
||||||
|
{errors.fields ? errors.fields.message : null}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Divider orientation="vertical" variant="middle" flexItem />
|
||||||
|
<Grid xs={12} md={7} lg={8} sx={{ pl: 2 }}>
|
||||||
|
<Divider sx={{ my: 2 }}>
|
||||||
|
<Chip label="اطلاعات فیلد" />
|
||||||
|
</Divider>
|
||||||
|
{selectedListItem !== null ? (
|
||||||
|
<AzmayeshFields
|
||||||
|
errors={errors}
|
||||||
|
selectedListItem={selectedListItem}
|
||||||
|
register={register}
|
||||||
|
setValue={setValue}
|
||||||
|
fields={fields}
|
||||||
|
watch={watch}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", py: 2 }}>
|
||||||
|
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#a2a2a2" }}>
|
||||||
|
از بخش لیست فیلد ها یک آیتم را انتخاب نمایید
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions sx={{ alignItems: "center", justifyContent: "center", py: 2 }}>
|
||||||
|
<Button variant="outlined" color="error" onClick={handleClose}>
|
||||||
|
بستن
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type={"submit"}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
sx={{ width: "200px" }}
|
||||||
|
>
|
||||||
|
{isSubmitting ? "در حال ثبت..." : "ثبت نوع آزمایش"}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</StyledForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormAndRequest;
|
||||||
@@ -1,222 +1,21 @@
|
|||||||
import {
|
import { Dialog } from "@mui/material";
|
||||||
Box,
|
import FormAndRequest from "./FormAndRequest";
|
||||||
Button,
|
import DialogLoading from "@/core/components/DialogLoading";
|
||||||
Chip,
|
|
||||||
Dialog,
|
|
||||||
DialogActions,
|
|
||||||
DialogContent,
|
|
||||||
Divider,
|
|
||||||
FormControl,
|
|
||||||
FormHelperText,
|
|
||||||
Grid,
|
|
||||||
InputLabel,
|
|
||||||
List,
|
|
||||||
OutlinedInput,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import StyledForm from "@/core/components/StyledForm";
|
|
||||||
import useRequest from "@/lib/hooks/useRequest";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { useFieldArray, useForm } from "react-hook-form";
|
|
||||||
import { array, object, string } from "yup";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
|
||||||
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
|
|
||||||
import ListItems from "./ListItems";
|
|
||||||
import AzmayeshFields from "./AzmayeshFields";
|
|
||||||
import { ADD_AZMAYESH_TYPE, UPDATE_AZMAYESH_TYPE } from "@/core/utils/routes";
|
|
||||||
|
|
||||||
const validationSchema = object({
|
|
||||||
name: string().required("عنوان نوع آزمایش را مشخص کنید!"),
|
|
||||||
fields: array()
|
|
||||||
.of(
|
|
||||||
object({
|
|
||||||
name: string().required("نام فیلد الزامی است"),
|
|
||||||
type: string().required("نوع فیلد الزامی است"),
|
|
||||||
options: array().when("type", {
|
|
||||||
is: "select",
|
|
||||||
then: (schema) => schema.min(1, "حداقل باید یک آیتم برای نوع انتخابی ایجاد کنید."),
|
|
||||||
otherwise: (schema) => schema.notRequired(),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.min(1, "حداقل باید یک فیلد ایجاد نمایید."),
|
|
||||||
});
|
|
||||||
|
|
||||||
const CandUAzmayeshType = ({ open, setOpen, mutate, rowId, updateInfo }) => {
|
|
||||||
const requestServer = useRequest({ auth: true });
|
|
||||||
const [selectedListItem, setSelectedListItem] = useState(null);
|
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
setOpen(false);
|
|
||||||
};
|
|
||||||
const defaultValues = {
|
|
||||||
name: updateInfo?.name || "",
|
|
||||||
fields: Array.isArray(updateInfo?.azmayesh_fields)
|
|
||||||
? updateInfo.azmayesh_fields.map((field) => ({
|
|
||||||
name: field.name || "",
|
|
||||||
type: field.type || "",
|
|
||||||
unit: field.unit || "",
|
|
||||||
options: field.option ? field.option : [],
|
|
||||||
}))
|
|
||||||
: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
register,
|
|
||||||
handleSubmit,
|
|
||||||
setValue,
|
|
||||||
watch,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur" });
|
|
||||||
|
|
||||||
const { fields, append, remove } = useFieldArray({
|
|
||||||
control,
|
|
||||||
name: "fields",
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleRemove = (index) => {
|
|
||||||
remove(index);
|
|
||||||
if (selectedListItem === index) {
|
|
||||||
setSelectedListItem(null);
|
|
||||||
} else if (selectedListItem > index) {
|
|
||||||
setSelectedListItem((prev) => prev - 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAddField = () => {
|
|
||||||
append({ name: "", type: "", unit: "", options: [] });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
|
||||||
setIsSubmitting(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("name", data.name);
|
|
||||||
data.fields.map((field, index) => {
|
|
||||||
formData.append(`fields[${index}][name]`, field.name);
|
|
||||||
formData.append(`fields[${index}][unit]`, field.unit);
|
|
||||||
formData.append(`fields[${index}][type]`, field.type);
|
|
||||||
if (field.options.length !== 0) formData.append(`fields[${index}][option]`, JSON.stringify(field.options));
|
|
||||||
});
|
|
||||||
|
|
||||||
requestServer(updateInfo ? `${UPDATE_AZMAYESH_TYPE}/${rowId}` : ADD_AZMAYESH_TYPE, "post", {
|
|
||||||
data: formData,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
mutate();
|
|
||||||
handleClose();
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
.finally(() => setIsSubmitting(false));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const CandUAzmayeshType = ({ open, setOpen, mutate, rowId, updateInfo, loadingOpen, fromUpdate = false }) => {
|
||||||
|
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} fullWidth={true} maxWidth={"lg"}>
|
<Dialog open={open} fullWidth maxWidth="lg">
|
||||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
{isUpdateReady ? (
|
||||||
<DialogContent dividers>
|
<FormAndRequest
|
||||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", my: 2 }}>
|
setOpen={setOpen}
|
||||||
<FormControl error={!!errors.name} size="small" variant="outlined" sx={{ width: "250px" }}>
|
mutate={mutate}
|
||||||
<InputLabel htmlFor="name">عنوان نوع آزمایش</InputLabel>
|
rowId={rowId}
|
||||||
<OutlinedInput
|
{...(fromUpdate ? { updateInfo } : {})}
|
||||||
id="name"
|
/>
|
||||||
label={"عنوان نوع آزمایش"}
|
) : (
|
||||||
autoComplete="off"
|
<DialogLoading loadingOpen={loadingOpen} />
|
||||||
{...register("name")}
|
)}
|
||||||
size="small"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
<FormHelperText id="name">{errors.name ? errors.name.message : null}</FormHelperText>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
<Grid container spacing={2} sx={{ justifyContent: "space-between" }}>
|
|
||||||
<Grid xs={12} md={4} lg={3} sx={{ px: 1 }}>
|
|
||||||
<Divider sx={{ my: 2 }}>
|
|
||||||
<Chip label="لیست فیلد ها" />
|
|
||||||
</Divider>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="success"
|
|
||||||
fullWidth
|
|
||||||
startIcon={<DataSaverOnIcon />}
|
|
||||||
sx={{ mb: 2 }}
|
|
||||||
onClick={handleAddField}
|
|
||||||
>
|
|
||||||
ایجاد فیلد جدید
|
|
||||||
</Button>
|
|
||||||
<List
|
|
||||||
sx={{
|
|
||||||
border: "1px dashed #e1e1e1",
|
|
||||||
borderRadius: "5px",
|
|
||||||
p: 1,
|
|
||||||
maxHeight: "300px",
|
|
||||||
overflowY: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{fields.length !== 0 ? (
|
|
||||||
fields.map((item, index) => (
|
|
||||||
<ListItems
|
|
||||||
key={index}
|
|
||||||
index={index}
|
|
||||||
selectedListItem={selectedListItem}
|
|
||||||
fields={fields}
|
|
||||||
handleRemove={handleRemove}
|
|
||||||
setSelectedListItem={setSelectedListItem}
|
|
||||||
watch={watch}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<Typography
|
|
||||||
variant="h6"
|
|
||||||
sx={{ color: "#a2a2a2", textAlign: "center", letterSpacing: "1px" }}
|
|
||||||
>
|
|
||||||
فیلدی وجود ندارد
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</List>
|
|
||||||
<Typography variant="caption" color="error">
|
|
||||||
{errors.fields ? errors.fields.message : null}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Divider orientation="vertical" variant="middle" flexItem />
|
|
||||||
<Grid xs={12} md={7} lg={8} sx={{ pl: 2 }}>
|
|
||||||
<Divider sx={{ my: 2 }}>
|
|
||||||
<Chip label="اطلاعات فیلد" />
|
|
||||||
</Divider>
|
|
||||||
{selectedListItem !== null ? (
|
|
||||||
<AzmayeshFields
|
|
||||||
errors={errors}
|
|
||||||
selectedListItem={selectedListItem}
|
|
||||||
register={register}
|
|
||||||
setValue={setValue}
|
|
||||||
fields={fields}
|
|
||||||
watch={watch}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", py: 2 }}>
|
|
||||||
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#a2a2a2" }}>
|
|
||||||
از بخش لیست فیلد ها یک آیتم را انتخاب نمایید
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions sx={{ alignItems: "center", justifyContent: "center", py: 2 }}>
|
|
||||||
<Button variant="outlined" color="error" onClick={handleClose}>
|
|
||||||
بستن
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type={"submit"}
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
disabled={isSubmitting}
|
|
||||||
sx={{ width: "200px" }}
|
|
||||||
>
|
|
||||||
{isSubmitting ? "در حال ثبت..." : "ثبت نوع آزمایش"}
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</StyledForm>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,15 +9,18 @@ const UpdateAzmayeshType = ({ rowId, mutate }) => {
|
|||||||
const requestServer = useRequest({ auth: true });
|
const requestServer = useRequest({ auth: true });
|
||||||
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
|
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
|
||||||
const [updateInfo, setUpdateInfo] = useState(null);
|
const [updateInfo, setUpdateInfo] = useState(null);
|
||||||
|
const [loadingOpen, setLoadingOpen] = useState(false);
|
||||||
|
|
||||||
const handleGetInfo = () => {
|
const handleGetInfo = () => {
|
||||||
|
setLoadingOpen(true);
|
||||||
|
setOpenUpdateDialog(true);
|
||||||
requestServer(`${GET_AZMAYESH_TYPE_LIST_TABLE}/${rowId}`, "get")
|
requestServer(`${GET_AZMAYESH_TYPE_LIST_TABLE}/${rowId}`, "get")
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setUpdateInfo(response.data.data);
|
setUpdateInfo(response.data.data);
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setOpenUpdateDialog(true);
|
setLoadingOpen(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ const UpdateAzmayeshType = ({ rowId, mutate }) => {
|
|||||||
mutate={mutate}
|
mutate={mutate}
|
||||||
updateInfo={updateInfo}
|
updateInfo={updateInfo}
|
||||||
rowId={rowId}
|
rowId={rowId}
|
||||||
|
loadingOpen={loadingOpen}
|
||||||
|
fromUpdate={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
36
src/core/components/DialogLoading.jsx
Normal file
36
src/core/components/DialogLoading.jsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { Box, Skeleton } from "@mui/material";
|
||||||
|
|
||||||
|
const DialogLoading = ({ loadingOpen }) => {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 2, p: 2 }}>
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: "1.5rem", width: "70%" }} />
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: "1rem", width: "90%" }} />
|
||||||
|
<Skeleton variant="rectangular" sx={{ borderRadius: "8px", height: "180px", width: "100%" }} />
|
||||||
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: "1rem", width: "80%" }} />
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: "1rem", width: "60%" }} />
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: "1rem", width: "70%" }} />
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "flex", gap: 2, mt: 2 }}>
|
||||||
|
<Skeleton
|
||||||
|
variant="rectangular"
|
||||||
|
sx={{
|
||||||
|
borderRadius: "8px",
|
||||||
|
height: "40px",
|
||||||
|
width: "30%",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Skeleton
|
||||||
|
variant="rectangular"
|
||||||
|
sx={{
|
||||||
|
borderRadius: "8px",
|
||||||
|
height: "40px",
|
||||||
|
width: "20%",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DialogLoading;
|
||||||
@@ -17,6 +17,16 @@ const theme = createTheme({
|
|||||||
contrastText: "#fff",
|
contrastText: "#fff",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
MuiBackdrop: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
backdropFilter: "blur(2px)",
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default theme;
|
export default theme;
|
||||||
|
|||||||
Reference in New Issue
Block a user