FPSMS-frontend
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.
 
 
 

276 linhas
10 KiB

  1. "use client";
  2. import React, { useCallback, useEffect, useMemo, useState } from "react";
  3. import SearchBox, { Criterion } from "../SearchBox";
  4. import { ItemsResult } from "@/app/api/settings/item";
  5. import SearchResults, { Column } from "../SearchResults";
  6. import { EditNote } from "@mui/icons-material";
  7. import { useRouter, useSearchParams } from "next/navigation";
  8. import { GridDeleteIcon } from "@mui/x-data-grid";
  9. import { TypeEnum } from "@/app/utils/typeEnum";
  10. import axios from "axios";
  11. import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api";
  12. import { useTranslation } from "react-i18next";
  13. import axiosInstance from "@/app/(main)/axios/axiosInstance";
  14. import Qs from 'qs';
  15. import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs
  16. import { ScheduleType } from "@/app/api/scheduling";
  17. import { ProdScheduleResult, SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions";
  18. import { defaultPagingController } from "../SearchResults/SearchResults";
  19. import { arrayToDateString, decimalFormatter } from "@/app/utils/formatUtil";
  20. import dayjs from "dayjs";
  21. import { uniqBy } from "lodash";
  22. // may need move to "index" or "actions"
  23. // type RecordStructure = {
  24. // id: number,
  25. // scheduledPeriod: string,
  26. // scheduledAt: string,
  27. // productCount: number,
  28. // };
  29. type Props = {
  30. type: ScheduleType;
  31. // records: RecordStructure[];
  32. defaultInputs: SearchProdSchedule;
  33. };
  34. type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "pageSize" | "pageNum">>;
  35. type SearchParamNames = keyof SearchQuery;
  36. const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => {
  37. const [filteredSchedules, setFilteredSchedules] = useState<ProdScheduleResult[]>([]);
  38. const { t } = useTranslation("schedule");
  39. const router = useRouter();
  40. // const [filterObj, setFilterObj] = useState({});
  41. // const [tempSelectedValue, setTempSelectedValue] = useState({});
  42. const [pagingController, setPagingController] = useState(defaultPagingController)
  43. const [totalCount, setTotalCount] = useState(0)
  44. const [inputs, setInputs] = useState(defaultInputs)
  45. const typeOptions = [
  46. {
  47. value: "detailed",
  48. label: t("Detailed")
  49. },
  50. {
  51. value: "manual",
  52. label: t("Manual")
  53. },
  54. ]
  55. const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
  56. () => {
  57. var searchCriteria: Criterion<SearchParamNames>[] = [
  58. { label: t("Schedule Period"), label2: t("Schedule Period To"), paramName: "schedulePeriod", type: "dateRange" },
  59. { label: t("Production Date"), paramName: "scheduleAt", type: "date" },
  60. { label: t("Product Count"), paramName: "totalEstProdCount", type: "text" },
  61. { label: t("Type"), paramName: "types", type: "autocomplete", options: typeOptions },
  62. ]
  63. return searchCriteria
  64. },
  65. [t]
  66. );
  67. // const onDetailClick = useCallback(
  68. // (item: ItemsResult) => {
  69. // router.push(`/settings/items/edit?id=${item.id}`);
  70. // },
  71. // [router]
  72. // );
  73. // const onDeleteClick = useCallback(
  74. // (item: ItemsResult) => {},
  75. // [router]
  76. // );
  77. const onDetailClick = (record: ProdScheduleResult) => {
  78. console.log("[debug] record", record);
  79. router.push(`/scheduling/detail/edit?id=${record.id}`);
  80. }
  81. const columns = useMemo<Column<ProdScheduleResult>[]>(
  82. () => [
  83. {
  84. name: "id",
  85. label: t("Details"),
  86. onClick: (record) => onDetailClick(record),
  87. buttonIcon: <EditNote />,
  88. },
  89. {
  90. name: "schedulePeriod",
  91. label: t("Demand Forecast Period"),
  92. renderCell: (params) => {
  93. return `${arrayToDateString(params.schedulePeriod)} - ${arrayToDateString(params.schedulePeriodTo)}`
  94. }
  95. },
  96. {
  97. name: "scheduleAt",
  98. label: t("Production Date"),
  99. renderCell: (params) => {
  100. return arrayToDateString(params.scheduleAt)
  101. }
  102. },
  103. {
  104. name: "totalEstProdCount",
  105. label: t("Product Count(s)"),
  106. headerAlign: "right",
  107. align: "right",
  108. renderCell: (params) => {
  109. return decimalFormatter.format(params.totalEstProdCount)
  110. }
  111. },
  112. {
  113. name: "type",
  114. label: t("Type"),
  115. renderCell: (params) => {
  116. return t(params.type)
  117. }
  118. },
  119. // {
  120. // name: "action",
  121. // label: t(""),
  122. // buttonIcon: <GridDeleteIcon />,
  123. // onClick: onDeleteClick,
  124. // },
  125. ],
  126. [filteredSchedules]
  127. );
  128. const refetchData = useCallback(async (query: Record<SearchParamNames, string> | SearchProdSchedule, actionType: "reset" | "search" | "paging") => {
  129. // console.log(query)
  130. const defaultTypes = ["detailed", "manual"]
  131. const convertedTypes = (query.types == undefined || typeof (query.types) == "string" ? query.types?.toLowerCase() == "all" ? defaultTypes : [query.types]
  132. : query.types.some((ele) => ele.toLowerCase() === "all") ? defaultTypes : query.types) as ScheduleType[];
  133. console.log(convertedTypes)
  134. console.log(query.types)
  135. const params: SearchProdSchedule = {
  136. scheduleAt: dayjs(query?.scheduleAt).isValid() ? query?.scheduleAt : undefined,
  137. schedulePeriod: dayjs(query?.schedulePeriod).isValid() ? query?.schedulePeriod : undefined,
  138. schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined,
  139. totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined,
  140. types: convertedTypes,
  141. pageNum: pagingController.pageNum - 1,
  142. pageSize: pagingController.pageSize
  143. }
  144. const response = await fetchProdSchedules(params)
  145. // console.log(response)
  146. if (response) {
  147. setTotalCount(response.total)
  148. switch (actionType) {
  149. case "reset":
  150. case "search":
  151. setFilteredSchedules(() => response.records)
  152. break;
  153. case "paging":
  154. setFilteredSchedules((fs) => uniqBy([...fs, ...response.records], "id"))
  155. break;
  156. }
  157. }
  158. }, [pagingController, setPagingController])
  159. useEffect(() => {
  160. refetchData(inputs, "paging")
  161. }, [pagingController])
  162. // useEffect(() => {
  163. // refetchData(filterObj);
  164. // }, [filterObj, pagingController.pageNum, pagingController.pageSize]);
  165. // const refetchData = async (filterObj: SearchQuery | null) => {
  166. // const authHeader = axiosInstance.defaults.headers['Authorization'];
  167. // if (!authHeader) {
  168. // return; // Exit the function if the token is not set
  169. // }
  170. // const params = {
  171. // pageNum: pagingController.pageNum,
  172. // pageSize: pagingController.pageSize,
  173. // ...filterObj,
  174. // ...tempSelectedValue,
  175. // }
  176. // try {
  177. // const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, {
  178. // params,
  179. // paramsSerializer: (params) => {
  180. // return Qs.stringify(params, { arrayFormat: 'repeat' });
  181. // },
  182. // });
  183. // //setFilteredItems(response.data.records);
  184. // setFilteredItems([
  185. // {
  186. // id: 1,
  187. // scheduledPeriod: "2025-05-11 to 2025-05-17",
  188. // scheduledAt: "2025-05-07",
  189. // productCount: 13,
  190. // },
  191. // {
  192. // id: 2,
  193. // scheduledPeriod: "2025-05-18 to 2025-05-24",
  194. // scheduledAt: "2025-05-14",
  195. // productCount: 15,
  196. // },
  197. // {
  198. // id: 3,
  199. // scheduledPeriod: "2025-05-25 to 2025-05-31",
  200. // scheduledAt: "2025-05-21",
  201. // productCount: 13,
  202. // },
  203. // ])
  204. // setPagingController({
  205. // ...pagingController,
  206. // totalCount: response.data.total
  207. // })
  208. // return response; // Return the data from the response
  209. // } catch (error) {
  210. // console.error('Error fetching items:', error);
  211. // throw error; // Rethrow the error for further handling
  212. // }
  213. // };
  214. const onReset = useCallback(() => {
  215. //setFilteredItems(items ?? []);
  216. // setFilterObj({});
  217. // setTempSelectedValue({});
  218. refetchData(inputs, "reset");
  219. }, []);
  220. return (
  221. <>
  222. <SearchBox
  223. criteria={searchCriteria}
  224. onSearch={(query) => {
  225. setInputs(() => (
  226. {
  227. scheduleAt: query?.scheduleAt,
  228. schedulePeriod: query?.schedulePeriod,
  229. schedulePeriodTo: query?.schedulePeriodTo,
  230. totalEstProdCount: Number(query?.totalEstProdCount),
  231. types: query.types as unknown as ScheduleType[]
  232. }
  233. ))
  234. refetchData(query, "search")
  235. }}
  236. onReset={onReset}
  237. />
  238. <SearchResults<ProdScheduleResult>
  239. items={filteredSchedules}
  240. columns={columns}
  241. setPagingController={setPagingController}
  242. pagingController={pagingController}
  243. totalCount={totalCount}
  244. // isAutoPaging={false}
  245. // hasCollapse={false}
  246. />
  247. </>
  248. );
  249. };
  250. export default DSOverview;