Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

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