From b40345170d7c8b82e72a1b3ad808745c89afb3ee Mon Sep 17 00:00:00 2001 From: Jason Chuang Date: Thu, 16 Apr 2026 22:27:44 +0800 Subject: [PATCH] various changes --- src/components/@extended/AnimateButton.js | 6 +- src/components/FiDataGrid.js | 1 + src/components/MainCard.js | 28 ++++- .../Announcement/Details/AnnouncementForm.js | 6 +- src/pages/DemandNote/Create/SearchForm.js | 2 +- src/pages/DemandNote/Export/SearchForm.js | 2 +- src/pages/DemandNote/Search/SearchForm.js | 2 +- .../DemandNote/Search_Public/DataGrid.js | 3 +- .../DemandNote/Search_Public/SearchForm.js | 4 +- src/pages/GFMIS/SearchForm.js | 6 +- src/pages/GazetteIssue/ExportForm.js | 6 +- src/pages/GazetteIssue/SearchForm.js | 6 +- src/pages/Holiday/DataGrid.js | 11 +- src/pages/Holiday/SearchForm.js | 14 ++- .../DetailPage/OrganizationCard.js | 106 +++++++++--------- .../DetailPage/OrganizationPubCard.js | 76 +++++++------ .../SearchPage/OrganizationSearchForm.js | 2 +- src/pages/Payment/Details_Public/index.js | 2 +- src/pages/Payment/Search_GLD/SearchForm.js | 12 +- src/pages/Payment/Search_Public/SearchForm.js | 7 +- src/pages/Proof/Create_FromApp/ProofForm.js | 18 ++- src/pages/Proof/Create_FromApp/index.js | 6 +- src/pages/Proof/Reply_Public/index.js | 11 +- src/pages/Proof/Search_GLD/DataGrid.js | 6 +- src/pages/Proof/Search_GLD/SearchForm.js | 31 +++-- src/pages/Proof/Search_Public/DataGrid.js | 2 +- src/pages/Proof/Search_Public/SearchForm.js | 16 +-- src/pages/PublicNotice/ApplyForm/index.js | 4 +- .../Details_GLD/ApplicationDetailCard.js | 10 +- .../Details_GLD/GazetteDetailCard.js | 16 ++- .../Details_GLD/StatusChangeDialog.js | 8 +- .../Details_GLD/tabTableDetail/ProofTab.js | 1 + .../tabTableDetail/StatusHistoryTab.js | 2 +- .../Details_GLD/tabTableDetail/TabTable.js | 6 +- .../Details_Public/ApplicationDetailCard.js | 2 +- .../Details_Public/StatusChangeDialog.js | 17 +-- .../Details_Public/tabTableDetail/ProofTab.js | 5 +- .../tabTableDetail/StatusHistoryTab.js | 2 +- src/pages/PublicNotice/ListPanel/BaseGrid.js | 4 +- .../ListPanel/PendingPaymentTab.js | 39 ++++--- .../ListPanel/SearchPublicNoticeForm.js | 12 +- .../ListPanel/SearchPublicNoticeTable.js | 4 +- src/pages/PublicNotice/Search_GLD/DataGrid.js | 6 +- .../PublicNotice/Search_GLD/SearchForm.js | 8 +- .../Search_Mark_As_Paid_GLD/SearchForm.js | 4 +- src/pages/Recon/SearchForm.js | 12 +- src/pages/Setting/SystemSetting/index.js | 2 +- src/pages/User/ChangePasswordPage/index.js | 11 +- .../UserInformationCard_Individual.js | 2 +- .../UserInformationCard_Individual_Pub.js | 4 +- .../UserInformationCard_Organization.js | 19 ++-- .../UserInformationCard_Organization_Pub.js | 18 ++- src/pages/User/ManagePage_OrgPublic/index.js | 38 ++++--- .../UserTable_Individual.js | 6 +- .../UserTable_Organization.js | 6 +- src/pages/authentication/AuthWrapper.js | 44 ++++---- src/pages/dashboard/Public/Notice.js | 6 +- src/pages/dashboard/Public/index.js | 8 +- .../pnspsUserGroupDetailPage/UserAddCard.js | 6 + src/routes/index.js | 8 +- src/utils/Combo.js | 19 +++- src/utils/SelectBase.js | 12 +- 62 files changed, 439 insertions(+), 324 deletions(-) diff --git a/src/components/@extended/AnimateButton.js b/src/components/@extended/AnimateButton.js index 0b82e86..9c21f4f 100644 --- a/src/components/@extended/AnimateButton.js +++ b/src/components/@extended/AnimateButton.js @@ -5,7 +5,7 @@ import { motion } from 'framer-motion'; // ==============================|| ANIMATION BUTTON ||============================== // -export default function AnimateButton({ children, type }) { +export default function AnimateButton({ children, type = 'scale' }) { switch (type) { case 'rotate': // only available in paid version case 'slide': // only available in paid version @@ -23,7 +23,3 @@ AnimateButton.propTypes = { children: PropTypes.node, type: PropTypes.oneOf(['slide', 'scale', 'rotate']) }; - -AnimateButton.defaultProps = { - type: 'scale' -}; diff --git a/src/components/FiDataGrid.js b/src/components/FiDataGrid.js index 89c3e25..6cc2923 100644 --- a/src/components/FiDataGrid.js +++ b/src/components/FiDataGrid.js @@ -279,6 +279,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight = true, ? { Pagination: () => ( { - + English @@ -202,7 +202,7 @@ const AnnouncementForm = ({ loadedData }) => { - + Traditional Chinese @@ -263,7 +263,7 @@ const AnnouncementForm = ({ loadedData }) => { - + Simplified Chinese diff --git a/src/pages/DemandNote/Create/SearchForm.js b/src/pages/DemandNote/Create/SearchForm.js index 140e93f..37ac1f1 100644 --- a/src/pages/DemandNote/Create/SearchForm.js +++ b/src/pages/DemandNote/Create/SearchForm.js @@ -201,7 +201,7 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData, _paymentCount, _p variant="contained" onClick={onSubmit} color="success" - minWidth={150} + sx={{ minWidth: 150 }} > Create diff --git a/src/pages/DemandNote/Export/SearchForm.js b/src/pages/DemandNote/Export/SearchForm.js index c33d201..3f15aae 100644 --- a/src/pages/DemandNote/Export/SearchForm.js +++ b/src/pages/DemandNote/Export/SearchForm.js @@ -201,7 +201,7 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData }) => { onClick={onSubmit} color="success" disabled={waitDownload} - minWidth={150} + sx={{ minWidth: 150 }} > Export diff --git a/src/pages/DemandNote/Search/SearchForm.js b/src/pages/DemandNote/Search/SearchForm.js index 3b2d891..0cb0589 100644 --- a/src/pages/DemandNote/Search/SearchForm.js +++ b/src/pages/DemandNote/Search/SearchForm.js @@ -443,7 +443,7 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, '& .MuiOutlinedInput-root': { height: 40 } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} renderInput={(params) => ( { - - return [StatusUtils.getStatus_i18n(params, locale) ] + return StatusUtils.getStatus_i18n(params, locale); }, }, { diff --git a/src/pages/DemandNote/Search_Public/SearchForm.js b/src/pages/DemandNote/Search_Public/SearchForm.js index d4402be..b7c0829 100644 --- a/src/pages/DemandNote/Search_Public/SearchForm.js +++ b/src/pages/DemandNote/Search_Public/SearchForm.js @@ -292,11 +292,9 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData, onG )} - InputLabelProps={{ - shrink: true - }} clearText={intl.formatMessage({ id: "muiClear" })} closeText={intl.formatMessage({ id: "muiClose" })} openText={intl.formatMessage({ id: "muiOpen" })} diff --git a/src/pages/GFMIS/SearchForm.js b/src/pages/GFMIS/SearchForm.js index c7923c3..a3c97b9 100644 --- a/src/pages/GFMIS/SearchForm.js +++ b/src/pages/GFMIS/SearchForm.js @@ -180,7 +180,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr filterOptions={(options) => options} options={ComboData.payMethod} value={payMethod} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={payMethod?.label ? payMethod?.label : ""} onChange={(event, newValue) => { if(newValue==null){ @@ -197,11 +197,9 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} /> diff --git a/src/pages/GazetteIssue/ExportForm.js b/src/pages/GazetteIssue/ExportForm.js index ae5b9b7..04207eb 100644 --- a/src/pages/GazetteIssue/ExportForm.js +++ b/src/pages/GazetteIssue/ExportForm.js @@ -76,7 +76,11 @@ const SearchGazetteIssueForm = ({ applyExport, comboData, waitDownload}) => { // defaultValue={selectedYear} options={comboList} // disabled={checkCountry} - getOptionLabel={(option) => option.label ? option.label : ""} + getOptionLabel={(option) => + option != null && typeof option === "object" && option.label != null + ? String(option.label) + : "" + } onChange={(event, newValue) => { setSelectedYear(newValue); }} diff --git a/src/pages/GazetteIssue/SearchForm.js b/src/pages/GazetteIssue/SearchForm.js index 37ad3d4..a9da2d3 100644 --- a/src/pages/GazetteIssue/SearchForm.js +++ b/src/pages/GazetteIssue/SearchForm.js @@ -74,7 +74,11 @@ const SearchGazetteIssueForm = ({ applySearch, comboData, onGridReady}) => { // defaultValue={selectedYear} options={comboList} // disabled={checkCountry} - getOptionLabel={(option) => option.label ? option.label : ""} + getOptionLabel={(option) => + option != null && typeof option === "object" && option.label != null + ? String(option.label) + : "" + } onChange={(event, newValue) => { setSelectedYear(newValue); }} diff --git a/src/pages/Holiday/DataGrid.js b/src/pages/Holiday/DataGrid.js index ea99cfc..60f68b6 100644 --- a/src/pages/Holiday/DataGrid.js +++ b/src/pages/Holiday/DataGrid.js @@ -9,14 +9,19 @@ import { dateStr } from "utils/DateUtils"; // ==============================|| EVENT TABLE ||============================== // +function holidayRowsFromResponse(recordList) { + if (Array.isArray(recordList)) return recordList; + if (recordList && Array.isArray(recordList.records)) return recordList.records; + return []; +} + export default function HolidayTable({ recordList, applyGridOnReady }) { - const [rows, setRows] = React.useState(recordList); + const [rows, setRows] = React.useState(() => holidayRowsFromResponse(recordList)); // const navigate = useNavigate() useEffect(() => { - // console.log(recordList) - setRows(recordList.records); + setRows(holidayRowsFromResponse(recordList)); }, [recordList]); const columns = [ diff --git a/src/pages/Holiday/SearchForm.js b/src/pages/Holiday/SearchForm.js index 3a49ec1..6f7fa91 100644 --- a/src/pages/Holiday/SearchForm.js +++ b/src/pages/Holiday/SearchForm.js @@ -17,7 +17,7 @@ import {ThemeProvider} from "@emotion/react"; const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { - const [selectedYear, setSelectedYear] = React.useState([]); + const [selectedYear, setSelectedYear] = React.useState(null); // const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); const [comboList, setComboList] = React.useState([]); // const [onReady, setOnReady] = React.useState(false); @@ -27,7 +27,7 @@ const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { handleSubmit } = useForm() const onSubmit = () => { - if (selectedYear !=null){ + if (selectedYear != null) { const temp = { year: selectedYear.label, }; @@ -40,8 +40,8 @@ const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { // console.log(comboData) // const labelValue = comboData.find(obj => obj.label === searchCriteria.year); // console.log(labelValue) - if(selectedYear.length == 0){ - setSelectedYear(comboData[0]) + if (!selectedYear) { + setSelectedYear(comboData[0]); } setComboList(comboData) // setSelectedYear(searchCriteria.dateFrom) @@ -74,7 +74,11 @@ const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { // defaultValue={selectedYear} options={comboList} // disabled={checkCountry} - getOptionLabel={(option) => option.label ? option.label : ""} + getOptionLabel={(option) => + option != null && typeof option === "object" && option.label != null + ? String(option.label) + : "" + } onChange={(event, newValue) => { setSelectedYear(newValue); }} diff --git a/src/pages/Organization/DetailPage/OrganizationCard.js b/src/pages/Organization/DetailPage/OrganizationCard.js index 4d8f97c..9b127cd 100644 --- a/src/pages/Organization/DetailPage/OrganizationCard.js +++ b/src/pages/Organization/DetailPage/OrganizationCard.js @@ -2,7 +2,7 @@ import { Grid, Button, Checkbox, FormControlLabel, Typography, Dialog, DialogTitle, DialogContent, DialogActions, - FormHelperText, TextField, + FormHelperText, TextField, CircularProgress, } from '@mui/material'; // import { FormControlLabel } from '@material-ui/core'; import MainCard from "components/MainCard"; @@ -111,56 +111,58 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { onSubmit: (values) => { if (values.country == null) { setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' })) - } else { - if (values.country.type == "hongKong" && values.district == null) { - setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' })) - } else { - let sentDateFrom = ""; - if (fromDateValue == null) { - setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })) - } else { - sentDateFrom = DateUtils.dateValue(fromDateValue) - HttpUtils.post({ - url: UrlUtils.POST_ORG_SAVE_PATH, - params: { - id: id > 0 ? id : null, - enCompanyName: values.enCompanyName, - chCompanyName: values.chCompanyName, - orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName, - brNo: values.brNo, - // brExpiryDate: values.brExpiryDate, - brExpiryDate: sentDateFrom, - enCompanyNameTemp: values.enCompanyNameTemp, - chCompanyNameTemp: values.chCompanyNameTemp, - brExpiryDateTemp: values.brExpiryDateTemp, - contactPerson: values.contactPerson, - contactTel: { - countryCode: values.tel_countryCode, - phoneNumber: values.phoneNumber - }, - faxNo: { - countryCode: values.fax_countryCode, - faxNumber: values.faxNumber - }, - addressTemp: { - country: values.country.type, - district: values.district?.type, - addressLine1: values.addressLine1, - addressLine2: values.addressLine2, - addressLine3: values.addressLine3, - }, - creditor: values.creditor, - }, - onSuccess: function () { - notifySaveSuccess() - loadDataFun(); - setEditMode(false); - } - }); - } - - } + return; + } + if (values.country.type == "hongKong" && values.district == null) { + setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' })) + return; + } + if (fromDateValue == null) { + setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })) + return; } + const sentDateFrom = DateUtils.dateValue(fromDateValue); + return new Promise((resolve, reject) => { + HttpUtils.post({ + url: UrlUtils.POST_ORG_SAVE_PATH, + params: { + id: id > 0 ? id : null, + enCompanyName: values.enCompanyName, + chCompanyName: values.chCompanyName, + orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName, + brNo: values.brNo, + brExpiryDate: sentDateFrom, + enCompanyNameTemp: values.enCompanyNameTemp, + chCompanyNameTemp: values.chCompanyNameTemp, + brExpiryDateTemp: values.brExpiryDateTemp, + contactPerson: values.contactPerson, + contactTel: { + countryCode: values.tel_countryCode, + phoneNumber: values.phoneNumber + }, + faxNo: { + countryCode: values.fax_countryCode, + faxNumber: values.faxNumber + }, + addressTemp: { + country: values.country.type, + district: values.district?.type, + addressLine1: values.addressLine1, + addressLine2: values.addressLine2, + addressLine3: values.addressLine3, + }, + creditor: values.creditor, + }, + onSuccess: function () { + notifySaveSuccess() + loadDataFun(); + setEditMode(false); + resolve(); + }, + onFail: () => reject(), + onError: () => reject(), + }); + }); } }); @@ -267,6 +269,8 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { variant="contained" type="submit" color="success" + disabled={formik.isSubmitting} + startIcon={formik.isSubmitting ? : null} > Create @@ -289,6 +293,8 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { variant="contained" type="submit" color="success" + disabled={formik.isSubmitting} + startIcon={formik.isSubmitting ? : null} > Save diff --git a/src/pages/Organization/DetailPage/OrganizationPubCard.js b/src/pages/Organization/DetailPage/OrganizationPubCard.js index ac75497..8368bbe 100644 --- a/src/pages/Organization/DetailPage/OrganizationPubCard.js +++ b/src/pages/Organization/DetailPage/OrganizationPubCard.js @@ -4,7 +4,7 @@ import { // Checkbox, FormControlLabel, Typography, Dialog, DialogTitle, DialogContent, DialogActions, - FormHelperText + FormHelperText, CircularProgress, } from '@mui/material'; // import { FormControlLabel } from '@material-ui/core'; import MainCard from "components/MainCard"; @@ -61,42 +61,46 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requiredValidNumber' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))), faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(), }), - onSubmit: values => { + onSubmit: (values) => { if (values.country == null) { setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' })) - } else { - if (values.country.type == "hongKong" && values.district == null) { - setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' })) - } else { - HttpUtils.post({ - url: UrlUtils.POST_PUB_ORG_SAVE_PATH, - params: { - contactPerson: values.contactPerson, - contactTel: { - countryCode: values.tel_countryCode, - phoneNumber: values.phoneNumber - }, - faxNo: { - countryCode: values.fax_countryCode, - faxNumber: values.faxNumber - }, - addressTemp: { - country: values.country.type, - district: values.district?.type, - addressLine1: values.addressLine1, - addressLine2: values.addressLine2, - addressLine3: values.addressLine3, - }, - //creditor: values.creditor, - }, - onSuccess: function () { - notifySaveSuccess() - loadDataFun(); - setEditMode(false); - } - }); - } + return; + } + if (values.country.type == "hongKong" && values.district == null) { + setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' })) + return; } + return new Promise((resolve, reject) => { + HttpUtils.post({ + url: UrlUtils.POST_PUB_ORG_SAVE_PATH, + params: { + contactPerson: values.contactPerson, + contactTel: { + countryCode: values.tel_countryCode, + phoneNumber: values.phoneNumber + }, + faxNo: { + countryCode: values.fax_countryCode, + faxNumber: values.faxNumber + }, + addressTemp: { + country: values.country.type, + district: values.district?.type, + addressLine1: values.addressLine1, + addressLine2: values.addressLine2, + addressLine3: values.addressLine3, + }, + }, + onSuccess: function () { + notifySaveSuccess() + loadDataFun(); + setEditMode(false); + resolve(); + }, + onFail: () => reject(), + onError: () => reject(), + }); + }); } }); @@ -147,6 +151,8 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { variant="contained" type="submit" color="success" + disabled={formik.isSubmitting} + startIcon={formik.isSubmitting ? : null} > @@ -171,6 +177,8 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { variant="contained" type="submit" color="success" + disabled={formik.isSubmitting} + startIcon={formik.isSubmitting ? : null} > diff --git a/src/pages/Organization/SearchPage/OrganizationSearchForm.js b/src/pages/Organization/SearchPage/OrganizationSearchForm.js index 914354c..97eaaef 100644 --- a/src/pages/Organization/SearchPage/OrganizationSearchForm.js +++ b/src/pages/Organization/SearchPage/OrganizationSearchForm.js @@ -154,7 +154,7 @@ const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, '& .MuiOutlinedInput-root': { height: 40 } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} renderInput={(params) => ( { {/*row 1*/} - + diff --git a/src/pages/Payment/Search_GLD/SearchForm.js b/src/pages/Payment/Search_GLD/SearchForm.js index 458d02c..41567fa 100644 --- a/src/pages/Payment/Search_GLD/SearchForm.js +++ b/src/pages/Payment/Search_GLD/SearchForm.js @@ -222,7 +222,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => filterOptions={(options) => options} options={ComboData.paymentStatus} value={status} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={status?.label ? status?.label : ""} onChange={(event, newValue) => { if(newValue==null){ @@ -239,11 +239,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} /> @@ -256,7 +254,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => filterOptions={(options) => options} options={ComboData.payMethod} value={payMethod} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={payMethod?.label ? payMethod?.label : ""} onChange={(event, newValue) => { if(newValue==null){ @@ -273,11 +271,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} /> diff --git a/src/pages/Payment/Search_Public/SearchForm.js b/src/pages/Payment/Search_Public/SearchForm.js index aa7ed92..1bbd5d9 100644 --- a/src/pages/Payment/Search_Public/SearchForm.js +++ b/src/pages/Payment/Search_Public/SearchForm.js @@ -206,13 +206,12 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => '& .MuiOutlinedInput-root': { height: 40 } }} renderInput={(params) => ( - )} - InputLabelProps={{ - shrink: true - }} clearText={intl.formatMessage({ id: "muiClear" })} closeText={intl.formatMessage({ id: "muiClose" })} openText={intl.formatMessage({ id: "muiOpen" })} diff --git a/src/pages/Proof/Create_FromApp/ProofForm.js b/src/pages/Proof/Create_FromApp/ProofForm.js index b67bdc8..87c536c 100644 --- a/src/pages/Proof/Create_FromApp/ProofForm.js +++ b/src/pages/Proof/Create_FromApp/ProofForm.js @@ -24,6 +24,16 @@ import Loadable from 'components/Loadable'; import { notifySaveSuccess } from 'utils/CommonFunction'; const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); +/** Keeps Formik fields defined so inputs stay controlled before API data loads. */ +const proofFormInitialValues = { + reviseDeadline: '', + proofPaymentDeadline: '', + length: '', + noOfPages: '', + fee: '', + groupType: '' +}; + const FormPanel = ({ formData }) => { const intl = useIntl(); const [data, setData] = React.useState({}); @@ -123,7 +133,7 @@ const FormPanel = ({ formData }) => { const formik = useFormik({ enableReinitialize: true, - initialValues: data, + initialValues: { ...proofFormInitialValues, ...data }, onSubmit: values => { setSaving(true); if (!attachments || attachments.length <= 0) { @@ -207,7 +217,7 @@ const FormPanel = ({ formData }) => { } return ( - @@ -425,7 +435,9 @@ const FormPanel = ({ formData }) => { options={ComboData.proofPrice} value={columnPrice} inputValue={(columnPrice?.label) ? columnPrice?.label : ""} - getOptionLabel={(option) => option.label ? option.label : ""} + getOptionLabel={(option) => + option != null && option.label != null ? String(option.label) : "" + } onChange={(event, newValue) => { setColumnPrice(newValue) formik.values["fee"] = newValue.value * formik.values.length; diff --git a/src/pages/Proof/Create_FromApp/index.js b/src/pages/Proof/Create_FromApp/index.js index e8df30a..371a98d 100644 --- a/src/pages/Proof/Create_FromApp/index.js +++ b/src/pages/Proof/Create_FromApp/index.js @@ -75,7 +75,7 @@ const Index = () => { : - +
@@ -88,7 +88,7 @@ const Index = () => { border={false} content={false} sx={{ - backgroundColor: "backgroundColor.default" + bgcolor: 'background.default' }} > @@ -126,7 +126,7 @@ const Index = () => { { { '', renderCell: (params) => { return ProofStatus.getStatus_Eng(params); }, diff --git a/src/pages/Proof/Search_GLD/SearchForm.js b/src/pages/Proof/Search_GLD/SearchForm.js index 1a31c80..9b38707 100644 --- a/src/pages/Proof/Search_GLD/SearchForm.js +++ b/src/pages/Proof/Search_GLD/SearchForm.js @@ -26,11 +26,15 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss const [type, setType] = React.useState([]); const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatus_GLD[searchCriteria.statusKey]:ComboData.proofStatus_GLD[0]); - const [orgSelected, setOrgSelected] = React.useState({}); + const [orgSelected, setOrgSelected] = React.useState(null); const [orgCombo, setOrgCombo] = React.useState(); - const [issueSelected, setIssueSelected] = React.useState({}); + const [issueSelected, setIssueSelected] = React.useState(null); const [issueCombo, setIssueCombo] = React.useState([]); - const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{}); + const [groupSelected, setGroupSelected] = React.useState( + searchCriteria.gazettGroup != undefined + ? ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup) ?? null + : null + ); const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); @@ -136,9 +140,9 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss function resetForm() { setType([]); setStatus(ComboData.proofStatus[0]); - setOrgSelected({}); - setIssueSelected({}); - setGroupSelected({}); + setOrgSelected(null); + setIssueSelected(null); + setGroupSelected(null); setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) setMaxDate(DateUtils.dateValue(new Date())) reset({ @@ -257,7 +261,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss options={ComboData.groupTitle} value={groupSelected} inputValue={(groupSelected?.label) ? groupSelected?.label : ""} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} onChange={(event, newValue) => { setGroupSelected(newValue); }} @@ -371,13 +375,12 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss '& .MuiOutlinedInput-root': { height: 40 } }} renderInput={(params) => ( - )} - InputLabelProps={{ - shrink: true - }} /> @@ -396,11 +399,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} onChange={(event, newValue) => { - if (newValue !== null) { - setOrgSelected(newValue); - }else{ - setOrgSelected({}); - } + setOrgSelected(newValue ?? null); }} sx={{ '& .MuiInputBase-root': { alignItems: 'center' }, diff --git a/src/pages/Proof/Search_Public/DataGrid.js b/src/pages/Proof/Search_Public/DataGrid.js index edad570..631da5c 100644 --- a/src/pages/Proof/Search_Public/DataGrid.js +++ b/src/pages/Proof/Search_Public/DataGrid.js @@ -170,7 +170,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea } }, { - id: 'actions', + field: 'proofStatus', headerName: intl.formatMessage({ id: 'status' }), width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, diff --git a/src/pages/Proof/Search_Public/SearchForm.js b/src/pages/Proof/Search_Public/SearchForm.js index 0a40d5c..8130182 100644 --- a/src/pages/Proof/Search_Public/SearchForm.js +++ b/src/pages/Proof/Search_Public/SearchForm.js @@ -29,7 +29,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o const [type, setType] = React.useState([]); const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatusFull[searchCriteria.statusKey]:ComboData.proofStatusFull[0]); - const [issueSelected, setIssueSelected] = React.useState({}); + const [issueSelected, setIssueSelected] = React.useState(null); const [issueCombo, setIssueCombo] = React.useState([]); const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{}); @@ -110,7 +110,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o if (issueComboData && issueComboData.length > 0) { setIssueCombo(issueComboData); if(searchCriteria.issueId!=undefined){ - setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) + setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId) ?? null) } } }, [issueComboData]); @@ -118,7 +118,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o function resetForm() { setType([]); setStatus(ComboData.proofStatusFull[0]); - setIssueSelected({}); + setIssueSelected(null); setGroupSelected({}); setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) setMaxDate(DateUtils.dateValue(new Date())) @@ -205,8 +205,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o id="issueId" options={issueCombo} value={issueSelected} + isOptionEqualToValue={(option, value) => option?.id === value?.id} inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""} - getOptionLabel={(option) => getIssueLabel(option)} + getOptionLabel={(option) => (option?.id ? getIssueLabel(option) : "")} onChange={(event, newValue) => { setIssueSelected(newValue); }} @@ -352,11 +353,12 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} clearText={intl.formatMessage({ id: "muiClear" })} closeText={intl.formatMessage({ id: "muiClose" })} openText={intl.formatMessage({ id: "muiOpen" })} diff --git a/src/pages/PublicNotice/ApplyForm/index.js b/src/pages/PublicNotice/ApplyForm/index.js index fa59aed..76593ed 100644 --- a/src/pages/PublicNotice/ApplyForm/index.js +++ b/src/pages/PublicNotice/ApplyForm/index.js @@ -64,7 +64,7 @@ const ApplyForm = () => { for (var i = 0; i < response?.gazetteIssueList?.length; i++) { let data = response.gazetteIssueList[i]; //let label = getIssueLabel(data); - selection.push(} label={getIssueLabel(data)} />); + selection.push(} label={getIssueLabel(data)} />); } setGazetteIssueList(response?.gazetteIssueList); setSelection(selection); @@ -80,7 +80,7 @@ const ApplyForm = () => { for (var i = 0; i < gazetteIssueList?.length; i++) { let data = gazetteIssueList[i]; let label = getIssueLabel(data); - selection.push(} label={label} />); + selection.push(} label={label} />); } setSelection(selection); } diff --git a/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js b/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js index d831392..ec48a37 100644 --- a/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js +++ b/src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js @@ -855,7 +855,7 @@ const ApplicationDetailCard = ( } }} > - Warning + Warning {warningText} @@ -877,7 +877,7 @@ const ApplicationDetailCard = ( }} >
- Remarks + Remarks @@ -928,7 +928,7 @@ const ApplicationDetailCard = ( filterOptions={(options) => options} options={ComboData.paymentMeans} value={paymentMeans} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={paymentMeans?.label ? paymentMeans?.label : ""} onChange={(event, newValue) => { setPaymentMeans(newValue); @@ -941,11 +941,9 @@ const ApplicationDetailCard = ( renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true, - }} disableClearable={true} /> diff --git a/src/pages/PublicNotice/Details_GLD/GazetteDetailCard.js b/src/pages/PublicNotice/Details_GLD/GazetteDetailCard.js index ae0e8e9..a6e1282 100644 --- a/src/pages/PublicNotice/Details_GLD/GazetteDetailCard.js +++ b/src/pages/PublicNotice/Details_GLD/GazetteDetailCard.js @@ -53,11 +53,11 @@ const GazetteDetailCard = ( setIssueNum(applicationDetailData.gazetteIssueDetail.volume + "/" + applicationDetailData.gazetteIssueDetail.issueYear + " No. " + applicationDetailData.gazetteIssueDetail.issueNo); setIssueDate(DateUtils.dateFormat(applicationDetailData.gazetteIssueDetail.issueDate, "D MMM YYYY (ddd)")); - setGazetteCode(applicationDetailData.data.groupNo) + setGazetteCode(applicationDetailData.data.groupNo ?? '') // console.log(applicationDetailData) setSysType(applicationDetailData.userData.sysType) - setCareOf(applicationDetailData.data.careOf) - setGroupTitle(applicationDetailData.data.groupTitle) + setCareOf(applicationDetailData.data.careOf ?? '') + setGroupTitle(applicationDetailData.data.groupTitle ?? '') if (applicationDetailData.data.mode != null){ setMode(applicationDetailData.data.mode); } @@ -73,7 +73,11 @@ const GazetteDetailCard = ( }, [issueNum]); const groupDetailClick = () => () => { - if (gazetteCode == null) { + // groupNo is normalized to '' when absent, so check empty string — not only null + const hasGazetteCode = + gazetteCode != null && + String(gazetteCode).trim() !== ""; + if (!hasGazetteCode) { setStatus("genGazetteCode"); return; } @@ -306,7 +310,9 @@ const GazetteDetailCard = ( maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } } }}> - Warning + + Warning + {warningText} diff --git a/src/pages/PublicNotice/Details_GLD/StatusChangeDialog.js b/src/pages/PublicNotice/Details_GLD/StatusChangeDialog.js index 0f7ddff..f32d8ed 100644 --- a/src/pages/PublicNotice/Details_GLD/StatusChangeDialog.js +++ b/src/pages/PublicNotice/Details_GLD/StatusChangeDialog.js @@ -147,6 +147,11 @@ const StatusChangeDialog = (props) => { id="gazetteGroup" options={groupTitleComboList} filterOptions={(options) => options} + getOptionLabel={(option) => { + if (option == null) return ""; + if (typeof option === "string") return option; + return option.label != null ? String(option.label) : ""; + }} inputValue={comboInputValue.label} onChange={(event, newValue) => { if (newValue != null && newValue != {}) { @@ -156,7 +161,6 @@ const StatusChangeDialog = (props) => { props.setSelectedGazetteGroup(newValue); formik.setFieldValue("", "") } else { - gazetteGroup props.setSelectedGazetteGroupInputType(""); } }} @@ -195,7 +199,7 @@ const StatusChangeDialog = (props) => { - + {content} diff --git a/src/pages/PublicNotice/Details_GLD/tabTableDetail/ProofTab.js b/src/pages/PublicNotice/Details_GLD/tabTableDetail/ProofTab.js index c192c68..6b7b5aa 100644 --- a/src/pages/PublicNotice/Details_GLD/tabTableDetail/ProofTab.js +++ b/src/pages/PublicNotice/Details_GLD/tabTableDetail/ProofTab.js @@ -86,6 +86,7 @@ export default function ProofTab({appId, setCount}) { } }, { + field: 'actions', type: 'actions', headerName: 'Proof Slip', width: 100, diff --git a/src/pages/PublicNotice/Details_GLD/tabTableDetail/StatusHistoryTab.js b/src/pages/PublicNotice/Details_GLD/tabTableDetail/StatusHistoryTab.js index a46c9d0..050ca2a 100644 --- a/src/pages/PublicNotice/Details_GLD/tabTableDetail/StatusHistoryTab.js +++ b/src/pages/PublicNotice/Details_GLD/tabTableDetail/StatusHistoryTab.js @@ -46,7 +46,7 @@ export default function StatusHistoryTab({appId, setCount}) { flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getStatusEng(params)] + return StatusUtils.getStatusEng(params); }, }, ]; diff --git a/src/pages/PublicNotice/Details_GLD/tabTableDetail/TabTable.js b/src/pages/PublicNotice/Details_GLD/tabTableDetail/TabTable.js index 1308cc4..b610bf4 100644 --- a/src/pages/PublicNotice/Details_GLD/tabTableDetail/TabTable.js +++ b/src/pages/PublicNotice/Details_GLD/tabTableDetail/TabTable.js @@ -43,9 +43,9 @@ const PublicNotice = ({ appId, proofCount, paymentCount, statusHistoryCount, set - - - + + + diff --git a/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js b/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js index 9fcde33..585b4e0 100644 --- a/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js +++ b/src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js @@ -655,9 +655,9 @@ const ApplicationDetailCard = ( {fileDetail?.filename} diff --git a/src/pages/PublicNotice/Details_Public/StatusChangeDialog.js b/src/pages/PublicNotice/Details_Public/StatusChangeDialog.js index 73581b8..82f7b7b 100644 --- a/src/pages/PublicNotice/Details_Public/StatusChangeDialog.js +++ b/src/pages/PublicNotice/Details_Public/StatusChangeDialog.js @@ -5,6 +5,7 @@ import { // material-ui import { + Box, Button, // Link, Stack, @@ -14,7 +15,6 @@ import { DialogContent, DialogContentText, DialogTitle, - FormLabel, } from '@mui/material'; import { useFormik,FormikProvider } from 'formik'; import * as yup from 'yup'; @@ -60,19 +60,20 @@ const StatusChangeDialog = (props) => { fullWidth={true} maxWidth={'xs'} > - - + + {status} {intl.formatMessage({id: 'publicNotice'})} - - - - {intl.formatMessage({id: 'confirmTo'})}{status} {intl.formatMessage({id: 'publicNoticeApp'})}? - + + + + {intl.formatMessage({id: 'confirmTo'})}{status} {intl.formatMessage({id: 'publicNoticeApp'})}? + + diff --git a/src/pages/PublicNotice/Details_Public/tabTableDetail/ProofTab.js b/src/pages/PublicNotice/Details_Public/tabTableDetail/ProofTab.js index 599a87c..8848466 100644 --- a/src/pages/PublicNotice/Details_Public/tabTableDetail/ProofTab.js +++ b/src/pages/PublicNotice/Details_Public/tabTableDetail/ProofTab.js @@ -25,8 +25,7 @@ export default function ProofTab({appId, setCount}) { const columns = [ { - - field: 'actions', + field: 'refNo', headerName: intl.formatMessage({id: 'proofId'}), width: 200, cellClassName: 'actions', @@ -36,7 +35,7 @@ export default function ProofTab({appId, setCount}) { }, }, { - id: 'actions', + field: 'status', headerName: intl.formatMessage({id: 'status'}), width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, diff --git a/src/pages/PublicNotice/Details_Public/tabTableDetail/StatusHistoryTab.js b/src/pages/PublicNotice/Details_Public/tabTableDetail/StatusHistoryTab.js index f5b8cab..179de2b 100644 --- a/src/pages/PublicNotice/Details_Public/tabTableDetail/StatusHistoryTab.js +++ b/src/pages/PublicNotice/Details_Public/tabTableDetail/StatusHistoryTab.js @@ -55,7 +55,7 @@ export default function StatusHistoryTab({appId, setCount}) { flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getStatusEng(params)] + return StatusUtils.getStatusEng(params); }, }, ]; diff --git a/src/pages/PublicNotice/ListPanel/BaseGrid.js b/src/pages/PublicNotice/ListPanel/BaseGrid.js index 1086776..1196ca9 100644 --- a/src/pages/PublicNotice/ListPanel/BaseGrid.js +++ b/src/pages/PublicNotice/ListPanel/BaseGrid.js @@ -41,7 +41,7 @@ export default function BaseGrid({setCount, url}) { flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [params.row.appNo+getModeIntl(params,intl)] + return params.row.appNo + getModeIntl(params, intl); }, }, { @@ -96,7 +96,7 @@ export default function BaseGrid({setCount, url}) { flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [getStatusIntl(params,intl)] + return getStatusIntl(params, intl); }, }, { diff --git a/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js b/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js index f88873d..7e6191f 100644 --- a/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js +++ b/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js @@ -298,7 +298,7 @@ export default function SubmittedTab({ setCount, url }) { flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getStatusIntl(params, intl)] + return StatusUtils.getStatusIntl(params, intl); }, }, { @@ -324,23 +324,27 @@ export default function SubmittedTab({ setCount, url }) { selectedRowItems.includes(row.id) ); for (var i = 0; i < datas?.length; i++) { - content.push(<> - - - : {datas[i].appNo} - - ({DateUtils.datetimeStr(datas[i].created)}) - - : {datas[i].remarks} -

- ); + content.push( + + + + : {datas[i].appNo} + + ({DateUtils.datetimeStr(datas[i].created)}) + + : {datas[i].remarks} +

+
+ ); totalAmount += datas[i].fee; } - content.push( - ($): {FormatUtils.currencyFormat(totalAmount)} -

-
); + content.push( + + ($): {FormatUtils.currencyFormat(totalAmount)} +

+
+ ); return content; } @@ -402,6 +406,11 @@ export default function SubmittedTab({ setCount, url }) { id="careOfCombo" value={selectedCareOf === null ? null : selectedCareOf} options={careOfComboList} + getOptionLabel={(option) => { + if (option == null) return ""; + if (typeof option === "string") return option; + return option.label != null ? String(option.label) : ""; + }} onChange={(event, newValue) => { // console.log(newValue) setSelectedCareOf(newValue); diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js index 446f865..499a53a 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js @@ -234,7 +234,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => } value={status} // inputValue={status?.labelCht} - getOptionLabel={(option) => intl.formatMessage({id: option.label})} + getOptionLabel={(option) => { + if (option == null || option.label == null) return ""; + const s = intl.formatMessage({ id: option.label }); + return typeof s === "string" ? s : String(s ?? ""); + }} onChange={(event, newValue) => { if(newValue ==null){ setStatus(localStorage.getItem('userData').creditor?ComboData.publicNoticeStatic_Creditor[0]:ComboData.publicNoticeStatic[0]); @@ -280,7 +284,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => } value={status} // inputValue={status?.labelCht} - getOptionLabel={(option) => intl.formatMessage({id: option.label})} + getOptionLabel={(option) => { + if (option == null || option.label == null) return ""; + const s = intl.formatMessage({ id: option.label }); + return typeof s === "string" ? s : String(s ?? ""); + }} onChange={(event, newValue) => { console.log(newValue) const findAllIndex = newValue.findIndex((ele) => { diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js index 2b048da..14dbf36 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js @@ -48,7 +48,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [params.row.appNo+getModeIntl(params,intl)] + return params.row.appNo + getModeIntl(params, intl); }, }, { @@ -126,7 +126,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea width: 200, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getStatusIntl(params, intl)] + return StatusUtils.getStatusIntl(params, intl); }, }, { diff --git a/src/pages/PublicNotice/Search_GLD/DataGrid.js b/src/pages/PublicNotice/Search_GLD/DataGrid.js index f0028b6..5d9ce4e 100644 --- a/src/pages/PublicNotice/Search_GLD/DataGrid.js +++ b/src/pages/PublicNotice/Search_GLD/DataGrid.js @@ -77,7 +77,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea width: 100, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getModeEng(params)] + return StatusUtils.getModeEng(params); }, }, { @@ -88,7 +88,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea width: 240, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [StatusUtils.getStatusEng(params)] + return StatusUtils.getStatusEng(params); }, }, { @@ -99,7 +99,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea width: 120, renderHeader: renderHeaderWithAria, renderCell: (params) => { - return [params.row.proofId != null ? "Yes" : ""] + return params.row.proofId != null ? "Yes" : ""; }, }, { diff --git a/src/pages/PublicNotice/Search_GLD/SearchForm.js b/src/pages/PublicNotice/Search_GLD/SearchForm.js index c3e7605..ef680b2 100644 --- a/src/pages/PublicNotice/Search_GLD/SearchForm.js +++ b/src/pages/PublicNotice/Search_GLD/SearchForm.js @@ -279,7 +279,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss setSelectedStatus(newValue); } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} sx={{ '& .MuiInputBase-root': { alignItems: 'center' }, '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, @@ -317,7 +317,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss setSelectedLabelsString(selectedLabelsString); } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} renderInput={(params) => ( option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} onChange={(event, newValue) => { setGroupSelected(newValue); }} @@ -470,7 +470,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, '& .MuiOutlinedInput-root': { height: 40 } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} renderInput={(params) => ( option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} sx={{ '& .MuiInputBase-root': { alignItems: 'center' }, '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, @@ -304,7 +304,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss setSelectedLabelsString(selectedLabelsString); } }} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} renderInput={(params) => ( { filterOptions={(options) => options} options={ComboData.paymentMethod} value={method} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={method?.label ? method?.label : ""} onChange={(event, newValue) => { if (newValue !== null) { @@ -200,11 +200,9 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} />
@@ -217,7 +215,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { filterOptions={(options) => options} options={ComboData.paymentStatus} value={status} - getOptionLabel={(option) => option.label} + getOptionLabel={(option) => (option?.label != null ? String(option.label) : "")} inputValue={status?.label ? status?.label : ""} onChange={(event, newValue) => { if (newValue !== null) { @@ -232,11 +230,9 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { renderInput={(params) => ( )} - InputLabelProps={{ - shrink: true - }} />
diff --git a/src/pages/Setting/SystemSetting/index.js b/src/pages/Setting/SystemSetting/index.js index c64851c..71925e4 100644 --- a/src/pages/Setting/SystemSetting/index.js +++ b/src/pages/Setting/SystemSetting/index.js @@ -135,7 +135,7 @@ const SystemSetting = () => {
- + { changePwdInFlightRef.current = false; setIsChangingPassword(false); }, + onFail: function () { + changePwdInFlightRef.current = false; + setIsChangingPassword(false); + }, onError:function (error) { // console.log(error.response.data); setExpiryErrText(intl.formatMessage({ id: error.response.data.error })) @@ -439,7 +444,11 @@ const Index = () => { - @@ -394,7 +389,7 @@ const UserInformationCard_Organization = ({ userData, loadDataFun, orgData }) => label: intl.formatMessage({ id: 'language' }) + ":", valueName: "preferLocale", dataList: ComboData.Locale, - getOptionLabel: (option) => option.label ? option.label : "", + getOptionLabel: (option) => (option?.label != null ? String(option.label) : ""), disabled: (!editMode), form: formik })} diff --git a/src/pages/User/DetailsPage_Organization/UserInformationCard_Organization_Pub.js b/src/pages/User/DetailsPage_Organization/UserInformationCard_Organization_Pub.js index 00f7cd7..0995452 100644 --- a/src/pages/User/DetailsPage_Organization/UserInformationCard_Organization_Pub.js +++ b/src/pages/User/DetailsPage_Organization/UserInformationCard_Organization_Pub.js @@ -1,6 +1,7 @@ // material-ui import { Grid, Typography, Button, + CircularProgress, // Dialog, DialogTitle, DialogContent, DialogActions, } from '@mui/material'; import MainCard from "components/MainCard"; @@ -59,8 +60,8 @@ const UserInformationCard_Organization_Pub = ({ userData, loadDataFun,}) => { tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({id: 'require3Number'}))).required(displayErrorMsg(intl.formatMessage({id: 'requireDialingCode'}))), phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({id: 'require8Number'}))).required(displayErrorMsg(intl.formatMessage({id: 'requireContactNumber'}))), }), - onSubmit: (values, { setSubmitting }) => { - return new Promise((resolve) => { + onSubmit: (values) => { + return new Promise((resolve, reject) => { HttpUtils.post({ url: UrlUtils.POST_PUB_ORG_USER, params: { @@ -75,18 +76,12 @@ const UserInformationCard_Organization_Pub = ({ userData, loadDataFun,}) => { preferLocale: values.preferLocale.type }, onSuccess: function () { - resolve(); notifySaveSuccess(); loadDataFun(); - }, - onFail: function () { - setSubmitting(false); resolve(); }, - onError: function () { - setSubmitting(false); - resolve(); - } + onFail: () => reject(), + onError: () => reject(), }); }); } @@ -149,6 +144,7 @@ const UserInformationCard_Organization_Pub = ({ userData, loadDataFun,}) => { type="submit" color="success" disabled={formik.isSubmitting} + startIcon={formik.isSubmitting ? : null} > @@ -244,7 +240,7 @@ const UserInformationCard_Organization_Pub = ({ userData, loadDataFun,}) => { label: intl.formatMessage({id: 'language'}) + ":", valueName: "preferLocale", dataList: ComboData.Locale, - getOptionLabel: (option) => option.label? option.label: "", + getOptionLabel: (option) => (option?.label != null ? String(option.label) : ""), disabled: (!editMode), form: formik })} diff --git a/src/pages/User/ManagePage_OrgPublic/index.js b/src/pages/User/ManagePage_OrgPublic/index.js index 5a24ba1..36ad3d4 100644 --- a/src/pages/User/ManagePage_OrgPublic/index.js +++ b/src/pages/User/ManagePage_OrgPublic/index.js @@ -78,9 +78,10 @@ const ManageOrgUserPage = () => { }); } - function getHeader(headerStr) { - return {headerStr}; - } + /** DataGrid `headerName` must be a string; use `renderHeader` for styled markup. */ + const renderStyledHeader = (params) => ( + {params.colDef.headerName} + ); function getStatus(params) { if (params.row.locked) { @@ -125,7 +126,8 @@ const ManageOrgUserPage = () => { { id: 'username', field: 'username', - headerName: getHeader(intl.formatMessage({ id: 'loginName' })), + headerName: intl.formatMessage({ id: 'loginName' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, @@ -133,7 +135,8 @@ const ManageOrgUserPage = () => { { id: 'contactPerson', field: 'contactPerson', - headerName: getHeader(intl.formatMessage({ id: 'userName' })), + headerName: intl.formatMessage({ id: 'userName' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, @@ -141,7 +144,8 @@ const ManageOrgUserPage = () => { { id: 'contactTel', field: 'contactTel', - headerName: getHeader(intl.formatMessage({ id: 'userContactNumber' })), + headerName: intl.formatMessage({ id: 'userContactNumber' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, valueGetter: (params) => { @@ -152,14 +156,16 @@ const ManageOrgUserPage = () => { { id: 'emailBus', field: 'emailBus', - headerName: getHeader(intl.formatMessage({ id: 'userContactEmail' })), + headerName: intl.formatMessage({ id: 'userContactEmail' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, }, { id: 'lastLogin', field: 'lastLogin', - headerName: getHeader(intl.formatMessage({ id: 'lastLoginDate' })), + headerName: intl.formatMessage({ id: 'lastLoginDate' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, valueGetter: (params) => { @@ -169,7 +175,8 @@ const ManageOrgUserPage = () => { { id: 'lastApply', field: 'lastApply', - headerName: getHeader(intl.formatMessage({ id: 'lastSubmissionDate' })), + headerName: intl.formatMessage({ id: 'lastSubmissionDate' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, valueGetter: () => { @@ -178,20 +185,21 @@ const ManageOrgUserPage = () => { }, { field: 'actions', - type: 'actions', - headerName: getHeader(intl.formatMessage({ id: 'status' })), + headerName: intl.formatMessage({ id: 'status' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, cellClassName: 'actions', - getActions: (params) => { - return [getStatus(params)] - }, + sortable: false, + filterable: false, + renderCell: (params) => getStatus(params), }, { id: 'primaryUser', field: 'primaryUser', type: 'bool', - headerName: getHeader(intl.formatMessage({ id: 'primary' })), + headerName: intl.formatMessage({ id: 'primary' }), + renderHeader: renderStyledHeader, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, renderCell: (params) => { diff --git a/src/pages/User/SearchPage_Individual/UserTable_Individual.js b/src/pages/User/SearchPage_Individual/UserTable_Individual.js index 181a287..b100afa 100644 --- a/src/pages/User/SearchPage_Individual/UserTable_Individual.js +++ b/src/pages/User/SearchPage_Individual/UserTable_Individual.js @@ -129,14 +129,16 @@ export default function UserTable_Individual({ searchCriteria, applyGridOnReady, if (params.row.verifiedDate) return [ } + label="Verified" color="success" />]; return [ } + label="Not verified" color="error" />]; }, diff --git a/src/pages/User/SearchPage_Organization/UserTable_Organization.js b/src/pages/User/SearchPage_Organization/UserTable_Organization.js index c215614..ee0b386 100644 --- a/src/pages/User/SearchPage_Organization/UserTable_Organization.js +++ b/src/pages/User/SearchPage_Organization/UserTable_Organization.js @@ -123,14 +123,16 @@ export default function UserTable_Organization({searchCriteria, applyGridOnReady if(params.row.verifiedDate) return [ } + label="Verified" color="success" />]; return [ } + label="Not verified" color="error" />]; }, diff --git a/src/pages/authentication/AuthWrapper.js b/src/pages/authentication/AuthWrapper.js index 7ce747b..5eb74e4 100644 --- a/src/pages/authentication/AuthWrapper.js +++ b/src/pages/authentication/AuthWrapper.js @@ -175,9 +175,11 @@ const AuthWrapper = ({ children }) => { '& p': { marginBottom: '12px', lineHeight: 1.7 } }} > - -
- + @@ -205,26 +207,24 @@ const AuthWrapper = ({ children }) => { > {checkPaymentSuspension() ? ( - -
- + ) : ( - -
- + )} diff --git a/src/pages/dashboard/Public/Notice.js b/src/pages/dashboard/Public/Notice.js index 28b8161..c53eae8 100644 --- a/src/pages/dashboard/Public/Notice.js +++ b/src/pages/dashboard/Public/Notice.js @@ -29,13 +29,13 @@ const SearchDemandNoteForm = (props) => { React.useEffect(() => { let list = [] if(listData == []) return; - listData.map((item) => { + listData.map((item, index) => { list.push( - + {locale === 'en' ?item.subjectEng:locale === 'zh-HK' ?item.subjectCht:item.subjectChs} {DateUtils.dateValue(item.announceDate)} {locale === 'en' ?item.contentEng:locale === 'zh-HK' ?item.contentCht:item.contentChs} - + ) }); diff --git a/src/pages/dashboard/Public/index.js b/src/pages/dashboard/Public/index.js index ae35e8d..09dff7d 100644 --- a/src/pages/dashboard/Public/index.js +++ b/src/pages/dashboard/Public/index.js @@ -92,10 +92,9 @@ const DashboardDefault = () => { HttpUtils.get({ url: UrlUtils.GET_MSG_DASHBOARD, onSuccess: function (response) { - let list = [] - response.map((item) => { - list.push( + const list = response.map((item) => ( - ) - }); + )); setItemList(list); setMessageOnReady(true); diff --git a/src/pages/pnspsUserGroupDetailPage/UserAddCard.js b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js index 4a6a289..8d6c7ef 100644 --- a/src/pages/pnspsUserGroupDetailPage/UserAddCard.js +++ b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js @@ -124,6 +124,12 @@ const UserAddCard = ({ isCollectData, updateGroupMember, userGroupData, isNewRec id="user-combo" value={selectedUser === null ? null : selectedUser} options={userComboList} + getOptionLabel={(option) => { + if (option == null) return ""; + if (typeof option === "string") return option; + const s = option.label ?? option.name ?? option.username ?? option.fullName ?? option.enName; + return s != null ? String(s) : ""; + }} onChange={(event, newValue) => { // console.log(newValue) setSelectedUser(newValue); diff --git a/src/routes/index.js b/src/routes/index.js index 1f0410c..b8db1ba 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -39,10 +39,10 @@ export default function ThemeRoutes() { return () => window.removeEventListener('storage', onStorage) }, [dispatch]) - if (isUserLoggedIn()) { - //auto logout if token not valid - SetupAxiosInterceptors(); - } + // Must run every render: SetupAxiosInterceptors uses useNavigate/useDispatch. Wrapping it in + // isUserLoggedIn() caused fewer hooks after logout (e.g. Change Password → Back to Login). + // Interceptor registration is still guarded inside by axiosInterceptorsSetup. + SetupAxiosInterceptors(); // console.log(); return useRoutes([{ path: '', diff --git a/src/utils/Combo.js b/src/utils/Combo.js index 6a04200..42f445b 100644 --- a/src/utils/Combo.js +++ b/src/utils/Combo.js @@ -12,6 +12,9 @@ export default function Combo({ isOptionEqualToValue, onInputChange, onChange, + /** TextField-only: must not be spread onto Autocomplete (root is a div). */ + error, + helperText, ...props }) { const formValue = form.values[valueName] ?? null; @@ -24,7 +27,7 @@ export default function Combo({ if (!formValue) return; try { const label = getOptionLabel ? getOptionLabel(formValue) : ""; - if (typeof label === "string") setInputValue(label); + if (label != null) setInputValue(typeof label === "string" ? label : String(label)); } catch { // ignore label errors } @@ -49,9 +52,15 @@ export default function Combo({ inputValue={inputValue} filterOptions={filterOptions} getOptionLabel={(opt) => { - if (!opt) return ""; - const v = getOptionLabel ? getOptionLabel(opt) : String(opt); - return typeof v === "string" ? v : ""; + if (opt == null) return ""; + let v; + try { + v = getOptionLabel ? getOptionLabel(opt) : String(opt); + } catch { + v = ""; + } + if (v == null) return ""; + return typeof v === "string" ? v : String(v); }} isOptionEqualToValue={(option, value) => { return isOptionEqualToValue @@ -78,6 +87,8 @@ export default function Combo({ renderInput={(params) => ( { + if (opt == null) return ""; + let v; + try { + v = getOptionLabel ? getOptionLabel(opt) : String(opt); + } catch { + v = ""; + } + if (v == null) return ""; + return typeof v === "string" ? v : String(v); + }} isOptionEqualToValue={(option, newValue)=>{ if(isOptionEqualToValue) isOptionEqualToValue(option,newValue, setValue,setInputValue )