| @@ -143,6 +143,9 @@ function Header(props) { | |||
| <li> | |||
| <Link className="userProfileGld" to='/user/profile'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users Profile</Typography></Link> | |||
| </li> | |||
| <li> | |||
| <Link className="systemSetting" to='/setting/sys'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>System Setting</Typography></Link> | |||
| </li> | |||
| </ul> | |||
| </li> | |||
| <li> | |||
| @@ -0,0 +1,125 @@ | |||
| // material-ui | |||
| import { | |||
| FormControl, | |||
| Button, | |||
| Grid, | |||
| // InputAdornment, | |||
| Typography, FormLabel, | |||
| OutlinedInput, | |||
| } from '@mui/material'; | |||
| import MainCard from "components/MainCard"; | |||
| import * as React from "react"; | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const Form = ({ selectedItem, onSave }) => { | |||
| const [data, setData] = React.useState({}); | |||
| const [value, setValue] = React.useState(""); | |||
| React.useEffect(() => { | |||
| //if user data from parent are not null | |||
| if (selectedItem !== undefined && Object.keys(selectedItem).length > 0) { | |||
| setData(selectedItem); | |||
| setValue(selectedItem.value) | |||
| } | |||
| }, [selectedItem]); | |||
| return ( | |||
| <MainCard elevation={0} | |||
| border={false} | |||
| content={false} | |||
| > | |||
| { | |||
| data?.name ? | |||
| <> | |||
| <Typography variant="h5" sx={{ mt: 3, ml: 3, mr: 3, borderBottom: "1px solid black" }}> | |||
| Update | |||
| </Typography> | |||
| <form> | |||
| <Grid container> | |||
| <Grid item xs={12} s={12} md={12} lg={12} sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={2} | |||
| sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <FormLabel>Name:</FormLabel> | |||
| </Grid> | |||
| <Grid item xs={8} > | |||
| <Typography> | |||
| {data?.name} | |||
| </Typography> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} s={12} md={12} lg={12} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={2} | |||
| sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <FormLabel >Type:</FormLabel> | |||
| </Grid> | |||
| <Grid item xs={8}> | |||
| <Typography> | |||
| {data?.type} | |||
| </Typography> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} s={12} md={12} lg={12} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={2} | |||
| sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <FormLabel>Category:</FormLabel> | |||
| </Grid> | |||
| <Grid item xs={8}> | |||
| <Typography> | |||
| {data?.category} | |||
| </Typography> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} s={12} md={12} lg={12} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={2} | |||
| sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <FormLabel>Value:</FormLabel> | |||
| </Grid> | |||
| <Grid item xs={8}> | |||
| <FormControl variant="outlined" fullWidth required> | |||
| <OutlinedInput | |||
| fullWidth | |||
| size="small" | |||
| value={value} | |||
| onChange={(event)=>{ | |||
| setValue(event.target.value); | |||
| }} | |||
| /> | |||
| </FormControl> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Button onClick={()=>{onSave({ name: data.name, value:value})}}>Save</Button> | |||
| </form> | |||
| </> | |||
| : | |||
| <Typography variant="h5" sx={{ mt: 3, ml: 3, mr: 3, borderBottom: "1px solid black" }}> | |||
| Please select system params. | |||
| </Typography> | |||
| } | |||
| </MainCard> | |||
| ); | |||
| }; | |||
| export default Form; | |||
| @@ -0,0 +1,77 @@ | |||
| // material-ui | |||
| import { | |||
| Box, | |||
| Typography | |||
| } from '@mui/material'; | |||
| import MainCard from "components/MainCard"; | |||
| import * as React from "react"; | |||
| import { FiDataGrid } from "components/FiDataGrid"; | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const Table = ({onRowClick, dataList}) => { | |||
| const [rows, setRows] = React.useState(dataList); | |||
| React.useEffect(() => { | |||
| setRows(dataList); | |||
| }, [dataList]); | |||
| const columns = [ | |||
| { | |||
| field: 'name', | |||
| headerName: 'Name', | |||
| width: 300, | |||
| }, | |||
| { | |||
| id: 'type', | |||
| field: 'type', | |||
| headerName: 'Type', | |||
| width: 150, | |||
| valueGetter: (params) => { | |||
| return params.row.type | |||
| } | |||
| }, | |||
| { | |||
| id: 'category', | |||
| field: 'category', | |||
| headerName: 'Category', | |||
| width: 150, | |||
| }, | |||
| { | |||
| id: 'value', | |||
| field: 'value', | |||
| headerName: 'Value', | |||
| flex: 1 | |||
| }, | |||
| ]; | |||
| return ( | |||
| <MainCard elevation={0} | |||
| border={false} | |||
| content={false} | |||
| height='100%' | |||
| > | |||
| <Typography variant="h5" sx={{mt: 3, ml: 3, mr: 3, borderBottom: "1px solid black"}}> | |||
| System Params | |||
| </Typography> | |||
| <div style={{ width: '100%' }}> | |||
| <Box sx={{ backgroundColor: "#fff", ml: 2 }} height='100%'> | |||
| <FiDataGrid | |||
| rows={rows} | |||
| columns={columns} | |||
| initialState={{ | |||
| pagination: { | |||
| paginationModel: { page: 0, pageSize: 10 }, | |||
| }, | |||
| }} | |||
| getRowHeight={() => 'auto'} | |||
| onRowClick={onRowClick} | |||
| /> | |||
| </Box> | |||
| </div> | |||
| </MainCard> | |||
| ); | |||
| }; | |||
| export default Table; | |||
| @@ -0,0 +1,110 @@ | |||
| import { | |||
| Grid, | |||
| Typography, | |||
| Stack, | |||
| Box, | |||
| } from '@mui/material'; | |||
| import * as React from "react"; | |||
| import { GET_SYS_PARAMS, } from "utils/ApiPathConst"; | |||
| import Loadable from 'components/Loadable'; | |||
| const Table = Loadable(React.lazy(() => import('./Table'))); | |||
| const Form = Loadable(React.lazy(() => import('./Form'))); | |||
| import { notifyActionSuccess } from 'utils/CommonFunction'; | |||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
| import * as HttpUtils from "utils/HttpUtils"; | |||
| const BackgroundHead = { | |||
| backgroundImage: `url(${titleBackgroundImg})`, | |||
| width: '100%', | |||
| height: '100%', | |||
| backgroundSize: 'contain', | |||
| backgroundRepeat: 'no-repeat', | |||
| backgroundColor: '#0C489E', | |||
| backgroundPosition: 'right' | |||
| } | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const SystemSetting = () => { | |||
| const [dataList, setDataList] = React.useState([]); | |||
| const [selectedItem, setSelectedItem] = React.useState({}); | |||
| React.useEffect(() => { | |||
| loadList(); | |||
| }, []); | |||
| const loadList=()=>{ | |||
| HttpUtils.get({ | |||
| url: GET_SYS_PARAMS, | |||
| onSuccess: (responseData)=>{ | |||
| setDataList(responseData); | |||
| } | |||
| }); | |||
| } | |||
| const onRowClick=(param)=>{ | |||
| setSelectedItem(param.row); | |||
| } | |||
| const onSave=(param)=>{ | |||
| HttpUtils.post({ | |||
| url: GET_SYS_PARAMS+"/update", | |||
| params:{ | |||
| name: param.name, | |||
| value: param.value | |||
| }, | |||
| onSuccess: ()=>{ | |||
| notifyActionSuccess(); | |||
| loadList(); | |||
| } | |||
| }); | |||
| } | |||
| return ( | |||
| <Grid container sx={{ minHeight: '90vh', backgroundColor: 'backgroundColor.default' }} direction="column" | |||
| justifyContent="flex-start"> | |||
| <> | |||
| <Grid item xs={12}> | |||
| <div style={BackgroundHead}> | |||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||
| <Typography ml={15} color='#FFF' variant="h4">System Setting</Typography> | |||
| </Stack> | |||
| </div> | |||
| </Grid> | |||
| {/*col 1*/} | |||
| <Grid item xs={12} > | |||
| <Grid container direction="row" sx={{ p: 2 }} spacing={2} > | |||
| <Grid item xs={12} md={8} lg={8} > | |||
| <Box xs={12} sx={{ borderRadius: '10px', backgroundColor: '#fff' }} > | |||
| <Table | |||
| dataList={dataList} | |||
| onRowClick={onRowClick} | |||
| /> | |||
| </Box> | |||
| </Grid> | |||
| <Grid item xs={12} md={4} lg={4}> | |||
| <Box xs={12} sx={{ borderRadius: '10px', backgroundColor: '#fff' }}> | |||
| <Form | |||
| selectedItem={selectedItem} | |||
| onSave={onSave} | |||
| /> | |||
| </Box> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| {/*col 2*/} | |||
| </> | |||
| </Grid> | |||
| ); | |||
| }; | |||
| export default SystemSetting; | |||
| @@ -19,6 +19,7 @@ const DemandNote_Search = Loadable(lazy(() => import('pages/DemandNote/Search')) | |||
| const DemandNote_Details = Loadable(lazy(() => import('pages/DemandNote/Details'))); | |||
| const GFMIS_Search = Loadable(lazy(() => import('pages/GFMIS'))); | |||
| const UserMaintainPage = Loadable(lazy(() => import('pages/User/GLDUserProfile'))); | |||
| const SystemSetting = Loadable(lazy(() => import('pages/Setting/SystemSetting'))); | |||
| // ==============================|| MAIN ROUTING ||============================== // | |||
| @@ -85,6 +86,10 @@ const GLDUserRoutes = { | |||
| path: '/user/profile', | |||
| element: <UserMaintainPage /> | |||
| }, | |||
| { | |||
| path: '/setting/sys', | |||
| element: <SystemSetting /> | |||
| }, | |||
| ] | |||
| }, | |||
| ] | |||
| @@ -4,6 +4,8 @@ import {apiPath} from "../auth/utils"; | |||
| export const REFRESH_TOKEN = "/refresh-token" | |||
| export const CHANGE_PASSWORD_PATH = "/user/change-password" | |||
| export const GET_SYS_PARAMS = apiPath+'/settings'; | |||
| //Group Config | |||
| export const GET_GROUP_LIST_PATH = '/group'; | |||
| export const GET_GROUP_COMBO_PATH = '/group/combo'; | |||
| @@ -177,7 +177,7 @@ export const notifyDownloadSuccess = () => { | |||
| }; | |||
| export const notifyActionSuccess = (actionMsg) => { | |||
| toast.success(`${actionMsg}`, { | |||
| toast.success(actionMsg??"Success", { | |||
| position: "bottom-right", | |||
| autoClose: 5000, | |||
| hideProgressBar: false, | |||
| @@ -20,6 +20,14 @@ export const put = ({url,params, onSuccess, onFail, onError}) =>{ | |||
| }); | |||
| }; | |||
| export const patch = ({url,params, onSuccess, onFail, onError}) =>{ | |||
| axios.patch(url,params).then( | |||
| (response)=>{onResponse(response, onSuccess, onFail);} | |||
| ).catch(error => { | |||
| return handleError(error,onError); | |||
| }); | |||
| }; | |||
| export const post = ({url, params, onSuccess, onFail, onError, headers}) =>{ | |||
| headers = headers?headers:{ | |||
| "Content-Type":"application/json" | |||
| @@ -137,7 +145,7 @@ const onResponse= (response, onSuccess, onFail) =>{ | |||
| } | |||
| if(onSuccess){ | |||
| onSuccess(response.data); | |||
| onSuccess(response?.data); | |||
| } | |||
| } | |||