From c291975daf6ac7bca107bde8a724434227eabc7f Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Wed, 6 Mar 2024 15:42:50 +0800 Subject: [PATCH] export audit log and add audit log page --- src/layout/MainLayout/Header/index.js | 3 + src/pages/AuditLog/AuditLogSearchForm.js | 180 +++++++++++++++++ src/pages/AuditLog/AuditLogTable.js | 81 ++++++++ src/pages/AuditLog/UserSearchForm.js | 182 ------------------ src/pages/AuditLog/UserTable.js | 142 -------------- src/pages/AuditLog/index.js | 22 ++- .../User/DetailsPage_Individual/index.js | 2 +- .../User/DetailsPage_Organization/index.js | 2 +- src/utils/ApiPathConst.js | 4 +- 9 files changed, 284 insertions(+), 334 deletions(-) create mode 100644 src/pages/AuditLog/AuditLogSearchForm.js create mode 100644 src/pages/AuditLog/AuditLogTable.js delete mode 100644 src/pages/AuditLog/UserSearchForm.js delete mode 100644 src/pages/AuditLog/UserTable.js diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index 5e52026..ca078fa 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -158,6 +158,9 @@ function Header(props) {
  • Gazette Issue
  • +
  • + Audit Log +
  • diff --git a/src/pages/AuditLog/AuditLogSearchForm.js b/src/pages/AuditLog/AuditLogSearchForm.js new file mode 100644 index 0000000..9eff05e --- /dev/null +++ b/src/pages/AuditLog/AuditLogSearchForm.js @@ -0,0 +1,180 @@ +// material-uisubDivision +import { + Button, + // FormControlLabel, + Grid, + TextField, + Typography +} from '@mui/material'; +import MainCard from "components/MainCard"; +import { useForm } from "react-hook-form"; + +import { + // useEffect, + // useState +} from "react"; + +import * as React from "react"; +// import { useNavigate } from "react-router"; +import {PNSPS_BUTTON_THEME} from "themes/buttonConst"; +import {ThemeProvider} from "@emotion/react"; +import * as DateUtils from "utils/DateUtils"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as HttpUtils from "utils/HttpUtils"; +import Loadable from 'components/Loadable'; + +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { + // const navigate = useNavigate(); + + const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); + const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); + const [onDownload, setOnDownload] = React.useState(false); + + const { reset, register, handleSubmit } = useForm() + const onSubmit = (data) => { + + const temp = { + username: data.userName, + modifiedTo: data.modifiedTo, + modifiedFrom: data.modifiedFrom, + }; + applySearch(temp); + }; + + + function resetForm() { + reset(); + } + + function exportExcel() { + setOnDownload(true) + HttpUtils.fileDownload({ + url: UrlUtils.AUDIT_LOG_EXPORT, + onResponse:()=>{ + setOnDownload(false) + }, + onError:()=>{ + setOnDownload(false) + } + }); + } + + return ( + + +
    + + {/*row 1*/} + + + Search + + + {/*row 2*/} + + + + + + + + + { + setMinDate(DateUtils.dateStr(newValue)); + }} + InputLabelProps={{ + shrink: true + }} + /> + + + + { + console.log(newValue) + setMaxDate(DateUtils.dateStr(newValue)); + }} + id="modifiedTo" + type="date" + label="Modified To" + defaultValue={searchCriteria.modifiedTo} + /> + + + + + {/*last row*/} + + + + + + {onDownload? + + : + + } + + + + + + + + + + + + +
    +
    + ); +}; + +export default AuditLogSearchForm; diff --git a/src/pages/AuditLog/AuditLogTable.js b/src/pages/AuditLog/AuditLogTable.js new file mode 100644 index 0000000..71c35a9 --- /dev/null +++ b/src/pages/AuditLog/AuditLogTable.js @@ -0,0 +1,81 @@ +// material-ui +import * as React from 'react'; +import {FiDataGrid} from "components/FiDataGrid"; +import {useEffect} from "react"; +import * as DateUtils from "utils/DateUtils" +import {useTheme} from "@emotion/react"; +import { + // Button, + // Typography, + useMediaQuery +} from '@mui/material'; +// ==============================|| EVENT TABLE ||============================== // + +export default function AuditLogTable({recordList}) { + const [rows, setRows] = React.useState(recordList); + + useEffect(() => { + setRows(recordList); + // console.log(recordList) + }, [recordList]); + const theme = useTheme(); + const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); + + const columns = [ + { + id: 'modified', + field: 'modified', + headerName: 'Date', + flex: isMdOrLg ? 1 : undefined, + valueGetter:(params)=>{ + return DateUtils.datetimeStr(params?.value); + } + }, + { + id: 'modifiedByName', + field: 'modifiedByName', + headerName: 'Username', + flex: isMdOrLg ? 1 : undefined, + }, + { + id: 'tableName', + field: 'tableName', + headerName: 'Table Name', + flex: isMdOrLg ? 1 : undefined, + }, + { + id: 'ref', + field: 'ref', + headerName: 'Ref', + flex: isMdOrLg ? 1 : undefined, + }, + { + id: 'oldData', + field: 'oldData', + headerName: 'Old Data', + flex: isMdOrLg ? 2 : undefined, + }, + { + id: 'newData', + field: 'newData', + headerName: 'New Data', + flex: isMdOrLg ? 2 : undefined, + }, + ]; + + // function handleRowDoubleClick(params) { + // navigate('/user/'+ params.id); + // } + + return ( +
    + 'auto'} + /> +
    + ); +} diff --git a/src/pages/AuditLog/UserSearchForm.js b/src/pages/AuditLog/UserSearchForm.js deleted file mode 100644 index 8a72d96..0000000 --- a/src/pages/AuditLog/UserSearchForm.js +++ /dev/null @@ -1,182 +0,0 @@ -// material-uisubDivision -import { - Button, - FormControlLabel, - Grid, TextField, - Typography -} from '@mui/material'; -import MainCard from "components/MainCard"; -import { useForm } from "react-hook-form"; - -import { - // useEffect, - useState -} from "react"; - -import Checkbox from "@mui/material/Checkbox"; -import * as React from "react"; -// import { useNavigate } from "react-router"; -import axios from "axios"; -import { GET_EMAIL_LIST } from 'utils/ApiPathConst'; -import {PNSPS_BUTTON_THEME} from "themes/buttonConst"; -import {ThemeProvider} from "@emotion/react"; - -// ==============================|| DASHBOARD - DEFAULT ||============================== // - - -const UserSearchForm = ({ applySearch }) => { - // const navigate = useNavigate(); - - const [type, setType] = useState([]); - const [locked, setLocked] = useState(false); - - - const { reset, register, handleSubmit } = useForm() - const onSubmit = (data) => { - - let typeArray = []; - - for (let i = 0; i < type.length; i++) { - typeArray.push(type[i].label); - } - - const temp = { - username: data.userName, - enName: data.fullenName, - post: data.post, - email: data.email, - locked: locked, - }; - applySearch(temp); - }; - - - function resetForm() { - setType([]); - setLocked(false); - reset(); - axios.get(`${GET_EMAIL_LIST}`) - .then(r => { - console.log(r) - }) - .catch(err => { - console.log(err) - }) - } - - return ( - - -
    - - {/*row 1*/} - - - Search - - - {/*row 2*/} - - - - - - - - - - - - - - - - - - - - setLocked(event.target.checked)} - name="checked" - color="primary" - size="small" - /> - } - label={Locked} - /> - - - - {/*last row*/} - - - - - - - - - - - - - - - - - -
    -
    - ); -}; - -export default UserSearchForm; diff --git a/src/pages/AuditLog/UserTable.js b/src/pages/AuditLog/UserTable.js deleted file mode 100644 index 9f866bc..0000000 --- a/src/pages/AuditLog/UserTable.js +++ /dev/null @@ -1,142 +0,0 @@ -// material-ui -import * as React from 'react'; -import { GridActionsCellItem,} from "@mui/x-data-grid"; -import {FiDataGrid} from "components/FiDataGrid"; -import EditIcon from '@mui/icons-material/Edit'; -import {useEffect} from "react"; -import {useNavigate} from "react-router-dom"; -import { useTheme } from '@mui/material/styles'; -import Checkbox from '@mui/material/Checkbox'; -import * as UrlUtils from "utils/ApiPathConst"; -import * as HttpUtils from 'utils/HttpUtils'; -import { notifyLockSuccess, notifyUnlockSuccess } from 'utils/CommonFunction'; - -// ==============================|| EVENT TABLE ||============================== // - -export default function UserTable({recordList,setChangeLocked}) { - const [rows, setRows] = React.useState(recordList); - const theme = useTheme(); - - const navigate = useNavigate() - - useEffect(() => { - setRows(recordList); - }, [recordList]); - - const handleEditClick = (id) => () => { - navigate('/user/'+ id); - }; - - const handleLock = (params) => () => { - setChangeLocked(false) - if (params.row.locked==true){ - doUnlock(params.id) - }else{ - doLock(params.id) - setRows(recordList); - } - } - - const doLock = (id) => { - HttpUtils.get({ - url: UrlUtils.GET_USER_LOCK+"/"+id, - onSuccess: function(){ - setRows(recordList); - setChangeLocked(true) - notifyLockSuccess() - } - }); - }; - - const doUnlock = (id) => { - HttpUtils.get({ - url: UrlUtils.GET_USER_UNLOCK+"/"+id, - onSuccess: function(){ - setRows(recordList); - setChangeLocked(true) - notifyUnlockSuccess() - } - }); - }; - - const columns = [ - { - field: 'actions', - type: 'actions', - headerName: 'Actions', - width: 100, - cellClassName: 'actions', - getActions: ({id}) => { - return [ - } - label="Edit" - className="textPrimary" - onClick={handleEditClick(id)} - color="primary" - />] - }, - }, - { - id: 'username', - field: 'username', - headerName: 'User Name', - flex: 1, - }, - { - id: 'enName', - field: 'enName', - headerName: 'Full Name', - flex: 1, - }, - { - id: 'post', - field: 'post', - headerName: 'Post', - flex: 1, - }, - { - id: 'emailAddress', - field: 'emailAddress', - headerName: 'Email', - flex: 1, - }, - - { - id: 'locked', - field: 'locked', - type: 'bool', - headerName: 'Locked', - flex: 1, - renderCell: (params) => { - return ( - - ); - }, - }, - ]; - - function handleRowDoubleClick(params) { - navigate('/user/'+ params.id); - } - - return ( -
    - 'auto'} - /> -
    - ); -} diff --git a/src/pages/AuditLog/index.js b/src/pages/AuditLog/index.js index 0e408b9..7ddda71 100644 --- a/src/pages/AuditLog/index.js +++ b/src/pages/AuditLog/index.js @@ -8,14 +8,15 @@ import { import MainCard from "components/MainCard"; import { useEffect, useState } from "react"; import axios from "axios"; -import { GLD_USER_PATH } from "utils/ApiPathConst"; +import { GET_AUDIT_LOG_LIST } from "utils/ApiPathConst"; import * as React from "react"; +import * as DateUtils from "utils/DateUtils"; import Loadable from 'components/Loadable'; import { lazy } from 'react'; const LoadingComponent = Loadable(lazy(() => import('../extra-pages/LoadingComponent'))); -const SearchForm = Loadable(lazy(() => import('./UserSearchForm'))); -const EventTable = Loadable(lazy(() => import('./UserTable'))); +const SearchForm = Loadable(lazy(() => import('./AuditLogSearchForm'))); +const EventTable = Loadable(lazy(() => import('./AuditLogTable'))); import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' const BackgroundHead = { @@ -31,7 +32,10 @@ const BackgroundHead = { const AuditLogPage = () => { const [record, setRecord] = useState([]); - const [searchCriteria, setSearchCriteria] = useState({}); + const [searchCriteria, setSearchCriteria] = React.useState({ + modifiedTo: DateUtils.dateStr(new Date()), + modifiedFrom: DateUtils.dateStr(new Date().setDate(new Date().getDate()-14)), + }); const [onReady, setOnReady] = useState(false); const [changelocked, setChangeLocked] = React.useState(false); @@ -50,7 +54,7 @@ const AuditLogPage = () => { }, [searchCriteria]); function getUserList() { - axios.get(`${GLD_USER_PATH}`, + axios.get(`${GET_AUDIT_LOG_LIST}`, { params: searchCriteria } ) .then((response) => { @@ -80,14 +84,18 @@ const AuditLogPage = () => {
    - View GLD User + Audit Log
    {/*row 1*/} - + {/*row 2*/} diff --git a/src/pages/User/DetailsPage_Individual/index.js b/src/pages/User/DetailsPage_Individual/index.js index 70e7d04..45a3718 100644 --- a/src/pages/User/DetailsPage_Individual/index.js +++ b/src/pages/User/DetailsPage_Individual/index.js @@ -125,7 +125,7 @@ const UserMaintainPage_Individual = () => { const getLoginLogList = () => { HttpUtils.get({ - url: `${UrlUtils.GET_Login_Log_List}`, + url: `${UrlUtils.GET_LOGIN_LOG_LIST}`, params:{ userId:params.id }, diff --git a/src/pages/User/DetailsPage_Organization/index.js b/src/pages/User/DetailsPage_Organization/index.js index 5a82336..ae3caf8 100644 --- a/src/pages/User/DetailsPage_Organization/index.js +++ b/src/pages/User/DetailsPage_Organization/index.js @@ -187,7 +187,7 @@ const UserMaintainPage_Organization = () => { const getLoginLogList = () => { HttpUtils.get({ - url: `${UrlUtils.GET_Login_Log_List}`, + url: `${UrlUtils.GET_LOGIN_LOG_LIST}`, params:{ userId:params.id }, diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 28bda55..ad61c6e 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -69,6 +69,7 @@ export const GET_FILE_DELETE = apiPath+'/file/delete'; export const DR_EXPORT = apiPath+'/settings/dr/export'; export const DR_IMPORT = apiPath+'/settings/dr/import'; +export const AUDIT_LOG_EXPORT = apiPath+'/settings/auditLog-export'; @@ -105,7 +106,7 @@ export const POST_CHECK_APP_EXPRITY_DATE = apiPath+'/application/checkExprityDat //GLD User export const POST_ADMIN_USER_REGISTER = apiPath+'/user/registry'; export const DELETE_USER = apiPath+'/user'; -export const GET_Login_Log_List = apiPath+'/user/loginLogList'; +export const GET_LOGIN_LOG_LIST = apiPath+'/user/loginLogList'; export const GET_PUBLIC_NOTICE_APPLY_DETAIL = apiPath+'/application/application-detail'; export const SET_PUBLIC_NOTICE_GROUP_DETAIL = apiPath+'/application/application-group-detail'; export const SET_PUBLIC_NOTICE_STATUS_NOT_ACCEPT = apiPath+'/application/application-detail-status-not-accept'; @@ -116,6 +117,7 @@ export const SET_PUBLIC_NOTICE_STATUS_RESUBMIT = apiPath+'/application/applicati export const SET_PUBLIC_NOTICE_STATUS_REVIEWED = apiPath+'/application/application-detail-status-reviewed'; export const SET_PUBLIC_NOTICE_STATUS_PUBLISH = apiPath+'/application/application-detail-status-publish'; export const UPDATE_PUBLIC_NOTICE_APPLY_DETAIL = apiPath+'/application/save'; +export const GET_AUDIT_LOG_LIST = apiPath+'/settings/auditLogList'; //gazette export const GET_ISSUE_COMBO = apiPath+'/gazette-issue/combo';//GET