# Conflicts: # src/components/DetailScheduleDetail/DetailScheudleDetailView.tsxmaster
@@ -2,7 +2,6 @@ | |||||
// import DetailSchedule from "@/components/DetailSchedule"; | // import DetailSchedule from "@/components/DetailSchedule"; | ||||
// import { getServerI18n } from "@/i18n"; | // import { getServerI18n } from "@/i18n"; | ||||
import { TypeEnum } from "../../../../app/utils/typeEnum"; | |||||
import DetailSchedule from "../../../../components/DetailSchedule"; | import DetailSchedule from "../../../../components/DetailSchedule"; | ||||
import { getServerI18n } from "../../../../i18n"; | import { getServerI18n } from "../../../../i18n"; | ||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
@@ -16,8 +15,8 @@ export const metadata: Metadata = { | |||||
}; | }; | ||||
const DetailScheduling: React.FC = async () => { | const DetailScheduling: React.FC = async () => { | ||||
const project = TypeEnum.PRODUCT | |||||
const { t } = await getServerI18n("detailScheduling"); | |||||
const { t } = await getServerI18n("schedule"); | |||||
const type = "detailed" | |||||
// preloadClaims(); | // preloadClaims(); | ||||
return ( | return ( | ||||
@@ -32,9 +31,9 @@ const DetailScheduling: React.FC = async () => { | |||||
{t("Detail Scheduling")} | {t("Detail Scheduling")} | ||||
</Typography> | </Typography> | ||||
</Stack> | </Stack> | ||||
<I18nProvider namespaces={["detailScheduling", "items", "common","schedule"]}> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<DetailSchedule.Loading />}> | <Suspense fallback={<DetailSchedule.Loading />}> | ||||
<DetailSchedule /> | |||||
<DetailSchedule type={type}/> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -1,6 +1,7 @@ | |||||
// import { TypeEnum } from "@/app/utils/typeEnum"; | // import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
// import RoughSchedule from "@/components/RoughSchedule"; | // import RoughSchedule from "@/components/RoughSchedule"; | ||||
// import { getServerI18n, I18nProvider } from "@/i18n"; | // import { getServerI18n, I18nProvider } from "@/i18n"; | ||||
import { testRoughSchedule } from "@/app/api/scheduling/actions"; | |||||
import { TypeEnum } from "../../../../app/utils/typeEnum"; | import { TypeEnum } from "../../../../app/utils/typeEnum"; | ||||
import RoughSchedule from "../../../../components/RoughSchedule"; | import RoughSchedule from "../../../../components/RoughSchedule"; | ||||
import { getServerI18n, I18nProvider } from "../../../../i18n"; | import { getServerI18n, I18nProvider } from "../../../../i18n"; | ||||
@@ -22,6 +23,10 @@ const roughScheduling: React.FC = async () => { | |||||
const type = "rough" | const type = "rough" | ||||
// preloadClaims(); | // preloadClaims(); | ||||
// async function testingRoughSchedule() { | |||||
// await testRoughSchedule(); | |||||
// } | |||||
return ( | return ( | ||||
<> | <> | ||||
<Stack | <Stack | ||||
@@ -33,19 +38,18 @@ const roughScheduling: React.FC = async () => { | |||||
<Typography variant="h4" marginInlineEnd={2}> | <Typography variant="h4" marginInlineEnd={2}> | ||||
{t("Demand Forecast")} | {t("Demand Forecast")} | ||||
</Typography> | </Typography> | ||||
{/* <Button | {/* <Button | ||||
variant="contained" | |||||
startIcon={<Add />} | |||||
LinkComponent={Link} | |||||
href="product/create" | |||||
> | |||||
{t("Create product")} | |||||
</Button> */} | |||||
variant="contained" | |||||
startIcon={<Add />} | |||||
onClick={() => testingRoughSchedule} | |||||
> | |||||
{t("Test Rough Scheduling")} | |||||
</Button> */} | |||||
</Stack> | </Stack> | ||||
<I18nProvider namespaces={["schedule", "common","items","project"]}> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<RoughSchedule.Loading />}> | <Suspense fallback={<RoughSchedule.Loading />}> | ||||
<RoughSchedule type={type}/> | |||||
<RoughSchedule type={type} /> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -4,13 +4,14 @@ import { convertObjToURLSearchParams } from "@/app/utils/commonUtil"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil" | import { serverFetchJson } from "@/app/utils/fetchUtil" | ||||
import { BASE_API_URL } from "@/config/api" | import { BASE_API_URL } from "@/config/api" | ||||
import { cache } from "react" | import { cache } from "react" | ||||
import { ScheduleType } from "."; | |||||
export interface SearchProdSchedule { | export interface SearchProdSchedule { | ||||
scheduleAt?: string; | scheduleAt?: string; | ||||
schedulePeriod?: string; | schedulePeriod?: string; | ||||
schedulePeriodTo?: string; | schedulePeriodTo?: string; | ||||
totalEstProdCount?: number; | totalEstProdCount?: number; | ||||
type?: "manual" | "detailed" | "rough"; | |||||
types?: ScheduleType[]; | |||||
pageSize?: number; | pageSize?: number; | ||||
pageNum?: number; | pageNum?: number; | ||||
} | } | ||||
@@ -40,4 +41,24 @@ export const fetchProdSchedules = cache(async (data: SearchProdSchedule | null) | |||||
tags: ["prodSchedules"] | tags: ["prodSchedules"] | ||||
} | } | ||||
}) | }) | ||||
}) | |||||
export const testRoughSchedule = cache(async () => { | |||||
return serverFetchJson(`${BASE_API_URL}/productionSchedule/testRoughSchedule`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) | |||||
export const testDetailSchedule = cache(async () => { | |||||
return serverFetchJson(`${BASE_API_URL}/productionSchedule/testDetailSchedule`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) | }) |
@@ -3,9 +3,9 @@ import { BASE_API_URL } from "@/config/api" | |||||
import { cache } from "react" | import { cache } from "react" | ||||
import "server-only" | import "server-only" | ||||
export type ScheduleType = "rough" | "detail"; | |||||
export type ScheduleType = "all" | "rough" | "detailed" | "manual"; | |||||
export interface ProdScheduleResult { | |||||
export interface RoughProdScheduleResult { | |||||
id: number; | id: number; | ||||
scheduleAt: number[]; | scheduleAt: number[]; | ||||
schedulePeriod: number[]; | schedulePeriod: number[]; | ||||
@@ -13,13 +13,13 @@ export interface ProdScheduleResult { | |||||
totalEstProdCount: number; | totalEstProdCount: number; | ||||
totalFGType: number; | totalFGType: number; | ||||
type: string; | type: string; | ||||
prodScheduleLinesByFg: ProdScheduleLineResultByFg[]; | |||||
prodScheduleLinesByFgByDate: { [assignDate: number]: ProdScheduleLineResultByFg[] }; | |||||
prodScheduleLinesByBom: ProdScheduleLineResultByBom[]; | |||||
prodScheduleLinesByBomByDate: { [assignDate: number]: ProdScheduleLineResultByBomByDate[] }; | |||||
prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; | |||||
prodScheduleLinesByFgByDate: { [assignDate: number]: RoughProdScheduleLineResultByFg[] }; | |||||
prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; | |||||
prodScheduleLinesByBomByDate: { [assignDate: number]: RoughProdScheduleLineResultByBomByDate[] }; | |||||
} | } | ||||
export interface ProdScheduleLineResultByFg { | |||||
export interface RoughProdScheduleLineResultByFg { | |||||
id: number; | id: number; | ||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
@@ -30,10 +30,10 @@ export interface ProdScheduleLineResultByFg { | |||||
estCloseBal: number; | estCloseBal: number; | ||||
priority: number; | priority: number; | ||||
assignDate: number; | assignDate: number; | ||||
bomMaterials: ProdScheduleLineBomMaterialResult[]; | |||||
bomMaterials: RoughProdScheduleLineBomMaterialResult[]; | |||||
} | } | ||||
export interface ProdScheduleLineBomMaterialResult { | |||||
export interface RoughProdScheduleLineBomMaterialResult { | |||||
id: number; | id: number; | ||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
@@ -43,7 +43,7 @@ export interface ProdScheduleLineBomMaterialResult { | |||||
uomName: string; | uomName: string; | ||||
} | } | ||||
export interface ProdScheduleLineResultByBom { | |||||
export interface RoughProdScheduleLineResultByBom { | |||||
id: number, | id: number, | ||||
code: string, | code: string, | ||||
name: string, | name: string, | ||||
@@ -60,7 +60,7 @@ export interface ProdScheduleLineResultByBom { | |||||
uomName: string, | uomName: string, | ||||
} | } | ||||
export interface ProdScheduleLineResultByBomByDate { | |||||
export interface RoughProdScheduleLineResultByBomByDate { | |||||
id: number, | id: number, | ||||
code: string, | code: string, | ||||
name: string, | name: string, | ||||
@@ -72,7 +72,7 @@ export interface ProdScheduleLineResultByBomByDate { | |||||
} | } | ||||
export const fetchProdScheduleDetail = cache(async (id: number) => { | export const fetchProdScheduleDetail = cache(async (id: number) => { | ||||
return serverFetchJson<ProdScheduleResult>(`${BASE_API_URL}/productionSchedule/detail/${id}`, { | |||||
return serverFetchJson<RoughProdScheduleResult>(`${BASE_API_URL}/productionSchedule/detail/${id}`, { | |||||
method: "GET", | method: "GET", | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
next: { | next: { | ||||
@@ -1,67 +1,75 @@ | |||||
"use client"; | "use client"; | ||||
import React, {useCallback, useEffect, useMemo, useState} from "react"; | |||||
import React, { useCallback, useEffect, useMemo, useState } from "react"; | |||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import { ItemsResult} from "@/app/api/settings/item"; | |||||
import { ItemsResult } from "@/app/api/settings/item"; | |||||
import SearchResults, { Column } from "../SearchResults"; | import SearchResults, { Column } from "../SearchResults"; | ||||
import { EditNote } from "@mui/icons-material"; | import { EditNote } from "@mui/icons-material"; | ||||
import { useRouter, useSearchParams } from "next/navigation"; | import { useRouter, useSearchParams } from "next/navigation"; | ||||
import { GridDeleteIcon } from "@mui/x-data-grid"; | import { GridDeleteIcon } from "@mui/x-data-grid"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
import axios from "axios"; | import axios from "axios"; | ||||
import {BASE_API_URL, NEXT_PUBLIC_API_URL} from "@/config/api"; | |||||
import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import axiosInstance from "@/app/(main)/axios/axiosInstance"; | import axiosInstance from "@/app/(main)/axios/axiosInstance"; | ||||
import Qs from 'qs'; | import Qs from 'qs'; | ||||
import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs | import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs | ||||
import { ScheduleType } from "@/app/api/scheduling"; | |||||
import { ProdScheduleResult, SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | |||||
import { defaultPagingController } from "../SearchResults/SearchResults"; | |||||
import { arrayToDateString, decimalFormatter } from "@/app/utils/formatUtil"; | |||||
import dayjs from "dayjs"; | |||||
import { uniqBy } from "lodash"; | |||||
// may need move to "index" or "actions" | // may need move to "index" or "actions" | ||||
type RecordStructure = { | |||||
id: number, | |||||
scheduledPeriod: string, | |||||
scheduledAt: string, | |||||
productCount: number, | |||||
}; | |||||
// type RecordStructure = { | |||||
// id: number, | |||||
// scheduledPeriod: string, | |||||
// scheduledAt: string, | |||||
// productCount: number, | |||||
// }; | |||||
type Props = { | type Props = { | ||||
records: RecordStructure[]; | |||||
type: ScheduleType; | |||||
// records: RecordStructure[]; | |||||
defaultInputs: SearchProdSchedule; | |||||
}; | }; | ||||
type SearchQuery = Partial<Omit<RecordStructure, "id">>; | |||||
type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "pageSize" | "pageNum">>; | |||||
type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
const DSOverview: React.FC<Props> = ({ records }) => { | |||||
const [filteredItems, setFilteredItems] = useState<RecordStructure[]>(records ?? []); | |||||
const { t } = useTranslation("detailScheduling"); | |||||
const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||||
const [filteredSchedules, setFilteredSchedules] = useState<ProdScheduleResult[]>([]); | |||||
const { t } = useTranslation("schedule"); | |||||
const router = useRouter(); | const router = useRouter(); | ||||
const [filterObj, setFilterObj] = useState({}); | |||||
const [tempSelectedValue, setTempSelectedValue] = useState({}); | |||||
const [pagingController, setPagingController] = useState({ | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
totalCount: 0, | |||||
}) | |||||
const [mode, redirPath] = useMemo(() => { | |||||
// var typeId = TypeEnum.CONSUMABLE_ID | |||||
let title = ""; | |||||
const mode = "Search"; | |||||
let redirPath = ""; | |||||
title = "Product"; | |||||
redirPath = "/scheduling/detail"; | |||||
return [mode, redirPath]; | |||||
}, []); | |||||
// const [filterObj, setFilterObj] = useState({}); | |||||
// const [tempSelectedValue, setTempSelectedValue] = useState({}); | |||||
const [pagingController, setPagingController] = useState(defaultPagingController) | |||||
const [totalCount, setTotalCount] = useState(0) | |||||
const [inputs, setInputs] = useState(defaultInputs) | |||||
const typeOptions = [ | |||||
{ | |||||
value: "detailed", | |||||
label: t("Detailed") | |||||
}, | |||||
{ | |||||
value: "manual", | |||||
label: t("Manual") | |||||
}, | |||||
] | |||||
const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | ||||
() => | |||||
[ | |||||
{ label: t("Schedule Period"), paramName: "scheduledPeriod", type: "dateRange" }, | |||||
{ label: t("Scheduled At"), paramName: "scheduledAt", type: "dateRange" }, | |||||
{ label: t("Product Count"), paramName: "productCount", type: "text" }, | |||||
() => { | |||||
var searchCriteria: Criterion<SearchParamNames>[] = [ | |||||
{ label: t("Schedule Period"), label2: t("Schedule Period To"), paramName: "schedulePeriod", type: "dateRange" }, | |||||
{ label: t("Production Date"), paramName: "scheduleAt", type: "date" }, | |||||
{ label: t("Product Count"), paramName: "totalEstProdCount", type: "text" }, | |||||
{ label: t("Type"), paramName: "types", type: "autocomplete", options: typeOptions }, | |||||
] | ] | ||||
, | |||||
[t, records] | |||||
return searchCriteria | |||||
}, | |||||
[t] | |||||
); | ); | ||||
// const onDetailClick = useCallback( | // const onDetailClick = useCallback( | ||||
@@ -71,36 +79,54 @@ const DSOverview: React.FC<Props> = ({ records }) => { | |||||
// [router] | // [router] | ||||
// ); | // ); | ||||
const onDeleteClick = useCallback( | |||||
(item: ItemsResult) => {}, | |||||
[router] | |||||
); | |||||
// const onDeleteClick = useCallback( | |||||
// (item: ItemsResult) => {}, | |||||
// [router] | |||||
// ); | |||||
const onDetailClick = (record: any) => { | |||||
const onDetailClick = (record: ProdScheduleResult) => { | |||||
console.log("[debug] record", record); | console.log("[debug] record", record); | ||||
router.push(`/scheduling/detail/edit?id=${record.id}`); | router.push(`/scheduling/detail/edit?id=${record.id}`); | ||||
} | } | ||||
const columns = useMemo<Column<RecordStructure>[]>( | |||||
const columns = useMemo<Column<ProdScheduleResult>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
name: "id", | name: "id", | ||||
label: t("Details"), | label: t("Details"), | ||||
onClick: (record)=>onDetailClick(record), | |||||
onClick: (record) => onDetailClick(record), | |||||
buttonIcon: <EditNote />, | buttonIcon: <EditNote />, | ||||
}, | }, | ||||
{ | { | ||||
name: "scheduledPeriod", | |||||
name: "schedulePeriod", | |||||
label: t("Demand Forecast Period"), | label: t("Demand Forecast Period"), | ||||
renderCell: (params) => { | |||||
return `${arrayToDateString(params.schedulePeriod)} - ${arrayToDateString(params.schedulePeriodTo)}` | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
name: "scheduledAt", | |||||
label: t("Scheduled At"), | |||||
name: "scheduleAt", | |||||
label: t("Production Date"), | |||||
renderCell: (params) => { | |||||
return arrayToDateString(params.scheduleAt) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
name: "productCount", | |||||
name: "totalEstProdCount", | |||||
label: t("Product Count(s)"), | label: t("Product Count(s)"), | ||||
headerAlign: "right", | |||||
align: "right", | |||||
renderCell: (params) => { | |||||
return decimalFormatter.format(params.totalEstProdCount) | |||||
} | |||||
}, | |||||
{ | |||||
name: "type", | |||||
label: t("Type"), | |||||
renderCell: (params) => { | |||||
return t(params.type) | |||||
} | |||||
}, | }, | ||||
// { | // { | ||||
// name: "action", | // name: "action", | ||||
@@ -109,92 +135,138 @@ const DSOverview: React.FC<Props> = ({ records }) => { | |||||
// onClick: onDeleteClick, | // onClick: onDeleteClick, | ||||
// }, | // }, | ||||
], | ], | ||||
[filteredItems] | |||||
[filteredSchedules] | |||||
); | ); | ||||
const refetchData = useCallback(async (query: Record<SearchParamNames, string> | SearchProdSchedule, actionType: "reset" | "search" | "paging") => { | |||||
// console.log(query) | |||||
const defaultTypes = ["detailed", "manual"] | |||||
const convertedTypes = (query.types == undefined || typeof (query.types) == "string" ? query.types?.toLowerCase() == "all" ? defaultTypes : [query.types] | |||||
: query.types.some((ele) => ele.toLowerCase() === "all") ? defaultTypes : query.types) as ScheduleType[]; | |||||
console.log(convertedTypes) | |||||
console.log(query.types) | |||||
const params: SearchProdSchedule = { | |||||
scheduleAt: dayjs(query?.scheduleAt).isValid() ? query?.scheduleAt : undefined, | |||||
schedulePeriod: dayjs(query?.schedulePeriod).isValid() ? query?.schedulePeriod : undefined, | |||||
schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined, | |||||
totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined, | |||||
types: convertedTypes, | |||||
pageNum: pagingController.pageNum - 1, | |||||
pageSize: pagingController.pageSize | |||||
} | |||||
const response = await fetchProdSchedules(params) | |||||
// console.log(response) | |||||
if (response) { | |||||
setTotalCount(response.total) | |||||
switch (actionType) { | |||||
case "reset": | |||||
case "search": | |||||
setFilteredSchedules(() => response.records) | |||||
break; | |||||
case "paging": | |||||
setFilteredSchedules((fs) => uniqBy([...fs, ...response.records], "id")) | |||||
break; | |||||
} | |||||
} | |||||
}, [pagingController, setPagingController]) | |||||
useEffect(() => { | useEffect(() => { | ||||
refetchData(filterObj); | |||||
refetchData(inputs, "paging") | |||||
}, [pagingController]) | |||||
}, [filterObj, pagingController.pageNum, pagingController.pageSize]); | |||||
// useEffect(() => { | |||||
// refetchData(filterObj); | |||||
const refetchData = async (filterObj: SearchQuery | null) => { | |||||
// }, [filterObj, pagingController.pageNum, pagingController.pageSize]); | |||||
const authHeader = axiosInstance.defaults.headers['Authorization']; | |||||
if (!authHeader) { | |||||
return; // Exit the function if the token is not set | |||||
} | |||||
// const refetchData = async (filterObj: SearchQuery | null) => { | |||||
const params ={ | |||||
pageNum: pagingController.pageNum, | |||||
pageSize: pagingController.pageSize, | |||||
...filterObj, | |||||
...tempSelectedValue, | |||||
} | |||||
// const authHeader = axiosInstance.defaults.headers['Authorization']; | |||||
// if (!authHeader) { | |||||
// return; // Exit the function if the token is not set | |||||
// } | |||||
try { | |||||
const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { | |||||
params, | |||||
paramsSerializer: (params) => { | |||||
return Qs.stringify(params, { arrayFormat: 'repeat' }); | |||||
}, | |||||
}); | |||||
//setFilteredItems(response.data.records); | |||||
setFilteredItems([ | |||||
{ | |||||
id: 1, | |||||
scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
scheduledAt: "2025-05-07", | |||||
productCount: 13, | |||||
}, | |||||
{ | |||||
id: 2, | |||||
scheduledPeriod: "2025-05-18 to 2025-05-24", | |||||
scheduledAt: "2025-05-14", | |||||
productCount: 15, | |||||
}, | |||||
{ | |||||
id: 3, | |||||
scheduledPeriod: "2025-05-25 to 2025-05-31", | |||||
scheduledAt: "2025-05-21", | |||||
productCount: 13, | |||||
}, | |||||
]) | |||||
setPagingController({ | |||||
...pagingController, | |||||
totalCount: response.data.total | |||||
}) | |||||
return response; // Return the data from the response | |||||
} catch (error) { | |||||
console.error('Error fetching items:', error); | |||||
throw error; // Rethrow the error for further handling | |||||
} | |||||
}; | |||||
// const params = { | |||||
// pageNum: pagingController.pageNum, | |||||
// pageSize: pagingController.pageSize, | |||||
// ...filterObj, | |||||
// ...tempSelectedValue, | |||||
// } | |||||
// try { | |||||
// const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { | |||||
// params, | |||||
// paramsSerializer: (params) => { | |||||
// return Qs.stringify(params, { arrayFormat: 'repeat' }); | |||||
// }, | |||||
// }); | |||||
// //setFilteredItems(response.data.records); | |||||
// setFilteredItems([ | |||||
// { | |||||
// id: 1, | |||||
// scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
// scheduledAt: "2025-05-07", | |||||
// productCount: 13, | |||||
// }, | |||||
// { | |||||
// id: 2, | |||||
// scheduledPeriod: "2025-05-18 to 2025-05-24", | |||||
// scheduledAt: "2025-05-14", | |||||
// productCount: 15, | |||||
// }, | |||||
// { | |||||
// id: 3, | |||||
// scheduledPeriod: "2025-05-25 to 2025-05-31", | |||||
// scheduledAt: "2025-05-21", | |||||
// productCount: 13, | |||||
// }, | |||||
// ]) | |||||
// setPagingController({ | |||||
// ...pagingController, | |||||
// totalCount: response.data.total | |||||
// }) | |||||
// return response; // Return the data from the response | |||||
// } catch (error) { | |||||
// console.error('Error fetching items:', error); | |||||
// throw error; // Rethrow the error for further handling | |||||
// } | |||||
// }; | |||||
const onReset = useCallback(() => { | const onReset = useCallback(() => { | ||||
//setFilteredItems(items ?? []); | //setFilteredItems(items ?? []); | ||||
setFilterObj({}); | |||||
setTempSelectedValue({}); | |||||
refetchData(null); | |||||
}, [records]); | |||||
// setFilterObj({}); | |||||
// setTempSelectedValue({}); | |||||
refetchData(inputs, "reset"); | |||||
}, []); | |||||
return ( | return ( | ||||
<> | <> | ||||
<SearchBox | <SearchBox | ||||
criteria={searchCriteria} | criteria={searchCriteria} | ||||
onSearch={(query) => { | onSearch={(query) => { | ||||
setFilterObj({ | |||||
...query | |||||
}) | |||||
setInputs(() => ( | |||||
{ | |||||
scheduleAt: query?.scheduleAt, | |||||
schedulePeriod: query?.schedulePeriod, | |||||
schedulePeriodTo: query?.schedulePeriodTo, | |||||
totalEstProdCount: Number(query?.totalEstProdCount), | |||||
types: query.types as unknown as ScheduleType[] | |||||
} | |||||
)) | |||||
refetchData(query, "search") | |||||
}} | }} | ||||
onReset={onReset} | onReset={onReset} | ||||
/> | /> | ||||
<SearchResults<RecordStructure> | |||||
items={filteredItems} | |||||
<SearchResults<ProdScheduleResult> | |||||
items={filteredSchedules} | |||||
columns={columns} | columns={columns} | ||||
setPagingController={setPagingController} | setPagingController={setPagingController} | ||||
pagingController={pagingController} | pagingController={pagingController} | ||||
isAutoPaging={false} | |||||
// hasCollapse={false} | |||||
totalCount={totalCount} | |||||
// isAutoPaging={false} | |||||
// hasCollapse={false} | |||||
/> | /> | ||||
</> | </> | ||||
); | ); | ||||
@@ -1,14 +1,26 @@ | |||||
import React from "react"; | import React from "react"; | ||||
import {DetailScheduleLoading} from "./DetailScheduleLoading"; | import {DetailScheduleLoading} from "./DetailScheduleLoading"; | ||||
import DSOverview from "./DetailScheduleSearchView"; | import DSOverview from "./DetailScheduleSearchView"; | ||||
import { ScheduleType } from "@/app/api/scheduling"; | |||||
import { SearchProdSchedule } from "@/app/api/scheduling/actions"; | |||||
interface SubComponents { | interface SubComponents { | ||||
Loading: typeof DetailScheduleLoading; | Loading: typeof DetailScheduleLoading; | ||||
} | } | ||||
const DetailScheduleWrapper: React.FC & SubComponents = async () => { | |||||
type Props = { | |||||
type: ScheduleType | |||||
} | |||||
const DetailScheduleWrapper: React.FC<Props> & SubComponents = async ({ | |||||
type | |||||
}) => { | |||||
const defaultInputs: SearchProdSchedule = { | |||||
types: ["detailed", "manual"] | |||||
} | |||||
return <DSOverview records={[]} />; | |||||
return <DSOverview type={type} defaultInputs={defaultInputs} />; | |||||
}; | }; | ||||
DetailScheduleWrapper.Loading = DetailScheduleLoading; | DetailScheduleWrapper.Loading = DetailScheduleLoading; | ||||
@@ -23,11 +23,14 @@ import { SaveDetailSchedule } from "./DetailScheudleDetailView"; | |||||
// temp interface input | // temp interface input | ||||
type Props = { | type Props = { | ||||
recordDetails: SaveDetailSchedule; | |||||
// recordDetails: SaveDetailSchedule; | |||||
isEditing: boolean; | isEditing: boolean; | ||||
}; | }; | ||||
const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing }) => { | |||||
const DetailInfoCard: React.FC<Props> = ({ | |||||
// recordDetails, | |||||
isEditing | |||||
}) => { | |||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
@@ -39,12 +42,12 @@ const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing }) => { | |||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<SaveDetailSchedule>(); | } = useFormContext<SaveDetailSchedule>(); | ||||
const [details, setDetails] = useState<SaveDetailSchedule|null>(null); | |||||
const [details, setDetails] = useState<SaveDetailSchedule | undefined>(undefined); | |||||
useEffect(() => { | useEffect(() => { | ||||
console.log("[debug] record details", recordDetails) | |||||
setDetails(recordDetails); | |||||
}, [recordDetails]) | |||||
console.log("[debug] record details", defaultValues) | |||||
setDetails(defaultValues as SaveDetailSchedule); | |||||
}, [defaultValues]) | |||||
useEffect(() => { | useEffect(() => { | ||||
console.log("[debug] isEdit", isEditing) | console.log("[debug] isEdit", isEditing) | ||||
@@ -36,7 +36,7 @@ type Props = { | |||||
isEditMode: boolean; | isEditMode: boolean; | ||||
// type: TypeEnum; | // type: TypeEnum; | ||||
defaultValues: Partial<SaveDetailSchedule> | undefined; | defaultValues: Partial<SaveDetailSchedule> | undefined; | ||||
qcChecks: ItemQc[] | |||||
// qcChecks: ItemQc[] | |||||
}; | }; | ||||
const DetailScheduleDetailView: React.FC<Props> = ({ | const DetailScheduleDetailView: React.FC<Props> = ({ | ||||
@@ -89,7 +89,7 @@ const DetailScheduleDetailView: React.FC<Props> = ({ | |||||
productionDate: "2025-05-07", | productionDate: "2025-05-07", | ||||
totalJobOrders: 13, | totalJobOrders: 13, | ||||
totalProductionQty: 21000, | totalProductionQty: 21000, | ||||
}, | |||||
} as SaveDetailSchedule, | |||||
}); | }); | ||||
const errors = formProps.formState.errors; | const errors = formProps.formState.errors; | ||||
@@ -157,7 +157,7 @@ const DetailScheduleDetailView: React.FC<Props> = ({ | |||||
{/* </Typography>*/} | {/* </Typography>*/} | ||||
{/*</Grid>*/} | {/*</Grid>*/} | ||||
<DetailInfoCard | <DetailInfoCard | ||||
recordDetails={formProps.formState.defaultValues as SaveDetailSchedule} | |||||
// recordDetails={formProps.formState.defaultValues} | |||||
isEditing={isEdit} | isEditing={isEdit} | ||||
/> | /> | ||||
<Stack | <Stack | ||||
@@ -2,7 +2,7 @@ | |||||
import { useCallback, useEffect, useMemo, useState } from "react"; | import { useCallback, useEffect, useMemo, useState } from "react"; | ||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import { ItemsResult } from "@/app/api/settings/item"; | |||||
import { ItemsResult, ItemsResultResponse } from "@/app/api/settings/item"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import SearchResults, { Column } from "../SearchResults"; | import SearchResults, { Column } from "../SearchResults"; | ||||
import { EditNote } from "@mui/icons-material"; | import { EditNote } from "@mui/icons-material"; | ||||
@@ -85,7 +85,7 @@ const ItemsSearch: React.FC<Props> = ({ items }) => { | |||||
...filterObj, | ...filterObj, | ||||
}; | }; | ||||
try { | try { | ||||
const response = await axiosInstance.get<ItemsResult[]>( | |||||
const response = await axiosInstance.get<ItemsResultResponse>( | |||||
`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, | `${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, | ||||
{ params } | { params } | ||||
); | ); | ||||
@@ -19,6 +19,7 @@ import { arrayToDateString, decimalFormatter } from "@/app/utils/formatUtil"; | |||||
import { isEqual, uniqBy } from "lodash"; | import { isEqual, uniqBy } from "lodash"; | ||||
import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
import { defaultPagingController } from "../SearchResults/SearchResults"; | import { defaultPagingController } from "../SearchResults/SearchResults"; | ||||
import { ScheduleType } from "@/app/api/scheduling"; | |||||
// type RecordStructure ={ | // type RecordStructure ={ | ||||
// id: number, | // id: number, | ||||
@@ -27,12 +28,12 @@ import { defaultPagingController } from "../SearchResults/SearchResults"; | |||||
// }; | // }; | ||||
type Props = { | type Props = { | ||||
type: SearchProdSchedule["type"]; | |||||
type: ScheduleType; | |||||
// initProdSchedules: ProdScheduleResultByPage; | // initProdSchedules: ProdScheduleResultByPage; | ||||
defaultInputs: SearchProdSchedule; | defaultInputs: SearchProdSchedule; | ||||
}; | }; | ||||
type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "type" | "pageSize" | "pageNum">>; | |||||
type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "types" | "pageSize" | "pageNum">>; | |||||
type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | ||||
@@ -64,12 +65,12 @@ const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||||
// [router] | // [router] | ||||
// ); | // ); | ||||
const onDeleteClick = useCallback( | |||||
(item: ItemsResult) => { }, | |||||
[router] | |||||
); | |||||
// const onDeleteClick = useCallback( | |||||
// (item: ItemsResult) => { }, | |||||
// [router] | |||||
// ); | |||||
const onDetailClick = (record: any) => { | |||||
const onDetailClick = (record: ProdScheduleResult) => { | |||||
console.log("[debug] record", record); | console.log("[debug] record", record); | ||||
router.push(`/scheduling/rough/edit?id=${record.id}`); | router.push(`/scheduling/rough/edit?id=${record.id}`); | ||||
} | } | ||||
@@ -127,7 +128,7 @@ const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||||
schedulePeriod: dayjs(query?.schedulePeriod).isValid() ? query?.schedulePeriod : undefined, | schedulePeriod: dayjs(query?.schedulePeriod).isValid() ? query?.schedulePeriod : undefined, | ||||
schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined, | schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined, | ||||
totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined, | totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined, | ||||
type: "rough", | |||||
types: ["rough"], | |||||
pageNum: pagingController.pageNum - 1, | pageNum: pagingController.pageNum - 1, | ||||
pageSize: pagingController.pageSize | pageSize: pagingController.pageSize | ||||
} | } | ||||
@@ -2,13 +2,14 @@ import { fetchAllItems } from "@/app/api/settings/item"; | |||||
import { RoughScheduleLoading } from "./RoughScheduleLoading"; | import { RoughScheduleLoading } from "./RoughScheduleLoading"; | ||||
import RSOverview from "./RoughSchedileSearchView"; | import RSOverview from "./RoughSchedileSearchView"; | ||||
import { SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | import { SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | ||||
import { ScheduleType } from "@/app/api/scheduling"; | |||||
interface SubComponents { | interface SubComponents { | ||||
Loading: typeof RoughScheduleLoading; | Loading: typeof RoughScheduleLoading; | ||||
} | } | ||||
type Props = { | type Props = { | ||||
type: SearchProdSchedule["type"] | |||||
type: ScheduleType | |||||
}; | }; | ||||
const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | ||||
@@ -18,7 +19,7 @@ const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | |||||
) => { | ) => { | ||||
// console.log(type) | // console.log(type) | ||||
const defaultInputs: SearchProdSchedule = { | const defaultInputs: SearchProdSchedule = { | ||||
type: "rough" | |||||
types: ["rough"] | |||||
} | } | ||||
// const [ | // const [ | ||||
@@ -18,7 +18,7 @@ import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | |||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
import { NumberInputProps } from "@/components/CreateItem/NumberInputProps"; | import { NumberInputProps } from "@/components/CreateItem/NumberInputProps"; | ||||
import { arrayToDateString, integerFormatter } from "@/app/utils/formatUtil"; | import { arrayToDateString, integerFormatter } from "@/app/utils/formatUtil"; | ||||
import { ProdScheduleResult } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleResult } from "@/app/api/scheduling"; | |||||
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; | import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; | ||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | ||||
@@ -38,12 +38,12 @@ const DetailInfoCard: React.FC<Props> = ({ isEditing }) => { | |||||
getValues, | getValues, | ||||
watch, | watch, | ||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<ProdScheduleResult>(); | |||||
} = useFormContext<RoughProdScheduleResult>(); | |||||
// const [details, setDetails] = useState(null); | // const [details, setDetails] = useState(null); | ||||
useEffect(() => { | useEffect(() => { | ||||
console.log("[debug] record details", getValues) | |||||
console.log("[debug] record details", getValues()) | |||||
// setDetails(recordDetails); | // setDetails(recordDetails); | ||||
}, [getValues]) | }, [getValues]) | ||||
@@ -15,7 +15,7 @@ type Props = { | |||||
const RoughScheduleDetailWrapper: React.FC<Props> & SubComponents = async ({ id, type }) => { | const RoughScheduleDetailWrapper: React.FC<Props> & SubComponents = async ({ id, type }) => { | ||||
const prodSchedule = id ? await fetchProdScheduleDetail(id) : undefined | const prodSchedule = id ? await fetchProdScheduleDetail(id) : undefined | ||||
return ( | return ( | ||||
<RoughScheduleDetailView | <RoughScheduleDetailView | ||||
isEditMode={Boolean(id)} | isEditMode={Boolean(id)} | ||||
@@ -24,13 +24,13 @@ import ViewByFGDetails from "@/components/RoughScheduleDetail/ViewByFGDetails"; | |||||
import ViewByBomDetails from "@/components/RoughScheduleDetail/ViewByBomDetails"; | import ViewByBomDetails from "@/components/RoughScheduleDetail/ViewByBomDetails"; | ||||
import ScheduleTable from "@/components/ScheduleTable"; | import ScheduleTable from "@/components/ScheduleTable"; | ||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | import { Column } from "@/components/ScheduleTable/ScheduleTable"; | ||||
import { ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { arrayToDayjs, dayjsToDateString } from "@/app/utils/formatUtil"; | import { arrayToDayjs, dayjsToDateString } from "@/app/utils/formatUtil"; | ||||
type Props = { | type Props = { | ||||
isEditMode: boolean; | isEditMode: boolean; | ||||
type: ScheduleType; | type: ScheduleType; | ||||
defaultValues: Partial<ProdScheduleResult> | undefined; | |||||
defaultValues: Partial<RoughProdScheduleResult> | undefined; | |||||
// qcChecks: ItemQc[] | // qcChecks: ItemQc[] | ||||
}; | }; | ||||
@@ -42,7 +42,6 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
// console.log(type) | // console.log(type) | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
const params = useSearchParams() | const params = useSearchParams() | ||||
console.log(params.get("id")) | |||||
const [serverError, setServerError] = useState(""); | const [serverError, setServerError] = useState(""); | ||||
const [tabIndex, setTabIndex] = useState(0); | const [tabIndex, setTabIndex] = useState(0); | ||||
const { t } = useTranslation("schedule") | const { t } = useTranslation("schedule") | ||||
@@ -51,7 +50,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
//const title = "Demand Forecast Detail" | //const title = "Demand Forecast Detail" | ||||
// console.log(typeId) | // console.log(typeId) | ||||
const formProps = useForm<ProdScheduleResult>({ | |||||
const formProps = useForm<RoughProdScheduleResult>({ | |||||
defaultValues: defaultValues ? defaultValues : { | defaultValues: defaultValues ? defaultValues : { | ||||
}, | }, | ||||
}); | }); | ||||
@@ -88,7 +87,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
router.replace(`/scheduling/rough`); | router.replace(`/scheduling/rough`); | ||||
}; | }; | ||||
const onSubmit = useCallback<SubmitHandler<ProdScheduleResult>>( | |||||
const onSubmit = useCallback<SubmitHandler<RoughProdScheduleResult>>( | |||||
async (data, event) => { | async (data, event) => { | ||||
let hasErrors = false; | let hasErrors = false; | ||||
console.log(errors) | console.log(errors) | ||||
@@ -109,7 +108,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
); | ); | ||||
// multiple tabs | // multiple tabs | ||||
const onSubmitError = useCallback<SubmitErrorHandler<ProdScheduleResult>>( | |||||
const onSubmitError = useCallback<SubmitErrorHandler<RoughProdScheduleResult>>( | |||||
(errors) => { }, | (errors) => { }, | ||||
[] | [] | ||||
); | ); | ||||
@@ -21,7 +21,7 @@ import { RiceBowl } from "@mui/icons-material"; | |||||
// import EditableSearchResults, { Column } from "@/components/SearchResults/EditableSearchResults"; | // import EditableSearchResults, { Column } from "@/components/SearchResults/EditableSearchResults"; | ||||
import { decimalFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter } from "@/app/utils/formatUtil"; | ||||
import { GridRenderCellParams } from "@mui/x-data-grid"; | import { GridRenderCellParams } from "@mui/x-data-grid"; | ||||
import { ProdScheduleLineResultByBom, ProdScheduleLineResultByBomByDate, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleLineResultByBom, RoughProdScheduleLineResultByBomByDate, RoughProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import ScheduleTable from "@/components/ScheduleTable"; | import ScheduleTable from "@/components/ScheduleTable"; | ||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | import { Column } from "@/components/ScheduleTable/ScheduleTable"; | ||||
@@ -63,7 +63,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
control, | control, | ||||
getValues, | getValues, | ||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<ProdScheduleResult>(); | |||||
} = useFormContext<RoughProdScheduleResult>(); | |||||
// const apiRef = useGridApiRef(); | // const apiRef = useGridApiRef(); | ||||
const { fields } = useFieldArray({ | const { fields } = useFieldArray({ | ||||
@@ -165,7 +165,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.availableQty) == "number") { | if (typeof (row.availableQty) == "number") { | ||||
return decimalFormatter.format(row.availableQty) | return decimalFormatter.format(row.availableQty) | ||||
} | } | ||||
@@ -180,7 +180,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.totalDemandQty) == "number") { | if (typeof (row.totalDemandQty) == "number") { | ||||
return decimalFormatter.format(row.totalDemandQty) | return decimalFormatter.format(row.totalDemandQty) | ||||
} | } | ||||
@@ -194,7 +194,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty1) == "number") { | if (typeof (row.demandQty1) == "number") { | ||||
return decimalFormatter.format(row.demandQty1) | return decimalFormatter.format(row.demandQty1) | ||||
} | } | ||||
@@ -208,7 +208,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty2) == "number") { | if (typeof (row.demandQty2) == "number") { | ||||
return decimalFormatter.format(row.demandQty2) | return decimalFormatter.format(row.demandQty2) | ||||
} | } | ||||
@@ -222,7 +222,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty3) == "number") { | if (typeof (row.demandQty3) == "number") { | ||||
return decimalFormatter.format(row.demandQty3) | return decimalFormatter.format(row.demandQty3) | ||||
} | } | ||||
@@ -236,7 +236,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty4) == "number") { | if (typeof (row.demandQty4) == "number") { | ||||
return decimalFormatter.format(row.demandQty4) | return decimalFormatter.format(row.demandQty4) | ||||
} | } | ||||
@@ -249,7 +249,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty5) == "number") { | if (typeof (row.demandQty5) == "number") { | ||||
return decimalFormatter.format(row.demandQty5) | return decimalFormatter.format(row.demandQty5) | ||||
} | } | ||||
@@ -263,7 +263,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty6) == "number") { | if (typeof (row.demandQty6) == "number") { | ||||
return decimalFormatter.format(row.demandQty6) | return decimalFormatter.format(row.demandQty6) | ||||
} | } | ||||
@@ -277,7 +277,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty7) == "number") { | if (typeof (row.demandQty7) == "number") { | ||||
return decimalFormatter.format(row.demandQty7) | return decimalFormatter.format(row.demandQty7) | ||||
} | } | ||||
@@ -288,7 +288,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
[t] | [t] | ||||
); | ); | ||||
const columns = useMemo<Column<ProdScheduleLineResultByBomByDate>[]>( | |||||
const columns = useMemo<Column<RoughProdScheduleLineResultByBomByDate>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -317,7 +317,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBomByDate) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBomByDate) => { | |||||
if (typeof (row.availableQty) == "number") { | if (typeof (row.availableQty) == "number") { | ||||
return decimalFormatter.format(row.availableQty) | return decimalFormatter.format(row.availableQty) | ||||
} | } | ||||
@@ -331,7 +331,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: ProdScheduleLineResultByBomByDate) => { | |||||
renderCell: (row: RoughProdScheduleLineResultByBomByDate) => { | |||||
if (typeof (row.demandQty) == "number") { | if (typeof (row.demandQty) == "number") { | ||||
return decimalFormatter.format(row.demandQty) | return decimalFormatter.format(row.demandQty) | ||||
} | } | ||||
@@ -342,15 +342,13 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
[] | [] | ||||
); | ); | ||||
console.log(getValues("prodScheduleLinesByBom")) | |||||
return ( | return ( | ||||
<Grid container spacing={2}> | <Grid container spacing={2}> | ||||
<Grid item xs={12} key={"all"}> | <Grid item xs={12} key={"all"}> | ||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{t("Material Demand List (7 Days)")} | {t("Material Demand List (7 Days)")} | ||||
</Typography> | </Typography> | ||||
<ScheduleTable<ProdScheduleLineResultByBom> | |||||
<ScheduleTable<RoughProdScheduleLineResultByBom> | |||||
// index={7} | // index={7} | ||||
type={type} | type={type} | ||||
items={getValues("prodScheduleLinesByBom")} | items={getValues("prodScheduleLinesByBom")} | ||||
@@ -368,7 +366,7 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{`${t("Material Demand Date")}: ${date}`} | {`${t("Material Demand Date")}: ${date}`} | ||||
</Typography> | </Typography> | ||||
<ScheduleTable<ProdScheduleLineResultByBomByDate> | |||||
<ScheduleTable<RoughProdScheduleLineResultByBomByDate> | |||||
// index={index} | // index={index} | ||||
type={type} | type={type} | ||||
items={getValues("prodScheduleLinesByBomByDate")[index + 1]} // Use the corresponding records for the day | items={getValues("prodScheduleLinesByBomByDate")[index + 1]} // Use the corresponding records for the day | ||||
@@ -21,7 +21,7 @@ import { RiceBowl } from "@mui/icons-material"; | |||||
import ScheduleTable from "@/components/ScheduleTable"; | import ScheduleTable from "@/components/ScheduleTable"; | ||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | import { Column } from "@/components/ScheduleTable/ScheduleTable"; | ||||
import { arrayToDayjs, dayjsToDateString, decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | import { arrayToDayjs, dayjsToDateString, decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | ||||
import { ProdScheduleLineResultByFg, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleLineResultByFg, RoughProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
type Props = { | type Props = { | ||||
apiRef: MutableRefObject<GridApiCommunity> | apiRef: MutableRefObject<GridApiCommunity> | ||||
@@ -50,7 +50,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) = | |||||
control, | control, | ||||
getValues, | getValues, | ||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<ProdScheduleResult>(); | |||||
} = useFormContext<RoughProdScheduleResult>(); | |||||
const { fields } = useFieldArray({ | const { fields } = useFieldArray({ | ||||
control, | control, | ||||
@@ -125,7 +125,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) = | |||||
}); | }); | ||||
}; | }; | ||||
const columns = useMemo<Column<ProdScheduleLineResultByFg>[]>( | |||||
const columns = useMemo<Column<RoughProdScheduleLineResultByFg>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -177,7 +177,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) = | |||||
[] | [] | ||||
); | ); | ||||
const overallColumns = useMemo<Column<ProdScheduleLineResultByFg>[]>( | |||||
const overallColumns = useMemo<Column<RoughProdScheduleLineResultByFg>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -270,7 +270,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) = | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{t("FG Demand List (7 Days)")} | {t("FG Demand List (7 Days)")} | ||||
</Typography> | </Typography> | ||||
<ScheduleTable<ProdScheduleLineResultByFg> | |||||
<ScheduleTable<RoughProdScheduleLineResultByFg> | |||||
// index={7} | // index={7} | ||||
type={type} | type={type} | ||||
items={getValues("prodScheduleLinesByFg")} | items={getValues("prodScheduleLinesByFg")} | ||||
@@ -288,9 +288,9 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) = | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{`${t("FG Demand Date")}: ${date}`} | {`${t("FG Demand Date")}: ${date}`} | ||||
</Typography> | </Typography> | ||||
<ScheduleTable<ProdScheduleLineResultByFg> | |||||
<ScheduleTable<RoughProdScheduleLineResultByFg> | |||||
type={type} | type={type} | ||||
items={getValues("prodScheduleLinesByFgByDate")[index + 1]} // Use the corresponding records for the day | |||||
items={getValues("prodScheduleLinesByFgByDate") && Object.entries(getValues("prodScheduleLinesByFgByDate")).length > 0 ? getValues("prodScheduleLinesByFgByDate")[index + 1] : []} // Use the corresponding records for the day | |||||
columns={columns} | columns={columns} | ||||
setPagingController={updatePagingController} | setPagingController={updatePagingController} | ||||
pagingController={pagingController[index]} | pagingController={pagingController[index]} | ||||
@@ -36,14 +36,14 @@ import { useSearchParams } from "next/navigation"; | |||||
import { decimalFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter } from "@/app/utils/formatUtil"; | ||||
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; | import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; | ||||
import HighlightOffIcon from '@mui/icons-material/HighlightOff'; | import HighlightOffIcon from '@mui/icons-material/HighlightOff'; | ||||
import { ProdScheduleLineBomMaterialResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleLineBomMaterialResult, ScheduleType } from "@/app/api/scheduling"; | |||||
interface ResultWithId { | interface ResultWithId { | ||||
id: number; | id: number; | ||||
} | } | ||||
interface Props { | interface Props { | ||||
bomMaterial: ProdScheduleLineBomMaterialResult[]; | |||||
bomMaterial: RoughProdScheduleLineBomMaterialResult[]; | |||||
type: ScheduleType | type: ScheduleType | ||||
} | } | ||||
@@ -23,7 +23,7 @@ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; | |||||
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | ||||
import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | ||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import { ProdScheduleLineBomMaterialResult, ProdScheduleLineResultByFg, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { RoughProdScheduleLineBomMaterialResult, RoughProdScheduleLineResultByFg, RoughProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
export interface ResultWithId { | export interface ResultWithId { | ||||
id: string | number; | id: string | number; | ||||
@@ -144,10 +144,10 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
return type === "rough"; | return type === "rough"; | ||||
} | } | ||||
function isDetailType( | |||||
function isDetailedType( | |||||
type: ScheduleType | type: ScheduleType | ||||
): type is "detail" { | |||||
return type === "detail"; | |||||
): type is "detailed" { | |||||
return type === "detailed"; | |||||
} | } | ||||
function Row(props: { row: T }) { | function Row(props: { row: T }) { | ||||
@@ -157,7 +157,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
return ( | return ( | ||||
<> | <> | ||||
<TableRow hover tabIndex={-1} key={row.id}> | <TableRow hover tabIndex={-1} key={row.id}> | ||||
{isDetailType(type) && <TableCell> | |||||
{isDetailedType(type) && <TableCell> | |||||
<IconButton disabled={!isEdit}> | <IconButton disabled={!isEdit}> | ||||
<PlayCircleOutlineIcon /> | <PlayCircleOutlineIcon /> | ||||
</IconButton> | </IconButton> | ||||
@@ -167,12 +167,12 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
{(editingRowId === row.id) ? ( | {(editingRowId === row.id) ? ( | ||||
<> | <> | ||||
{ | { | ||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => handleSaveClick(row)}> | |||||
isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => handleSaveClick(row)}> | |||||
<SaveIcon /> | <SaveIcon /> | ||||
</IconButton> | </IconButton> | ||||
} | } | ||||
{ | { | ||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => setEditingRowId(null)}> | |||||
isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => setEditingRowId(null)}> | |||||
<CancelIcon /> | <CancelIcon /> | ||||
</IconButton> | </IconButton> | ||||
} | } | ||||
@@ -190,13 +190,13 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
) : ( | ) : ( | ||||
<> | <> | ||||
{ | { | ||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
onClick={() => handleEditClick(row.id as number)}> | onClick={() => handleEditClick(row.id as number)}> | ||||
<EditIcon /> | <EditIcon /> | ||||
</IconButton> | </IconButton> | ||||
} | } | ||||
{ | { | ||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
onClick={() => handleDeleteClick(row.id as number)}> | onClick={() => handleDeleteClick(row.id as number)}> | ||||
<DeleteIcon /> | <DeleteIcon /> | ||||
</IconButton> | </IconButton> | ||||
@@ -278,7 +278,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
<TableCell> | <TableCell> | ||||
<BomMaterialTable | <BomMaterialTable | ||||
type={type} | type={type} | ||||
bomMaterial={(row as unknown as ProdScheduleLineResultByFg).bomMaterials} | |||||
bomMaterial={(row as unknown as RoughProdScheduleLineResultByFg).bomMaterials} | |||||
/> | /> | ||||
</TableCell> | </TableCell> | ||||
</TableRow> | </TableRow> | ||||
@@ -298,7 +298,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||||
<Table stickyHeader> | <Table stickyHeader> | ||||
<TableHead> | <TableHead> | ||||
<TableRow> | <TableRow> | ||||
{isDetailType(type) && <TableCell>{t("Release")}</TableCell>} | |||||
{isDetailedType(type) && <TableCell>{t("Release")}</TableCell>} | |||||
{(isEditable || hasCollapse) && <TableCell>{t("Actions")}</TableCell>} {/* Action Column Header */} | {(isEditable || hasCollapse) && <TableCell>{t("Actions")}</TableCell>} {/* Action Column Header */} | ||||
{columns.map((column, idx) => ( | {columns.map((column, idx) => ( | ||||
<TableCell style={column.style} key={`${column.field.toString()}${idx}`}> | <TableCell style={column.style} key={`${column.field.toString()}${idx}`}> | ||||
@@ -196,7 +196,7 @@ function SearchBox<T extends string>({ | |||||
<Grid key={c.paramName} item xs={6}> | <Grid key={c.paramName} item xs={6}> | ||||
{c.type === "text" && ( | {c.type === "text" && ( | ||||
<TextField | <TextField | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
fullWidth | fullWidth | ||||
onChange={makeInputChangeHandler(c.paramName)} | onChange={makeInputChangeHandler(c.paramName)} | ||||
value={inputs[c.paramName]} | value={inputs[c.paramName]} | ||||
@@ -204,7 +204,7 @@ function SearchBox<T extends string>({ | |||||
)} | )} | ||||
{c.type === "multi-select" && ( | {c.type === "multi-select" && ( | ||||
<MultiSelect | <MultiSelect | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
options={c?.options} | options={c?.options} | ||||
selectedValues={c.filterObj?.[c.paramName] ?? []} | selectedValues={c.filterObj?.[c.paramName] ?? []} | ||||
onChange={c.handleSelectionChange} | onChange={c.handleSelectionChange} | ||||
@@ -213,9 +213,9 @@ function SearchBox<T extends string>({ | |||||
)} | )} | ||||
{c.type === "select" && ( | {c.type === "select" && ( | ||||
<FormControl fullWidth> | <FormControl fullWidth> | ||||
<InputLabel>{c.label}</InputLabel> | |||||
<InputLabel>{t(c.label)}</InputLabel> | |||||
<Select | <Select | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
onChange={makeSelectChangeHandler(c.paramName)} | onChange={makeSelectChangeHandler(c.paramName)} | ||||
value={inputs[c.paramName]} | value={inputs[c.paramName]} | ||||
> | > | ||||
@@ -230,9 +230,9 @@ function SearchBox<T extends string>({ | |||||
)} | )} | ||||
{c.type === "select-labelled" && ( | {c.type === "select-labelled" && ( | ||||
<FormControl fullWidth> | <FormControl fullWidth> | ||||
<InputLabel>{c.label}</InputLabel> | |||||
<InputLabel>{t(c.label)}</InputLabel> | |||||
<Select | <Select | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
onChange={makeSelectChangeHandler(c.paramName)} | onChange={makeSelectChangeHandler(c.paramName)} | ||||
value={inputs[c.paramName]} | value={inputs[c.paramName]} | ||||
> | > | ||||
@@ -312,7 +312,7 @@ function SearchBox<T extends string>({ | |||||
</MenuItem> | </MenuItem> | ||||
); | ); | ||||
}} | }} | ||||
renderInput={(params) => <TextField {...params} variant="outlined" label={c.label} />} | |||||
renderInput={(params) => <TextField {...params} variant="outlined" label={t(c.label)} />} | |||||
/> | /> | ||||
)} | )} | ||||
{c.type === "dateRange" && ( | {c.type === "dateRange" && ( | ||||
@@ -324,7 +324,7 @@ function SearchBox<T extends string>({ | |||||
<Box display="flex"> | <Box display="flex"> | ||||
<FormControl fullWidth> | <FormControl fullWidth> | ||||
<DatePicker | <DatePicker | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
onChange={makeDateChangeHandler(c.paramName)} | onChange={makeDateChangeHandler(c.paramName)} | ||||
value={dayjs(inputs[c.paramName]).isValid() ? dayjs(inputs[c.paramName]) : null} | value={dayjs(inputs[c.paramName]).isValid() ? dayjs(inputs[c.paramName]) : null} | ||||
/> | /> | ||||
@@ -339,7 +339,7 @@ function SearchBox<T extends string>({ | |||||
</Box> | </Box> | ||||
<FormControl fullWidth> | <FormControl fullWidth> | ||||
<DatePicker | <DatePicker | ||||
label={c.label2} | |||||
label={c.label2 ? t(c.label2) : null} | |||||
onChange={makeDateToChangeHandler(c.paramName)} | onChange={makeDateToChangeHandler(c.paramName)} | ||||
value={dayjs(inputs[`${c.paramName}To`]).isValid() ? dayjs(inputs[`${c.paramName}To`]) : null} | value={dayjs(inputs[`${c.paramName}To`]).isValid() ? dayjs(inputs[`${c.paramName}To`]) : null} | ||||
/> | /> | ||||
@@ -356,7 +356,7 @@ function SearchBox<T extends string>({ | |||||
<Box display="flex"> | <Box display="flex"> | ||||
<FormControl fullWidth> | <FormControl fullWidth> | ||||
<DatePicker | <DatePicker | ||||
label={c.label} | |||||
label={t(c.label)} | |||||
onChange={makeDateChangeHandler(c.paramName)} | onChange={makeDateChangeHandler(c.paramName)} | ||||
/> | /> | ||||
</FormControl> | </FormControl> | ||||
@@ -1,6 +1,6 @@ | |||||
"use client"; | "use client"; | ||||
import React, { useEffect, useState } from "react"; | |||||
import React, { CSSProperties, useEffect, useState } from "react"; | |||||
import Paper from "@mui/material/Paper"; | import Paper from "@mui/material/Paper"; | ||||
import Table from "@mui/material/Table"; | import Table from "@mui/material/Table"; | ||||
import TableBody from "@mui/material/TableBody"; | import TableBody from "@mui/material/TableBody"; | ||||
@@ -23,6 +23,7 @@ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; | |||||
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | ||||
import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | ||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import { RoughProdScheduleLineResultByFg } from "@/app/api/scheduling"; | |||||
export interface ResultWithId { | export interface ResultWithId { | ||||
id: string | number; | id: string | number; | ||||
} | } | ||||
@@ -32,8 +33,9 @@ interface BaseColumn<T extends ResultWithId> { | |||||
label: string; | label: string; | ||||
type: string; | type: string; | ||||
options?: T[]; | options?: T[]; | ||||
renderCell?: (T) => void; | |||||
style?: Partial<HTMLElement["style"]> & { [propName: string]: string }; | |||||
renderCell?: (params: T) => React.ReactNode; | |||||
style?: Partial<HTMLElement["style"]> & { [propName: string]: string } & CSSProperties; | |||||
// style?: Partial<HTMLElement["style"]> & { [propName: string]: string }; | |||||
} | } | ||||
interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> { | interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> { | ||||
@@ -52,7 +54,11 @@ interface Props<T extends ResultWithId> { | |||||
noWrapper?: boolean, | noWrapper?: boolean, | ||||
setPagingController: (value: { pageNum: number; pageSize: number; totalCount: number, index?: number }) => void, | setPagingController: (value: { pageNum: number; pageSize: number; totalCount: number, index?: number }) => void, | ||||
pagingController: { pageNum: number; pageSize: number; totalCount: number }, | pagingController: { pageNum: number; pageSize: number; totalCount: number }, | ||||
isAutoPaging: boolean | |||||
isAutoPaging: boolean, | |||||
index: any, | |||||
isEdit: any, | |||||
isEditable: any, | |||||
hasCollapse: any, | |||||
} | } | ||||
function EditableSearchResults<T extends ResultWithId>({ | function EditableSearchResults<T extends ResultWithId>({ | ||||
@@ -78,7 +84,7 @@ function EditableSearchResults<T extends ResultWithId>({ | |||||
}, [items]) | }, [items]) | ||||
const handleChangePage = (_event: unknown, newPage: number) => { | const handleChangePage = (_event: unknown, newPage: number) => { | ||||
setPage(newPage); | setPage(newPage); | ||||
setPagingController({ ...pagingController, pageNum: newPage + 1 }, (index ?? -1)); | |||||
// setPagingController({ ...pagingController, pageNum: newPage + 1 }, (index ?? -1)); | |||||
}; | }; | ||||
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => { | const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => { | ||||
@@ -134,7 +140,7 @@ function EditableSearchResults<T extends ResultWithId>({ | |||||
<> | <> | ||||
<TableRow hover tabIndex={-1} key={row.id}> | <TableRow hover tabIndex={-1} key={row.id}> | ||||
<TableCell> | <TableCell> | ||||
<IconButton disable={!isEdit}> | |||||
<IconButton disabled={!isEdit}> | |||||
<PlayCircleOutlineIcon /> | <PlayCircleOutlineIcon /> | ||||
</IconButton> | </IconButton> | ||||
</TableCell> | </TableCell> | ||||
@@ -208,15 +214,15 @@ function EditableSearchResults<T extends ResultWithId>({ | |||||
onChange={(e) => handleInputChange(row.id as number, columnName, e.target.value)} | onChange={(e) => handleInputChange(row.id as number, columnName, e.target.value)} | ||||
/> | /> | ||||
); | ); | ||||
case 'multi-select': | |||||
return ( | |||||
<MultiSelect | |||||
//label={column.label} | |||||
options={column.options} | |||||
selectedValues={[]} | |||||
onChange={(selectedValues) => handleInputChange(row.id as number, columnName, selectedValues)} | |||||
/> | |||||
); | |||||
// case 'multi-select': | |||||
// return ( | |||||
// <MultiSelect | |||||
// //label={column.label} | |||||
// options={column.options} | |||||
// selectedValues={[]} | |||||
// onChange={(selectedValues) => handleInputChange(row.id as number, columnName, selectedValues)} | |||||
// /> | |||||
// ); | |||||
case 'read-only': | case 'read-only': | ||||
return ( | return ( | ||||
<span> | <span> | ||||
@@ -253,7 +259,7 @@ function EditableSearchResults<T extends ResultWithId>({ | |||||
<TableRow> | <TableRow> | ||||
<TableCell> | <TableCell> | ||||
<TempInputGridForMockUp | <TempInputGridForMockUp | ||||
stockInLine={row.lines as any[]} | |||||
stockInLine={(row as unknown as {lines: string[]}).lines as any[]} | |||||
/> | /> | ||||
</TableCell> | </TableCell> | ||||
</TableRow> | </TableRow> | ||||
@@ -10,7 +10,8 @@ | |||||
"Demand Forecast Detail": "需求預測詳情", | "Demand Forecast Detail": "需求預測詳情", | ||||
"Details": "詳情", | "Details": "詳情", | ||||
"Schedule": "排程", | "Schedule": "排程", | ||||
"Schedule Period": "排程期間", | |||||
"Schedule Period": "排程時期", | |||||
"Schedule Period To": "排程時期至", | |||||
"Schedule Detail": "排程詳情", | "Schedule Detail": "排程詳情", | ||||
"Schedule At": "排程時間", | "Schedule At": "排程時間", | ||||
"Search": "搜尋", | "Search": "搜尋", | ||||
@@ -23,7 +24,7 @@ | |||||
"CODE": "編號", | "CODE": "編號", | ||||
"Product Count": "產品數量", | "Product Count": "產品數量", | ||||
"Scheduled At": "排程時間", | "Scheduled At": "排程時間", | ||||
"Demand Forecast Period": "需求預測期間", | |||||
"Demand Forecast Period": "需求預測時期", | |||||
"FG & Material Demand Forecast Detail": "成品及物料需求預測詳情", | "FG & Material Demand Forecast Detail": "成品及物料需求預測詳情", | ||||
"FG & Material Demand Forecast": "成品及物料需求預測", | "FG & Material Demand Forecast": "成品及物料需求預測", | ||||
"Total Estimated Demand Qty": "總預估需求量", | "Total Estimated Demand Qty": "總預估需求量", | ||||