'auto'}
columns={columns}
customPageSize={10}
onRowDoubleClick={handleEditClick}
diff --git a/src/pages/Payment/Search_GLD/SearchForm.js b/src/pages/Payment/Search_GLD/SearchForm.js
index 44ad2036..13607221 100644
--- a/src/pages/Payment/Search_GLD/SearchForm.js
+++ b/src/pages/Payment/Search_GLD/SearchForm.js
@@ -18,6 +18,21 @@ import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
+
+const getDefaultDateFrom = () => DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14));
+const getDefaultDateTo = () => DateUtils.dateValue(new Date());
+
+const isSubmitDateEmpty = (value) =>
+ value == null || value === "" || value === "dd / mm / yyyy";
+
+const isBlank = (value) => value == null || String(value).trim() === "";
+
+const toDayjsOrNull = (value) => {
+ if (isSubmitDateEmpty(value)) return null;
+ const d = dayjs(value);
+ return d.isValid() ? d : null;
+};
+
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => {
@@ -25,12 +40,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
const [status, setStatus] = React.useState(ComboData.paymentStatus[0]);
const [payMethod, setPayMethod] = React.useState(ComboData.payMethod[0]);
-
- const { reset, register, handleSubmit } = useForm()
const marginBottom = 2.5;
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");
+ const prevHasOtherRef = React.useRef(null);
React.useEffect(() => {
if(searchCriteria.status!=undefined){
@@ -72,20 +86,77 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
setToDateValue(maxDate);
}, [maxDate]);
+ const { reset, register, handleSubmit, watch } = useForm({
+ defaultValues: {
+ code: searchCriteria.code || "",
+ transNo: searchCriteria.transNo || ""
+ }
+ });
+ const code = watch("code");
+ const transNo = watch("transNo");
+
// add near the top inside the component (after useState for payMethod)
const toPayMethodArray = (opt) => {
if (!opt || opt.type === 'all') return [];
return Array.isArray(opt.type) ? opt.type : [opt.type];
};
+ const clearSubmitDates = () => {
+ setMinDate(null);
+ setMaxDate(null);
+ };
+
+ const restoreDefaultSubmitDates = () => {
+ setMinDate(getDefaultDateFrom());
+ setMaxDate(getDefaultDateTo());
+ };
+
+ const hasOtherCriteria = (textFields = {}) => {
+ if (!isBlank(textFields.code)) return true;
+ if (!isBlank(textFields.transNo)) return true;
+ if (status?.type && status.type !== "all" && status.type !== "") return true;
+ if (payMethod?.type && payMethod.type !== "all") return true;
+ return false;
+ };
+
+ React.useEffect(() => {
+ const hasOther = hasOtherCriteria({ code, transNo });
+ if (prevHasOtherRef.current === null) {
+ prevHasOtherRef.current = hasOther;
+ return;
+ }
+ if (hasOther && !prevHasOtherRef.current) {
+ clearSubmitDates();
+ } else if (!hasOther && prevHasOtherRef.current) {
+ // Only refill defaults when From or To is empty; keep user-entered dates otherwise
+ if (isSubmitDateEmpty(minDate) || isSubmitDateEmpty(maxDate)) {
+ restoreDefaultSubmitDates();
+ }
+ }
+ prevHasOtherRef.current = hasOther;
+ }, [code, transNo, status, payMethod]);
const onSubmit = (data) => {
let sentDateFrom = "";
let sentDateTo = "";
- if (fromDateValue != "dd / mm / yyyy" && toDateValue != "dd / mm / yyyy") {
- sentDateFrom = DateUtils.dateValue(fromDateValue)
- sentDateTo = DateUtils.dateValue(toDateValue)
+ const hasOther = hasOtherCriteria({
+ code: data.code,
+ transNo: data.transNo
+ });
+ const datesEmpty = isSubmitDateEmpty(fromDateValue) || isSubmitDateEmpty(toDateValue)
+ || minDate == null || maxDate == null;
+
+ if (!hasOther && datesEmpty) {
+ const dateFrom = getDefaultDateFrom();
+ const dateTo = getDefaultDateTo();
+ setMinDate(dateFrom);
+ setMaxDate(dateTo);
+ sentDateFrom = dateFrom;
+ sentDateTo = dateTo;
+ } else if (!datesEmpty) {
+ sentDateFrom = DateUtils.dateValue(fromDateValue);
+ sentDateTo = DateUtils.dateValue(toDateValue);
}
const temp = {
@@ -98,18 +169,36 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
start:0,
limit:10
};
+ if (searchCriteria?.sort && searchCriteria?.direction) {
+ temp.sort = searchCriteria.sort;
+ temp.direction = searchCriteria.direction;
+ }
applySearch(temp);
};
function resetForm() {
setStatus(ComboData.paymentStatus[0]);
- setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
- setMaxDate(DateUtils.dateValue(new Date()))
+ setPayMethod(ComboData.payMethod[0]);
+ const dateFrom = getDefaultDateFrom();
+ const dateTo = getDefaultDateTo();
+ setMinDate(dateFrom);
+ setMaxDate(dateTo);
reset({
code:"",
transNo:""
});
- localStorage.setItem('searchCriteria',"")
+ prevHasOtherRef.current = false;
+ localStorage.setItem('searchCriteria',"");
+ applySearch({
+ code: "",
+ transNo: "",
+ dateFrom,
+ dateTo,
+ status: "",
+ payMethod: [],
+ start: 0,
+ limit: 10
+ });
}
@@ -150,22 +239,21 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
setReceiptFromError(newError)}
+ onError={() => {}}
slotProps={{
- field: { readOnly: true, },
- // textField: {
- // helperText: receiptFromErrorMessage,
- // },
+ field: { readOnly: true, clearable: true },
+ textField: {
+ InputLabelProps: { shrink: true },
+ error: false,
+ helperText: null
+ },
}}
format="DD/MM/YYYY"
label="Payment Date (From)"
- value={minDate === null ? null : dayjs(minDate)}
- maxDate={maxDate === null ? null : dayjs(maxDate)}
+ value={toDayjsOrNull(minDate)}
+ maxDate={toDayjsOrNull(maxDate)}
onChange={(newValue) => {
- // console.log(newValue)
- if(newValue!=null){
- setMinDate(newValue);
- }
+ setMinDate(newValue && newValue.isValid?.() ? newValue : null);
}}
/>
@@ -176,22 +264,21 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
setReceiptFromError(newError)}
+ onError={() => {}}
slotProps={{
- field: { readOnly: true, },
- // textField: {
- // helperText: receiptFromErrorMessage,
- // },
+ field: { readOnly: true, clearable: true },
+ textField: {
+ InputLabelProps: { shrink: true },
+ error: false,
+ helperText: null
+ },
}}
format="DD/MM/YYYY"
label="Payment Date (To)"
- value={maxDate === null ? null : dayjs(maxDate)}
- minDate={minDate === null ? null : dayjs(minDate)}
+ value={toDayjsOrNull(maxDate)}
+ minDate={toDayjsOrNull(minDate)}
onChange={(newValue) => {
- // console.log(newValue)
- if(newValue!=null){
- setMaxDate(newValue);
- }
+ setMaxDate(newValue && newValue.isValid?.() ? newValue : null);
}}
/>
diff --git a/src/pages/Payment/Search_Public/DataGrid.js b/src/pages/Payment/Search_Public/DataGrid.js
index 7489960f..0827d725 100644
--- a/src/pages/Payment/Search_Public/DataGrid.js
+++ b/src/pages/Payment/Search_Public/DataGrid.js
@@ -119,7 +119,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea
'auto'}
columns={columns}
customPageSize={10}
onRowDoubleClick={handleEditDoubleClick}
diff --git a/src/pages/Payment/Search_Public/SearchForm.js b/src/pages/Payment/Search_Public/SearchForm.js
index cce567f8..677685a1 100644
--- a/src/pages/Payment/Search_Public/SearchForm.js
+++ b/src/pages/Payment/Search_Public/SearchForm.js
@@ -20,6 +20,21 @@ import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
+
+const getDefaultDateFrom = () => DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14));
+const getDefaultDateTo = () => DateUtils.dateValue(new Date());
+
+const isSubmitDateEmpty = (value) =>
+ value == null || value === "" || value === "dd / mm / yyyy";
+
+const isBlank = (value) => value == null || String(value).trim() === "";
+
+const toDayjsOrNull = (value) => {
+ if (isSubmitDateEmpty(value)) return null;
+ const d = dayjs(value);
+ return d.isValid() ? d : null;
+};
+
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => {
const intl = useIntl();
@@ -29,9 +44,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");
+ const prevHasOtherRef = React.useRef(null);
React.useEffect(() => {
- // console.log(minDate)
setFromDateValue(minDate);
}, [minDate]);
@@ -55,15 +70,72 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
}
}
- const { reset, register, handleSubmit } = useForm()
+ const { reset, register, handleSubmit, watch } = useForm({
+ defaultValues: {
+ code: searchCriteria.code || "",
+ transNo: searchCriteria.transNo || ""
+ }
+ });
+ const code = watch("code");
+ const transNo = watch("transNo");
+
+ const clearSubmitDates = () => {
+ setMinDate(null);
+ setMaxDate(null);
+ };
+
+ const restoreDefaultSubmitDates = () => {
+ setMinDate(getDefaultDateFrom());
+ setMaxDate(getDefaultDateTo());
+ };
+
+ const hasOtherCriteria = (textFields = {}) => {
+ if (!isBlank(textFields.code)) return true;
+ if (!isBlank(textFields.transNo)) return true;
+ if (status?.type && status.type !== "all" && status.type !== "") return true;
+ return false;
+ };
+
+ React.useEffect(() => {
+ const hasOther = hasOtherCriteria({ code, transNo });
+ if (prevHasOtherRef.current === null) {
+ prevHasOtherRef.current = hasOther;
+ return;
+ }
+ if (hasOther && !prevHasOtherRef.current) {
+ clearSubmitDates();
+ } else if (!hasOther && prevHasOtherRef.current) {
+ // Only refill defaults when From or To is empty; keep user-entered dates otherwise
+ if (isSubmitDateEmpty(minDate) || isSubmitDateEmpty(maxDate)) {
+ restoreDefaultSubmitDates();
+ }
+ }
+ prevHasOtherRef.current = hasOther;
+ }, [code, transNo, status]);
const onSubmit = (data) => {
let sentDateFrom = "";
let sentDateTo = "";
- if( fromDateValue!="dd / mm / yyyy"&&toDateValue!="dd / mm / yyyy"){
- sentDateFrom = DateUtils.dateValue(fromDateValue)
- sentDateTo = DateUtils.dateValue(toDateValue)
+
+ const hasOther = hasOtherCriteria({
+ code: data.code,
+ transNo: data.transNo
+ });
+ const datesEmpty = isSubmitDateEmpty(fromDateValue) || isSubmitDateEmpty(toDateValue)
+ || minDate == null || maxDate == null;
+
+ if (!hasOther && datesEmpty) {
+ const dateFrom = getDefaultDateFrom();
+ const dateTo = getDefaultDateTo();
+ setMinDate(dateFrom);
+ setMaxDate(dateTo);
+ sentDateFrom = dateFrom;
+ sentDateTo = dateTo;
+ } else if (!datesEmpty) {
+ sentDateFrom = DateUtils.dateValue(fromDateValue);
+ sentDateTo = DateUtils.dateValue(toDateValue);
}
+
const temp = {
code: data.code,
transNo: data.transNo,
@@ -73,18 +145,34 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
start:0,
limit:10
};
+ if (searchCriteria?.sort && searchCriteria?.direction) {
+ temp.sort = searchCriteria.sort;
+ temp.direction = searchCriteria.direction;
+ }
applySearch(temp);
};
function resetForm() {
setStatus(ComboData.paymentStatus[0]);
- setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
- setMaxDate(DateUtils.dateValue(new Date()))
+ const dateFrom = getDefaultDateFrom();
+ const dateTo = getDefaultDateTo();
+ setMinDate(dateFrom);
+ setMaxDate(dateTo);
reset({
code:"",
transNo:""
});
- localStorage.setItem('searchCriteria',"")
+ prevHasOtherRef.current = false;
+ localStorage.setItem('searchCriteria',"");
+ applySearch({
+ code: "",
+ transNo: "",
+ dateFrom,
+ dateTo,
+ status: "",
+ start: 0,
+ limit: 10
+ });
}
@@ -128,23 +216,21 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
setReceiptFromError(newError)}
+ onError={() => {}}
slotProps={{
- field: { readOnly: true, },
- // textField: {
- // helperText: receiptFromErrorMessage,
- // },
+ field: { readOnly: true, clearable: true },
+ textField: {
+ InputLabelProps: { shrink: true },
+ error: false,
+ helperText: null
+ },
}}
format="DD/MM/YYYY"
label={intl.formatMessage({id: 'payDateFrom'})}
- // defaultValue={searchCriteria.dateFrom}
- value={minDate === null ? null : dayjs(minDate)}
- maxDate={maxDate === null ? null : dayjs(maxDate)}
+ value={toDayjsOrNull(minDate)}
+ maxDate={toDayjsOrNull(maxDate)}
onChange={(newValue) => {
- // console.log(newValue)
- if(newValue!=null){
- setMinDate(newValue);
- }
+ setMinDate(newValue && newValue.isValid?.() ? newValue : null);
}}
/>
@@ -156,23 +242,21 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) =>
setReceiptFromError(newError)}
+ onError={() => {}}
slotProps={{
- field: { readOnly: true, },
- // textField: {
- // helperText: receiptFromErrorMessage,
- // },
+ field: { readOnly: true, clearable: true },
+ textField: {
+ InputLabelProps: { shrink: true },
+ error: false,
+ helperText: null
+ },
}}
format="DD/MM/YYYY"
label={intl.formatMessage({id: 'payDateTo'})}
- // defaultValue={searchCriteria.dateTo}
- value={maxDate === null ? null : dayjs(maxDate)}
- minDate={minDate === null ? null : dayjs(minDate)}
+ value={toDayjsOrNull(maxDate)}
+ minDate={toDayjsOrNull(minDate)}
onChange={(newValue) => {
- // console.log(newValue)
- if(newValue!=null){
- setMaxDate(newValue);
- }
+ setMaxDate(newValue && newValue.isValid?.() ? newValue : null);
}}
/>
diff --git a/src/pages/Payment/index.js b/src/pages/Payment/index.js
index c9c203f2..02789d16 100644
--- a/src/pages/Payment/index.js
+++ b/src/pages/Payment/index.js
@@ -435,6 +435,7 @@ const Index = () => {
// const confirmPaymentHandle = () => () => {
useEffect(() => {
if (confirmPayment){
+ setOnPayment(true);
HttpUtils.post({
url: UrlUtils.POST_CHECK_APP_EXPRITY_DATE,
params: {
@@ -445,12 +446,22 @@ const Index = () => {
setAfterConfirmPayment(true);
return;
}
+ setOnPayment(false);
+ setConfirmPayment(false);
let str = "";
responData.msg.forEach((item) => {
str += "App: " + item.appNo + ", 到期日: " + DateUtils.datetimeStr_Cht(item.expiryDate) + "\n";
});
setExpiryDateErrText(str.split('\n').map(str => <>{str}
>));
setExpiryDateErr(true);
+ },
+ onFail: () => {
+ setOnPayment(false);
+ setConfirmPayment(false);
+ },
+ onError: () => {
+ setOnPayment(false);
+ setConfirmPayment(false);
}
});
}
@@ -493,7 +504,7 @@ const Index = () => {
onClick={() => paymentClick()}
sx={{ mt: 4, ...PAY_CONTAINED_BUTTON_SX }}
>
-
+
diff --git a/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js b/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js
index f2296e84..6b244c60 100644
--- a/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js
+++ b/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js
@@ -15,8 +15,8 @@ const GroupAuthTable = Loadable(lazy(() => import('./GroupAuthTable')));
const GroupAuthCard = ({isCollectData, updateUserAuthList,userGroupData,isNewRecord, editMode}) => {
const [currentAuthData, setCurrentAuthData] = React.useState({});
const [onReady, setOnReady] = useState(false);
- const [selectedRow, setSelectedRow] = useState([]);
- const [referenceRow, setReferenceRow] = useState([]);
+ const [selectedRow, setSelectedRow] = useState(userGroupData?.authIds || []);
+ const [referenceRow, setReferenceRow] = useState(userGroupData?.authIds || []);
const [_editMode, setEditMode] = useState(editMode);
useEffect(()=>{
@@ -39,14 +39,22 @@ const GroupAuthCard = ({isCollectData, updateUserAuthList,userGroupData,isNewRec
}
}, [currentAuthData]);
+ const toIdList = (ids) => {
+ if (!ids) {
+ return [];
+ }
+ const raw = Array.isArray(ids) ? ids : (ids.ids ? Array.from(ids.ids) : []);
+ return raw.map((id) => Number(id)).filter((id) => !Number.isNaN(id));
+ };
+
useEffect(() => {
- //upload latest data to parent
- let deletedList = referenceRow.filter(x => !selectedRow.includes(x));
+ const currentIds = toIdList(selectedRow);
+ const referenceIds = toIdList(referenceRow);
updateUserAuthList({
- "currentList": selectedRow,
- "deletedList": deletedList
+ currentList: currentIds,
+ deletedList: referenceIds.filter((id) => !currentIds.includes(id))
});
- }, [isCollectData]);
+ }, [isCollectData, selectedRow, referenceRow]);
return (
diff --git a/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js b/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js
index 568c4bae..64193f9f 100644
--- a/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js
+++ b/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js
@@ -98,8 +98,10 @@ export default function GroupAuthTable({setSelectedRow, userAuth,isNewRecord, ed
rowSelectionModel={currentSelectedRow}
onRowSelectionModelChange={(ids) => {
if(_editMode){
- setSelectedRow(ids);
- setCurrentSelectedRow(ids);
+ const raw = Array.isArray(ids) ? ids : (ids?.ids ? Array.from(ids.ids) : []);
+ const nextIds = raw.map((id) => Number(id)).filter((id) => !Number.isNaN(id));
+ setSelectedRow(nextIds);
+ setCurrentSelectedRow(nextIds);
}
}}
autoHeight
diff --git a/src/pages/pnspsUserGroupDetailPage/UserAddCard.js b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js
index 8d6c7ef5..3c761d7d 100644
--- a/src/pages/pnspsUserGroupDetailPage/UserAddCard.js
+++ b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js
@@ -90,12 +90,11 @@ const UserAddCard = ({ isCollectData, updateGroupMember, userGroupData, isNewRec
}, [currentUserData]);
useEffect(() => {
- //upload latest data to parent
updateGroupMember({
- "currentList": groupUserData,
- "deletedList": deletedList
+ currentList: groupUserData,
+ deletedList: deletedList
});
- }, [isCollectData]);
+ }, [isCollectData, groupUserData, deletedList]);
return (
diff --git a/src/pages/pnspsUserGroupDetailPage/index.js b/src/pages/pnspsUserGroupDetailPage/index.js
index 1920c3f6..b0cde9d4 100644
--- a/src/pages/pnspsUserGroupDetailPage/index.js
+++ b/src/pages/pnspsUserGroupDetailPage/index.js
@@ -47,12 +47,12 @@ const UserMaintainPage = () => {
const [isCollectData, setIsCollectData] = useState(false);
const [editedGroupData, setEditedGroupData] = useState({});
const [userGroupData, setUserGroupData] = useState([]);
- const [userAuthData, setUserAuthData] = useState([]);
const saveInProgressRef = useRef(false);
- const [groupMember, setGroupMember] = useState([]);
+ const userAuthDataRef = useRef([]);
+ const deletedAuthListRef = useRef([]);
+ const groupMemberRef = useRef([]);
+ const deletedUserListRef = useRef([]);
const [isNewRecord, setIsNewRecord] = useState(false);
- const [deletedUserList, setDeletedUserList] = useState([]);
- const [deletedAuthList, setDeletedAuthList] = useState([]);
const [isWindowOpen, setIsWindowOpen] = useState(false);
const handleClose = () => {
@@ -84,13 +84,17 @@ const UserMaintainPage = () => {
}
function updateGroupMember(groupMember) {
- setGroupMember(groupMember.currentList);
- setDeletedUserList(groupMember.deletedList);
+ const currentList = groupMember.currentList || [];
+ const deletedList = groupMember.deletedList || [];
+ groupMemberRef.current = currentList;
+ deletedUserListRef.current = deletedList;
}
- function updateUserAuthList(userAuthData) {
- setUserAuthData(userAuthData.currentList);
- setDeletedAuthList(userAuthData.deletedList);
+ function updateUserAuthList(authData) {
+ const currentList = authData.currentList || [];
+ const deletedList = authData.deletedList || [];
+ userAuthDataRef.current = currentList;
+ deletedAuthListRef.current = deletedList;
}
const submitData = async () => {
@@ -106,19 +110,36 @@ const UserMaintainPage = () => {
return;
}
const latestGroupFormData = getLatestGroupFormData();
- const finalDeletedUserList = getDeletedRecordWithRefList(deletedUserList, getIdList(groupMember));
+ const latestGroupMember = groupMemberRef.current;
+ const latestAuthIds = userAuthDataRef.current;
+ const latestDeletedAuthIds = deletedAuthListRef.current;
+ const finalDeletedUserList = getDeletedRecordWithRefList(
+ deletedUserListRef.current,
+ getIdList(latestGroupMember)
+ );
const response = await axios.post(POST_AND_UPDATE_USER_GROUP, {
id: parseInt(params.id) !== -1 ? parseInt(params.id) : null,
name: latestGroupFormData.userGroupName,
description: latestGroupFormData.description,
- addUserIds: getIdList(groupMember),
+ addUserIds: getIdList(latestGroupMember),
removeUserIds: finalDeletedUserList,
- addAuthIds: userAuthData,
- removeAuthIds: deletedAuthList,
+ addAuthIds: latestAuthIds,
+ removeAuthIds: latestDeletedAuthIds,
});
if (response.status === 200) {
- navigate('/usergroupSearchview');
notifySaveSuccess();
+ const savedId = response.data?.id;
+ const currentId = parseInt(params.id);
+ if ((currentId === -1 || Number.isNaN(currentId)) && savedId) {
+ navigate(`/userGroup/${savedId}`, { replace: true });
+ await loadGroupData(savedId);
+ } else {
+ await loadGroupData(currentId);
+ }
+ setIsNewRecord(false);
+ setEditMode(false);
+ deletedUserListRef.current = [];
+ deletedAuthListRef.current = [];
}
} catch (error) {
console.log(error);
@@ -177,14 +198,19 @@ const UserMaintainPage = () => {
return true;
};
+ const loadGroupData = async (groupId) => {
+ const response = await axios.get(`${GET_GROUP_LIST_PATH}/${groupId}`);
+ if (response.status === 200) {
+ setUserGroupData(response.data);
+ const loadedAuthIds = response.data?.authIds || [];
+ userAuthDataRef.current = loadedAuthIds;
+ }
+ return response;
+ };
+
useEffect(() => {
if (params.id > 0) {
- axios.get(`${GET_GROUP_LIST_PATH}/${params.id}`)
- .then((response) => {
- if (response.status === 200) {
- setUserGroupData(response.data);
- }
- })
+ loadGroupData(params.id)
.catch(error => {
console.log(error);
return false;
diff --git a/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js b/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js
index 3d2890f2..42b15030 100644
--- a/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js
+++ b/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js
@@ -68,7 +68,7 @@ export default function UserGroupTable({searchCriteria, applyGridOnReady,applySe
({
- ...(ownerState.color === "cancel" && {
- borderColor: "#9E9E9E",
- }),
- '&:active': {
- boxShadow: 'none',
- transform: 'none',
- },
+ ...(ownerState.color === "cancel" && {
+ borderColor: "#9E9E9E",
+ }),
+ textTransform: 'none',
+ '&:active': {
+ boxShadow: 'none',
+ transform: 'none',
+ },
}),
contained: ({ theme, ownerState }) => ({
...(ownerState.color === "cancel" && {
diff --git a/src/translations/en.json b/src/translations/en.json
index fe01b1f8..4ac4ff17 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -121,6 +121,7 @@
"iAmSmartNoIdNoMsg": "Invalid information, please return to the creation of account page.",
"mainPage": "Main Page",
+ "backToMainPage": "Back to Main Page",
"myPublicNotice": "My Public Notices",
"publicNotice": "Public Notice",
"publicNoticeApp": "Public Notice Application",
@@ -421,8 +422,8 @@
"payId": "Payment No.",
"payIdNRefer": "Payment No. / Payment Reference No.",
"payConfirm": "Confirm payment",
- "payCancel": "Cancel payment",
- "payAlert": "Please don’t close this window, you may either complete this payment or cancel this payment by the button at the bottom of this page.",
+ "payCancel": "Cancel Payment",
+ "payAlert": "Please do not refresh or close this page during payment to avoid payment failure. In case of cancellation, please use the “Cancel Payment” button at the bottom of this page.",
"payTotalDeatail": "Total Payment Amount",
"payDeatail": "Total Payment Amount",
"payTotal": "Total Payment Amount",
@@ -455,7 +456,9 @@
"paymentLimitPrice2":" is only applicable when minimum amount is HK$0.10 and maximum amount is HK$9,999,999.99",
"paymentLimitPPS":" Payment could not be made via mobile device browsers, please use desktop computers to make payment.",
"paymentMethod": "Payment Method",
- "paymentProcessLimited":"Please complete the payment process within 15 minutes. Note: For FPS payments, scanning, payment and all necessary approvals must be finished within 3 minutes due to security-related QR code expiry.",
+ "paymentProcessLimited1":"Please complete the payment process within 15 minutes.",
+ "paymentProcessLimited2":"Please do not refresh or close any page during payment to avoid payment failure.",
+ "paymentProcessLimited3":"Note: For FPS payments, scanning, payment and all necessary approvals must be finished within 3 minutes due to security-related QR code expiry.",
"publicNoticeDetailTitle": "Public Notice Application Information",
"applyPerson": "Applicant",
@@ -514,12 +517,14 @@
"payNPGOMethod":"NPGO Collection Office",
"payOnlineBtn":"Pay Online",
"fpsQrcodeTitle1":"Please scan the following QR code",
- "fpsQrcodeTitle2":"QR code is valid for 3 minutes",
+ "fpsQrcodeTitle2":"QR code is valid for 3 minutes only",
"fpsQrcodeTitle3":"Please complete the payment process within the specified time",
"fpsQrcodeTitle4":"Remaining time:",
"fpsQrcodeTitle5":"s",
"fpsQrcodeExpired":"QR code has expired.",
- "fpsPaymentErrorMsg":"An error occurred while loading the payment QR code. Please do not refresh/reload this page manually during the payment. If the payment was not made successfully, please click 'Cancel payment' button and make the payment again. Sorry for the inconvenience caused.",
+ "fpsPaymentErrorMsg1":"The payment QR code is no longer valid after reloading the page. Please verify your banking transaction history:",
+ "fpsPaymentErrorMsg2":"If payment was deducted: Please contact Accounts Section (Tel.: 2231 5183/2231 5318) with your transaction details.",
+ "fpsPaymentErrorMsg3":"If payment was not deducted: Please click \"Back to Main Page\" and try again after 30 minutes.",
"fpsSelectPaymentApp":"Please Select Bank App",
"payDnRemark": "Payment proof (e.g. ATM receipt, internet banking record) to be sent to gld_acct@gld.gov.hk by {date} 12:30 p.m.",
diff --git a/src/translations/zh-CN.json b/src/translations/zh-CN.json
index 85538704..d7aec8d3 100644
--- a/src/translations/zh-CN.json
+++ b/src/translations/zh-CN.json
@@ -90,7 +90,9 @@
"fpsQrcodeTitle4":"剩余时间:",
"fpsQrcodeTitle5":"秒",
"fpsQrcodeExpired":"二维码已过期",
- "fpsPaymentErrorMsg":"载入支付二维码时发生错误。请勿在付款过程中更新此页面。如果付款未完成,请点击「取消支付」按钮并重新支付。由此造成的不便,敬请谅解。",
+ "fpsPaymentErrorMsg1":"页面重新加载时发生错误,支付二维码已失效。请先确认银行交易纪录:",
+ "fpsPaymentErrorMsg2":"如已扣款:请联络会计组(电话:2231 5183 / 2231 5318)并提供交易信息。",
+ "fpsPaymentErrorMsg3":"如未扣款:请点击「返回主页」并等待30分钟后重新尝试。",
"fpsSelectPaymentApp":"请选择付款支付程序",
"payDnRemark": "在{date}下午12时30分前将付款证明(例如银行入数纸或网上银行付款记录)电邮至 gld_acct@gld.gov.hk",
@@ -159,6 +161,7 @@
"iAmSmartNoIdNoMsg": "无效资料,请返回建立账户页面。",
"mainPage": "主页",
+ "backToMainPage": "返回主页",
"publicNotice": "公共启事",
"publicNoticeApp": "公共啟事申请",
"myPublicNotice": "我的公共启事",
@@ -456,7 +459,7 @@
"payIdNRefer": "付款编号 / 付款参考编号",
"payConfirm": "确认付款",
"payCancel": "取消付款",
- "payAlert": "请不要关闭此窗口,您可以通过此页面底部的按钮完成此付款或取消此付款。",
+ "payAlert": "付款过程中请勿重新整理或关闭此页面,以免支付失败。如需取消,请使用本页底部的「取消付款」按钮。",
"payTotalDeatail": "付款总额",
"payDeatail": "付款总额",
"payTotal": "付款总额",
@@ -490,7 +493,9 @@
"paymentLimitPrice2":"只适用于最小金额为 0.10 港元及最高金额为 9,999,999.99港元",
"paymentLimitPPS":"付款不适用于流动装置的浏览器,请使用桌面电脑。",
"paymentMethod": "付款方式",
- "paymentProcessLimited":"请于15分钟内完成付款程序。 注意:使用转数快(FPS)时,因二维码具安全时效限制,须于3分钟内完成扫码、付款及所有相关审核程序。",
+ "paymentProcessLimited1":"请于15分钟内完成付款程序。",
+ "paymentProcessLimited2":"付款过程中请勿重新整理或关闭任何页面,以免支付失败。",
+ "paymentProcessLimited3":"注意:使用转数快(FPS)时,因二维码具安全时效限制,须于3分钟内完成扫码、付款及所有相关审核程序。",
"publicNoticeDetailTitle": "公共启事申请资料",
"applyPerson": "申请人",
diff --git a/src/translations/zh-HK.json b/src/translations/zh-HK.json
index 2d64cacc..eb7f37f9 100644
--- a/src/translations/zh-HK.json
+++ b/src/translations/zh-HK.json
@@ -90,7 +90,9 @@
"fpsQrcodeTitle4":"剩餘時間:",
"fpsQrcodeTitle5":"秒",
"fpsQrcodeExpired":"二維碼已過期",
- "fpsPaymentErrorMsg":"載入支付二維碼時發生錯誤。請勿在付款過程中更新此頁面。如果付款未完成,請點擊「取消支付」按鈕並重新支付。由此造成的不便,敬請諒解。",
+ "fpsPaymentErrorMsg1":"頁面重新載入時發生錯誤,支付二維碼已失效。請先確認銀行交易紀錄:",
+ "fpsPaymentErrorMsg2":"如已扣款:請聯絡會計組(電話:2231 5183 / 2231 5318)並提供交易資料。",
+ "fpsPaymentErrorMsg3":"如未扣款:請點擊「返回主頁」並等待30分鐘後重新嘗試。",
"fpsSelectPaymentApp":"請選擇付款支付程式",
"payDnRemark": "在{date}下午12時30分前將付款證明(例如銀行入數紙或網上銀行付款記錄)電郵至 gld_acct@gld.gov.hk",
@@ -159,6 +161,7 @@
"iAmSmartNoIdNoMsg": "無效資料,請返回建立賬戶頁面。",
"mainPage": "主頁",
+ "backToMainPage": "返回主頁",
"publicNotice": "公共啟事",
"publicNoticeApp": "公共啟事申請",
"myPublicNotice": "我的公共啟事",
@@ -457,7 +460,7 @@
"payIdNRefer": "付款編號 / 付款參考編號",
"payConfirm": "確認付款",
"payCancel": "取消付款",
- "payAlert": "請不要關閉此窗口,您可以透過本頁底部的按鈕完成此付款或取消本付款。",
+ "payAlert": "付款過程中請勿重新整理或關閉此頁面,以免支付失敗。如需取消,請使用本頁底部的「取消付款」按鈕。",
"payTotalDeatail": "付款總額",
"payDeatail": "付款總額",
"payTotal": "付款總額",
@@ -491,7 +494,9 @@
"paymentLimitPrice2":"只適用於最小金額為 0.10 港元及最高金額為 9,999,999.99港元",
"paymentLimitPPS":"付款不適用於流動裝置的瀏覽器,請使用桌面電腦。",
"paymentMethod": "付款方法",
- "paymentProcessLimited":"請於15分鐘內完成付款程序。 注意:使用轉數快(FPS)時,因二維碼具安全時效限制,須於3分鐘內完成掃碼、付款及所有相關審核程序。",
+ "paymentProcessLimited1":"請於15分鐘內完成付款程序。",
+ "paymentProcessLimited2":"付款過程中請勿重新整理或關閉任何頁面,以免支付失敗。",
+ "paymentProcessLimited3":"注意:使用轉數快(FPS)時,因二維碼具安全時效限制,須於3分鐘內完成掃碼、付款及所有相關審核程序。",
"publicNoticeDetailTitle": "公共啟事申請資料",
"applyPerson": "申請人",