From 5f22c8c64909562fbf5980c11254bd7ad08aa98f Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Tue, 3 Jun 2025 02:01:23 +0800 Subject: [PATCH 01/28] update keep only online payment after 2026-01-28 --- src/pages/Proof/Reply_Public/ProofForm.js | 179 +++++++++--------- .../ApplyForm/PublicNoticeApplyForm.js | 118 ++++++------ src/pages/PublicNotice/ApplyForm/index.js | 11 +- src/utils/Utils.js | 15 ++ 4 files changed, 179 insertions(+), 144 deletions(-) diff --git a/src/pages/Proof/Reply_Public/ProofForm.js b/src/pages/Proof/Reply_Public/ProofForm.js index b0ee8e0..9b22a44 100644 --- a/src/pages/Proof/Reply_Public/ProofForm.js +++ b/src/pages/Proof/Reply_Public/ProofForm.js @@ -26,7 +26,10 @@ import { notifyActionSuccess } from 'utils/CommonFunction'; import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; import { ThemeProvider } from "@emotion/react"; import { FormattedMessage, useIntl } from "react-intl"; -import { isDummyLoggedIn } from "utils/Utils" +import { + isDummyLoggedIn, + checkIsOnlyOnlinePayment + } from "utils/Utils" const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); //import * as ProofStatus from "utils/statusUtils/ProofStatus"; @@ -46,6 +49,7 @@ const FormPanel = ({ formData }) => { const [warningTitle, setWarningTitle] = React.useState(""); const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); const [warningText, setWarningText] = React.useState(""); + const [isOnlyOnlinePayment, setOnlyOnlinePayment] = React.useState(); const navigate = useNavigate() const params = useParams(); @@ -61,6 +65,7 @@ const FormPanel = ({ formData }) => { React.useEffect(() => { if (formData) { setData(formData); + setOnlyOnlinePayment(checkIsOnlyOnlinePayment(formData.issueDate)) if (isDummyLoggedIn()) { set_paymentMethod("demandNote") } @@ -461,90 +466,94 @@ const FormPanel = ({ formData }) => { }} /> - - - {isOverDnReviseDeadline() ? - <> : - { - set_paymentMethod("demandNote") - }} - /> - } - - - -
{ - setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) - setWarningText( - <>: -
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
- -
- - - ); - setIsWarningPopUp(true); - }}> - - {DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"} - {DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"} - - - - - - - - { - isOverNpgoReviseDeadline() ? - <> : - { - set_paymentMethod("office") - }} - /> - } - - - -
{ - setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) - setWarningText( - <>: -
    -
  • -
  • -
  • -
  • -
- - ); - setIsWarningPopUp(true); - }}>
- - {DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"11:30 a.m.":"上午11時30分"} - {DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"12:00 p.m.":"下午12時"} - - - - + {!isOnlyOnlinePayment? + <> + + + {isOverDnReviseDeadline() ? + <> : + { + set_paymentMethod("demandNote") + }} + /> + } + + + +
{ + setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) + setWarningText( + <>: +
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+ +
+ + + ); + setIsWarningPopUp(true); + }}> + + {DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"} + {DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"} + + + + + + + + { + isOverNpgoReviseDeadline() ? + <> : + { + set_paymentMethod("office") + }} + /> + } + + + +
{ + setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) + setWarningText( + <>: +
    +
  • +
  • +
  • +
  • +
+ + ); + setIsWarningPopUp(true); + }}>
+ + {DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"11:30 a.m.":"上午11時30分"} + {DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"12:00 p.m.":"下午12時"} + + + + + :null + } diff --git a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js index 11e6021..bffd396 100644 --- a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js +++ b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js @@ -33,7 +33,7 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo // ==============================|| DASHBOARD - DEFAULT ||============================== // -const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) => { +const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList, isOnlyOnlinePayment }) => { const [isWarningPopUp, setIsWarningPopUp] = useState(false); const [warningTitle, setWarningTitle] = useState(""); const [warningText, setWarningText] = useState(""); @@ -383,62 +383,66 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) => }} /> - - -
{ - setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) - setWarningText( - <>: -
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
- -
- - - ); - setIsWarningPopUp(true); - }}> - - {DateUtils.dateFormat(closingDateOff, dft)} {locale==='en'?"5:00 p.m.":"下午5時"} - - - - - - -
{ - setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) - setWarningText( - <>: -
    -
  • -
  • -
  • -
  • -
- - ); - setIsWarningPopUp(true); - }}>
- - {DateUtils.dateFormat(closeDate, dft)} {locale==='en'?"12:00 p.m.":"下午12時"} - - - - + {!isOnlyOnlinePayment? + <> + + +
{ + setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) + setWarningText( + <>: +
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+ +
+ + + ); + setIsWarningPopUp(true); + }}> + + {DateUtils.dateFormat(closingDateOff, dft)} {locale==='en'?"5:00 p.m.":"下午5時"} + + + + + + +
{ + setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) + setWarningText( + <>: +
    +
  • +
  • +
  • +
  • +
+ + ); + setIsWarningPopUp(true); + }}>
+ + {DateUtils.dateFormat(closeDate, dft)} {locale==='en'?"12:00 p.m.":"下午12時"} + + + + + :null + } diff --git a/src/pages/PublicNotice/ApplyForm/index.js b/src/pages/PublicNotice/ApplyForm/index.js index 74c581b..ba36ace 100644 --- a/src/pages/PublicNotice/ApplyForm/index.js +++ b/src/pages/PublicNotice/ApplyForm/index.js @@ -20,6 +20,7 @@ const PublicNoticeApplyForm = Loadable(lazy(() => import('./PublicNoticeApplyFor import { // isORGLoggedIn, isDummyLoggedIn, + checkIsOnlyOnlinePayment // isCreditorLoggedIn } from "utils/Utils"; // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -29,6 +30,7 @@ const ApplyForm = () => { const [gazetteIssueList, setGazetteIssueList] = React.useState([]); const [selections, setSelection] = React.useState([]); + const [isOnlyOnlinePayment, setOnlyOnlinePayment] = React.useState(); const [isLoading, setLoding] = React.useState(true); const intl = useIntl(); @@ -64,6 +66,7 @@ const ApplyForm = () => { setGazetteIssueList(response?.gazetteIssueList); setSelection(selection); setUserData(response); + setOnlyOnlinePayment(checkIsOnlyOnlinePayment(response?.gazetteIssueList[0].issueDate)) } }); }; @@ -106,8 +109,11 @@ const ApplyForm = () => { React.useEffect(() => { - if (userData !== null) setLoding(false); - }, [userData]); + if (userData !== null&& isOnlyOnlinePayment !== null){ + setLoding(false); + // console.log(isOnlyOnlinePayment) + } + }, [userData,isOnlyOnlinePayment]); return ( isLoading ? @@ -121,6 +127,7 @@ const ApplyForm = () => { loadedData={userData} _selections={selections} gazetteIssueList = {gazetteIssueList} + isOnlyOnlinePayment = {isOnlyOnlinePayment} /> ); }; diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 4923a10..b14ee03 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -181,4 +181,19 @@ export const isPasswordExpiry = () =>{ return false; } +} + +export const checkIsOnlyOnlinePayment = (date) => { + const targetDate = new Date("2026-01-28") + const checkDate = DateUtils.convertToDate(date) + if (isDummyLoggedIn()){ + return false; + } + // console.log(checkDate) + // console.log(targetDate) + if (checkDate >= targetDate) { + return true + } else { + return false; + } } \ No newline at end of file From afb6d486f7621e09e134a6e0df843af242aee6ab Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Fri, 6 Jun 2025 01:45:20 +0800 Subject: [PATCH 02/28] add checking for creditor btn --- .../DetailPage/OrganizationCard.js | 64 ++++++++++--------- src/pages/Proof/Reply_Public/ProofForm.js | 4 +- src/pages/PublicNotice/ApplyForm/index.js | 2 +- src/utils/Utils.js | 18 +++++- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/pages/Organization/DetailPage/OrganizationCard.js b/src/pages/Organization/DetailPage/OrganizationCard.js index 76fa33f..1bdf7fb 100644 --- a/src/pages/Organization/DetailPage/OrganizationCard.js +++ b/src/pages/Organization/DetailPage/OrganizationCard.js @@ -14,6 +14,7 @@ import { useEffect, useState, lazy } from "react"; import * as DateUtils from 'utils/DateUtils'; import * as HttpUtils from 'utils/HttpUtils'; import * as UrlUtils from "utils/ApiPathConst"; +import {checkMarkAsCreditClient} from 'utils/Utils'; import * as FieldUtils from "utils/FieldUtils"; import * as ComboData from "utils/ComboData"; const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent'))); @@ -312,30 +313,33 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { { currentUserData.creditor ? - - - - - - : - <> + !checkMarkAsCreditClient()? - + :null + : + <> + {!checkMarkAsCreditClient()? + + + + + :null + } { isGrantedAny("MAINTAIN_DEMANDNOTE")? @@ -385,18 +389,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { })} - - } - label="is Credit Client" - name="creditor" - onChange={() => { - formik.setFieldValue("creditor", !formik.values.creditor); - }} - disabled={true} - //disabled={!editMode && !createMode} - /> - + {!checkMarkAsCreditClient()? + + } + label="is Credit Client" + name="creditor" + onChange={() => { + formik.setFieldValue("creditor", !formik.values.creditor); + }} + disabled={true} + //disabled={!editMode && !createMode} + /> + :null + } diff --git a/src/pages/Proof/Reply_Public/ProofForm.js b/src/pages/Proof/Reply_Public/ProofForm.js index 9b22a44..7459d13 100644 --- a/src/pages/Proof/Reply_Public/ProofForm.js +++ b/src/pages/Proof/Reply_Public/ProofForm.js @@ -65,9 +65,11 @@ const FormPanel = ({ formData }) => { React.useEffect(() => { if (formData) { setData(formData); - setOnlyOnlinePayment(checkIsOnlyOnlinePayment(formData.issueDate)) + setOnlyOnlinePayment(checkIsOnlyOnlinePayment()) if (isDummyLoggedIn()) { set_paymentMethod("demandNote") + } else if (checkIsOnlyOnlinePayment()){ + set_paymentMethod("online") } } }, [formData]); diff --git a/src/pages/PublicNotice/ApplyForm/index.js b/src/pages/PublicNotice/ApplyForm/index.js index ba36ace..0286ad0 100644 --- a/src/pages/PublicNotice/ApplyForm/index.js +++ b/src/pages/PublicNotice/ApplyForm/index.js @@ -66,7 +66,7 @@ const ApplyForm = () => { setGazetteIssueList(response?.gazetteIssueList); setSelection(selection); setUserData(response); - setOnlyOnlinePayment(checkIsOnlyOnlinePayment(response?.gazetteIssueList[0].issueDate)) + setOnlyOnlinePayment(checkIsOnlyOnlinePayment()) } }); }; diff --git a/src/utils/Utils.js b/src/utils/Utils.js index b14ee03..591aa92 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -183,9 +183,9 @@ export const isPasswordExpiry = () =>{ } -export const checkIsOnlyOnlinePayment = (date) => { - const targetDate = new Date("2026-01-28") - const checkDate = DateUtils.convertToDate(date) +export const checkIsOnlyOnlinePayment = () => { + const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const checkDate = DateUtils.convertToDate(new Date()) if (isDummyLoggedIn()){ return false; } @@ -196,4 +196,16 @@ export const checkIsOnlyOnlinePayment = (date) => { } else { return false; } +} + +export const checkMarkAsCreditClient = () => { + const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const checkDate = DateUtils.convertToDate(new Date()) + // console.log(targetDate) + // console.log(checkDate >= targetDate) + if (checkDate >= targetDate) { + return true + } else { + return false; + } } \ No newline at end of file From d94a603775349a76598e0db1e89dac6b9fd7a92d Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Sun, 13 Jul 2025 22:55:37 +0800 Subject: [PATCH 03/28] update application payment with issueDate show --- .../ApplyForm/PublicNoticeApplyForm.js | 8 ++++++-- src/pages/PublicNotice/ApplyForm/index.js | 12 ++++++------ src/utils/Utils.js | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js index bffd396..fbe2860 100644 --- a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js +++ b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js @@ -19,7 +19,8 @@ import ForwardIcon from '@mui/icons-material/Forward'; import { isORGLoggedIn, isDummyLoggedIn, - isCreditorLoggedIn + isCreditorLoggedIn, + checkIsOnlyOnlinePaymentByIssueDate } from "utils/Utils"; import { useNavigate } from "react-router-dom"; @@ -33,7 +34,7 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo // ==============================|| DASHBOARD - DEFAULT ||============================== // -const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList, isOnlyOnlinePayment }) => { +const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) => { const [isWarningPopUp, setIsWarningPopUp] = useState(false); const [warningTitle, setWarningTitle] = useState(""); const [warningText, setWarningText] = useState(""); @@ -51,6 +52,7 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList, isOn const [issueId, setIssueId] = useState(loadedData.issueId); const [closeDate, setCloseDate] = useState(null); const [closingDateOff, setClosingDateOff] = useState(null); + const [isOnlyOnlinePayment, setOnlyOnlinePayment] = useState(); const navigate = useNavigate(); const BackgroundHead = { @@ -83,6 +85,8 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList, isOn if (data.id == issueId) { setCloseDate(data.closingDate) setClosingDateOff(data.closingDateOff) + setOnlyOnlinePayment(checkIsOnlyOnlinePaymentByIssueDate(data.issueDate)) + break; } } diff --git a/src/pages/PublicNotice/ApplyForm/index.js b/src/pages/PublicNotice/ApplyForm/index.js index 0286ad0..b445939 100644 --- a/src/pages/PublicNotice/ApplyForm/index.js +++ b/src/pages/PublicNotice/ApplyForm/index.js @@ -20,7 +20,7 @@ const PublicNoticeApplyForm = Loadable(lazy(() => import('./PublicNoticeApplyFor import { // isORGLoggedIn, isDummyLoggedIn, - checkIsOnlyOnlinePayment + // checkIsOnlyOnlinePaymentByIssueDate // isCreditorLoggedIn } from "utils/Utils"; // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -30,7 +30,7 @@ const ApplyForm = () => { const [gazetteIssueList, setGazetteIssueList] = React.useState([]); const [selections, setSelection] = React.useState([]); - const [isOnlyOnlinePayment, setOnlyOnlinePayment] = React.useState(); + const [isLoading, setLoding] = React.useState(true); const intl = useIntl(); @@ -66,7 +66,7 @@ const ApplyForm = () => { setGazetteIssueList(response?.gazetteIssueList); setSelection(selection); setUserData(response); - setOnlyOnlinePayment(checkIsOnlyOnlinePayment()) + // setOnlyOnlinePayment(checkIsOnlyOnlinePayment()) } }); }; @@ -109,11 +109,11 @@ const ApplyForm = () => { React.useEffect(() => { - if (userData !== null&& isOnlyOnlinePayment !== null){ + if (userData !== null){ setLoding(false); // console.log(isOnlyOnlinePayment) } - }, [userData,isOnlyOnlinePayment]); + }, [userData]); return ( isLoading ? @@ -127,7 +127,7 @@ const ApplyForm = () => { loadedData={userData} _selections={selections} gazetteIssueList = {gazetteIssueList} - isOnlyOnlinePayment = {isOnlyOnlinePayment} + // isOnlyOnlinePayment = {isOnlyOnlinePayment} /> ); }; diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 591aa92..c90574c 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -183,6 +183,21 @@ export const isPasswordExpiry = () =>{ } +export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { + const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const checkDate = DateUtils.convertToDate(date) + if (isDummyLoggedIn()){ + return false; + } + // console.log(checkDate) + // console.log(targetDate) + if (checkDate >= targetDate) { + return true + } else { + return false; + } +} + export const checkIsOnlyOnlinePayment = () => { const targetDate = new Date(2026, 0, 28, 8, 0, 0) const checkDate = DateUtils.convertToDate(new Date()) From 345d0970e411f35bd15e2f795d71aa35a4c038f0 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Mon, 14 Jul 2025 00:19:53 +0800 Subject: [PATCH 04/28] add sample date --- src/utils/Utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/Utils.js b/src/utils/Utils.js index c90574c..ca8f9d5 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -184,7 +184,8 @@ export const isPasswordExpiry = () =>{ } export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const targetDate = new Date(2026, 0, 28, 8, 0, 0) //2026-01-28T08:00:00.000Z + // const targetDate = new Date(2025, 6, 13, 8, 0, 0); //2025-07-13T08:00:00.000Z const checkDate = DateUtils.convertToDate(date) if (isDummyLoggedIn()){ return false; From cf09c0215dc53e1a589b9091357f76f2423c8b90 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Mon, 14 Jul 2025 02:59:29 +0800 Subject: [PATCH 05/28] update proof payment method check --- src/pages/Proof/Reply_Public/ProofForm.js | 6 +++--- src/utils/Utils.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/Proof/Reply_Public/ProofForm.js b/src/pages/Proof/Reply_Public/ProofForm.js index 7459d13..df3919e 100644 --- a/src/pages/Proof/Reply_Public/ProofForm.js +++ b/src/pages/Proof/Reply_Public/ProofForm.js @@ -28,7 +28,7 @@ import { ThemeProvider } from "@emotion/react"; import { FormattedMessage, useIntl } from "react-intl"; import { isDummyLoggedIn, - checkIsOnlyOnlinePayment + checkIsOnlyOnlinePaymentByIssueDate } from "utils/Utils" const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); @@ -65,10 +65,10 @@ const FormPanel = ({ formData }) => { React.useEffect(() => { if (formData) { setData(formData); - setOnlyOnlinePayment(checkIsOnlyOnlinePayment()) + setOnlyOnlinePayment(checkIsOnlyOnlinePaymentByIssueDate(formData.issueDate)) if (isDummyLoggedIn()) { set_paymentMethod("demandNote") - } else if (checkIsOnlyOnlinePayment()){ + } else if (checkIsOnlyOnlinePaymentByIssueDate(formData.issueDate)){ set_paymentMethod("online") } } diff --git a/src/utils/Utils.js b/src/utils/Utils.js index ca8f9d5..48a19b9 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -184,8 +184,8 @@ export const isPasswordExpiry = () =>{ } export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) //2026-01-28T08:00:00.000Z - // const targetDate = new Date(2025, 6, 13, 8, 0, 0); //2025-07-13T08:00:00.000Z + const targetDate = new Date(2026, 1, 6, 0, 0, 0) //2026-02-06T00:00:00.000Z + // const targetDate = new Date(2025, 6, 18, 0, 0, 0); //2025-07-13T00:00:00.000Z const checkDate = DateUtils.convertToDate(date) if (isDummyLoggedIn()){ return false; @@ -200,7 +200,7 @@ export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { } export const checkIsOnlyOnlinePayment = () => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const targetDate = new Date(2026, 1, 6, 8, 0, 0) const checkDate = DateUtils.convertToDate(new Date()) if (isDummyLoggedIn()){ return false; @@ -215,7 +215,7 @@ export const checkIsOnlyOnlinePayment = () => { } export const checkMarkAsCreditClient = () => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const targetDate = new Date(2026, 1, 6, 8, 0, 0) const checkDate = DateUtils.convertToDate(new Date()) // console.log(targetDate) // console.log(checkDate >= targetDate) From a73453306b9767c2947536e75c7830ed2690974e Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 14 Jul 2025 03:42:01 +0800 Subject: [PATCH 06/28] update --- src/utils/Utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/Utils.js b/src/utils/Utils.js index ca8f9d5..7f9b817 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -184,7 +184,7 @@ export const isPasswordExpiry = () =>{ } export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) //2026-01-28T08:00:00.000Z + const targetDate = new Date(2025, 6, 25, 0, 0, 0) //2026-01-28T08:00:00.000Z // const targetDate = new Date(2025, 6, 13, 8, 0, 0); //2025-07-13T08:00:00.000Z const checkDate = DateUtils.convertToDate(date) if (isDummyLoggedIn()){ @@ -200,7 +200,7 @@ export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { } export const checkIsOnlyOnlinePayment = () => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const targetDate = new Date(2025, 6, 25, 0, 0, 0) const checkDate = DateUtils.convertToDate(new Date()) if (isDummyLoggedIn()){ return false; @@ -215,7 +215,7 @@ export const checkIsOnlyOnlinePayment = () => { } export const checkMarkAsCreditClient = () => { - const targetDate = new Date(2026, 0, 28, 8, 0, 0) + const targetDate = new Date(2025, 6, 25, 0, 0, 0) const checkDate = DateUtils.convertToDate(new Date()) // console.log(targetDate) // console.log(checkDate >= targetDate) From d59bff36dd3ec6cbe76cc77576a88c3b41b5509d Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 31 Jul 2025 11:54:58 +0800 Subject: [PATCH 07/28] date hardcode --- src/utils/Utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 7f9b817..f42acea 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -184,7 +184,7 @@ export const isPasswordExpiry = () =>{ } export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { - const targetDate = new Date(2025, 6, 25, 0, 0, 0) //2026-01-28T08:00:00.000Z + const targetDate = new Date(2025, 7, 1, 0, 0, 0) //2026-01-28T08:00:00.000Z hardcode // const targetDate = new Date(2025, 6, 13, 8, 0, 0); //2025-07-13T08:00:00.000Z const checkDate = DateUtils.convertToDate(date) if (isDummyLoggedIn()){ @@ -200,7 +200,7 @@ export const checkIsOnlyOnlinePaymentByIssueDate = (date) => { } export const checkIsOnlyOnlinePayment = () => { - const targetDate = new Date(2025, 6, 25, 0, 0, 0) + const targetDate = new Date(2025, 7, 1, 0, 0, 0) // hardcode const checkDate = DateUtils.convertToDate(new Date()) if (isDummyLoggedIn()){ return false; @@ -215,7 +215,7 @@ export const checkIsOnlyOnlinePayment = () => { } export const checkMarkAsCreditClient = () => { - const targetDate = new Date(2025, 6, 25, 0, 0, 0) + const targetDate = new Date(2025, 6, 15, 0, 0, 0) // hardcode const checkDate = DateUtils.convertToDate(new Date()) // console.log(targetDate) // console.log(checkDate >= targetDate) From 8307b7a05245ec2eb5107d89198ee84021175640 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Thu, 8 May 2025 00:11:00 +0800 Subject: [PATCH 08/28] update proof searchCriteria save --- src/auth/index.js | 2 ++ src/auth/utils.js | 12 ++++++++++++ src/pages/Proof/Search_GLD/SearchForm.js | 10 ++++++---- src/pages/Proof/Search_GLD/index.js | 7 +++++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/auth/index.js b/src/auth/index.js index 5ee7c76..abb2c55 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -32,6 +32,7 @@ export const handleLogin = data => { localStorage.setItem('accessToken', data.accessToken) localStorage.setItem('refreshToken', data.refreshToken) localStorage.setItem('axiosToken', "Bearer " + data.accessToken) + localStorage.setItem('searchCriteria',"") //localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1)) localStorage.setItem(refreshIntervalName, "60") // for demo only @@ -91,6 +92,7 @@ export const handleLogoutFunction = () => { localStorage.removeItem('refreshToken') localStorage.removeItem('webtoken') localStorage.removeItem('transactionid') + localStorage.removeItem('searchCriteria') //localStorage.removeItem(config.storageUserRoleKeyName) localStorage.removeItem('expiredAlertShown') localStorage.removeItem(refreshIntervalName) diff --git a/src/auth/utils.js b/src/auth/utils.js index d42953b..28e527a 100644 --- a/src/auth/utils.js +++ b/src/auth/utils.js @@ -130,4 +130,16 @@ export const getPaymentMethod = (paymentMethod) => { if (paymentMethod == "demandNote") return 'payDnMethod'; if (paymentMethod == "office") return 'payNPGOMethod'; return "other"; +} + +export const getSearchCriteria = (path) =>{ + let searchCriteria = "" + if (localStorage.getItem('searchCriteria')==""){ + return searchCriteria + } else if (Object.keys(localStorage.getItem('searchCriteria')).length>0){ + searchCriteria = JSON.parse(localStorage.getItem("searchCriteria")) + if (searchCriteria.path === path){ + return searchCriteria.data + } + } } \ No newline at end of file diff --git a/src/pages/Proof/Search_GLD/SearchForm.js b/src/pages/Proof/Search_GLD/SearchForm.js index f27481b..ad484aa 100644 --- a/src/pages/Proof/Search_GLD/SearchForm.js +++ b/src/pages/Proof/Search_GLD/SearchForm.js @@ -25,12 +25,12 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss }) => { const [type, setType] = React.useState([]); - const [status, setStatus] = React.useState(ComboData.proofStatus[0]); - const [orgSelected, setOrgSelected] = React.useState({}); + const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatus_GLD[searchCriteria.statusKey]:ComboData.proofStatus_GLD[0]); + const [orgSelected, setOrgSelected] = React.useState(searchCriteria.orgId!=undefined?orgComboData && orgComboData.length > 0?orgComboData.find(item => item.key === searchCriteria.orgId):{}:{}); const [orgCombo, setOrgCombo] = React.useState(); - const [issueSelected, setIssueSelected] = React.useState({}); + const [issueSelected, setIssueSelected] = React.useState(searchCriteria.issueId!=undefined?issueComboData && issueComboData.length > 0?issueComboData.find(item => item.id === searchCriteria.issueId):{}:{}); const [issueCombo, setIssueCombo] = React.useState([]); - const [groupSelected, setGroupSelected] = React.useState({}); + const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{}); const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); @@ -73,6 +73,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss dateTo: sentDateTo, contact: data.contact, orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", + statusKey:status?.key, }; @@ -123,6 +124,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) setMaxDate(DateUtils.dateValue(new Date())) reset(); + localStorage.setItem('searchCriteria',"") } function getIssueLabel(data) { diff --git a/src/pages/Proof/Search_GLD/index.js b/src/pages/Proof/Search_GLD/index.js index 3c0c5a5..88092ac 100644 --- a/src/pages/Proof/Search_GLD/index.js +++ b/src/pages/Proof/Search_GLD/index.js @@ -10,6 +10,7 @@ import * as React from "react"; import * as HttpUtils from "utils/HttpUtils"; import * as DateUtils from "utils/DateUtils"; import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; +import { getSearchCriteria } from "auth/utils"; import Loadable from 'components/Loadable'; const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); @@ -42,6 +43,11 @@ const UserSearchPage_Individual = () => { React.useEffect(() => { getOrgCombo(); getIssueCombo(); + if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ + setSearchCriteria(getSearchCriteria(window.location.pathname)) + }else{ + localStorage.setItem('searchCriteria',"") + } }, []); React.useEffect(() => { @@ -72,6 +78,7 @@ const UserSearchPage_Individual = () => { function applySearch(input) { setGridOnReady(true) setSearchCriteria(input); + localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) } function applyGridOnReady(input) { From 78a5d3917e69cd15da6a5975872a347266b139ae Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Fri, 9 May 2025 00:19:40 +0800 Subject: [PATCH 09/28] update public search criteria save --- src/auth/utils.js | 2 + .../Announcement/Search_Public/SearchForm.js | 20 ++++- src/pages/Announcement/Search_Public/index.js | 24 ++++-- src/pages/Message/Search/DataGrid.js | 51 +++++++----- src/pages/Message/Search/SearchForm.js | 7 +- src/pages/Message/Search/index.js | 69 ++++++++++------ src/pages/Payment/Search_Public/SearchForm.js | 3 +- src/pages/Payment/Search_Public/index.js | 18 ++++- src/pages/Proof/Search_GLD/SearchForm.js | 10 ++- src/pages/Proof/Search_Public/SearchForm.js | 9 ++- src/pages/Proof/Search_Public/index.js | 7 ++ .../ListPanel/SearchPublicNoticeForm.js | 16 ++++ .../ListPanel/SearchPublicNoticeTab.js | 80 ++++++++++++------- 13 files changed, 232 insertions(+), 84 deletions(-) diff --git a/src/auth/utils.js b/src/auth/utils.js index 28e527a..8c046b0 100644 --- a/src/auth/utils.js +++ b/src/auth/utils.js @@ -140,6 +140,8 @@ export const getSearchCriteria = (path) =>{ searchCriteria = JSON.parse(localStorage.getItem("searchCriteria")) if (searchCriteria.path === path){ return searchCriteria.data + } else { + return "" } } } \ No newline at end of file diff --git a/src/pages/Announcement/Search_Public/SearchForm.js b/src/pages/Announcement/Search_Public/SearchForm.js index 9fd286c..ad249d1 100644 --- a/src/pages/Announcement/Search_Public/SearchForm.js +++ b/src/pages/Announcement/Search_Public/SearchForm.js @@ -39,6 +39,22 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => setToDateValue(maxDate); }, [maxDate]); + const _sx = { + padding: "4 2 4 2", + boxShadow: 1, + border: 1, + borderColor: '#DDD', + '& .MuiDataGrid-cell': { + borderTop: 1, + borderBottom: 1, + borderColor: "#EEE" + }, + '& .MuiDataGrid-footerContainer': { + border: 1, + borderColor: "#EEE" + } + } + const marginBottom = 2.5; const { reset, register, handleSubmit } = useForm() const onSubmit = (data) => { @@ -61,6 +77,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) setMaxDate(DateUtils.dateValue(new Date())) reset(); + localStorage.setItem('searchCriteria',"") } @@ -68,7 +85,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
@@ -187,6 +204,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => variant="contained" type="submit" disabled={onGridReady} + aria-label={intl.formatMessage({id: 'submit'})} > diff --git a/src/pages/Announcement/Search_Public/index.js b/src/pages/Announcement/Search_Public/index.js index 780d302..cece798 100644 --- a/src/pages/Announcement/Search_Public/index.js +++ b/src/pages/Announcement/Search_Public/index.js @@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' import { FormattedMessage } from "react-intl"; +import { getSearchCriteria } from "auth/utils"; const BackgroundHead = { backgroundImage: `url(${titleBackgroundImg})`, @@ -29,21 +30,32 @@ const BackgroundHead = { const UserSearchPage_Individual = () => { - const [searchCriteria, setSearchCriteria] = React.useState({ - dateTo: DateUtils.dateValue(new Date()), - dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 90)), - }); + const [searchCriteria, setSearchCriteria] = React.useState({}); const [onReady, setOnReady] = React.useState(false); const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - setOnReady(true); + if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ + setSearchCriteria(getSearchCriteria(window.location.pathname)) + }else{ + localStorage.setItem('searchCriteria',"") + setSearchCriteria({ + dateTo: DateUtils.dateValue(new Date()), + dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), + }) + } + }, []); + + React.useEffect(() => { + if(Object.keys(searchCriteria).length>0){ + setOnReady(true); + } }, [searchCriteria]); function applySearch(input) { - setGridOnReady(true) setSearchCriteria(input); + localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) } function applyGridOnReady(input) { diff --git a/src/pages/Message/Search/DataGrid.js b/src/pages/Message/Search/DataGrid.js index 9c04a2e..60c4a1f 100644 --- a/src/pages/Message/Search/DataGrid.js +++ b/src/pages/Message/Search/DataGrid.js @@ -5,13 +5,21 @@ import { useNavigate } from "react-router-dom"; import { FiDataGrid } from "components/FiDataGrid"; import {useIntl} from "react-intl"; import { clickableLink } from 'utils/CommonFunction'; +import {GET_MSG_LIST} from "utils/ApiPathConst"; + // ==============================|| EVENT TABLE ||============================== // -export default function MsgTable({ recordList }) { - const [rows, setRows] = React.useState(recordList); +export default function MsgTable({ searchCriteria, applyGridOnReady }) { + const navigate = useNavigate() const intl = useIntl(); + const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); + + React.useEffect(() => { + set_searchCriteria(searchCriteria); + }, [searchCriteria]); + const _sx = { padding: "4 2 4 2", boxShadow: 1, @@ -25,25 +33,24 @@ export default function MsgTable({ recordList }) { '& .MuiDataGrid-footerContainer': { border: 1, borderColor: "#EEE" - } + }, + "& .MuiDataGrid-columnHeaderTitle": { + whiteSpace: "normal", + lineHeight: "normal" + }, + "& .MuiDataGrid-columnHeader": { + // Forced to use important since overriding inline styles + height: "unset !important" + }, } - - React.useEffect(() => { - setRows(recordList); - }, [recordList]); - - const handleEditClick = (params) => () => { - navigate('/msg/details/' + params.row.id); - }; - const columns = [ { id: 'sentDate', field: 'sentDate', headerName: intl.formatMessage({id: 'date'}), width: 170, - renderCell: (params) => { - return DateUtils.datetimeStr(params.row.sentDate); + valueGetter: (params) => { + return DateUtils.datetimeStr(params?.value); }, }, { @@ -57,16 +64,24 @@ export default function MsgTable({ recordList }) { }, ]; + function handleEditClick(params) { + navigate('/msg/details/' + params.row.id); + } + return ( -
+
'auto'} onRowDoubleClick={handleEditClick} + applyGridOnReady={applyGridOnReady} + doLoad={React.useMemo(() => ({ + url: GET_MSG_LIST, + params: _searchCriteria, + }), [_searchCriteria])} />
); diff --git a/src/pages/Message/Search/SearchForm.js b/src/pages/Message/Search/SearchForm.js index f53b157..06123b9 100644 --- a/src/pages/Message/Search/SearchForm.js +++ b/src/pages/Message/Search/SearchForm.js @@ -21,7 +21,7 @@ import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; // ==============================|| DASHBOARD - DEFAULT ||============================== // -const SearchForm = ({ applySearch, searchCriteria }) => { +const SearchForm = ({ applySearch, searchCriteria, onGridReady }) => { const intl = useIntl(); const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); @@ -64,7 +64,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => { sentDateTo = DateUtils.dateValue(toDateValue) } const temp = { - keywork: data.keywork, + keyword: data.keyword, dateFrom: sentDateFrom, dateTo: sentDateTo, }; @@ -75,6 +75,8 @@ const SearchForm = ({ applySearch, searchCriteria }) => { setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) setMaxDate(DateUtils.dateValue(new Date())) reset(); + localStorage.setItem('searchCriteria',"") + } @@ -196,6 +198,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => {
diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js index e69aade..1104edf 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js @@ -18,7 +18,7 @@ import { FormattedMessage, useIntl } from "react-intl"; import * as React from 'react'; // ==============================|| EVENT TABLE ||============================== // -export default function SearchPublicNoticeTable({ searchCriteria, applySearch }) { +export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) { const navigate = useNavigate() const theme = useTheme(); const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); @@ -142,16 +142,19 @@ export default function SearchPublicNoticeTable({ searchCriteria, applySearch }) 'auto'} + onRowDoubleClick={handleRowDoubleClick} + applyGridOnReady = {applyGridOnReady} applySearch={applySearch} - // doLoad={{ - // url: GET_PUBLIC_NOTICE_LIST, - // params: _searchCriteria - // }} + tab={"application"} doLoad={React.useMemo(() => ({ url: GET_PUBLIC_NOTICE_LIST, params: _searchCriteria, + applyGridOnReady: applyGridOnReady, + // callback: function (responseData) { + // setRows(responseData?.records); + // // applyGridOnReady(false) + // } }), [_searchCriteria])} />
From 065acd93f6c13fc4c74c785c12cf4dcb96826998 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Mon, 23 Jun 2025 00:39:42 +0800 Subject: [PATCH 21/28] FIx FPS cancel --- src/pages/Payment/FPS/FPS.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/pages/Payment/FPS/FPS.js b/src/pages/Payment/FPS/FPS.js index 8bd049d..ed8b6d0 100644 --- a/src/pages/Payment/FPS/FPS.js +++ b/src/pages/Payment/FPS/FPS.js @@ -286,7 +286,8 @@ const Index = () => { } }, onError: function(){ - cancelPayment() + alert("ERROR") + // cancelPayment() // clearInterval(currentTimer.current); } }); @@ -301,16 +302,17 @@ const Index = () => { // console.log(timeOutDate) // console.log(currentTime) // console.log(timeOutDate.getTime()-currentTime.getTime()) - getPaymentStatus(); - - if (timeOutDate.getTime() Date: Thu, 26 Jun 2025 23:34:15 +0800 Subject: [PATCH 22/28] update jvm page --- src/pages/JVM/index.js | 236 ++++++++++++++++++++++++++++++++++++ src/routes/GLDUserRoutes.js | 6 + src/routes/LoginRoutes.js | 2 - 3 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 src/pages/JVM/index.js diff --git a/src/pages/JVM/index.js b/src/pages/JVM/index.js new file mode 100644 index 0000000..561b6d8 --- /dev/null +++ b/src/pages/JVM/index.js @@ -0,0 +1,236 @@ +// import { useState } from 'react'; + +// material-ui +import { + Grid, + Typography, + Stack +} from '@mui/material'; +import * as React from "react"; + +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const JVMDefault = () => { + // const userData = JSON.parse(localStorage.getItem("userData")); + + React.useEffect(() => { + localStorage.setItem('searchCriteria',"") + }, []) + + const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize:'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' + } + + const htmlContent = ` + +
+

Certainly! Here's the complete implementation, showing both the updated Java controller to provide JVM + information in MB, and the corresponding UI code that will display the information. +

+

Step 1: Java Code (Controller)

+

This Spring Boot controller exposes the JVM information (including heap memory usage, operating system + details, and uptime) in MB, and it provides it via a REST API (/jvm-info). +

+

+        import org.springframework.web.bind.annotation.GetMapping;
+        import org.springframework.web.bind.annotation.RestController;
+
+        import java.lang.management.ManagementFactory;
+        import java.lang.management.MemoryMXBean;
+        import java.lang.management.MemoryUsage;
+        import java.lang.management.OperatingSystemMXBean;
+        import java.util.HashMap;
+        import java.util.Map;
+
+        @RestController
+        public class JvmInfoController {
+
+            @GetMapping("/jvm-info")
+            public Map getJvmInfo() {
+                Map jvmInfo = new HashMap<>();
+
+                // Get the Operating System MXBean for system-related info
+                OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
+                jvmInfo.put("osName", osBean.getName());
+                jvmInfo.put("osVersion", osBean.getVersion());
+                jvmInfo.put("osArch", osBean.getArch());
+
+                // Get memory info and convert bytes to MB
+                MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
+                MemoryUsage heapMemoryUsage = memoryBean.getHeapMemoryUsage();
+                jvmInfo.put("heapMemoryInitMB", bytesToMB(heapMemoryUsage.getInit()));
+                jvmInfo.put("heapMemoryUsedMB", bytesToMB(heapMemoryUsage.getUsed()));
+                jvmInfo.put("heapMemoryMaxMB", bytesToMB(heapMemoryUsage.getMax()));
+                jvmInfo.put("heapMemoryCommittedMB", bytesToMB(heapMemoryUsage.getCommitted()));
+
+                // Get JVM uptime and other stats
+                long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
+                jvmInfo.put("jvmUptimeMillis", uptime);
+
+                return jvmInfo;
+            }
+
+            // Helper function to convert bytes to MB
+            private long bytesToMB(long bytes) {
+                return bytes / (1024 * 1024);
+            }
+        }
+      
+ +

Step 2: Frontend UI (HTML + JavaScript)

+

Here’s the frontend HTML page that will display the JVM information in a clean and readable format. It + uses JavaScript (fetch API) to get data from the /jvm-info endpoint and display it in a pre block +

+
+        <!DOCTYPE html>
+        <html lang="en">
+        <head>
+            <meta charset="UTF-8">
+            <meta name="viewport" content="width=device-width, initial-scale=1.0">
+            <title>JVM Information</title>
+            <style>
+                body {
+                    font-family: Arial, sans-serif;
+                    margin: 20px;
+                }
+                h1 {
+                    color: #333;
+                }
+                pre {
+                    background-color: #f4f4f4;
+                    padding: 10px;
+                    border-radius: 5px;
+                    font-size: 14px;
+                    line-height: 1.6;
+                    color: #333;
+                    max-height: 400px;
+                    overflow-y: scroll;
+                }
+                .container {
+                    max-width: 800px;
+                    margin: 0 auto;
+                }
+            </style>
+            <script>
+                function fetchJvmInfo() {
+                    fetch('/jvm-info')
+                        .then(response => response.json())
+                        .then(data => {
+                            document.getElementById("jvmInfo").innerHTML = JSON.stringify(data, null, 2);
+                        })
+                        .catch(error => console.error('Error fetching JVM info:', error));
+                }
+
+                window.onload = fetchJvmInfo;
+            </script>
+        </head>
+        <body>
+            <div class="container">
+                <h1>JVM Information</h1>
+                <pre id="jvmInfo">Loading...</pre>
+            </div>
+        </body>
+        </html>
+      
+ +

Breakdown of the Information Displayed

+

1. Operating System Info:

+
    +
  • osName: The name of the operating system (e.g., Windows, Linux)
  • +
  • osVersion: The version of the operating system
  • +
  • osArch: The architecture of the operating system (e.g., x86_64)
  • +
+ +

2. Memory Usage Info:

+
    +
  • heapMemoryInitMB: The initial heap memory available to the JVM (in MB)
  • +
  • heapMemoryUsedMB: The current memory being used by the JVM (in MB)
  • +
  • heapMemoryMaxMB: The maximum heap memory that the JVM can use (in MB)
  • +
  • heapMemoryCommittedMB: The amount of memory committed by the JVM (in MB)
  • +
+ +

3. JVM Uptime:

+
    +
  • jvmUptimeMillis: The time the JVM has been running (in milliseconds)
  • +
+ +

Example JSON Output (after fetching data):

+

If the /jvm-info API returns the following JSON, it will be displayed on the UI:

+
+        {
+          "osName": "Windows 10",
+          "osVersion": "10.0",
+          "osArch": "amd64",
+          "heapMemoryInitMB": 128,
+          "heapMemoryUsedMB": 50,
+          "heapMemoryMaxMB": 1024,
+          "heapMemoryCommittedMB": 512,
+          "jvmUptimeMillis": 123456789
+        }
+      
+ +

UI Display Example

+

On the webpage, this information will be displayed as follows in a neatly formatted block:

+
+        JVM Information
+        {
+          "osName": "Windows 10",
+          "osVersion": "10.0",
+          "osArch": "amd64",
+          "heapMemoryInitMB": 128,
+          "heapMemoryUsedMB": 50,
+          "heapMemoryMaxMB": 1024,
+          "heapMemoryCommittedMB": 512,
+          "jvmUptimeMillis": 123456789
+        }
+      
+

Styling and Functionality:

+
    +
  1. Styling:The page has simple, clean styling with a scrollable pre block to display the JSON output in an organized manner. You can easily tweak the look and feel using CSS.
  2. +
  3. Dynamic Fetching:When the page loads, it automatically fetches the JVM information from the backend and updates the UI.
  4. +
+ +

Optional Enhancements

+
    +
  1. Graphical Visualization: You could use a library like Chart.js to visualize memory usage in graphs (e.g., pie charts for heap memory)
  2. +
  3. Auto-Refresh: You can add a refresh button or periodically fetch the data at a set interval (e.g., every 30 seconds) using setInterval() in JavaScript
  4. +
+

Let me know if you need further help with customization or any other features!

+
+ `; + + return ( + + +
+ + + JVM Information + + +
+
+ +
+ + + ); +}; + +export default JVMDefault; diff --git a/src/routes/GLDUserRoutes.js b/src/routes/GLDUserRoutes.js index 1cdcfcc..1d10174 100644 --- a/src/routes/GLDUserRoutes.js +++ b/src/routes/GLDUserRoutes.js @@ -33,6 +33,7 @@ const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport'))); const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); +const JVMDefault = Loadable(lazy(() => import('pages/JVM'))); // ==============================|| MAIN ROUTING ||============================== // @@ -192,6 +193,11 @@ const GLDUserRoutes = { path: '/setting/auditLog', element: }:{}, + isGranted("MAINTAIN_SETTING")? + { + path: '/jvm', + element: + }:{}, { path: '/user/changePassword', diff --git a/src/routes/LoginRoutes.js b/src/routes/LoginRoutes.js index 683b609..65b776d 100644 --- a/src/routes/LoginRoutes.js +++ b/src/routes/LoginRoutes.js @@ -41,8 +41,6 @@ const IAmSmart_PleaseLoginCallback = Loadable(lazy(() => import('pages/iAmSmart/ const VerifyPage = Loadable(lazy(() => import('pages/authentication/Verify'))); const Testfps = Loadable(lazy(() => import('pages/Payment/FPS/FPSTest'))); const Payment_FPS_CallBack = Loadable(lazy(() => import('pages/Payment/FPS/fpscallback'))); - - // ==============================|| AUTH ROUTING ||============================== // const LoginRoutes = { From 6f7b42e36c9335693515a43872ef3769f019e1bc Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Sat, 28 Jun 2025 00:44:19 +0800 Subject: [PATCH 23/28] add get jvm info --- src/pages/JVM/index.js | 283 +++++++++++--------------------------- src/utils/ApiPathConst.js | 3 + 2 files changed, 87 insertions(+), 199 deletions(-) diff --git a/src/pages/JVM/index.js b/src/pages/JVM/index.js index 561b6d8..a719cad 100644 --- a/src/pages/JVM/index.js +++ b/src/pages/JVM/index.js @@ -4,233 +4,118 @@ import { Grid, Typography, - Stack + Stack, + Paper, + Box, + CircularProgress, + Button } from '@mui/material'; import * as React from "react"; +import { GET_JVM_INFO } from "utils/ApiPathConst"; +import axios from "axios"; import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' -// ==============================|| DASHBOARD - DEFAULT ||============================== // const JVMDefault = () => { - // const userData = JSON.parse(localStorage.getItem("userData")); + const [jvmInfo, setJvmInfo] = React.useState(null); + const [loading, setLoading] = React.useState(true); + const [error, setError] = React.useState(null); + const fetchJvmInfo = () => { + setLoading(true); + setError(null); + axios.get(`${GET_JVM_INFO}`) + .then((response) => { + if (response.status === 200) { + console.log(response) + setJvmInfo(response.data); + } + }) + .catch(error => { + setError(error); + setLoading(false); + }); + }; + + React.useEffect(() => { + localStorage.setItem('searchCriteria', ""); + setLoading(false); + }, []); + React.useEffect(() => { - localStorage.setItem('searchCriteria',"") - }, []) + if(jvmInfo != null) { + if (Object.keys(jvmInfo).length > 0 && jvmInfo !== undefined) { + setLoading(false); + } + } + }, [jvmInfo]); const BackgroundHead = { backgroundImage: `url(${titleBackgroundImg})`, width: '100%', height: '100%', - backgroundSize:'contain', + backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundColor: '#0C489E', backgroundPosition: 'right' - } - - const htmlContent = ` - -
-

Certainly! Here's the complete implementation, showing both the updated Java controller to provide JVM - information in MB, and the corresponding UI code that will display the information. -

-

Step 1: Java Code (Controller)

-

This Spring Boot controller exposes the JVM information (including heap memory usage, operating system - details, and uptime) in MB, and it provides it via a REST API (/jvm-info). -

-

-        import org.springframework.web.bind.annotation.GetMapping;
-        import org.springframework.web.bind.annotation.RestController;
-
-        import java.lang.management.ManagementFactory;
-        import java.lang.management.MemoryMXBean;
-        import java.lang.management.MemoryUsage;
-        import java.lang.management.OperatingSystemMXBean;
-        import java.util.HashMap;
-        import java.util.Map;
-
-        @RestController
-        public class JvmInfoController {
-
-            @GetMapping("/jvm-info")
-            public Map getJvmInfo() {
-                Map jvmInfo = new HashMap<>();
-
-                // Get the Operating System MXBean for system-related info
-                OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
-                jvmInfo.put("osName", osBean.getName());
-                jvmInfo.put("osVersion", osBean.getVersion());
-                jvmInfo.put("osArch", osBean.getArch());
-
-                // Get memory info and convert bytes to MB
-                MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
-                MemoryUsage heapMemoryUsage = memoryBean.getHeapMemoryUsage();
-                jvmInfo.put("heapMemoryInitMB", bytesToMB(heapMemoryUsage.getInit()));
-                jvmInfo.put("heapMemoryUsedMB", bytesToMB(heapMemoryUsage.getUsed()));
-                jvmInfo.put("heapMemoryMaxMB", bytesToMB(heapMemoryUsage.getMax()));
-                jvmInfo.put("heapMemoryCommittedMB", bytesToMB(heapMemoryUsage.getCommitted()));
-
-                // Get JVM uptime and other stats
-                long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
-                jvmInfo.put("jvmUptimeMillis", uptime);
-
-                return jvmInfo;
-            }
-
-            // Helper function to convert bytes to MB
-            private long bytesToMB(long bytes) {
-                return bytes / (1024 * 1024);
-            }
-        }
-      
- -

Step 2: Frontend UI (HTML + JavaScript)

-

Here’s the frontend HTML page that will display the JVM information in a clean and readable format. It - uses JavaScript (fetch API) to get data from the /jvm-info endpoint and display it in a pre block -

-
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>JVM Information</title>
-            <style>
-                body {
-                    font-family: Arial, sans-serif;
-                    margin: 20px;
-                }
-                h1 {
-                    color: #333;
-                }
-                pre {
-                    background-color: #f4f4f4;
-                    padding: 10px;
-                    border-radius: 5px;
-                    font-size: 14px;
-                    line-height: 1.6;
-                    color: #333;
-                    max-height: 400px;
-                    overflow-y: scroll;
-                }
-                .container {
-                    max-width: 800px;
-                    margin: 0 auto;
-                }
-            </style>
-            <script>
-                function fetchJvmInfo() {
-                    fetch('/jvm-info')
-                        .then(response => response.json())
-                        .then(data => {
-                            document.getElementById("jvmInfo").innerHTML = JSON.stringify(data, null, 2);
-                        })
-                        .catch(error => console.error('Error fetching JVM info:', error));
-                }
-
-                window.onload = fetchJvmInfo;
-            </script>
-        </head>
-        <body>
-            <div class="container">
-                <h1>JVM Information</h1>
-                <pre id="jvmInfo">Loading...</pre>
-            </div>
-        </body>
-        </html>
-      
- -

Breakdown of the Information Displayed

-

1. Operating System Info:

-
    -
  • osName: The name of the operating system (e.g., Windows, Linux)
  • -
  • osVersion: The version of the operating system
  • -
  • osArch: The architecture of the operating system (e.g., x86_64)
  • -
- -

2. Memory Usage Info:

-
    -
  • heapMemoryInitMB: The initial heap memory available to the JVM (in MB)
  • -
  • heapMemoryUsedMB: The current memory being used by the JVM (in MB)
  • -
  • heapMemoryMaxMB: The maximum heap memory that the JVM can use (in MB)
  • -
  • heapMemoryCommittedMB: The amount of memory committed by the JVM (in MB)
  • -
- -

3. JVM Uptime:

-
    -
  • jvmUptimeMillis: The time the JVM has been running (in milliseconds)
  • -
- -

Example JSON Output (after fetching data):

-

If the /jvm-info API returns the following JSON, it will be displayed on the UI:

-
-        {
-          "osName": "Windows 10",
-          "osVersion": "10.0",
-          "osArch": "amd64",
-          "heapMemoryInitMB": 128,
-          "heapMemoryUsedMB": 50,
-          "heapMemoryMaxMB": 1024,
-          "heapMemoryCommittedMB": 512,
-          "jvmUptimeMillis": 123456789
-        }
-      
- -

UI Display Example

-

On the webpage, this information will be displayed as follows in a neatly formatted block:

-
-        JVM Information
-        {
-          "osName": "Windows 10",
-          "osVersion": "10.0",
-          "osArch": "amd64",
-          "heapMemoryInitMB": 128,
-          "heapMemoryUsedMB": 50,
-          "heapMemoryMaxMB": 1024,
-          "heapMemoryCommittedMB": 512,
-          "jvmUptimeMillis": 123456789
-        }
-      
-

Styling and Functionality:

-
    -
  1. Styling:The page has simple, clean styling with a scrollable pre block to display the JSON output in an organized manner. You can easily tweak the look and feel using CSS.
  2. -
  3. Dynamic Fetching:When the page loads, it automatically fetches the JVM information from the backend and updates the UI.
  4. -
- -

Optional Enhancements

-
    -
  1. Graphical Visualization: You could use a library like Chart.js to visualize memory usage in graphs (e.g., pie charts for heap memory)
  2. -
  3. Auto-Refresh: You can add a refresh button or periodically fetch the data at a set interval (e.g., every 30 seconds) using setInterval() in JavaScript
  4. -
-

Let me know if you need further help with customization or any other features!

-
- `; + }; return ( - +
- + JVM Information
- -
+ + + + + + {loading ? ( + + + + ) : error ? ( + Error: {error.message} + ) : jvmInfo ? ( + + {JSON.stringify(jvmInfo, null, 2)} + + ) : ( + No data available + )} + ); }; -export default JVMDefault; +export default JVMDefault; \ No newline at end of file diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 8879c99..c9d6c7b 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -237,3 +237,6 @@ export const GET_HOLIDAY = apiPath+'/holiday/list'; //GET export const POST_HOLIDAY = apiPath+'/holiday/import'; //POST export const GET_HOLIDAY_COMBO = apiPath+'/holiday/combo'; //GET export const GET_HOLIDAY_TEMPLATE = apiPath+'/holiday/export'; //GET + + +export const GET_JVM_INFO = apiPath+'/jvm-info'; //GET From d42078b8febeff50b9fa7a4b7a78cec24942460d Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Mon, 30 Jun 2025 02:45:19 +0800 Subject: [PATCH 24/28] update download btn disable --- src/components/FileList.js | 10 +++++++++ src/pages/AuditLog/AuditLogSearchForm.js | 21 ++++++++----------- src/pages/DemandNote/Search/DataGrid.js | 10 ++++++++- .../SearchPage/OrganizationSearchForm.js | 11 +++++++++- .../Payment/Details_GLD/PaymentDetails.js | 12 ++++------- .../Payment/Details_Public/PaymentDetails.js | 16 ++++++-------- .../Proof/Reply_GLD/ApplicationDetails.js | 12 +++++++++-- .../Details_GLD/ApplicationDetailCard.js | 12 +++++++++-- .../Details_Public/ApplicationDetailCard.js | 11 +++++++++- 9 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/components/FileList.js b/src/components/FileList.js index bd142ea..412649f 100644 --- a/src/components/FileList.js +++ b/src/components/FileList.js @@ -19,6 +19,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable const theme = useTheme(); const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); const intl = useIntl(); + const [onDownload, setOnDownload] = React.useState(false); React.useEffect(() => { loadData(); @@ -41,10 +42,17 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable }; const onDownloadClick = (fileId, skey, filename) => () => { + setOnDownload(true) HttpUtils.fileDownload({ fileId: fileId, skey: skey, filename: filename, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } }); }; @@ -91,6 +99,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable className="textPrimary" onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} color="primary" + disabled={onDownload} />] }, }, @@ -139,6 +148,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable className="textPrimary" onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} color="primary" + disabled={onDownload} />] }, }, diff --git a/src/pages/AuditLog/AuditLogSearchForm.js b/src/pages/AuditLog/AuditLogSearchForm.js index 722ed7b..034e861 100644 --- a/src/pages/AuditLog/AuditLogSearchForm.js +++ b/src/pages/AuditLog/AuditLogSearchForm.js @@ -21,8 +21,8 @@ import {ThemeProvider} from "@emotion/react"; import * as DateUtils from "utils/DateUtils"; import * as UrlUtils from "utils/ApiPathConst"; import * as HttpUtils from "utils/HttpUtils"; -import Loadable from 'components/Loadable'; -const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +// import Loadable from 'components/Loadable'; +// const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); import {DatePicker} from "@mui/x-date-pickers/DatePicker"; import dayjs from "dayjs"; @@ -190,16 +190,13 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria, onGridReady}) => { {isGranted("MAINTAIN_SETTING") ? - {onDownload? - - : - - } + : null } diff --git a/src/pages/DemandNote/Search/DataGrid.js b/src/pages/DemandNote/Search/DataGrid.js index 2ceb8d8..fc2afda 100644 --- a/src/pages/DemandNote/Search/DataGrid.js +++ b/src/pages/DemandNote/Search/DataGrid.js @@ -41,6 +41,7 @@ export default function SearchDemandNote({ applySearch, searchCriteria, applyGri const [_searchCriteria, set_searchCriteria] = useState({}); const [selectedRowItems, setSelectedRowItems] = useState([]); const navigate = useNavigate() + const [onDownload, setOnDownload] = useState(false); useEffect(() => { set_searchCriteria(searchCriteria); @@ -86,10 +87,17 @@ export default function SearchDemandNote({ applySearch, searchCriteria, applyGri } const onDownloadClick = (params) => () => { + setOnDownload(true) HttpUtils.fileDownload({ fileId: params.row.fileId, skey: params.row.skey, filename: params.row.filename, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } }); }; @@ -282,7 +290,7 @@ export default function SearchDemandNote({ applySearch, searchCriteria, applyGri ), width: 280, renderCell: (params) => { - return ; + return ; }, }, { diff --git a/src/pages/Organization/SearchPage/OrganizationSearchForm.js b/src/pages/Organization/SearchPage/OrganizationSearchForm.js index 32e16bc..5e3f609 100644 --- a/src/pages/Organization/SearchPage/OrganizationSearchForm.js +++ b/src/pages/Organization/SearchPage/OrganizationSearchForm.js @@ -24,6 +24,7 @@ const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => const [type, setType] = useState([]); const [creditorSelected, setCreditorSelected] = React.useState(ComboData.CreditorStatus[0]); const { reset, register, handleSubmit } = useForm() + const [onDownload, setOnDownload] = React.useState(false); useEffect(() => { if(searchCriteria.creditor!=undefined){ @@ -65,8 +66,15 @@ const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => } const doExport=()=>{ + setOnDownload(true) HttpUtils.fileDownload({ - url: UrlUtils.GET_ORG_EXPORT + url: UrlUtils.GET_ORG_EXPORT, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } }); } @@ -164,6 +172,7 @@ const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => diff --git a/src/pages/Payment/Details_GLD/PaymentDetails.js b/src/pages/Payment/Details_GLD/PaymentDetails.js index 80c979a..0e9f69e 100644 --- a/src/pages/Payment/Details_GLD/PaymentDetails.js +++ b/src/pages/Payment/Details_GLD/PaymentDetails.js @@ -165,14 +165,10 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { - {onDownload? - - : - - } + diff --git a/src/pages/Payment/Details_Public/PaymentDetails.js b/src/pages/Payment/Details_Public/PaymentDetails.js index 98cef4a..3dc13e5 100644 --- a/src/pages/Payment/Details_Public/PaymentDetails.js +++ b/src/pages/Payment/Details_Public/PaymentDetails.js @@ -208,16 +208,12 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { - {onDownload? - - : - - } + diff --git a/src/pages/Proof/Reply_GLD/ApplicationDetails.js b/src/pages/Proof/Reply_GLD/ApplicationDetails.js index 239d5ff..85b35ef 100644 --- a/src/pages/Proof/Reply_GLD/ApplicationDetails.js +++ b/src/pages/Proof/Reply_GLD/ApplicationDetails.js @@ -34,6 +34,7 @@ const ApplicationDetailCard = ({ const [data, setData] = useState({}); const [cancelPopUp, setCancelPopUp] = useState(false); + const [onDownload, setOnDownload] = useState(false); useEffect(() => { if (formData) { @@ -108,8 +109,15 @@ const ApplicationDetailCard = ({ } const genProof = () => { + setOnDownload(true) HttpUtils.fileDownload({ - url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id + url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } }); } @@ -130,7 +138,7 @@ const ApplicationDetailCard = ({ component="span" variant="contained" size="large" - disabled={!showProofBtn} + disabled={!showProofBtn||onDownload} onClick={genProof} > Proof Slip diff --git a/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js b/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js index b3a2ab1..dfbce06 100644 --- a/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js +++ b/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js @@ -56,6 +56,7 @@ const ApplicationDetailCard = ( const [warningText, setWarningText] = useState(""); const [remarksPopUp, setRemarksPopUp] = useState(false); + const [onDownload, setOnDownload] = useState(false); useEffect(() => { //if user data from parent are not null @@ -84,12 +85,19 @@ const ApplicationDetailCard = ( } const onDownloadClick = () => () => { + setOnDownload(true) HttpUtils.fileDownload({ fileId: fileDetail?.id, skey: fileDetail?.skey, filename: fileDetail?.filename, + onResponse:()=>{ + setOnDownload(false) + notifyDownloadSuccess() + }, + onError:()=>{ + setOnDownload(false) + } }); - notifyDownloadSuccess() setUploadStatus(true) }; @@ -680,7 +688,7 @@ const ApplicationDetailCard = ( size="small" variant="contained" onClick={onDownloadClick()} - disabled={!fileDetail?.filename} + disabled={!fileDetail?.filename||onDownload} sx={{ textTransform: 'capitalize', alignItems: 'end', diff --git a/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js b/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js index 26bb9b5..ae4c712 100644 --- a/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js +++ b/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js @@ -61,6 +61,8 @@ const ApplicationDetailCard = ( const [onReady, setOnReady] = useState(false); const [issueNum, setIssueNum] = useState(""); const [issueDate, setIssueDate] = useState(""); + const [onDownload, setOnDownload] = useState(false); + const { register, // getValues } = useForm(); @@ -89,10 +91,17 @@ const ApplicationDetailCard = ( }, [currentApplicationDetailData]); const onDownloadClick = () => () => { + setOnDownload(true) HttpUtils.fileDownload({ fileId: fileDetail?.id, skey: fileDetail?.skey, filename: fileDetail?.filename, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } }); }; @@ -646,7 +655,7 @@ const ApplicationDetailCard = ( aria-label={intl.formatMessage({ id: 'download' })} title={intl.formatMessage({ id: 'download' })} color="save" - disabled={!fileDetail?.filename} + disabled={!fileDetail?.filename||onDownload} startIcon={} > From 59988b5b67ac34c0a46edd7741b1d1921f3fa325 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Thu, 3 Jul 2025 02:05:26 +0800 Subject: [PATCH 25/28] update recon download file btn --- src/pages/Recon/SearchForm.js | 93 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/src/pages/Recon/SearchForm.js b/src/pages/Recon/SearchForm.js index e7c60ee..c236000 100644 --- a/src/pages/Recon/SearchForm.js +++ b/src/pages/Recon/SearchForm.js @@ -13,8 +13,8 @@ import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst"; import {ThemeProvider} from "@emotion/react"; import * as ComboData from "utils/ComboData"; import * as DateUtils from "utils/DateUtils"; -import Loadable from 'components/Loadable'; -const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +// import Loadable from 'components/Loadable'; +// const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); import {DatePicker} from "@mui/x-date-pickers/DatePicker"; import dayjs from "dayjs"; @@ -422,66 +422,63 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { - {onLoad? - - + + + - : - - + - - + View + + + + + + - - - - - - - - - - - - - - {/* - {onDownload? - - : + + - } - */} - - } + + + + + {/* + {onDownload? + + : + + } + */} + From b9f2959e4421dc29dca2562f66ac9cc137d0b456 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Wed, 30 Jul 2025 05:37:33 +0800 Subject: [PATCH 26/28] update db check page /databaseHealthCheck --- .../extra-pages/DatabaseHealthCheck/index.js | 79 +++++++++++++++++++ src/routes/LoginRoutes.js | 5 ++ 2 files changed, 84 insertions(+) create mode 100644 src/pages/extra-pages/DatabaseHealthCheck/index.js diff --git a/src/pages/extra-pages/DatabaseHealthCheck/index.js b/src/pages/extra-pages/DatabaseHealthCheck/index.js new file mode 100644 index 0000000..dbd12ff --- /dev/null +++ b/src/pages/extra-pages/DatabaseHealthCheck/index.js @@ -0,0 +1,79 @@ +import { Grid, Typography, Stack, } from '@mui/material'; +import { useState, useEffect, lazy } from "react"; + +import Loadable from 'components/Loadable'; +// import { useIntl, FormattedMessage } from "react-intl"; +import { get } from "utils/HttpUtils" +import {GET_SYS_SETTING} from "utils/ApiPathConst" + +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: 'auto', + height: 'auto', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} + +const LoadingComponent = Loadable(lazy(() => import('pages/extra-pages/LoadingComponent'))); + +// import DownloadIcon from '@mui/icons-material/Download'; + +const DatabaseHealthCheck = () => { + // const intl = useIntl(); + // const { locale } = intl; + const [onReady, setOnReady] = useState(false); + const [sysEnv, setSysEnv] = useState(""); + + useEffect(() => { + loadSysSetting(); + }, []); + + // useEffect(() => { + // setOnReady(true); + // }, [locale]); + + const loadSysSetting = () => { + get({ + url: GET_SYS_SETTING, + onSuccess: (responseData) => { + // console.log(responseData) + setSysEnv(responseData.sysEnv); + setOnReady(true); + } + }); + } + + return ( + !onReady ? + + + + + + : + ( + + +
+ + + Database Health Check + + +
+
+ + +
{sysEnv}
Connection OK +
+
+
+ ) + ); + +} + +export default DatabaseHealthCheck; \ No newline at end of file diff --git a/src/routes/LoginRoutes.js b/src/routes/LoginRoutes.js index 65b776d..790a421 100644 --- a/src/routes/LoginRoutes.js +++ b/src/routes/LoginRoutes.js @@ -17,6 +17,7 @@ const ImportantNoticePage = Loadable(lazy(() => import('pages/extra-pages/Import const AboutUsPage = Loadable(lazy(() => import('pages/extra-pages/AboutUs'))); const UserMenuPage = Loadable(lazy(() => import('pages/extra-pages/UserMenu'))); const UserMenuPubPage = Loadable(lazy(() => import('pages/extra-pages/UserMenuPub'))); +const DatabaseHealthCheckPage = Loadable(lazy(() => import('pages/extra-pages/DatabaseHealthCheck'))); const ForgotPassword = Loadable(lazy(() => import('pages/authentication/ForgotPassword'))); @@ -91,6 +92,10 @@ const LoginRoutes = { path: 'userGuidePub', element: }, + { + path: 'databaseHealthCheck', + element: + }, { path: 'iamsmart/logincallback', element: From a12cb4da7d32dc35914cb9d1b8e1ef05789126a2 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Thu, 31 Jul 2025 21:25:42 +0800 Subject: [PATCH 27/28] update check page --- src/layout/MainLayout/index.js | 36 +++++++----- .../extra-pages/DatabaseHealthCheck/index.js | 56 ++----------------- src/utils/ApiPathConst.js | 1 + 3 files changed, 29 insertions(+), 64 deletions(-) diff --git a/src/layout/MainLayout/index.js b/src/layout/MainLayout/index.js index 5e0b641..c8c21d1 100644 --- a/src/layout/MainLayout/index.js +++ b/src/layout/MainLayout/index.js @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import { Outlet } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; +import { useLocation } from 'react-router-dom'; // material-ui import { useTheme } from '@mui/material/styles'; @@ -31,7 +32,8 @@ const MainLayout = () => { const theme = useTheme(); const matchDownLG = useMediaQuery(theme.breakpoints.down('lg')); const dispatch = useDispatch(); - + const location = useLocation(); + const hideNavbarRoutes = ['/databaseHealthCheck'] const { drawerOpen } = useSelector((state) => state.menu); // drawer toggler @@ -55,18 +57,26 @@ const MainLayout = () => { }, [drawerOpen]); return ( - -
- {/* */} - - {/* */} - {/* */} - - - -