You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

260 lines
9.7 KiB

  1. import {
  2. Grid,
  3. Typography,
  4. Stack,
  5. Button,
  6. Dialog, DialogTitle, DialogContent, DialogActions,
  7. } from '@mui/material';
  8. import * as UrlUtils from "utils/ApiPathConst";
  9. import * as React from "react";
  10. import * as HttpUtils from "utils/HttpUtils";
  11. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  12. import Loadable from 'components/Loadable';
  13. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  14. import MainCard from 'components/MainCard';
  15. const ExportForm = Loadable(React.lazy(() => import('./ExportForm')));
  16. const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
  17. const GazetteIssueTable = Loadable(React.lazy(() => import('./DataGrid')));
  18. const BackgroundHead = {
  19. backgroundImage: `url(${titleBackgroundImg})`,
  20. width: '100%',
  21. height: '100%',
  22. backgroundSize: 'contain',
  23. backgroundRepeat: 'no-repeat',
  24. backgroundColor: '#0C489E',
  25. backgroundPosition: 'right'
  26. };
  27. import { PNSPS_LONG_BUTTON_THEME } from "themes/buttonConst";
  28. import { ThemeProvider } from "@emotion/react";
  29. import { dateStr_Year } from "utils/DateUtils";
  30. import { notifySaveSuccess } from 'utils/CommonFunction';
  31. import { isGrantedAny } from "auth/utils";
  32. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  33. const Index = () => {
  34. const [comboData, setComboData] = React.useState([]);
  35. const [holidayComboData, setHolidayComboData] = React.useState([]);
  36. const [onReady, setOnReady] = React.useState(false);
  37. const [onGridReady, setGridOnReady] = React.useState(false);
  38. const [onSearchReady, setOnSearchReady] = React.useState(false);
  39. const [onExportReady, setOnExportReady] = React.useState(false);
  40. const [searchCriteria, setSearchCriteria] = React.useState({
  41. year: dateStr_Year(new Date()),
  42. });
  43. const [exportCriteria, setExportCriteria] = React.useState({});
  44. const [attachments, setAttachments] = React.useState([]);
  45. const [waitImport, setWaitImport] = React.useState(false);
  46. const [waitDownload, setWaitDownload] = React.useState(false);
  47. const [isWarningPopUp, setIsWarningPopUp] = React.useState(false);
  48. const [warningText, setWarningText] = React.useState("");
  49. React.useEffect(() => {
  50. setOnSearchReady(false);
  51. loadCombo();
  52. }, [searchCriteria]);
  53. function loadCombo() {
  54. HttpUtils.get({
  55. url: UrlUtils.GET_ISSUE_YEAR_COMBO,
  56. onSuccess: (responseData) => {
  57. let combo = responseData;
  58. setComboData(combo);
  59. setOnSearchReady(true);
  60. loadHolidayCombo(true);
  61. }
  62. });
  63. }
  64. function loadHolidayCombo() {
  65. HttpUtils.get({
  66. url: UrlUtils.GET_HOLIDAY_COMBO,
  67. onSuccess: (responseData) => {
  68. let combo = responseData;
  69. setHolidayComboData(combo);
  70. setOnExportReady(true);
  71. setOnReady(true);
  72. }
  73. });
  74. }
  75. function applySearch(input) {
  76. setGridOnReady(true);
  77. setSearchCriteria(input);
  78. }
  79. function applyExport(input) {
  80. setExportCriteria(input);
  81. }
  82. function applyGridOnReady(input) {
  83. setGridOnReady(input);
  84. }
  85. React.useEffect(() => {
  86. if (Object.keys(exportCriteria).length > 0) {
  87. doExport();
  88. }
  89. }, [exportCriteria]);
  90. React.useEffect(() => {
  91. if (attachments.length > 0) {
  92. importHoliday();
  93. }
  94. }, [attachments]);
  95. const readFile = (event) => {
  96. let file = event.target.files[0];
  97. if (file) {
  98. if (!file.name.toLowerCase().endsWith(".xlsx")) {
  99. setWarningText("Please upload a valid file (File format: .xlsx).");
  100. setIsWarningPopUp(true);
  101. event.target.value = "";
  102. return;
  103. }
  104. file['id'] = attachments.length;
  105. setAttachments([...attachments, file]);
  106. event.target.value = "";
  107. }
  108. };
  109. const doExport = () => {
  110. setWaitDownload(true);
  111. HttpUtils.fileDownload({
  112. url: UrlUtils.GET_ISSUE_LIST,
  113. params: exportCriteria,
  114. onResponse: () => {
  115. setTimeout(() => setWaitDownload(false), 500);
  116. }
  117. });
  118. };
  119. const importHoliday = () => {
  120. setWaitImport(true);
  121. if (!attachments || attachments.length <= 0) {
  122. setWarningText("Please upload file.");
  123. setWaitImport(false);
  124. return;
  125. }
  126. HttpUtils.postWithFiles({
  127. url: UrlUtils.POST_ISSUE_FILE,
  128. files: attachments,
  129. onSuccess: () => {
  130. notifySaveSuccess();
  131. setWaitImport(false);
  132. setAttachments([]);
  133. loadCombo();
  134. }
  135. });
  136. };
  137. return (
  138. !onReady ?
  139. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
  140. <Grid item>
  141. <LoadingComponent />
  142. </Grid>
  143. </Grid>
  144. :
  145. (
  146. <Grid container sx={{ minHeight: '87vh', backgroundColor: 'backgroundColor.default' }} direction="column" justifyContent="flex-start" alignItems="center">
  147. <Grid item xs={12} width="100%">
  148. <div style={BackgroundHead} width="100%">
  149. <Stack direction="row" height='70px'>
  150. <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>Gazette Issue</Typography>
  151. </Stack>
  152. </div>
  153. </Grid>
  154. {!onExportReady ?
  155. <LoadingComponent /> :
  156. <Grid item xs={12} md={12} lg={12} width="100%">
  157. <ExportForm
  158. applyExport={applyExport}
  159. comboData={holidayComboData}
  160. waitDownload={waitDownload}
  161. />
  162. </Grid>
  163. }
  164. {isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) &&
  165. <Grid item xs={12} md={12} lg={6} width="100%">
  166. <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ ml: 2, mt: 1 }}>
  167. <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
  168. <Button
  169. component="label"
  170. variant="contained"
  171. size="large"
  172. disabled={waitImport}
  173. >
  174. <Typography variant="h5">Upload Files</Typography>
  175. <input
  176. id="uploadFileBtn"
  177. name="file"
  178. type="file"
  179. accept=".xlsx"
  180. hidden
  181. disabled={waitImport}
  182. onChange={readFile}
  183. aria-label="Upload Excel file (.xlsx)"
  184. />
  185. </Button>
  186. </ThemeProvider>
  187. </Stack>
  188. </Grid>
  189. }
  190. {/* Row 1 */}
  191. <Grid item xs={12} md={12} lg={12} width="100%">
  192. <SearchForm
  193. applySearch={applySearch}
  194. comboData={comboData}
  195. onGridReady={onGridReady}
  196. />
  197. </Grid>
  198. {/* Row 2 */}
  199. {!onSearchReady ?
  200. <LoadingComponent /> :
  201. <Grid item xs={12} md={12} lg={12} width="100%">
  202. <MainCard elevation={0} border={false} content={false}>
  203. <GazetteIssueTable
  204. searchCriteria={searchCriteria}
  205. applyGridOnReady={applyGridOnReady}
  206. />
  207. </MainCard>
  208. </Grid>
  209. }
  210. <Dialog
  211. open={isWarningPopUp}
  212. onClose={() => setIsWarningPopUp(false)}
  213. PaperProps={{
  214. sx: {
  215. minWidth: '40vw',
  216. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  217. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  218. }
  219. }}
  220. >
  221. <DialogTitle>
  222. <Typography variant="h3">Warning</Typography>
  223. </DialogTitle>
  224. <DialogContent style={{ display: 'flex' }}>
  225. <Typography variant="h4" style={{ padding: '16px' }}>{warningText}</Typography>
  226. </DialogContent>
  227. <DialogActions>
  228. <Button onClick={() => setIsWarningPopUp(false)}>
  229. <Typography variant="h5">OK</Typography>
  230. </Button>
  231. </DialogActions>
  232. </Dialog>
  233. </Grid>
  234. )
  235. );
  236. };
  237. export default Index;