您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

486 行
23 KiB

  1. // material-ui
  2. import {
  3. Button,
  4. Grid, TextField,
  5. Autocomplete,
  6. Typography
  7. } from '@mui/material';
  8. import MainCard from "components/MainCard";
  9. import { useForm } from "react-hook-form";
  10. import * as React from "react";
  11. import * as ComboData from "utils/ComboData";
  12. import * as DateUtils from "utils/DateUtils";
  13. import * as FormatUtils from "utils/FormatUtils";
  14. import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst";
  15. import {ThemeProvider} from "@emotion/react";
  16. import { useIntl } from "react-intl";
  17. import {DatePicker} from "@mui/x-date-pickers/DatePicker";
  18. import dayjs from "dayjs";
  19. import {DemoItem} from "@mui/x-date-pickers/internals/demo";
  20. import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
  21. import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
  22. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  23. const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady
  24. }) => {
  25. const [type, setType] = React.useState([]);
  26. const [orgSelected, setOrgSelected] = React.useState({});
  27. const [orgCombo, setOrgCombo] = React.useState();
  28. const [issueSelected, setIssueSelected] = React.useState({});
  29. const [issueCombo, setIssueCombo] = React.useState([]);
  30. const [selectedStatus, setSelectedStatus] = React.useState(ComboData.denmandNoteStatus[0]);
  31. const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
  32. const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
  33. const [fromDateValue, setFromDateValue] = React.useState(searchCriteria.dateFrom);
  34. const [toDateValue, setToDateValue] = React.useState(searchCriteria.dateTo);
  35. const [minDueDate, setMinDueDate] = React.useState(null);
  36. const [maxDueDate, setMaxDueDate] = React.useState(null);
  37. const [fromDueDateValue, setFromDueDateValue] = React.useState(null);
  38. const [toDueDateValue, setToDueDateValue] = React.useState(null);
  39. const intl = useIntl();
  40. const { locale } = intl;
  41. React.useEffect(() => {
  42. if(searchCriteria.status!=undefined){
  43. if(searchCriteria.status === ""){
  44. ComboData.denmandNoteStatus[0]
  45. }else{
  46. setSelectedStatus(ComboData.denmandNoteStatus.find(item => item.type === searchCriteria.status))
  47. }
  48. if(searchCriteria.dueDateFrom != ""){
  49. setMinDueDate(DateUtils.dateValue(searchCriteria.dueDateFrom))
  50. }else{
  51. setMinDueDate(null)
  52. }
  53. if(searchCriteria.dueDateTo != ""){
  54. setMaxDueDate(DateUtils.dateValue(searchCriteria.dueDateTo))
  55. }else{
  56. setMaxDueDate(null);
  57. }
  58. }else{
  59. setSelectedStatus(ComboData.denmandNoteStatus[0])
  60. }
  61. }, [searchCriteria]);
  62. React.useEffect(() => {
  63. setFromDateValue(minDate);
  64. }, [minDate]);
  65. React.useEffect(() => {
  66. setToDateValue(maxDate);
  67. }, [maxDate]);
  68. React.useEffect(() => {
  69. setFromDueDateValue(minDueDate);
  70. }, [minDueDate]);
  71. React.useEffect(() => {
  72. setToDueDateValue(maxDueDate);
  73. }, [maxDueDate]);
  74. const { reset, register, handleSubmit } = useForm()
  75. const onSubmit = (data) => {
  76. data.status = selectedStatus?.type;
  77. let typeArray = [];
  78. let sentDateFrom = "";
  79. let sentDateTo = "";
  80. let sentDueDateFrom = "";
  81. let sentDueDateTo = "";
  82. for (let i = 0; i < type.length; i++) {
  83. typeArray.push(type[i].label);
  84. }
  85. if (fromDateValue != "dd / mm / yyyy" && toDateValue != "dd / mm / yyyy") {
  86. sentDateFrom = DateUtils.dateValue(fromDateValue)
  87. sentDateTo = DateUtils.dateValue(toDateValue)
  88. }
  89. if (fromDueDateValue != "dd / mm / yyyy" && toDueDateValue != "dd / mm / yyyy") {
  90. sentDueDateFrom = DateUtils.dateValue(fromDueDateValue)
  91. sentDueDateTo = DateUtils.dateValue(toDueDateValue)
  92. }
  93. const temp = {
  94. appNo: data.appNo,
  95. issueId: issueSelected?.id,
  96. orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "",
  97. dnNo: data.dnNo,
  98. dateFrom: sentDateFrom,
  99. dateTo: sentDateTo,
  100. dueDateFrom: sentDueDateFrom,
  101. dueDateTo: sentDueDateTo,
  102. status: (data?.status === '' || data?.status?.includes("all")) ? "" : data.status,
  103. start:0,
  104. limit:10
  105. };
  106. applySearch(temp);
  107. };
  108. React.useEffect(() => {
  109. if (orgComboData && orgComboData.length > 0) {
  110. setOrgCombo(orgComboData);
  111. if(searchCriteria.orgId!=undefined){
  112. setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId))
  113. }
  114. }
  115. }, [orgComboData]);
  116. React.useEffect(() => {
  117. if (issueComboData && issueComboData.length > 0) {
  118. setIssueCombo(issueComboData);
  119. if(searchCriteria.issueId!=undefined){
  120. setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
  121. }
  122. }
  123. }, [issueComboData]);
  124. function resetForm() {
  125. setType([]);
  126. setOrgSelected({});
  127. setIssueSelected({});
  128. setSelectedStatus(ComboData.denmandNoteStatus[0]);
  129. setMinDueDate(null);
  130. setMaxDueDate(null);
  131. setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
  132. setMaxDate(DateUtils.dateValue(new Date()))
  133. reset({
  134. appNo:"",
  135. dnNo:"",
  136. });
  137. localStorage.setItem('searchCriteria',"")
  138. }
  139. function getIssueLabel(data) {
  140. let issueYear = data.issueYear
  141. let volume = data.volume;
  142. let issueNo = data.issueNo;
  143. let issueDate = data.issueDate;
  144. if (locale === 'zh-HK') {
  145. return issueYear
  146. + " 第" + volume + "卷,"
  147. + " 第" + issueNo + "期,"
  148. + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日")
  149. + " (" + DateUtils.getWeekdayStr_ZH(issueDate) + ")";
  150. } else if (locale === 'zh-CN') {
  151. return issueYear
  152. + " 第" + volume + "卷,"
  153. + " 第" + issueNo + "期,"
  154. + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日")
  155. + " (" + DateUtils.getWeekdayStr_CN(issueDate) + ")";
  156. }
  157. return issueYear
  158. + " Vol. " + FormatUtils.zeroPad(volume, 3)
  159. + ", No. " + FormatUtils.zeroPad(issueNo, 2)
  160. + ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)");
  161. }
  162. return (
  163. <MainCard xs={12} md={12} lg={12}
  164. border={false}
  165. content={false}
  166. sx={{ backgroundColor: '#fff' }}
  167. >
  168. <form onSubmit={handleSubmit(onSubmit)}>
  169. <Grid container sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1 }} width="98%">
  170. {/*row 1*/}
  171. <Grid item justifyContent="space-between" alignItems="center" sx={{mt:1, ml:3,mb:2.5}}>
  172. <Typography variant="pnspsFormHeader" >
  173. Search
  174. </Typography>
  175. </Grid>
  176. {/*row 2*/}
  177. <Grid container display="flex" alignItems={"center"}>
  178. <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  179. <Autocomplete
  180. {...register("issueId")}
  181. disablePortal
  182. id="issueId"
  183. size="small"
  184. options={issueCombo}
  185. value={issueSelected}
  186. inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""}
  187. getOptionLabel={(option) => getIssueLabel(option)}
  188. onChange={(event, newValue) => {
  189. setIssueSelected(newValue);
  190. }}
  191. sx={{
  192. '& .MuiInputBase-root': { alignItems: 'center' },
  193. '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' },
  194. '& .MuiOutlinedInput-root': { height: 40 }
  195. }}
  196. renderInput={(params) => (
  197. <TextField {...params}
  198. label="Gazette Issue No."
  199. InputLabelProps={{
  200. shrink: true
  201. }}
  202. />
  203. )}
  204. />
  205. </Grid>
  206. <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  207. <TextField
  208. fullWidth
  209. {...register("appNo")}
  210. id='appNo'
  211. label={"Application No."}
  212. defaultValue={searchCriteria.appNo}
  213. InputLabelProps={{
  214. shrink: true
  215. }}
  216. />
  217. </Grid>
  218. {
  219. orgCombo ?
  220. <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  221. <Autocomplete
  222. {...register("orgId")}
  223. disablePortal
  224. id="orgId"
  225. options={orgCombo}
  226. groupBy={(option) => option.groupType}
  227. size="small"
  228. value={orgSelected}
  229. getOptionLabel={(option) => option.name? option.name : ""}
  230. inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""}
  231. onChange={(event, newValue) => {
  232. if (newValue !== null) {
  233. setOrgSelected(newValue);
  234. }else{
  235. setOrgSelected({});
  236. }
  237. }}
  238. sx={{
  239. '& .MuiInputBase-root': { alignItems: 'center' },
  240. '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' },
  241. '& .MuiOutlinedInput-root': { height: 40 }
  242. }}
  243. renderInput={(params) => (
  244. <TextField {...params}
  245. label="Organisation"
  246. InputLabelProps={{
  247. shrink: true
  248. }}
  249. />
  250. )}
  251. renderGroup={(params) => (
  252. <Grid item key={params.key}>
  253. <Typography fontSize={20} fontStyle="italic" p={1}>
  254. {params.group}
  255. </Typography>
  256. {params.children}
  257. </Grid>
  258. )}
  259. />
  260. </Grid>
  261. : <></>
  262. }
  263. <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  264. <TextField
  265. fullWidth
  266. {...register("dnNo")}
  267. id='dnNo'
  268. label="DN No."
  269. defaultValue={searchCriteria.dnNo}
  270. InputLabelProps={{
  271. shrink: true
  272. }}
  273. />
  274. </Grid>
  275. <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
  276. <Grid container spacing={1}>
  277. <Grid item xs={6}>
  278. <LocalizationProvider dateAdapter={AdapterDayjs}>
  279. <DemoItem components={['DatePicker']}>
  280. <DatePicker
  281. id="dateFrom"
  282. // onError={(newError) => setReceiptFromError(newError)}
  283. slotProps={{
  284. field: { readOnly: true, },
  285. // textField: {
  286. // helperText: receiptFromErrorMessage,
  287. // },
  288. }}
  289. format="DD/MM/YYYY"
  290. label={"Issue Date (From)"}
  291. value={minDate === null ? null : dayjs(minDate)}
  292. maxDate={maxDate === null ? null : dayjs(maxDate)}
  293. onChange={(newValue) => {
  294. // console.log(newValue)
  295. if(newValue!=null){
  296. setMinDate(newValue);
  297. }
  298. }}
  299. />
  300. </DemoItem >
  301. </LocalizationProvider>
  302. </Grid>
  303. <Grid item xs={6}>
  304. <LocalizationProvider dateAdapter={AdapterDayjs}>
  305. <DemoItem components={['DatePicker']}>
  306. <DatePicker
  307. id="dateTo"
  308. // onError={(newError) => setReceiptFromError(newError)}
  309. slotProps={{
  310. field: { readOnly: true, },
  311. // textField: {
  312. // helperText: receiptFromErrorMessage,
  313. // },
  314. }}
  315. format="DD/MM/YYYY"
  316. label={"Issue Date (To)"}
  317. value={maxDate === null ? null : dayjs(maxDate)}
  318. minDate={minDate === null ? null : dayjs(minDate)}
  319. onChange={(newValue) => {
  320. // console.log(newValue)
  321. if(newValue!=null){
  322. setMaxDate(newValue);
  323. }
  324. }}
  325. />
  326. </DemoItem >
  327. </LocalizationProvider>
  328. </Grid>
  329. </Grid>
  330. </Grid>
  331. <Grid item xs={9} s={6} md={6} lg={3.5} sx={{ml:3, mr:2, mb:3}}>
  332. <Grid container spacing={1}>
  333. <Grid item xs={6}>
  334. <LocalizationProvider dateAdapter={AdapterDayjs}>
  335. <DemoItem components={['DatePicker']}>
  336. <DatePicker
  337. id="dueDateFrom"
  338. // onError={(newError) => setReceiptFromError(newError)}
  339. slotProps={{
  340. field: { readOnly: true, },
  341. textField: {
  342. // helperText: receiptFromErrorMessage,
  343. InputLabelProps: { shrink: true }
  344. },
  345. }}
  346. format="DD/MM/YYYY"
  347. label={"Due Date (From)"}
  348. value={minDueDate === null ? null : dayjs(minDueDate)}
  349. maxDate={maxDueDate === null ? null : dayjs(maxDueDate)}
  350. onChange={(newValue) => {
  351. // console.log(newValue)
  352. setMinDueDate(newValue);
  353. }}
  354. />
  355. </DemoItem >
  356. </LocalizationProvider>
  357. </Grid>
  358. <Grid item xs={6}>
  359. <LocalizationProvider dateAdapter={AdapterDayjs}>
  360. <DemoItem components={['DatePicker']}>
  361. <DatePicker
  362. id="dueDateTo"
  363. // onError={(newError) => setReceiptFromError(newError)}
  364. slotProps={{
  365. field: { readOnly: true, },
  366. textField: {
  367. // helperText: receiptFromErrorMessage,
  368. InputLabelProps: { shrink: true }
  369. },
  370. }}
  371. format="DD/MM/YYYY"
  372. label={"Due Date (To)"}
  373. value={maxDueDate === null ? null : dayjs(maxDueDate)}
  374. minDate={minDueDate === null ? null : dayjs(minDueDate)}
  375. onChange={(newValue) => {
  376. // console.log(newValue)
  377. setMaxDueDate(newValue);
  378. }}
  379. />
  380. </DemoItem >
  381. </LocalizationProvider>
  382. </Grid>
  383. </Grid>
  384. </Grid>
  385. <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  386. <Autocomplete
  387. size="small"
  388. {...register("status")}
  389. id="status"
  390. options={ComboData.denmandNoteStatus}
  391. value={selectedStatus}
  392. onChange={(event, newValue) => {
  393. if(newValue==null){
  394. setSelectedStatus(ComboData.denmandNoteStatus[0]);
  395. }else{
  396. setSelectedStatus(newValue);
  397. }
  398. }}
  399. sx={{
  400. '& .MuiInputBase-root': { alignItems: 'center' },
  401. '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' },
  402. '& .MuiOutlinedInput-root': { height: 40 }
  403. }}
  404. getOptionLabel={(option) => option.label}
  405. renderInput={(params) => (
  406. <TextField
  407. {...params}
  408. label="Status"
  409. InputLabelProps={{
  410. shrink: true
  411. }}
  412. />
  413. )}
  414. />
  415. </Grid>
  416. </Grid>
  417. {/*last row*/}
  418. <Grid container maxWidth justifyContent="flex-end">
  419. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  420. <Grid item sx={{ ml: 3, mb:3 }}>
  421. <Button
  422. variant="contained"
  423. color="cancel"
  424. onClick={resetForm}
  425. >
  426. Reset
  427. </Button>
  428. </Grid>
  429. <Grid item sx={{ ml: 3, mr: 3, mb:3}}>
  430. <Button
  431. variant="contained"
  432. type="submit"
  433. disabled={onGridReady}
  434. >
  435. Submit
  436. </Button>
  437. </Grid>
  438. </ThemeProvider>
  439. </Grid>
  440. </Grid>
  441. </form>
  442. </MainCard>
  443. );
  444. };
  445. export default SearchDemandNoteForm;