| @@ -1,6 +1,7 @@ | |||
| // import { TypeEnum } from "@/app/utils/typeEnum"; | |||
| // import RoughSchedule from "@/components/RoughSchedule"; | |||
| // import { getServerI18n, I18nProvider } from "@/i18n"; | |||
| import { testRoughSchedule } from "@/app/api/scheduling/actions"; | |||
| import { TypeEnum } from "../../../../app/utils/typeEnum"; | |||
| import RoughSchedule from "../../../../components/RoughSchedule"; | |||
| import { getServerI18n, I18nProvider } from "../../../../i18n"; | |||
| @@ -22,6 +23,10 @@ const roughScheduling: React.FC = async () => { | |||
| const type = "rough" | |||
| // preloadClaims(); | |||
| // async function testingRoughSchedule() { | |||
| // await testRoughSchedule(); | |||
| // } | |||
| return ( | |||
| <> | |||
| <Stack | |||
| @@ -33,19 +38,18 @@ const roughScheduling: React.FC = async () => { | |||
| <Typography variant="h4" marginInlineEnd={2}> | |||
| {t("Demand Forecast")} | |||
| </Typography> | |||
| {/* <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> | |||
| <I18nProvider namespaces={["schedule", "common","items","project"]}> | |||
| <I18nProvider namespaces={["schedule", "common"]}> | |||
| <Suspense fallback={<RoughSchedule.Loading />}> | |||
| <RoughSchedule type={type}/> | |||
| <RoughSchedule type={type} /> | |||
| </Suspense> | |||
| </I18nProvider> | |||
| </> | |||
| @@ -19,6 +19,7 @@ import { arrayToDateString, decimalFormatter } from "@/app/utils/formatUtil"; | |||
| import { isEqual, uniqBy } from "lodash"; | |||
| import dayjs from "dayjs"; | |||
| import { defaultPagingController } from "../SearchResults/SearchResults"; | |||
| import { ScheduleType } from "@/app/api/scheduling"; | |||
| // type RecordStructure ={ | |||
| // id: number, | |||
| @@ -27,17 +28,17 @@ import { defaultPagingController } from "../SearchResults/SearchResults"; | |||
| // }; | |||
| type Props = { | |||
| type: SearchProdSchedule["type"]; | |||
| type: ScheduleType; | |||
| // initProdSchedules: ProdScheduleResultByPage; | |||
| defaultInputs: SearchProdSchedule; | |||
| }; | |||
| type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "type" | "pageSize" | "pageNum">>; | |||
| type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "types" | "pageSize" | "pageNum">>; | |||
| type SearchParamNames = keyof SearchQuery; | |||
| const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||
| const [filteredSchedules, setFilteredSchedules] = useState<ProdScheduleResult[]>([]); | |||
| const { t } = useTranslation("scheduling"); | |||
| const { t } = useTranslation("schedule"); | |||
| const router = useRouter(); | |||
| // const [filterObj, setFilterObj] = useState({}); | |||
| // const [tempSelectedValue, setTempSelectedValue] = useState({}); | |||
| @@ -64,12 +65,12 @@ const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||
| // [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); | |||
| 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, | |||
| schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined, | |||
| totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined, | |||
| type: "rough", | |||
| types: ["rough"], | |||
| pageNum: pagingController.pageNum - 1, | |||
| pageSize: pagingController.pageSize | |||
| } | |||
| @@ -2,13 +2,14 @@ import { fetchAllItems } from "@/app/api/settings/item"; | |||
| import { RoughScheduleLoading } from "./RoughScheduleLoading"; | |||
| import RSOverview from "./RoughSchedileSearchView"; | |||
| import { SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | |||
| import { ScheduleType } from "@/app/api/scheduling"; | |||
| interface SubComponents { | |||
| Loading: typeof RoughScheduleLoading; | |||
| } | |||
| type Props = { | |||
| type: SearchProdSchedule["type"] | |||
| type: ScheduleType | |||
| }; | |||
| const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | |||
| @@ -18,7 +19,7 @@ const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | |||
| ) => { | |||
| // console.log(type) | |||
| const defaultInputs: SearchProdSchedule = { | |||
| type: "rough" | |||
| types: ["rough"] | |||
| } | |||
| // const [ | |||
| @@ -36,14 +36,14 @@ import { useSearchParams } from "next/navigation"; | |||
| import { decimalFormatter } from "@/app/utils/formatUtil"; | |||
| import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; | |||
| import HighlightOffIcon from '@mui/icons-material/HighlightOff'; | |||
| import { ProdScheduleLineBomMaterialResult, ScheduleType } from "@/app/api/scheduling"; | |||
| import { RoughProdScheduleLineBomMaterialResult, ScheduleType } from "@/app/api/scheduling"; | |||
| interface ResultWithId { | |||
| id: number; | |||
| } | |||
| interface Props { | |||
| bomMaterial: ProdScheduleLineBomMaterialResult[]; | |||
| bomMaterial: RoughProdScheduleLineBomMaterialResult[]; | |||
| type: ScheduleType | |||
| } | |||
| @@ -23,7 +23,7 @@ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; | |||
| import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | |||
| import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | |||
| 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 { | |||
| id: string | number; | |||
| @@ -144,10 +144,10 @@ function ScheduleTable<T extends ResultWithId>({ | |||
| return type === "rough"; | |||
| } | |||
| function isDetailType( | |||
| function isDetailedType( | |||
| type: ScheduleType | |||
| ): type is "detail" { | |||
| return type === "detail"; | |||
| ): type is "detailed" { | |||
| return type === "detailed"; | |||
| } | |||
| function Row(props: { row: T }) { | |||
| @@ -157,7 +157,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||
| return ( | |||
| <> | |||
| <TableRow hover tabIndex={-1} key={row.id}> | |||
| {isDetailType(type) && <TableCell> | |||
| {isDetailedType(type) && <TableCell> | |||
| <IconButton disabled={!isEdit}> | |||
| <PlayCircleOutlineIcon /> | |||
| </IconButton> | |||
| @@ -167,12 +167,12 @@ function ScheduleTable<T extends ResultWithId>({ | |||
| {(editingRowId === row.id) ? ( | |||
| <> | |||
| { | |||
| isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => handleSaveClick(row)}> | |||
| isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => handleSaveClick(row)}> | |||
| <SaveIcon /> | |||
| </IconButton> | |||
| } | |||
| { | |||
| isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => setEditingRowId(null)}> | |||
| isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => setEditingRowId(null)}> | |||
| <CancelIcon /> | |||
| </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)}> | |||
| <EditIcon /> | |||
| </IconButton> | |||
| } | |||
| { | |||
| isDetailType(type) && isEditable && <IconButton disabled={!isEdit} | |||
| isDetailedType(type) && isEditable && <IconButton disabled={!isEdit} | |||
| onClick={() => handleDeleteClick(row.id as number)}> | |||
| <DeleteIcon /> | |||
| </IconButton> | |||
| @@ -278,7 +278,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||
| <TableCell> | |||
| <BomMaterialTable | |||
| type={type} | |||
| bomMaterial={(row as unknown as ProdScheduleLineResultByFg).bomMaterials} | |||
| bomMaterial={(row as unknown as RoughProdScheduleLineResultByFg).bomMaterials} | |||
| /> | |||
| </TableCell> | |||
| </TableRow> | |||
| @@ -298,7 +298,7 @@ function ScheduleTable<T extends ResultWithId>({ | |||
| <Table stickyHeader> | |||
| <TableHead> | |||
| <TableRow> | |||
| {isDetailType(type) && <TableCell>{t("Release")}</TableCell>} | |||
| {isDetailedType(type) && <TableCell>{t("Release")}</TableCell>} | |||
| {(isEditable || hasCollapse) && <TableCell>{t("Actions")}</TableCell>} {/* Action Column Header */} | |||
| {columns.map((column, 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}> | |||
| {c.type === "text" && ( | |||
| <TextField | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| fullWidth | |||
| onChange={makeInputChangeHandler(c.paramName)} | |||
| value={inputs[c.paramName]} | |||
| @@ -204,7 +204,7 @@ function SearchBox<T extends string>({ | |||
| )} | |||
| {c.type === "multi-select" && ( | |||
| <MultiSelect | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| options={c?.options} | |||
| selectedValues={c.filterObj?.[c.paramName] ?? []} | |||
| onChange={c.handleSelectionChange} | |||
| @@ -213,9 +213,9 @@ function SearchBox<T extends string>({ | |||
| )} | |||
| {c.type === "select" && ( | |||
| <FormControl fullWidth> | |||
| <InputLabel>{c.label}</InputLabel> | |||
| <InputLabel>{t(c.label)}</InputLabel> | |||
| <Select | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| onChange={makeSelectChangeHandler(c.paramName)} | |||
| value={inputs[c.paramName]} | |||
| > | |||
| @@ -230,9 +230,9 @@ function SearchBox<T extends string>({ | |||
| )} | |||
| {c.type === "select-labelled" && ( | |||
| <FormControl fullWidth> | |||
| <InputLabel>{c.label}</InputLabel> | |||
| <InputLabel>{t(c.label)}</InputLabel> | |||
| <Select | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| onChange={makeSelectChangeHandler(c.paramName)} | |||
| value={inputs[c.paramName]} | |||
| > | |||
| @@ -312,7 +312,7 @@ function SearchBox<T extends string>({ | |||
| </MenuItem> | |||
| ); | |||
| }} | |||
| renderInput={(params) => <TextField {...params} variant="outlined" label={c.label} />} | |||
| renderInput={(params) => <TextField {...params} variant="outlined" label={t(c.label)} />} | |||
| /> | |||
| )} | |||
| {c.type === "dateRange" && ( | |||
| @@ -324,7 +324,7 @@ function SearchBox<T extends string>({ | |||
| <Box display="flex"> | |||
| <FormControl fullWidth> | |||
| <DatePicker | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| onChange={makeDateChangeHandler(c.paramName)} | |||
| value={dayjs(inputs[c.paramName]).isValid() ? dayjs(inputs[c.paramName]) : null} | |||
| /> | |||
| @@ -339,7 +339,7 @@ function SearchBox<T extends string>({ | |||
| </Box> | |||
| <FormControl fullWidth> | |||
| <DatePicker | |||
| label={c.label2} | |||
| label={c.label2 ? t(c.label2) : null} | |||
| onChange={makeDateToChangeHandler(c.paramName)} | |||
| 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"> | |||
| <FormControl fullWidth> | |||
| <DatePicker | |||
| label={c.label} | |||
| label={t(c.label)} | |||
| onChange={makeDateChangeHandler(c.paramName)} | |||
| /> | |||
| </FormControl> | |||
| @@ -10,7 +10,8 @@ | |||
| "Demand Forecast Detail": "需求預測詳情", | |||
| "Details": "詳情", | |||
| "Schedule": "排程", | |||
| "Schedule Period": "排程期間", | |||
| "Schedule Period": "排程時期", | |||
| "Schedule Period To": "排程時期至", | |||
| "Schedule Detail": "排程詳情", | |||
| "Schedule At": "排程時間", | |||
| "Search": "搜尋", | |||
| @@ -23,7 +24,7 @@ | |||
| "CODE": "編號", | |||
| "Product Count": "產品數量", | |||
| "Scheduled At": "排程時間", | |||
| "Demand Forecast Period": "需求預測期間", | |||
| "Demand Forecast Period": "需求預測時期", | |||
| "FG & Material Demand Forecast Detail": "成品及物料需求預測詳情", | |||
| "FG & Material Demand Forecast": "成品及物料需求預測", | |||
| "Total Estimated Demand Qty": "總預估需求量", | |||