diff --git a/src/pages/pnspsUserGroupDetailPage/index.js b/src/pages/pnspsUserGroupDetailPage/index.js index fd60e30..fe35c5a 100644 --- a/src/pages/pnspsUserGroupDetailPage/index.js +++ b/src/pages/pnspsUserGroupDetailPage/index.js @@ -3,13 +3,14 @@ import { Button, Grid, Typography, Stack, Box } from '@mui/material'; -import { useEffect, useState, lazy } from "react"; +import { useEffect, useState, useRef, lazy } from "react"; import axios from "axios"; import { useParams } from "react-router-dom"; import { GeneralConfirmWindow, getDeletedRecordWithRefList, getIdList, + notifyActionError, notifyDeleteSuccess, notifySaveSuccess } from "../../utils/CommonFunction"; @@ -47,7 +48,7 @@ const UserMaintainPage = () => { const [editedGroupData, setEditedGroupData] = useState({}); const [userGroupData, setUserGroupData] = useState([]); const [userAuthData, setUserAuthData] = useState([]); - const [userConfirm, setUserConfirm] = useState(false); + const saveInProgressRef = useRef(false); const [groupMember, setGroupMember] = useState([]); const [isNewRecord, setIsNewRecord] = useState(false); const [deletedUserList, setDeletedUserList] = useState([]); @@ -92,10 +93,89 @@ const UserMaintainPage = () => { setDeletedAuthList(userAuthData.deletedList); } - const submitData = () => { - setUserConfirm(true); + const submitData = async () => { + if (!onReady || saveInProgressRef.current) { + return; + } + saveInProgressRef.current = true; setIsCollectData(!isCollectData); - } + + try { + const isNameValid = await validateGroupName(); + if (!isNameValid) { + return; + } + const latestGroupFormData = getLatestGroupFormData(); + const finalDeletedUserList = getDeletedRecordWithRefList(deletedUserList, getIdList(groupMember)); + 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), + removeUserIds: finalDeletedUserList, + addAuthIds: userAuthData, + removeAuthIds: deletedAuthList, + }); + if (response.status === 200) { + navigate('/usergroupSearchview'); + notifySaveSuccess(); + } + } catch (error) { + console.log(error); + notifyActionError(error?.response?.data?.message || "Save failed."); + } finally { + saveInProgressRef.current = false; + } + }; + + const normalizeName = (name) => (name || "").trim().toLowerCase(); + + const getLatestGroupFormData = () => { + const nameEl = document.getElementById("groupName"); + const descEl = document.getElementById("description"); + // Prefer what the user actually typed. Parent `editedGroupData` can still be stale on the + // first Save click (sync runs after `isCollectData` toggles in a child effect). + return { + userGroupName: nameEl != null ? nameEl.value : (editedGroupData?.userGroupName ?? ""), + description: descEl != null ? descEl.value : (editedGroupData?.description ?? "") + }; + }; + + const validateGroupName = async () => { + const latestGroupFormData = getLatestGroupFormData(); + const groupName = (latestGroupFormData.userGroupName || "").trim(); + if (groupName.length === 0) { + notifyActionError("User Group Name is required."); + return false; + } + + try { + const response = await axios.get(GET_GROUP_LIST_PATH, { + params: { + name: groupName, + start: 0, + limit: 1000 + } + }); + const records = response?.data?.records || []; + const currentId = parseInt(params.id); + const isDuplicateName = records.some((record) => + normalizeName(record?.name) === normalizeName(groupName) && + parseInt(record?.id) !== currentId + ); + + if (isDuplicateName) { + notifyActionError(`User Group Name "${groupName}" already exists.`); + return false; + } + } catch (error) { + console.log(error); + notifyActionError("Unable to validate User Group Name. Please try again."); + return false; + } + + return true; + }; useEffect(() => { if (params.id > 0) { @@ -134,36 +214,6 @@ const UserMaintainPage = () => { } }, [userGroupData]); - useEffect(() => { - if (userConfirm && onReady) { - //avoid delete and add user at the same time - let finalDeletedUserList = getDeletedRecordWithRefList(deletedUserList, getIdList(groupMember)); - // console.log(finalDeletedUserList) - axios.post(POST_AND_UPDATE_USER_GROUP, - { - "id": parseInt(params.id) !== -1 ? parseInt(params.id) : null, - "name": editedGroupData.userGroupName, - "description": editedGroupData.description, - "addUserIds": getIdList(groupMember), - "removeUserIds": finalDeletedUserList, - "addAuthIds": userAuthData, - "removeAuthIds": deletedAuthList, - }, - ) - .then((response) => { - if (response.status === 200) { - navigate('/usergroupSearchview'); - notifySaveSuccess() - } - }) - .catch(error => { - console.log(error); - return false; - }); - } - setUserConfirm(false); - }, [editedGroupData, userGroupData, userAuthData]); - return ( !onReady ?