Parcourir la source

update report in gld page

CR013B2
Alex Cheung il y a 3 mois
Parent
révision
d2b5f0407c
6 fichiers modifiés avec 547 ajouts et 1 suppressions
  1. +3
    -0
      src/layout/MainLayout/Header/index.js
  2. +230
    -0
      src/pages/Report/FullListForm.js
  3. +200
    -0
      src/pages/Report/SummaryForm.js
  4. +106
    -0
      src/pages/Report/index.js
  5. +6
    -1
      src/routes/GLDUserRoutes.js
  6. +2
    -0
      src/utils/ApiPathConst.js

+ 3
- 0
src/layout/MainLayout/Header/index.js Voir le fichier

@@ -333,6 +333,9 @@ function Header(props) {
:
<></>
}
<li>
<Link className="report" to='/setting/report'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1}}>Report</Typography></Link>
</li>
</ul>
</li>
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}>


+ 230
- 0
src/pages/Report/FullListForm.js Voir le fichier

@@ -0,0 +1,230 @@
// material-ui
import {
Button,
Grid, TextField,
Autocomplete,
Typography
} from '@mui/material';
import MainCard from "components/MainCard";
import { useForm } from "react-hook-form";
import * as React from "react";
import * as DateUtils from "utils/DateUtils";
import {ThemeProvider} from "@emotion/react";
import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst";
import * as FormatUtils from "utils/FormatUtils";
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";

import {DatePicker} from "@mui/x-date-pickers/DatePicker";
import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";

// ==============================|| DASHBOARD - DEFAULT ||============================== //
const FullListForm = ({ searchCriteria, issueComboData}) => {

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");

const [issueSelected, setIssueSelected] = React.useState({});
const [issueCombo, setIssueCombo] = React.useState([]);
const [waitDownload, setWaitDownload] = React.useState(false);

React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
React.useEffect(() => {
setToDateValue(maxDate);
}, [maxDate]);

const marginBottom = 2.5;
const { reset, register, handleSubmit } = useForm()
const doExport = () => {
setWaitDownload(true)
let sentDateFrom = "";
let sentDateTo = "";
if( fromDateValue!="dd / mm / yyyy"&&toDateValue!="dd / mm / yyyy"){
sentDateFrom = DateUtils.dateValue(fromDateValue)
sentDateTo = DateUtils.dateValue(toDateValue)
}

const temp = {
issueId: issueSelected?.id,
dateFrom: sentDateFrom,
dateTo: sentDateTo
};
HttpUtils.fileDownload({
url: UrlUtils.GEN_FULL_LIST,
params: temp,
onResponse: () => {
setTimeout(()=> setWaitDownload(false), 500)
}
});
};

React.useEffect(() => {
if (issueComboData && issueComboData.length > 0) {
setIssueCombo(issueComboData);
if(searchCriteria.issueId!=undefined){
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
}
}
}, [issueComboData]);

const getIssueLabel=(data)=> {
let issueYear = data.issueYear
let volume = data.volume;
let issueNo = data.issueNo;
let issueDate = data.issueDate;
return issueYear
+ " Vol. " + FormatUtils.zeroPad(volume, 3)
+ ", No. " + FormatUtils.zeroPad(issueNo, 2)
+ ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)");
}

function resetForm() {
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset({contact:""});
}


return (
<MainCard xs={12} md={12} lg={12}
border={false}
content={false}
sx={{ backgroundColor: '#fff' }}
>

<form onSubmit={handleSubmit()}>
<Grid container sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: marginBottom}} width="98%">
{/*row 1*/}
<Grid item justifyContent="space-between" alignItems="center" sx={{mt:1,ml:3,mb:marginBottom}}>
<Typography variant="pnspsFormHeader" >
Search
</Typography>
</Grid>
{/*row 2*/}
<Grid container display="flex" alignItems={"center"}>
<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: marginBottom }}>
<Autocomplete
{...register("issueId")}
disablePortal
size="small"
id="issueId"
options={issueCombo}
value={issueSelected}
inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""}
getOptionLabel={(option) => getIssueLabel(option)}
onChange={(event, newValue) => {
setIssueSelected(newValue);
}}
renderInput={(params) => (
<TextField {...params}
label="Gazette Issue No."
InputLabelProps={{
shrink: true
}}
/>
)}
/>
</Grid>

<Grid item xs={12} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:marginBottom}}>
<Grid container spacing={1}>
<Grid item xs={6}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateFrom"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
label={"Submit Date (From)"}
value={minDate === null ? null : dayjs(minDate)}
maxDate={maxDate === null ? null : dayjs(maxDate)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setMinDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</Grid>

<Grid item xs={6}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateTo"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
label={"Submit Date (To)"}
value={maxDate === null ? null : dayjs(maxDate)}
minDate={minDate === null ? null : dayjs(minDate)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setMaxDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</Grid>
</Grid>
</Grid>
</Grid>

{/*last row*/}
<Grid container maxWidth justifyContent="flex-end">
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Grid item sx={{ ml: 3 }}>
<Button
variant="contained"
color="green"
onClick={()=>{
doExport()
}}
disabled={waitDownload}
>
Export Full List
</Button>
</Grid>
<Grid item sx={{ ml: 3 }}>
<Button
variant="contained"
color="cancel"
onClick={resetForm}
>
Reset
</Button>
</Grid>
</ThemeProvider>
</Grid>
</Grid>
</form>
</MainCard>
);
};

export default FullListForm;

+ 200
- 0
src/pages/Report/SummaryForm.js Voir le fichier

@@ -0,0 +1,200 @@
// material-ui
import {
Button,
Grid,
TextField,
Typography
} from '@mui/material';
import MainCard from "components/MainCard";
import { useForm } from "react-hook-form";
import * as React from "react";
import * as DateUtils from "utils/DateUtils";
import {ThemeProvider} from "@emotion/react";
import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst";
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";

import {DatePicker} from "@mui/x-date-pickers/DatePicker";
import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";

// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SummaryForm = ({ searchCriteria}) => {

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");


const [waitDownload, setWaitDownload] = React.useState(false);

React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
React.useEffect(() => {
setToDateValue(maxDate);
}, [maxDate]);

const marginBottom = 2.5;
const { reset, register, handleSubmit } = useForm()
const onSubmit = (data) => {
setWaitDownload(true)
let sentDateFrom = "";
let sentDateTo = "";
if( fromDateValue!="dd / mm / yyyy"&&toDateValue!="dd / mm / yyyy"){
sentDateFrom = DateUtils.dateValue(fromDateValue)
sentDateTo = DateUtils.dateValue(toDateValue)
}

const temp = {
dateFrom: sentDateFrom,
dateTo: sentDateTo,
contact: data.contact,
};
doExport(temp);
};

const doExport = (temp) => {
HttpUtils.fileDownload({
url: UrlUtils.GEN_SUMMARY_LIST,
params: temp,
onResponse: () => {
setTimeout(()=> setWaitDownload(false), 500)
}
});
};

function resetForm() {
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset({contact:""});
}


return (
<MainCard xs={12} md={12} lg={12}
border={false}
content={false}
sx={{ backgroundColor: '#fff' }}
>

<form onSubmit={handleSubmit(onSubmit)}>
<Grid container sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: marginBottom}} width="98%">
{/*row 1*/}
<Grid item justifyContent="space-between" alignItems="center" sx={{mt:1,ml:3,mb:marginBottom}}>
<Typography variant="pnspsFormHeader" >
Search
</Typography>
</Grid>
{/*row 2*/}
<Grid container display="flex" alignItems={"center"}>
<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: marginBottom }}>
<TextField
fullWidth
{...register("contact")}
id="contact"
label={"Client"}
defaultValue={searchCriteria.contact}
InputLabelProps={{
shrink: true
}}
/>

</Grid>

<Grid item xs={12} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:marginBottom}}>
<Grid container spacing={1}>
<Grid item xs={6}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateFrom"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
label={"Submit Date (From)"}
value={minDate === null ? null : dayjs(minDate)}
maxDate={maxDate === null ? null : dayjs(maxDate)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setMinDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</Grid>

<Grid item xs={6}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateTo"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
label={"Submit Date (To)"}
value={maxDate === null ? null : dayjs(maxDate)}
minDate={minDate === null ? null : dayjs(minDate)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setMaxDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</Grid>
</Grid>
</Grid>
</Grid>

{/*last row*/}
<Grid container maxWidth justifyContent="flex-end">
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Grid item sx={{ ml: 3 }}>
<Button
variant="contained"
color="green"
type="submit"
disabled={waitDownload}
>
Export Summary List
</Button>
</Grid>
<Grid item sx={{ ml: 3 }}>
<Button
variant="contained"
color="cancel"
onClick={resetForm}
>
Reset
</Button>
</Grid>
</ThemeProvider>
</Grid>
</Grid>
</form>
</MainCard>
);
};

export default SummaryForm;

+ 106
- 0
src/pages/Report/index.js Voir le fichier

@@ -0,0 +1,106 @@
// material-ui
import {
Grid,
Typography,
Stack
} from '@mui/material';
import MainCard from "components/MainCard";
import * as React from "react";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
const FullListForm = Loadable(React.lazy(() => import('./FullListForm')));
const SummaryForm = Loadable(React.lazy(() => import('./SummaryForm')));
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
height: '100%',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundColor: '#0C489E',
backgroundPosition: 'right'
}

// ==============================|| DASHBOARD - DEFAULT ||============================== //

const ReportSearchPage = () => {

const [searchCriteria, setSearchCriteria] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
const [issueCombo, setIssueCombo] = React.useState([]);

React.useEffect(() => {
getIssueCombo();
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

function getIssueCombo() {
HttpUtils.get({
url: UrlUtils.GET_ISSUE_COMBO,
onSuccess: function (responseData) {
let combo = responseData;
setIssueCombo(combo);
}
});
}

React.useEffect(() => {
setOnReady(true);
}, [searchCriteria]);


return (
!onReady ?
<Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
<Grid item>
<LoadingComponent />
</Grid>
</Grid>
:
<Grid container sx={{ minHeight: '95vh',backgroundColor: 'backgroundColor.default' }} direction="column">
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Announcement</Typography>
</Stack>
</div>
</Grid>
{/*row 1*/}
<Grid item xs={12} md={12} lg={12} sx={{mb: -1}}>
<FullListForm
searchCriteria={searchCriteria}
issueComboData={issueCombo}
/>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{mb: -1}}>
<SummaryForm
searchCriteria={searchCriteria}
/>
</Grid>
{/*row 2*/}
<Grid item xs={12} md={12} lg={12}>
<MainCard elevation={0}
border={false}
content={false}
sx={{ backgroundColor: '#fff' }}
>
</MainCard>
</Grid>
</Grid>
);
}
export default ReportSearchPage;

+ 6
- 1
src/routes/GLDUserRoutes.js Voir le fichier

@@ -34,6 +34,7 @@ const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index')));
const ReconReportPage = Loadable(lazy(() => import('pages/Recon')));
const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage')));
const JVMDefault = Loadable(lazy(() => import('pages/JVM')));
const ReportPage = Loadable(lazy(() => import('pages/Report')));

// ==============================|| MAIN ROUTING ||============================== //

@@ -202,7 +203,11 @@ const GLDUserRoutes = {
{
path: '/user/changePassword',
element: <ChangePasswordPage />
}
},
{
path: '/setting/report',
element: <ReportPage />
},
]
}
]


+ 2
- 0
src/utils/ApiPathConst.js Voir le fichier

@@ -237,6 +237,8 @@ export const GEN_PAYMENT_RECEIPT = apiPath+'/payment/receipt'; //POST
export const GEN_GFMIS_XML = apiPath+'/gfmis'; //GET
export const VIEW_RECON_REPORT = apiPath+'/reportings/report'; //GET
export const GEN_RECON_REPORT = apiPath+'/reportings/download'; //GET
export const GEN_FULL_LIST = apiPath+'/application/export-full-excel'; //GET
export const GEN_SUMMARY_LIST = apiPath+'/application/export-summary-excel'; //GET

//Holiday
export const GET_HOLIDAY = apiPath+'/holiday/list'; //GET


Chargement…
Annuler
Enregistrer