// material-ui import { Button, Grid, Typography, Stack, Box } from '@mui/material'; 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"; import { POST_AND_UPDATE_USER_GROUP, GET_GROUP_LIST_PATH } from "utils/ApiPathConst"; import Loadable from 'components/Loadable'; const LoadingComponent = Loadable(lazy(() => import('../extra-pages/LoadingComponent'))); const GroupAuthCard = Loadable(lazy(() => import('./GroupAuthCard'))); const UserGroupInfoCard = Loadable(lazy(() => import('./UserGroupInfoCard'))); const UserAddCard = Loadable(lazy(() => import('./UserAddCard'))); import { useNavigate } from "react-router"; import ForwardIcon from '@mui/icons-material/Forward'; import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' import { isGrantedAny } from "auth/utils"; const BackgroundHead = { backgroundImage: `url(${titleBackgroundImg})`, width: '100%', height: '100%', backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundColor: '#0C489E', backgroundPosition: 'right' } // ==============================|| DASHBOARD - DEFAULT ||============================== // const UserMaintainPage = () => { const params = useParams(); const navigate = useNavigate(); const [onReady, setOnReady] = useState(false); const [editMode, setEditMode] = useState(false); const [isCollectData, setIsCollectData] = useState(false); const [editedGroupData, setEditedGroupData] = useState({}); const [userGroupData, setUserGroupData] = useState([]); const [userAuthData, setUserAuthData] = useState([]); const saveInProgressRef = useRef(false); const userAuthDataRef = useRef([]); const deletedAuthListRef = useRef([]); const groupMemberRef = useRef([]); const deletedUserListRef = useRef([]); const [groupMember, setGroupMember] = useState([]); const [isNewRecord, setIsNewRecord] = useState(false); const [deletedUserList, setDeletedUserList] = useState([]); const [deletedAuthList, setDeletedAuthList] = useState([]); const [isWindowOpen, setIsWindowOpen] = useState(false); const handleClose = () => { setIsWindowOpen(false); }; const handleDeleteClick = () => { setIsWindowOpen(true); }; function deleteData() { axios.delete(`${GET_GROUP_LIST_PATH}/${params.id}`, ) .then((response) => { if (response.status === 204) { notifyDeleteSuccess() setIsWindowOpen(false); navigate('/usergroupSearchview'); } }) .catch(error => { console.log(error); return false; }); } function updateGroupObject(groupData) { setEditedGroupData(groupData); } function updateGroupMember(groupMember) { const currentList = groupMember.currentList || []; const deletedList = groupMember.deletedList || []; groupMemberRef.current = currentList; deletedUserListRef.current = deletedList; setGroupMember(currentList); setDeletedUserList(deletedList); } function updateUserAuthList(userAuthData) { const currentList = userAuthData.currentList || []; const deletedList = userAuthData.deletedList || []; userAuthDataRef.current = currentList; deletedAuthListRef.current = deletedList; setUserAuthData(currentList); setDeletedAuthList(deletedList); } 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 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(latestGroupMember), removeUserIds: finalDeletedUserList, addAuthIds: latestAuthIds, removeAuthIds: latestDeletedAuthIds, }); if (response.status === 200) { 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 = []; setDeletedUserList([]); setDeletedAuthList([]); } } 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; }; 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; setUserAuthData(loadedAuthIds); } return response; }; useEffect(() => { if (params.id > 0) { loadGroupData(params.id) .catch(error => { console.log(error); return false; }); } else { //new record case setUserGroupData( { "authIds": [], "data": {}, "userIds": [] } ); setIsNewRecord(true); setEditMode(true); } }, []); useEffect(() => { if (Object.keys(userGroupData).length > 0 && userGroupData !== undefined) { setOnReady(true); } else if (isNewRecord) { setOnReady(true); } }, [userGroupData]); return ( !onReady ? : {isNewRecord ? "Create User Group" : "Maintain User Group"} { navigate("/usergroupSearchview") }}> {/*top button*/} { isGrantedAny("MAINTAIN_GROUP")? {editMode ? <> { location.reload() }} color="secondary" > Reset & Back Save > : <> { setEditMode(true) }} > Edit Delete User Group > } :<>> } {/*col 1*/} {/*col 2*/} ); }; export default UserMaintainPage;