From b3cf6279d434fe805ccdb649e14f7cc8acb9f6d6 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Wed, 23 Aug 2023 10:09:34 +0800 Subject: [PATCH] add group detail page --- src/pages/pnspsUserDetailPage/index.js | 2 +- .../pnspsUserGroupDetailPage/GroupAuthCard.js | 60 ++++++++ .../GroupAuthTable.js | 80 ++++++++++ .../pnspsUserGroupDetailPage/UserAddCard.js | 133 +++++++++++++++++ .../pnspsUserGroupDetailPage/UserAddTable.js | 91 ++++++++++++ .../UserGroupInfoCard.js | 105 ++++++++++++++ src/pages/pnspsUserGroupDetailPage/index.js | 137 ++++++++++++++++++ src/pages/pnspsUserGroupSearchPage/index.js | 64 +++++--- src/routes/SettingRoutes.js | 13 +- src/utils/ApiPathConst.js | 7 +- src/utils/CommonFunction.js | 14 ++ 11 files changed, 676 insertions(+), 30 deletions(-) create mode 100644 src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js create mode 100644 src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js create mode 100644 src/pages/pnspsUserGroupDetailPage/UserAddCard.js create mode 100644 src/pages/pnspsUserGroupDetailPage/UserAddTable.js create mode 100644 src/pages/pnspsUserGroupDetailPage/UserGroupInfoCard.js create mode 100644 src/pages/pnspsUserGroupDetailPage/index.js create mode 100644 src/utils/CommonFunction.js diff --git a/src/pages/pnspsUserDetailPage/index.js b/src/pages/pnspsUserDetailPage/index.js index b6fab10..12e24a5 100644 --- a/src/pages/pnspsUserDetailPage/index.js +++ b/src/pages/pnspsUserDetailPage/index.js @@ -45,7 +45,7 @@ const UserMaintainPage = () => { } useEffect(() => { - + console.log(params) axios.get(`${apiPath}${GET_USER_PATH}/${params.id}`) .then((response) => { if (response.status === 200) { diff --git a/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js b/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js new file mode 100644 index 0000000..490ac1e --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/GroupAuthCard.js @@ -0,0 +1,60 @@ +// material-ui +import { + Typography +} from '@mui/material'; +import MainCard from "../../components/MainCard"; +import * as React from "react"; +import {useEffect, useState} from "react"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +import GroupAuthTable from "./GroupAuthTable"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const GroupAuthCard = ({isCollectData, updateUserAuthList,userGroupData}) => { + const [currentAuthData, setCurrentAuthData] = React.useState({}); + const [onReady, setOnReady] = useState(false); + const [selectedRow, setSelectedRow] = useState([]); + + useEffect(() => { + //if user data from parent are not null + if (Object.keys(userGroupData).length > 0 && userGroupData !== undefined) { + setCurrentAuthData(userGroupData.data); + setSelectedRow(userGroupData.authIds); + } + }, [userGroupData]); + + useEffect(() => { + //if state data are ready and assign to different field + if (Object.keys(userGroupData).length > 0 && currentAuthData !== undefined) { + setOnReady(true); + } + }, [currentAuthData]); + + useEffect(() => { + //upload latest data to parent + updateUserAuthList(selectedRow); + }, [isCollectData]); + + + return ( + !onReady ? + + : + + + User Authority + + + + + ); +}; + +export default GroupAuthCard; diff --git a/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js b/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js new file mode 100644 index 0000000..f48e546 --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/GroupAuthTable.js @@ -0,0 +1,80 @@ +// material-ui +import { + DataGrid, +} from "@mui/x-data-grid"; +import {useEffect, useState} from "react"; +import axios from "axios"; +import {apiPath} from "../../auth/utils"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +import * as React from "react"; +import {GET_GROUP_AUTH_LIST} from "../../utils/ApiPathConst"; + +// ==============================|| EVENT TABLE ||============================== // + +export default function GroupAuthTable({setSelectedRow, userAuth}) { + const [authData, setAuthData] = useState([]); + const [onReady, setOnReady] = useState(false); + const [currentSelectedRow, setCurrentSelectedRow] = useState(userAuth); + + useEffect(() => { + axios.get(`${apiPath}${GET_GROUP_AUTH_LIST}`) + .then((response) => { + if (response.status === 200) { + setAuthData(response.data.records); + } + }) + .catch(error => { + console.log(error); + return false; + }); + }, []); + + useEffect(() => { + //if state data are ready and assign to different field + if (authData.length > 0) { + setOnReady(true); + } + }, [authData]); + + const columns = [ + { + id: 'module', + field: 'module', + headerName: 'Module', + flex: 1, + }, + { + id: 'authority', + field: 'name', + headerName: 'Authority', + flex: 2, + }, + ]; + + return ( + !onReady ? + + : +
+ { + console.log(ids); + setSelectedRow(ids); + setCurrentSelectedRow(ids); + }} + autoHeight + /> +
+ ); +} diff --git a/src/pages/pnspsUserGroupDetailPage/UserAddCard.js b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js new file mode 100644 index 0000000..8f4806c --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/UserAddCard.js @@ -0,0 +1,133 @@ +// material-ui +import { + Button, + Grid, TextField, + Typography +} from '@mui/material'; +import MainCard from "../../components/MainCard"; +import * as React from "react"; +import {useEffect, useState} from "react"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +import UserAddTable from "./UserAddTable"; +import {GET_GROUP_MEMBER_LIST_PATH, GET_USER_COMBO_LIST} from "../../utils/ApiPathConst"; +import axios from "axios"; +import {apiPath} from "../../auth/utils"; +import Autocomplete from "@mui/material/Autocomplete"; +import {getIdList} from "../../utils/CommonFunction"; +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const UserAddCard = ({isCollectData, updateGroupMember,userGroupData}) => { + const [currentUserData, setCurrentUserData] = React.useState({}); + const [onReady, setOnReady] = useState(false); + const [groupUserData, setGroupUserData] = useState([]); + const [userComboList, setUserComboList] = useState([]); + const [selectedUser, setSelectedUser] = useState(null); + + function updateUserList (){ + const idList = getIdList(groupUserData); + if(!idList.includes(selectedUser.id)){ + const userList = [...groupUserData, selectedUser]; + setGroupUserData(userList); + console.log(userList); + } + } + + useEffect(() => { + axios.get(`${apiPath}${GET_USER_COMBO_LIST}`) + .then((response) => { + if (response.status === 200) { + setUserComboList(response.data.records); + } + }) + .catch(error => { + console.log(error); + return false; + }); + }, []); + + useEffect(() => { + //if user data from parent are not null + if (Object.keys(userGroupData).length > 0 && userGroupData !== undefined) { + setCurrentUserData(userGroupData.data); + } + }, [userGroupData]); + + useEffect(() => { + //if state data are ready and assign to different field + if (Object.keys(userGroupData).length > 0 &¤tUserData !== undefined) { + axios.get(`${apiPath}${GET_GROUP_MEMBER_LIST_PATH}?id=${userGroupData.data.id}`) + .then((response) => { + if (response.status === 200) { + setGroupUserData(response.data.records); + } + setOnReady(true); + }) + .catch(error => { + console.log(error); + return false; + }); + } + }, [currentUserData]); + + useEffect(() => { + //upload latest data to parent + updateGroupMember(groupUserData); + }, [isCollectData]); + + + return ( + !onReady ? + + : + + + User(s) + + + + + User: + + + { + setSelectedUser(newValue); + }} + renderInput={(params) => } + /> + + + + + + + + + + ); +}; + +export default UserAddCard; diff --git a/src/pages/pnspsUserGroupDetailPage/UserAddTable.js b/src/pages/pnspsUserGroupDetailPage/UserAddTable.js new file mode 100644 index 0000000..8e2b766 --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/UserAddTable.js @@ -0,0 +1,91 @@ +// material-ui +import { + DataGrid, GridActionsCellItem, +} from "@mui/x-data-grid"; +import {useEffect, useState} from "react"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +import * as React from "react"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import {removeObjectWithId} from "../../utils/CommonFunction"; + +// ==============================|| EVENT TABLE ||============================== // + +export default function UserAddTable({setGroupUserData, userList}) { + const [groupData, setGroupData] = useState([]); + const [onReady, setOnReady] = useState(false); + + useEffect(() => { + setGroupData(userList); + }, []); + + useEffect(() => { + setGroupData(userList); + }, [userList]); + + useEffect(() => { + //if state data are ready and assign to different field + if (groupData !== undefined) { + setOnReady(true); + } + }, [groupData]); + + const handleDeleteClick = (id) => () => { + const newList =removeObjectWithId(groupData,id) + setGroupUserData(newList); + setGroupData(newList); + }; + + const columns = [ + { + field: 'actions', + type: 'actions', + headerName: 'Actions', + width: 100, + cellClassName: 'actions', + getActions: ({id}) => { + return [ + } + label="Delete" + onClick={handleDeleteClick(id)} + color="inherit" + />, + ] + }, + }, + { + id: 'name', + field: 'name', + headerName: 'User', + flex: 1, + }, + { + id: 'subDiv', + field: 'subDivisionName', + headerName: 'Sub-Division', + flex: 1, + }, + ]; + + return ( + !onReady ? + + : +
+ +
+ ); +} diff --git a/src/pages/pnspsUserGroupDetailPage/UserGroupInfoCard.js b/src/pages/pnspsUserGroupDetailPage/UserGroupInfoCard.js new file mode 100644 index 0000000..d5a0797 --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/UserGroupInfoCard.js @@ -0,0 +1,105 @@ +// material-ui +import { + Grid, TextField, Typography +} from '@mui/material'; +import MainCard from "../../components/MainCard"; +import * as React from "react"; +import {useForm} from "react-hook-form"; +import {useEffect, useState} from "react"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +//import {useParams} from "react-router-dom"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const UserGroupInfoCard = ({isCollectData, updateGroupObject,userGroupData}) => { + //const params = useParams(); + const [currentUserGroupData, setCurrentUserGroupData] = React.useState({}); + const [onReady, setOnReady] = useState(false); + const {register, getValues} = useForm() + + useEffect(() => { + //if user data from parent are not null + if (Object.keys(userGroupData).length > 0 && userGroupData !== undefined) { + setCurrentUserGroupData(userGroupData.data); + } + }, [userGroupData]); + + useEffect(() => { + //if state data are ready and assign to different field + if (Object.keys(userGroupData).length > 0 &¤tUserGroupData !== undefined) { + setOnReady(true); + } + }, [currentUserGroupData]); + + useEffect(() => { + //upload latest data to parent + const values = getValues(); + const objectData ={ + ...values, + } + updateGroupObject(objectData); + }, [isCollectData]); + + + return ( + !onReady ? + + : + + + Information + + +
+ + + + + User Group Name: + + + + + + + + + + + + User Group Description: + + + + + + + + +
+
+ ); +}; + +export default UserGroupInfoCard; diff --git a/src/pages/pnspsUserGroupDetailPage/index.js b/src/pages/pnspsUserGroupDetailPage/index.js new file mode 100644 index 0000000..2695165 --- /dev/null +++ b/src/pages/pnspsUserGroupDetailPage/index.js @@ -0,0 +1,137 @@ +// material-ui +import { + Button, + Grid, Typography +} from '@mui/material'; +import {useEffect, useState} from "react"; +import * as React from "react"; +import axios from "axios"; +import {apiPath} from "../../auth/utils"; +import {useParams} from "react-router-dom"; +import LoadingComponent from "../extra-pages/LoadingComponent"; +import {GET_GROUP_LIST_PATH} from "../../utils/ApiPathConst"; +import GroupAuthCard from "./GroupAuthCard"; +import UserGroupInfoCard from "./UserGroupInfoCard"; +import UserAddCard from "./UserAddCard"; +import {getIdList} from "../../utils/CommonFunction"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const UserMaintainPage = () => { + const params = useParams(); + const [onReady, setOnReady] = useState(false); + const [isCollectData, setIsCollectData] = useState(false); + const [editedGroupData, setEditedGroupData] = useState({}); + const [userGroupData,setUserGroupData] = useState([]); + const [userAuthData,setUserAuthData] = useState([]); + const [userConfirm, setUserConfirm] = useState(false); + const [groupMember, setGroupMember] = useState([]); + + function updateGroupObject(groupData) { + setEditedGroupData(groupData); + } + + function updateGroupMember(groupMember){ + setGroupMember(groupMember); + } + + function updateUserAuthList(userAuthData){ + setUserAuthData(userAuthData); + } + + const submitData = () => { + setUserConfirm(true); + setIsCollectData(!isCollectData); + } + + useEffect(() => { + axios.get(`${apiPath}${GET_GROUP_LIST_PATH}/${params.id}`) + .then((response) => { + if (response.status === 200) { + setUserGroupData(response.data); + } + }) + .catch(error => { + console.log(error); + return false; + }); + }, []); + + useEffect(() => { + console.log(userGroupData); + setOnReady(true); + }, [userGroupData]); + + useEffect(() => { + if(userConfirm && onReady){ + console.log("update in parents"); + console.log(editedGroupData); + console.log(groupMember); + console.log(getIdList(groupMember)); + console.log(userAuthData); + } + setUserConfirm(false); + }, [editedGroupData,userGroupData,userAuthData]); + + return ( + !onReady ? + + : + + + Maintain User Group + + {/*col 1*/} + + + + + + + + + + + + {/*col 2*/} + + + + + {/*bottom button*/} + + + + + + + + + ); +}; + +export default UserMaintainPage; diff --git a/src/pages/pnspsUserGroupSearchPage/index.js b/src/pages/pnspsUserGroupSearchPage/index.js index d5a8399..6aa9969 100644 --- a/src/pages/pnspsUserGroupSearchPage/index.js +++ b/src/pages/pnspsUserGroupSearchPage/index.js @@ -1,5 +1,7 @@ // material-ui import { + Box, + Button, Grid, Typography } from '@mui/material'; import MainCard from "../../components/MainCard"; @@ -16,7 +18,7 @@ import * as React from "react"; const UserGroupSearchPanel = () => { - const [record,setRecord] = useState([]); + const [record, setRecord] = useState([]); const [searchCriteria, setSearchCriteria] = useState({}); const [onReady, setOnReady] = useState(false); @@ -32,7 +34,7 @@ const UserGroupSearchPanel = () => { getGroupList(); }, [searchCriteria]); - function getGroupList(){ + function getGroupList() { axios.get(`${apiPath}${GET_GROUP_LIST_PATH}`, {params: searchCriteria} ) @@ -47,7 +49,7 @@ const UserGroupSearchPanel = () => { }); } - function applySearch(input){ + function applySearch(input) { setSearchCriteria(input); } @@ -55,27 +57,43 @@ const UserGroupSearchPanel = () => { !onReady ? : - - - View User Group - - {/*row 1*/} - - - - {/*row 2*/} - - - - - + + + + + + View User Group + + + + + + + - + {/*row 1*/} + + + + {/*row 2*/} + + + + + + + ); }; diff --git a/src/routes/SettingRoutes.js b/src/routes/SettingRoutes.js index 4a7b8fa..4710b60 100644 --- a/src/routes/SettingRoutes.js +++ b/src/routes/SettingRoutes.js @@ -8,9 +8,10 @@ import MainLayout from "../layout/MainLayout"; const SettingPage = Loadable(lazy(() => import('pages/pnspsSettingPage'))); const PasswordPolicyPage = Loadable(lazy(()=> import('pages/pnspsPasswordPolicyPage'))) const UserSettingPage = Loadable(lazy(()=>import ('pages/pnspsUserSettingPage/'))); -const UserGroupSearchPage = Loadable(lazy(() => import('pages/pnspsUserGroupSearchPage'))); const UserSearchPage = Loadable(lazy(()=>import ('pages/pnspsUserSearchPage'))); const UserMaintainPage = Loadable(lazy(() => import('pages/pnspsUserDetailPage'))); +const UserGroupSearchPage = Loadable(lazy(() => import('pages/pnspsUserGroupSearchPage'))); +const UserGroupDetailPage = Loadable(lazy(() => import('pages/pnspsUserGroupDetailPage'))); // ==============================|| AUTH ROUTING ||============================== // @@ -23,13 +24,17 @@ const SettingRoutes = { element: }, { - path: '/user/:id', - element: + path: '/userGroup/:id', + element: }, { path: 'userSearchview', element: }, + { + path: '/user/:id', + element: + }, { path: 'usersetting', element: @@ -41,7 +46,7 @@ const SettingRoutes = { { path: 'passwordpolicy', element: - } + }, ] }; diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index bda6106..2a52c0f 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -1,4 +1,7 @@ -export const GET_GROUP_COMBO_PATH = "/group/combo" export const GET_GROUP_LIST_PATH = "/group" +export const GET_GROUP_COMBO_PATH = "/group/combo" +export const GET_GROUP_MEMBER_LIST_PATH = "/group/member" +export const GET_GROUP_AUTH_LIST = "/group/auth/combo" export const GET_USER_PATH = "/user" -export const GET_AUTH_LIST = "/user/auth/combo" \ No newline at end of file +export const GET_AUTH_LIST = "/user/auth/combo" +export const GET_USER_COMBO_LIST = "/user/combo" \ No newline at end of file diff --git a/src/utils/CommonFunction.js b/src/utils/CommonFunction.js new file mode 100644 index 0000000..5bf7263 --- /dev/null +++ b/src/utils/CommonFunction.js @@ -0,0 +1,14 @@ +export function getIdList(input){ + const output = input.map(function (obj) { + return obj.id; + }); + return output; +} + +export function removeObjectWithId(arr, id) { + // Making a copy with the Array from() method + const arrCopy = Array.from(arr); + const objWithIdIndex = arrCopy.findIndex((obj) => obj.id === id); + arrCopy.splice(objWithIdIndex, 1); + return arrCopy; +} \ No newline at end of file