| @@ -4,6 +4,7 @@ import { | |||
| Typography, | |||
| Stack, | |||
| Button, | |||
| CircularProgress, | |||
| Dialog, DialogTitle, DialogContent, DialogActions, | |||
| } from '@mui/material'; | |||
| import MainCard from "components/MainCard"; | |||
| @@ -55,6 +56,8 @@ const Index = () => { | |||
| const [isPreviewLoading, setIsPreviewLoading] = React.useState(false); | |||
| const [isPopUp, setIsPopUp] = React.useState(false); | |||
| const [isXmlDialogSubmitting, setIsXmlDialogSubmitting] = React.useState(false); | |||
| const xmlDownloadInFlightRef = React.useRef(false); | |||
| const [downloadInput, setDownloadInput] = React.useState(); | |||
| const [selectedIds, setSelectedIds] = React.useState([]); | |||
| @@ -66,6 +69,13 @@ const Index = () => { | |||
| setInputDateValue(inputDate); | |||
| }, [inputDate]); | |||
| React.useEffect(() => { | |||
| if (!isPopUp) { | |||
| xmlDownloadInFlightRef.current = false; | |||
| setIsXmlDialogSubmitting(false); | |||
| } | |||
| }, [isPopUp]); | |||
| React.useEffect(() => { | |||
| setOnReady(true); | |||
| }, [searchCriteria]); | |||
| @@ -94,66 +104,61 @@ const Index = () => { | |||
| function downloadXML() { | |||
| console.log(selectedIds.join(',')) | |||
| setIsPopUp(false) | |||
| if (xmlDownloadInFlightRef.current) return; | |||
| xmlDownloadInFlightRef.current = true; | |||
| console.log(selectedIds.join(',')); | |||
| setIsXmlDialogSubmitting(true); | |||
| let sentDateFrom = ""; | |||
| if (inputDateValue != "dd / mm / yyyy") { | |||
| sentDateFrom = DateUtils.dateValue(inputDateValue) | |||
| sentDateFrom = DateUtils.dateValue(inputDateValue); | |||
| } | |||
| HttpUtils.get({ | |||
| url: GEN_GFMIS_XML + "/today", | |||
| params:{ | |||
| params: { | |||
| dateTo: downloadInput.dateTo, | |||
| dateFrom: downloadInput.dateFrom, | |||
| inputDate: sentDateFrom, | |||
| paymentId: selectedIds.join(',') | |||
| }, | |||
| onSuccess: (responseData) => { | |||
| // console.log(responseData) | |||
| const parser = new DOMParser(); | |||
| const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | |||
| // Get the DCBHeader element | |||
| const dcbHeader = xmlDoc.querySelector("DCBHeader"); | |||
| // Get the Receipt and Allocation elements | |||
| const receiptElement = dcbHeader.querySelector("Receipt"); | |||
| const allocationElement = dcbHeader.querySelector("Allocation"); | |||
| const paymentMethodElements = Array.from(dcbHeader.querySelectorAll("PaymentMethod")); | |||
| // Remove existing elements from DCBHeader | |||
| dcbHeader.innerHTML = ""; | |||
| dcbHeader.appendChild(receiptElement); | |||
| dcbHeader.appendChild(allocationElement); | |||
| if (paymentMethodElements) { | |||
| paymentMethodElements.forEach((paymentMethodElement) => { | |||
| dcbHeader.appendChild(paymentMethodElement); | |||
| }); | |||
| dcbHeader.appendChild(paymentMethodElement); | |||
| }); | |||
| } | |||
| const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | |||
| const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | |||
| // console.log(updatedXmlString) | |||
| const blob = new Blob([updatedXmlString], { type: 'application/xml' }); | |||
| // Create a download link | |||
| const link = document.createElement('a'); | |||
| link.href = URL.createObjectURL(blob); | |||
| link.download = filename+'.xml'; | |||
| // Append the link to the document body | |||
| link.download = filename + '.xml'; | |||
| document.body.appendChild(link); | |||
| // Programmatically click the link to trigger the download | |||
| link.click(); | |||
| // Clean up the link | |||
| document.body.removeChild(link); | |||
| setIsPopUp(false); | |||
| }, | |||
| onFinally: () => { | |||
| xmlDownloadInFlightRef.current = false; | |||
| setIsXmlDialogSubmitting(false); | |||
| } | |||
| }); | |||
| // open(UrlUtils.GEN_GFMIS_XML + "/today?online=true") | |||
| } | |||
| }); | |||
| } | |||
| function applySearch(input) { | |||
| @@ -263,7 +268,11 @@ const Index = () => { | |||
| </Grid> | |||
| <Dialog | |||
| open={isPopUp} | |||
| onClose={() => setIsPopUp(false)} | |||
| onClose={() => { | |||
| if (isXmlDialogSubmitting) return; | |||
| setIsPopUp(false); | |||
| }} | |||
| disableEscapeKeyDown={isXmlDialogSubmitting} | |||
| PaperProps={{ | |||
| sx: { | |||
| minWidth: '40vw', | |||
| @@ -300,8 +309,22 @@ const Index = () => { | |||
| </LocalizationProvider> | |||
| </DialogContent> | |||
| <DialogActions> | |||
| <Button onClick={() => setIsPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
| <Button onClick={() => downloadXML()}><Typography variant="h5">Confirm</Typography></Button> | |||
| <Button | |||
| onClick={() => { | |||
| if (isXmlDialogSubmitting) return; | |||
| setIsPopUp(false); | |||
| }} | |||
| disabled={isXmlDialogSubmitting} | |||
| > | |||
| <Typography variant="h5">Cancel</Typography> | |||
| </Button> | |||
| <Button | |||
| onClick={() => downloadXML()} | |||
| disabled={isXmlDialogSubmitting} | |||
| startIcon={isXmlDialogSubmitting ? <CircularProgress color="inherit" size={20} /> : null} | |||
| > | |||
| <Typography variant="h5">Confirm</Typography> | |||
| </Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </Grid> | |||
| @@ -8,12 +8,13 @@ import { | |||
| Button, | |||
| Stack, | |||
| Dialog, DialogTitle, DialogContent, DialogActions, | |||
| CircularProgress, | |||
| } from '@mui/material'; | |||
| import { useFormik } from 'formik'; | |||
| import { useIntl } from 'react-intl'; | |||
| import {isGranted} from "auth/utils"; | |||
| import {useState,useEffect,lazy} from "react"; | |||
| import {useState, useEffect, useRef, lazy} from "react"; | |||
| import * as HttpUtils from "utils/HttpUtils" | |||
| import * as UrlUtils from "utils/ApiPathConst" | |||
| import * as DateUtils from "utils/DateUtils" | |||
| @@ -36,6 +37,8 @@ const ApplicationDetailCard = ({ | |||
| const [data, setData] = useState({}); | |||
| const [cancelPopUp, setCancelPopUp] = useState(false); | |||
| const [cancelLoading, setCancelLoading] = useState(false); | |||
| const cancellingRef = useRef(false); | |||
| const [onDownload, setOnDownload] = useState(false); | |||
| const [alertMsg, setAlertMsg] = useState(''); | |||
| const [showAlert, setShowAlert] = useState(false); | |||
| @@ -98,17 +101,30 @@ const ApplicationDetailCard = ({ | |||
| } | |||
| const confirmCancel = () => { | |||
| setCancelPopUp(false); | |||
| if (cancellingRef.current) return; | |||
| cancellingRef.current = true; | |||
| setCancelLoading(true); | |||
| HttpUtils.get({ | |||
| url: UrlUtils.CANCEL_PROOF + "/" + params.id, | |||
| onSuccess: function (responseData) { | |||
| cancellingRef.current = false; | |||
| setCancelLoading(false); | |||
| if (responseData && responseData.success === false) { | |||
| setCancelPopUp(false); | |||
| const msg = responseData.msg ? intl.formatMessage({ id: responseData.msg }) : intl.formatMessage({ id: 'proofAlreadyCancelled' }); | |||
| setAlertMsg(msg); | |||
| setShowAlert(true); | |||
| } else { | |||
| window.location.reload(false); | |||
| } | |||
| }, | |||
| onFail: () => { | |||
| cancellingRef.current = false; | |||
| setCancelLoading(false); | |||
| }, | |||
| onError: () => { | |||
| cancellingRef.current = false; | |||
| setCancelLoading(false); | |||
| } | |||
| }); | |||
| } | |||
| @@ -348,15 +364,24 @@ const ApplicationDetailCard = ({ | |||
| <div> | |||
| <Dialog | |||
| open={cancelPopUp} | |||
| onClose={() => setCancelPopUp(false)} | |||
| onClose={() => { | |||
| if (cancelLoading) return; | |||
| setCancelPopUp(false); | |||
| }} | |||
| > | |||
| <DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle> | |||
| <DialogContent style={{ display: 'flex', }}> | |||
| <Typography variant="h4" style={{ padding: '16px' }}>Are you sure you want to cancel this proof?</Typography> | |||
| </DialogContent> | |||
| <DialogActions> | |||
| <Button onClick={() => setCancelPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
| <Button onClick={() => confirmCancel()}><Typography variant="h5">Confirm</Typography></Button> | |||
| <Button onClick={() => setCancelPopUp(false)} disabled={cancelLoading}><Typography variant="h5">Cancel</Typography></Button> | |||
| <Button | |||
| onClick={() => confirmCancel()} | |||
| disabled={cancelLoading} | |||
| startIcon={cancelLoading ? <CircularProgress color="inherit" size={20} /> : null} | |||
| > | |||
| <Typography variant="h5">Confirm</Typography> | |||
| </Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| <Dialog open={showAlert} onClose={() => setShowAlert(false)}> | |||
| @@ -9,6 +9,7 @@ import { | |||
| Stack, | |||
| Dialog, DialogTitle, DialogContent, DialogActions, InputAdornment, Autocomplete | |||
| } from '@mui/material'; | |||
| import LoadingButton from '@mui/lab/LoadingButton'; | |||
| import { isGranted, delBugMode, getPaymentMethodGLD} from "auth/utils"; | |||
| const MainCard = Loadable(lazy(() => import('components/MainCard'))); | |||
| import { useForm } from "react-hook-form"; | |||
| @@ -37,14 +38,42 @@ import { notifyActionError } from 'utils/CommonFunction'; | |||
| import { isGrantedAny } from "auth/utils"; | |||
| import { useIntl } from "react-intl"; | |||
| /** Contained buttons with custom bg must restyle disabled/loading or they stay green/orange. */ | |||
| const publishWithdrawLoadingSx = (mainBg, hoverBg) => (theme) => ({ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end', | |||
| backgroundColor: mainBg, | |||
| color: '#fff', | |||
| '&:hover:not(.Mui-disabled):not(.MuiLoadingButton-loading)': { | |||
| backgroundColor: hoverBg, | |||
| }, | |||
| '&.Mui-disabled, &.MuiLoadingButton-loading': { | |||
| backgroundColor: theme.palette.action.disabledBackground, | |||
| color: theme.palette.action.disabled, | |||
| }, | |||
| '&.Mui-disabled .MuiSvgIcon-root, &.MuiLoadingButton-loading .MuiSvgIcon-root': { | |||
| color: theme.palette.action.disabled, | |||
| }, | |||
| '&.Mui-disabled .MuiTypography-root, &.MuiLoadingButton-loading .MuiTypography-root': { | |||
| color: `${theme.palette.action.disabled} !important`, | |||
| }, | |||
| }); | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const ApplicationDetailCard = ( | |||
| { applicationDetailData, | |||
| setStatus, | |||
| setUploadStatus | |||
| setUploadStatus, | |||
| statusDialogOpen = false, | |||
| statusDialogKind = "", | |||
| statusActionLoading = false, | |||
| } | |||
| ) => { | |||
| const publishWithdrawBusy = | |||
| statusActionLoading || | |||
| (statusDialogOpen && (statusDialogKind === 'publish' || statusDialogKind === 'withdraw')); | |||
| const [currentApplicationDetailData, setCurrentApplicationDetailData] = useState({}); | |||
| const [companyName, setCompanyName] = useState({}); | |||
| const [orgDetail, setOrgDetail] = useState({}); | |||
| @@ -168,10 +197,12 @@ const ApplicationDetailCard = ( | |||
| }; | |||
| const withdrawnClick = () => () => { | |||
| if (publishWithdrawBusy) return; | |||
| setStatus("withdraw") | |||
| }; | |||
| const doPublish = () => () => { | |||
| if (publishWithdrawBusy) return; | |||
| setStatus("publish") | |||
| } | |||
| @@ -334,31 +365,26 @@ const ApplicationDetailCard = ( | |||
| </> : | |||
| (currentApplicationDetailData.status == "confirmed" && currentApplicationDetailData.creditor == 1) ? | |||
| <> | |||
| <Button | |||
| <LoadingButton | |||
| // size="large" | |||
| variant="contained" | |||
| onClick={doPublish()} | |||
| disabled={setCompleteDisable()} | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end', | |||
| backgroundColor: '#52b202' | |||
| }}> | |||
| disabled={setCompleteDisable() || publishWithdrawBusy} | |||
| loading={statusActionLoading && statusDialogKind === 'publish'} | |||
| sx={publishWithdrawLoadingSx('#52b202', '#489f04')}> | |||
| <DoneIcon /> | |||
| <Typography ml={1} variant="h5">Publish</Typography> | |||
| </Button> | |||
| <Button | |||
| </LoadingButton> | |||
| <LoadingButton | |||
| // size="large" | |||
| variant="contained" | |||
| onClick={withdrawnClick()} | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end', | |||
| backgroundColor: '#ffa733' | |||
| }}> | |||
| disabled={publishWithdrawBusy} | |||
| loading={statusActionLoading && statusDialogKind === 'withdraw'} | |||
| sx={publishWithdrawLoadingSx('#ffa733', '#e8982e')}> | |||
| <CloseIcon /> | |||
| <Typography ml={1} variant="h5">Withdraw</Typography> | |||
| </Button> | |||
| </LoadingButton> | |||
| </> | |||
| : | |||
| ( | |||
| @@ -392,18 +418,16 @@ const ApplicationDetailCard = ( | |||
| <DoneIcon /> | |||
| <Typography ml={1} variant="h5">Publish</Typography> | |||
| </Button> | |||
| <Button | |||
| <LoadingButton | |||
| // size="large" | |||
| variant="contained" | |||
| onClick={withdrawnClick()} | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end', | |||
| backgroundColor: '#ffa733' | |||
| }}> | |||
| disabled={publishWithdrawBusy} | |||
| loading={statusActionLoading && statusDialogKind === 'withdraw'} | |||
| sx={publishWithdrawLoadingSx('#ffa733', '#e8982e')}> | |||
| <CloseIcon /> | |||
| <Typography ml={1} variant="h5">Withdraw</Typography> | |||
| </Button> | |||
| </LoadingButton> | |||
| </> : null | |||
| ) | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| import { | |||
| useEffect, | |||
| useState | |||
| useState, | |||
| useRef | |||
| } from "react"; | |||
| // material-ui | |||
| @@ -16,8 +17,9 @@ import { | |||
| FormLabel, | |||
| Autocomplete, | |||
| TextField, | |||
| Grid | |||
| Grid, | |||
| } from '@mui/material'; | |||
| import LoadingButton from '@mui/lab/LoadingButton'; | |||
| import * as ComboData from "utils/ComboData"; | |||
| import { useFormik, FormikProvider } from 'formik'; | |||
| @@ -30,8 +32,15 @@ const StatusChangeDialog = (props) => { | |||
| const [remarks, setRemarks] = useState(""); | |||
| const [helperText, setHelperText] = useState(""); | |||
| const [comboInputValue, setComboInputValue] = useState({}); | |||
| const [positiveSubmitting, setPositiveSubmitting] = useState(false); | |||
| const positiveOnceRef = useRef(false); | |||
| const groupTitleComboList = ComboData.groupTitle; | |||
| const confirmLoading = Boolean(props.confirmLoading) || positiveSubmitting; | |||
| const gazetteGroupMissing = | |||
| props.getStatus === "genGazetteCode" && | |||
| Object.keys(props.selectedGazetteGroup ?? {}).length === 0; | |||
| useEffect(() => { | |||
| setComboInputValue({}); | |||
| if (props.getStatus == "genGazetteCode") { | |||
| @@ -58,22 +67,40 @@ const StatusChangeDialog = (props) => { | |||
| } | |||
| }, [props.getStatus]); | |||
| useEffect(() => { | |||
| if (!props.open) { | |||
| positiveOnceRef.current = false; | |||
| setPositiveSubmitting(false); | |||
| } | |||
| }, [props.open]); | |||
| const wasConfirmLoadingRef = useRef(false); | |||
| useEffect(() => { | |||
| if (wasConfirmLoadingRef.current && !props.confirmLoading) { | |||
| positiveOnceRef.current = false; | |||
| setPositiveSubmitting(false); | |||
| } | |||
| wasConfirmLoadingRef.current = Boolean(props.confirmLoading); | |||
| }, [props.confirmLoading]); | |||
| const acceptedHandle = () => () => { | |||
| const getStatus = props.getStatus.status; | |||
| if (getStatus == "notAccepted") { | |||
| if (!remarks || remarks == "") | |||
| if (confirmLoading) return; | |||
| if (positiveOnceRef.current) return; | |||
| const statusKey = props.getStatus; | |||
| if (statusKey === "notAccepted" || statusKey === "resubmit") { | |||
| if (!remarks || remarks === "") { | |||
| setHelperText("Please enter reason"); | |||
| } | |||
| if (!helperText) { | |||
| props.setReason({ "reason": remarks }); | |||
| if (remarks != null && remarks != "") { | |||
| // console.log(remarks) | |||
| // props.setStatusWindowAccepted(true); | |||
| return; | |||
| } | |||
| setHelperText(""); | |||
| props.setReason({ "reason": remarks }); | |||
| } | |||
| if (getStatus != "notAccepted") { | |||
| props.setStatusWindowAccepted(true); | |||
| } | |||
| positiveOnceRef.current = true; | |||
| setPositiveSubmitting(true); | |||
| props.setStatusWindowAccepted(true); | |||
| }; | |||
| @@ -181,7 +208,10 @@ const StatusChangeDialog = (props) => { | |||
| return ( | |||
| <Dialog | |||
| open={props.open} | |||
| onClose={props.handleClose} | |||
| onClose={() => { | |||
| if (confirmLoading) return; | |||
| props.handleClose(); | |||
| }} | |||
| fullWidth={true} | |||
| maxWidth={'md'} | |||
| > | |||
| @@ -207,18 +237,24 @@ const StatusChangeDialog = (props) => { | |||
| </FormikProvider> | |||
| <Stack direction="row" justifyContent="space-around"> | |||
| <DialogActions> | |||
| <Button variant="contained" onClick={props.handleClose} autoFocus > | |||
| <Button variant="contained" onClick={props.handleClose} autoFocus disabled={confirmLoading}> | |||
| <Typography variant="h5"> | |||
| Cancel | |||
| </Typography> | |||
| </Button> | |||
| </DialogActions> | |||
| <DialogActions> | |||
| <Button variant="contained" color="success" onClick={acceptedHandle()} autoFocus disabled={Object.keys(props.selectedGazetteGroup).length === 0 && props.getStatus === "genGazetteCode"}> | |||
| <Typography variant="h5"> | |||
| <LoadingButton | |||
| variant="contained" | |||
| color="success" | |||
| onClick={acceptedHandle()} | |||
| loading={confirmLoading} | |||
| disabled={gazetteGroupMissing} | |||
| > | |||
| <Typography variant="h5" component="span"> | |||
| {prositiveBtnText} | |||
| </Typography> | |||
| </Button> | |||
| </LoadingButton> | |||
| </DialogActions> | |||
| </Stack> | |||
| </Dialog> | |||
| @@ -70,6 +70,7 @@ const PublicNoticeDetail_GLD = () => { | |||
| const [open, setOpen] = useState(false); | |||
| const [getStatus, setStatus] = useState(""); | |||
| const [statusWindowAccepted, setStatusWindowAccepted] = useState(false); | |||
| const [statusConfirmLoading, setStatusConfirmLoading] = useState(false); | |||
| const [selectedGazetteGroup, setSelectedGazetteGroup] = useState({}); | |||
| const [selectedGazetteGroupInputType, setSelectedGazetteGroupInputType] = useState(""); | |||
| const [getReason, setReason] = useState({}); | |||
| @@ -182,24 +183,30 @@ const PublicNoticeDetail_GLD = () => { | |||
| }; | |||
| useEffect(() => { | |||
| if (statusWindowAccepted) { | |||
| if (getStatus == "genGazetteCode") { | |||
| onAcceptedClick() | |||
| } else if (getStatus == "complete") { | |||
| onComplatedClick() | |||
| } else if (getStatus == "withdraw") { | |||
| onWithdrawnClick() | |||
| } else if (getStatus == "notAccepted") { | |||
| onNotAcceptClick(getReason); | |||
| } else if (getStatus == "resubmit") { | |||
| onReSubmitClick(getReason); | |||
| } else if (getStatus == "publish") { | |||
| onPublishClick(); | |||
| } else if (getStatus == "revoke") { | |||
| onRevokeClick(); | |||
| } else if(getStatus == "paid"){ | |||
| onPaidClick(); | |||
| } | |||
| if (!statusWindowAccepted) { | |||
| setStatusConfirmLoading(false); | |||
| return; | |||
| } | |||
| setStatusConfirmLoading(true); | |||
| if (getStatus == "genGazetteCode") { | |||
| onAcceptedClick() | |||
| } else if (getStatus == "complete") { | |||
| onComplatedClick() | |||
| } else if (getStatus == "withdraw") { | |||
| onWithdrawnClick() | |||
| } else if (getStatus == "notAccepted") { | |||
| onNotAcceptClick(getReason); | |||
| } else if (getStatus == "resubmit") { | |||
| onReSubmitClick(getReason); | |||
| } else if (getStatus == "publish") { | |||
| onPublishClick(); | |||
| } else if (getStatus == "revoke") { | |||
| onRevokeClick(); | |||
| } else if(getStatus == "paid"){ | |||
| onPaidClick(); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }, [statusWindowAccepted]); | |||
| @@ -223,12 +230,23 @@ const PublicNoticeDetail_GLD = () => { | |||
| .catch(error => { | |||
| console.log(error); | |||
| return false; | |||
| }) | |||
| .finally(() => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }; | |||
| const onNotAcceptClick = (reason) => { | |||
| if (params.id <= 0) return; | |||
| if (params.id <= 0) { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| return; | |||
| } | |||
| HttpUtils.post({ | |||
| url: `${SET_PUBLIC_NOTICE_STATUS_NOT_ACCEPT}/${params.id}`, | |||
| params: reason, | |||
| @@ -238,12 +256,24 @@ const PublicNoticeDetail_GLD = () => { | |||
| // location.reload(); | |||
| loadApplicationDetail() | |||
| notifySaveSuccess() | |||
| }, | |||
| onFail: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onError: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }); | |||
| } | |||
| const onPublishClick = () => { | |||
| if (params.id <= 0) return; | |||
| if (params.id <= 0) { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| return; | |||
| } | |||
| HttpUtils.get({ | |||
| url: `${SET_PUBLIC_NOTICE_STATUS_PUBLISH}/${params.id}`, | |||
| onSuccess: function () { | |||
| @@ -251,6 +281,18 @@ const PublicNoticeDetail_GLD = () => { | |||
| handleClose(); | |||
| loadApplicationDetail() | |||
| notifySaveSuccess() | |||
| }, | |||
| onFail: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onError: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onFinally: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }); | |||
| } | |||
| @@ -270,7 +312,14 @@ const PublicNoticeDetail_GLD = () => { | |||
| .catch(error => { | |||
| console.log(error); | |||
| return false; | |||
| }) | |||
| .finally(() => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }; | |||
| @@ -289,7 +338,14 @@ const PublicNoticeDetail_GLD = () => { | |||
| .catch(error => { | |||
| console.log(error); | |||
| return false; | |||
| }) | |||
| .finally(() => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }; | |||
| @@ -307,7 +363,14 @@ const PublicNoticeDetail_GLD = () => { | |||
| .catch(error => { | |||
| console.log(error); | |||
| return false; | |||
| }) | |||
| .finally(() => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }; | |||
| @@ -322,6 +385,14 @@ const PublicNoticeDetail_GLD = () => { | |||
| // location.reload(); | |||
| loadApplicationDetail() | |||
| notifySaveSuccess() | |||
| }, | |||
| onFail: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onError: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }); | |||
| // axios.post(`${SET_PUBLIC_NOTICE_STATUS_RESUBMIT}/${params.id}`) | |||
| @@ -338,11 +409,18 @@ const PublicNoticeDetail_GLD = () => { | |||
| // console.log(error); | |||
| // return false; | |||
| // }); | |||
| } else { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }; | |||
| const onRevokeClick = () => { | |||
| if (params.id <= 0) return; | |||
| if (params.id <= 0) { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| return; | |||
| } | |||
| HttpUtils.get({ | |||
| url: `${SET_PUBLIC_NOTICE_STATUS_REVOKE}/${params.id}`, | |||
| onSuccess: function () { | |||
| @@ -350,6 +428,18 @@ const PublicNoticeDetail_GLD = () => { | |||
| handleClose(); | |||
| loadApplicationDetail() | |||
| notifySaveSuccess() | |||
| }, | |||
| onFail: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onError: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| }, | |||
| onFinally: () => { | |||
| setStatusConfirmLoading(false); | |||
| setStatusWindowAccepted(false); | |||
| } | |||
| }); | |||
| } | |||
| @@ -383,6 +473,7 @@ const PublicNoticeDetail_GLD = () => { | |||
| issueDate={issueDate} | |||
| issueNum={issueNum} | |||
| gazetteIssue={gazetteIssue} | |||
| confirmLoading={statusConfirmLoading} | |||
| //combo value | |||
| selectedGazetteGroup={selectedGazetteGroup} | |||
| setSelectedGazetteGroup={setSelectedGazetteGroup} | |||
| @@ -425,6 +516,9 @@ const PublicNoticeDetail_GLD = () => { | |||
| setUpdateApplicationObject={setUpdateApplicationObject} | |||
| isEditMode={isEditMode} | |||
| setiIsSave={setiIsSave} | |||
| statusDialogOpen={open} | |||
| statusDialogKind={getStatus} | |||
| statusActionLoading={statusConfirmLoading} | |||
| // isNewRecord={isNewRecord} | |||
| /> | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| import { | |||
| useEffect, | |||
| useState | |||
| useState, | |||
| useRef | |||
| } from "react"; | |||
| // material-ui | |||
| @@ -15,6 +16,7 @@ import { | |||
| DialogContent, | |||
| DialogContentText, | |||
| DialogTitle, | |||
| CircularProgress, | |||
| } from '@mui/material'; | |||
| import { useFormik,FormikProvider } from 'formik'; | |||
| import * as yup from 'yup'; | |||
| @@ -26,6 +28,7 @@ import {useIntl} from "react-intl"; | |||
| const StatusChangeDialog = (props) => { | |||
| const [status, setStatus] = useState(""); | |||
| const intl = useIntl(); | |||
| const confirmOnceRef = useRef(false); | |||
| useEffect(() => { | |||
| // console.log(Object.keys(!props.selectedGazetteGroup).length) | |||
| @@ -33,9 +36,25 @@ const StatusChangeDialog = (props) => { | |||
| setStatus(intl.formatMessage({id: 'cancel'})) | |||
| } | |||
| }, [props.getStatus]); | |||
| useEffect(() => { | |||
| if (!props.open) { | |||
| confirmOnceRef.current = false; | |||
| } | |||
| }, [props.open]); | |||
| const wasConfirmLoadingRef = useRef(false); | |||
| useEffect(() => { | |||
| if (wasConfirmLoadingRef.current && !props.confirmLoading) { | |||
| confirmOnceRef.current = false; | |||
| } | |||
| wasConfirmLoadingRef.current = props.confirmLoading; | |||
| }, [props.confirmLoading]); | |||
| const acceptedHandle = () => () =>{ | |||
| // console.log(selectedGazetteGroup) | |||
| if (props.confirmLoading) return; | |||
| if (confirmOnceRef.current) return; | |||
| confirmOnceRef.current = true; | |||
| props.setStatusWindowAccepted(true) | |||
| }; | |||
| @@ -86,6 +105,7 @@ const StatusChangeDialog = (props) => { | |||
| onClick={props.handleClose} | |||
| autoFocus | |||
| color="cancel" | |||
| disabled={props.confirmLoading} | |||
| > | |||
| <FormattedMessage id="cancel"/> | |||
| </Button> | |||
| @@ -96,6 +116,8 @@ const StatusChangeDialog = (props) => { | |||
| color="save" | |||
| onClick={acceptedHandle()} | |||
| autoFocus | |||
| disabled={props.confirmLoading} | |||
| startIcon={props.confirmLoading ? <CircularProgress color="inherit" size={20} /> : null} | |||
| > | |||
| <FormattedMessage id="confirm"/> | |||
| </Button> | |||
| @@ -1,6 +1,7 @@ | |||
| import React, { | |||
| useEffect, | |||
| useState, | |||
| useRef, | |||
| lazy | |||
| } from "react"; | |||
| @@ -49,6 +50,8 @@ const DashboardDefault = () => { | |||
| const [open, setOpen] = useState(false); | |||
| const [getStatus, setStatus] = useState(""); | |||
| const [statusWindowAccepted, setStatusWindowAccepted] = useState(false); | |||
| const [cancelLoading, setCancelLoading] = useState(false); | |||
| const cancellingRef = useRef(false); | |||
| const [proofCount, setProofCount] = useState(0); | |||
| const [paymentCount, setPaymentCount] = useState(0); | |||
| @@ -137,7 +140,10 @@ const DashboardDefault = () => { | |||
| }, [getStatus]); | |||
| const onCancelledClick = () => { | |||
| if (cancellingRef.current) return; | |||
| if (params.id > 0) { | |||
| cancellingRef.current = true; | |||
| setCancelLoading(true); | |||
| axios.get(`${SET_PUBLIC_NOTICE_STATUS_CANCELLED}/${params.id}`) | |||
| .then((response) => { | |||
| if (response.status === 204) { | |||
| @@ -151,13 +157,23 @@ const DashboardDefault = () => { | |||
| .catch(error => { | |||
| console.log(error); | |||
| return false; | |||
| }) | |||
| .finally(() => { | |||
| cancellingRef.current = false; | |||
| setCancelLoading(false); | |||
| }); | |||
| } | |||
| }; | |||
| return ( | |||
| <Grid container sx={{ backgroundColor: '#ffffff' }} direction="column"> | |||
| <StatusChangeDialog open={open} handleClose={handleClose} setStatusWindowAccepted={setStatusWindowAccepted} getStatus={getStatus} /> | |||
| <StatusChangeDialog | |||
| open={open} | |||
| handleClose={handleClose} | |||
| setStatusWindowAccepted={setStatusWindowAccepted} | |||
| getStatus={getStatus} | |||
| confirmLoading={cancelLoading} | |||
| /> | |||
| <Grid item xs={12}> | |||
| <div style={BackgroundHead}> | |||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||
| @@ -2,7 +2,7 @@ import axios from "axios"; | |||
| import { FILE_UP_POST, FILE_DOWN_GET } from "../utils/ApiPathConst"; | |||
| import qs from 'qs'; | |||
| export const get = ({ url, params, onSuccess, onFail, onError }) => { | |||
| export const get = ({ url, params, onSuccess, onFail, onError, onFinally }) => { | |||
| axios.get(url, { | |||
| params, | |||
| paramsSerializer: (p) => qs.stringify(p, { arrayFormat: 'repeat' }) // <-- FIX | |||
| @@ -10,6 +10,10 @@ export const get = ({ url, params, onSuccess, onFail, onError }) => { | |||
| (response) => { onResponse(response, onSuccess, onFail); } | |||
| ).catch((error) => { | |||
| return handleError(error, onError); | |||
| }).finally(() => { | |||
| if (typeof onFinally === 'function') { | |||
| onFinally(); | |||
| } | |||
| }); | |||
| }; | |||