| @@ -51,7 +51,9 @@ export default async function MainLayout({ | |||
| }} | |||
| > | |||
| <Stack spacing={2}> | |||
| <Breadcrumb /> | |||
| <I18nProvider namespaces={["common"]}> | |||
| <Breadcrumb /> | |||
| </I18nProvider> | |||
| {children} | |||
| </Stack> | |||
| </Box> | |||
| @@ -5,6 +5,7 @@ import Typography from "@mui/material/Typography"; | |||
| import Link from "next/link"; | |||
| import MUILink from "@mui/material/Link"; | |||
| import { usePathname } from "next/navigation"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const pathToLabelMap: { [path: string]: string } = { | |||
| "": "Overview", | |||
| @@ -21,11 +22,14 @@ const pathToLabelMap: { [path: string]: string } = { | |||
| "/inventory": "Inventory", | |||
| "/settings/importTesting": "Import Testing", | |||
| "/do": "Delivery Order", | |||
| "/pickOrder": "Pick Order", | |||
| "/po": "Purchase Order", | |||
| }; | |||
| const Breadcrumb = () => { | |||
| const pathname = usePathname(); | |||
| const segments = pathname.split("/"); | |||
| const { t } = useTranslation("common") | |||
| return ( | |||
| <Breadcrumbs> | |||
| @@ -36,7 +40,7 @@ const Breadcrumb = () => { | |||
| if (index === segments.length - 1) { | |||
| return ( | |||
| <Typography key={index} color="text.primary"> | |||
| {label} | |||
| {t(label)} | |||
| </Typography> | |||
| ); | |||
| } else { | |||
| @@ -48,7 +52,7 @@ const Breadcrumb = () => { | |||
| component={Link} | |||
| href={href || "/"} | |||
| > | |||
| {label} | |||
| {t(label)} | |||
| </MUILink> | |||
| ); | |||
| } | |||
| @@ -54,26 +54,26 @@ const NavigationContent: React.FC = () => { | |||
| label: "Pick Order", | |||
| path: "/pickOrder", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Cons. Pick Order", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Delivery Pick Order", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Warehouse", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Location Transfer Order", | |||
| path: "", | |||
| }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Cons. Pick Order", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Delivery Pick Order", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Warehouse", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Location Transfer Order", | |||
| // path: "", | |||
| // }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "View item In-out And inventory Ledger", | |||
| @@ -81,45 +81,45 @@ const NavigationContent: React.FC = () => { | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Production", | |||
| path: "", | |||
| children: [ | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Job Order", | |||
| path: "/production", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Job Order Traceablity ", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Work Order", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Work Order Traceablity ", | |||
| path: "", | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Quality Control Log", | |||
| path: "", | |||
| children: [ | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Quality Control Log", | |||
| path: "", | |||
| }, | |||
| ], | |||
| }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Production", | |||
| // path: "", | |||
| // children: [ | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Job Order", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Job Order Traceablity ", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Work Order", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Work Order Traceablity ", | |||
| // path: "", | |||
| // }, | |||
| // ], | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Quality Control Log", | |||
| // path: "", | |||
| // children: [ | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Quality Control Log", | |||
| // path: "", | |||
| // }, | |||
| // ], | |||
| // }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Delivery", | |||
| @@ -132,40 +132,40 @@ const NavigationContent: React.FC = () => { | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Report", | |||
| path: "", | |||
| children: [ | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "report", | |||
| path: "", | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Recipe", | |||
| path: "", | |||
| children: [ | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "FG Recipe", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "SFG Recipe", | |||
| path: "", | |||
| }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Recipe", | |||
| path: "", | |||
| }, | |||
| ], | |||
| }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Report", | |||
| // path: "", | |||
| // children: [ | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "report", | |||
| // path: "", | |||
| // }, | |||
| // ], | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Recipe", | |||
| // path: "", | |||
| // children: [ | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "FG Recipe", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "SFG Recipe", | |||
| // path: "", | |||
| // }, | |||
| // { | |||
| // icon: <RequestQuote />, | |||
| // label: "Recipe", | |||
| // path: "", | |||
| // }, | |||
| // ], | |||
| // }, | |||
| { | |||
| icon: <RequestQuote />, | |||
| label: "Scheduling", | |||
| @@ -0,0 +1,12 @@ | |||
| interface Props { | |||
| } | |||
| const ConsolidatedPickOrders: React.FC<Props> = ({ | |||
| }) => { | |||
| return <></> | |||
| } | |||
| export default ConsolidatedPickOrders; | |||
| @@ -8,6 +8,8 @@ import SearchResults, { Column } from "../SearchResults"; | |||
| import { flatten, groupBy, intersectionWith, isEmpty, map, sortBy, sortedUniq, uniqBy, upperCase, upperFirst } from "lodash"; | |||
| import { arrayToDateString, arrayToDayjs, dateStringToDayjs } from "@/app/utils/formatUtil"; | |||
| import dayjs from "dayjs"; | |||
| import { Button, Grid, Stack, Tab, Tabs, TabsProps } from "@mui/material"; | |||
| import PickOrders from "./PickOrders"; | |||
| interface Props { | |||
| pickOrders: PickOrderResult[]; | |||
| @@ -27,6 +29,14 @@ const PickOrderSearch: React.FC<Props> = ({ | |||
| const [filteredPickOrders, setFilteredPickOrders] = useState(pickOrders) | |||
| const [tabIndex, setTabIndex] = useState(0); | |||
| const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | |||
| (_e, newValue) => { | |||
| setTabIndex(newValue); | |||
| }, | |||
| [], | |||
| ); | |||
| const searchCriteria: Criterion<SearchParamNames>[] = useMemo(() => [ | |||
| { label: t("Code"), paramName: "code", type: "text" }, | |||
| { label: t("Target Date From"), label2: t("Target Date To"), paramName: "targetDate", type: "dateRange" }, | |||
| @@ -43,9 +53,12 @@ const PickOrderSearch: React.FC<Props> = ({ | |||
| "label") | |||
| }, | |||
| { | |||
| label: t("Items"), paramName: "items", type: "autocomplete", multiple: true, | |||
| label: t("Items"), paramName: "items", type: "autocomplete", // multiple: true, | |||
| options: uniqBy(flatten(sortBy( | |||
| pickOrders.map((po) => po.items ? po.items.map((item) => ({ value: item.name, label: item.name, group: item.type })): []), | |||
| pickOrders.map((po) => po.items ? po.items.map((item) => ({ | |||
| value: item.name, label: item.name, | |||
| // group: item.type | |||
| })) : []), | |||
| "label")), "value") | |||
| }, | |||
| ], [t]) | |||
| @@ -54,52 +67,6 @@ const PickOrderSearch: React.FC<Props> = ({ | |||
| setFilteredPickOrders(pickOrders) | |||
| }, [pickOrders]) | |||
| const columns = useMemo<Column<PickOrderResult>[]>(() => [ | |||
| { | |||
| name: "code", | |||
| label: t("Code"), | |||
| }, | |||
| { | |||
| name: "consoCode", | |||
| label: t("Consolidated Code"), | |||
| renderCell: (params) => { | |||
| return params.consoCode ?? "N/A" | |||
| } | |||
| }, | |||
| { | |||
| name: "type", | |||
| label: t("type"), | |||
| renderCell: (params) => { | |||
| return upperCase(params.type) | |||
| } | |||
| }, | |||
| { | |||
| name: "items", | |||
| label: t("Items"), | |||
| renderCell: (params) => { | |||
| return params.items?.map((i) => i.name).join(", ") | |||
| } | |||
| }, | |||
| { | |||
| name: "targetDate", | |||
| label: t("Target Date"), | |||
| renderCell: (params) => { | |||
| return arrayToDateString(params.targetDate) | |||
| } | |||
| }, | |||
| { | |||
| name: "releasedBy", | |||
| label: t("Released By"), | |||
| }, | |||
| { | |||
| name: "status", | |||
| label: t("Status"), | |||
| renderCell: (params) => { | |||
| return upperFirst(params.status) | |||
| } | |||
| }, | |||
| ], [t]) | |||
| return ( | |||
| <> | |||
| <SearchBox | |||
| @@ -107,27 +74,27 @@ const PickOrderSearch: React.FC<Props> = ({ | |||
| onSearch={(query) => { | |||
| setFilteredPickOrders( | |||
| pickOrders.filter( | |||
| (po) =>{ | |||
| (po) => { | |||
| const poTargetDateStr = arrayToDayjs(po.targetDate) | |||
| // console.log(intersectionWith(po.items?.map(item => item.name), query.items)) | |||
| return po.code.toLowerCase().includes(query.code.toLowerCase()) | |||
| && (isEmpty(query.targetDate) || poTargetDateStr.isSame(query.targetDate) || poTargetDateStr.isAfter(query.targetDate)) | |||
| && (isEmpty(query.targetDateTo) || poTargetDateStr.isSame(query.targetDateTo) || poTargetDateStr.isBefore(query.targetDateTo)) | |||
| && (intersectionWith(["All"], query.items).length > 0 || intersectionWith(po.items?.map(item => item.name), query.items).length > 0) | |||
| && (query.status.toLowerCase() == "all" || po.status.toLowerCase().includes(query.status.toLowerCase())) | |||
| && (query.type.toLowerCase() == "all" || po.type.toLowerCase().includes(query.type.toLowerCase())) | |||
| && (isEmpty(query.targetDate) || poTargetDateStr.isSame(query.targetDate) || poTargetDateStr.isAfter(query.targetDate)) | |||
| && (isEmpty(query.targetDateTo) || poTargetDateStr.isSame(query.targetDateTo) || poTargetDateStr.isBefore(query.targetDateTo)) | |||
| && (intersectionWith(["All"], query.items).length > 0 || intersectionWith(po.items?.map(item => item.name), query.items).length > 0) | |||
| && (query.status.toLowerCase() == "all" || po.status.toLowerCase().includes(query.status.toLowerCase())) | |||
| && (query.type.toLowerCase() == "all" || po.type.toLowerCase().includes(query.type.toLowerCase())) | |||
| } | |||
| ) | |||
| ) | |||
| }} | |||
| onReset={onReset} | |||
| /> | |||
| <SearchResults<PickOrderResult> items={filteredPickOrders} columns={columns} pagingController={{ | |||
| pageNum: 0, | |||
| pageSize: 0, | |||
| totalCount: 0, | |||
| }} /> | |||
| <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||
| <Tab label={t("Pick Orders")} iconPosition="end" /> | |||
| <Tab label={t("Consolidated Pick Orders")} iconPosition="end" /> | |||
| </Tabs> | |||
| {tabIndex === 0 && <PickOrders filteredPickOrders={filteredPickOrders}/>} | |||
| </> | |||
| ) | |||
| } | |||
| @@ -0,0 +1,100 @@ | |||
| import { Button, Grid } from "@mui/material"; | |||
| import SearchResults, { Column } from "../SearchResults/SearchResults"; | |||
| import { PickOrderResult } from "@/app/api/pickOrder"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { useCallback, useMemo, useState } from "react"; | |||
| import { isEmpty, upperCase, upperFirst } from "lodash"; | |||
| import { arrayToDateString } from "@/app/utils/formatUtil"; | |||
| interface Props { | |||
| filteredPickOrders: PickOrderResult[], | |||
| } | |||
| const PickOrders: React.FC<Props> = ({ | |||
| filteredPickOrders | |||
| }) => { | |||
| const { t } = useTranslation("pickOrder") | |||
| const [selectedRows, setSelectedRows] = useState<(string | number)[]>([]); | |||
| const handleConsolidatedRows = useCallback(() => { | |||
| }, [selectedRows]) | |||
| const columns = useMemo<Column<PickOrderResult>[]>(() => [ | |||
| { | |||
| name: "id", | |||
| label: "", | |||
| type: "checkbox", | |||
| disabled: (params) => { | |||
| return !isEmpty(params.consoCode); | |||
| } | |||
| }, | |||
| { | |||
| name: "code", | |||
| label: t("Code"), | |||
| }, | |||
| { | |||
| name: "consoCode", | |||
| label: t("Consolidated Code"), | |||
| renderCell: (params) => { | |||
| return params.consoCode ?? "N/A" | |||
| } | |||
| }, | |||
| { | |||
| name: "type", | |||
| label: t("type"), | |||
| renderCell: (params) => { | |||
| return upperCase(params.type) | |||
| } | |||
| }, | |||
| { | |||
| name: "items", | |||
| label: t("Items"), | |||
| renderCell: (params) => { | |||
| return params.items?.map((i) => i.name).join(", ") | |||
| } | |||
| }, | |||
| { | |||
| name: "targetDate", | |||
| label: t("Target Date"), | |||
| renderCell: (params) => { | |||
| return arrayToDateString(params.targetDate) | |||
| } | |||
| }, | |||
| { | |||
| name: "releasedBy", | |||
| label: t("Released By"), | |||
| }, | |||
| { | |||
| name: "status", | |||
| label: t("Status"), | |||
| renderCell: (params) => { | |||
| return upperFirst(params.status) | |||
| } | |||
| }, | |||
| ], [t]) | |||
| return ( | |||
| <Grid container rowGap={1}> | |||
| <Grid item xs={3}> | |||
| <Button | |||
| disabled={selectedRows.length < 1} | |||
| variant="outlined" | |||
| > | |||
| {t("Consolidate")} | |||
| </Button> | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| <SearchResults<PickOrderResult> items={filteredPickOrders} columns={columns} pagingController={{ | |||
| pageNum: 0, | |||
| pageSize: 0 | |||
| }} | |||
| checkboxIds={selectedRows} | |||
| setCheckboxIds={setSelectedRows} | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| ) | |||
| } | |||
| export default PickOrders; | |||
| @@ -1,6 +1,6 @@ | |||
| "use client"; | |||
| import React, { Dispatch, SetStateAction } from "react"; | |||
| import React, { ChangeEvent, Dispatch, MouseEvent, SetStateAction, useCallback, useState } from "react"; | |||
| import Paper from "@mui/material/Paper"; | |||
| import Table from "@mui/material/Table"; | |||
| import TableBody from "@mui/material/TableBody"; | |||
| @@ -14,6 +14,7 @@ import TableRow from "@mui/material/TableRow"; | |||
| import IconButton, { IconButtonOwnProps } from "@mui/material/IconButton"; | |||
| import { | |||
| ButtonOwnProps, | |||
| Checkbox, | |||
| Icon, | |||
| IconOwnProps, | |||
| SxProps, | |||
| @@ -26,7 +27,7 @@ export interface ResultWithId { | |||
| id: string | number; | |||
| } | |||
| type ColumnType = "icon" | "decimal" | "integer"; | |||
| type ColumnType = "icon" | "decimal" | "integer" | "checkbox"; | |||
| interface BaseColumn<T extends ResultWithId> { | |||
| name: keyof T; | |||
| @@ -56,6 +57,13 @@ interface IntegerColumn<T extends ResultWithId> extends BaseColumn<T> { | |||
| type: "integer"; | |||
| } | |||
| interface CheckboxColumn<T extends ResultWithId> extends BaseColumn<T> { | |||
| type: "checkbox"; | |||
| disabled?: (params: T) => boolean; | |||
| // checkboxIds: readonly (string | number)[], | |||
| // setCheckboxIds: (ids: readonly (string | number)[]) => void | |||
| } | |||
| interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> { | |||
| onClick: (item: T) => void; | |||
| buttonIcon: React.ReactNode; | |||
| @@ -67,6 +75,7 @@ export type Column<T extends ResultWithId> = | |||
| | BaseColumn<T> | |||
| | IconColumn<T> | |||
| | DecimalColumn<T> | |||
| | CheckboxColumn<T> | |||
| | ColumnWithAction<T>; | |||
| interface Props<T extends ResultWithId> { | |||
| @@ -77,9 +86,11 @@ interface Props<T extends ResultWithId> { | |||
| setPagingController?: Dispatch<SetStateAction<{ | |||
| pageNum: number; | |||
| pageSize: number; | |||
| }>> | |||
| pagingController: { pageNum: number; pageSize: number;}; | |||
| }>> | |||
| pagingController: { pageNum: number; pageSize: number; }; | |||
| isAutoPaging?: boolean; | |||
| checkboxIds?: (string | number)[]; | |||
| setCheckboxIds?: Dispatch<SetStateAction<(string | number)[]>>; | |||
| } | |||
| function isActionColumn<T extends ResultWithId>( | |||
| @@ -106,14 +117,20 @@ function isIntegerColumn<T extends ResultWithId>( | |||
| return column.type === "integer"; | |||
| } | |||
| function isCheckboxColumn<T extends ResultWithId>( | |||
| column: Column<T> | |||
| ): column is CheckboxColumn<T> { | |||
| return column.type === "checkbox"; | |||
| } | |||
| // Icon Component Functions | |||
| function convertObjectKeysToLowercase<T extends object>( | |||
| obj: T | |||
| ): object | undefined { | |||
| return obj | |||
| ? Object.fromEntries( | |||
| Object.entries(obj).map(([key, value]) => [key.toLowerCase(), value]) | |||
| ) | |||
| Object.entries(obj).map(([key, value]) => [key.toLowerCase(), value]) | |||
| ) | |||
| : undefined; | |||
| } | |||
| @@ -144,9 +161,9 @@ function handleIconIcons<T extends ResultWithId>( | |||
| return column.icon ?? <CheckCircleOutlineIcon fontSize="small" />; | |||
| } | |||
| export const defaultPagingController:{ pageNum: number; pageSize: number} = { | |||
| "pageNum": 1, | |||
| "pageSize": 10, | |||
| export const defaultPagingController: { pageNum: number; pageSize: number } = { | |||
| "pageNum": 1, | |||
| "pageSize": 10, | |||
| } | |||
| function SearchResults<T extends ResultWithId>({ | |||
| items, | |||
| @@ -155,7 +172,9 @@ function SearchResults<T extends ResultWithId>({ | |||
| pagingController, | |||
| setPagingController, | |||
| isAutoPaging = true, | |||
| totalCount | |||
| totalCount, | |||
| checkboxIds = [], | |||
| setCheckboxIds = undefined, | |||
| }: Props<T>) { | |||
| const [page, setPage] = React.useState(0); | |||
| const [rowsPerPage, setRowsPerPage] = React.useState(10); | |||
| @@ -189,6 +208,28 @@ function SearchResults<T extends ResultWithId>({ | |||
| } | |||
| }; | |||
| // checkbox | |||
| const handleRowClick = useCallback((event: MouseEvent<unknown>, id: string | number) => { | |||
| if (setCheckboxIds) { | |||
| const selectedIndex = checkboxIds.indexOf(id); | |||
| let newSelected: (string | number)[] = []; | |||
| if (selectedIndex === -1) { | |||
| newSelected = newSelected.concat(checkboxIds, id); | |||
| } else if (selectedIndex === 0) { | |||
| newSelected = newSelected.concat(checkboxIds.slice(1)); | |||
| } else if (selectedIndex === checkboxIds.length - 1) { | |||
| newSelected = newSelected.concat(checkboxIds.slice(0, -1)); | |||
| } else if (selectedIndex > 0) { | |||
| newSelected = newSelected.concat( | |||
| checkboxIds.slice(0, selectedIndex), | |||
| checkboxIds.slice(selectedIndex + 1), | |||
| ); | |||
| } | |||
| setCheckboxIds(newSelected); | |||
| } | |||
| }, [checkboxIds]) | |||
| const table = ( | |||
| <> | |||
| <TableContainer sx={{ maxHeight: 440 }}> | |||
| @@ -209,29 +250,16 @@ function SearchResults<T extends ResultWithId>({ | |||
| <TableBody> | |||
| {isAutoPaging | |||
| ? items | |||
| .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) | |||
| .map((item) => { | |||
| return ( | |||
| <TableRow hover tabIndex={-1} key={item.id}> | |||
| {columns.map((column, idx) => { | |||
| const columnName = column.name; | |||
| return ( | |||
| <TabelCells | |||
| key={`${columnName.toString()}-${idx}`} | |||
| column={column} | |||
| columnName={columnName} | |||
| idx={idx} | |||
| item={item} | |||
| /> | |||
| ); | |||
| })} | |||
| </TableRow> | |||
| ); | |||
| }) | |||
| : items.map((item) => { | |||
| .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) | |||
| .map((item) => { | |||
| return ( | |||
| <TableRow hover tabIndex={-1} key={item.id}> | |||
| <TableRow | |||
| hover | |||
| tabIndex={-1} | |||
| key={item.id} | |||
| onClick={setCheckboxIds ? (event) => handleRowClick(event, item.id) : undefined} | |||
| role={setCheckboxIds ? "checkbox" : undefined} | |||
| > | |||
| {columns.map((column, idx) => { | |||
| const columnName = column.name; | |||
| @@ -242,12 +270,33 @@ function SearchResults<T extends ResultWithId>({ | |||
| columnName={columnName} | |||
| idx={idx} | |||
| item={item} | |||
| checkboxIds={checkboxIds} | |||
| /> | |||
| ); | |||
| })} | |||
| </TableRow> | |||
| ); | |||
| })} | |||
| }) | |||
| : items.map((item) => { | |||
| return ( | |||
| <TableRow hover tabIndex={-1} key={item.id}> | |||
| {columns.map((column, idx) => { | |||
| const columnName = column.name; | |||
| return ( | |||
| <TabelCells | |||
| key={`${columnName.toString()}-${idx}`} | |||
| column={column} | |||
| columnName={columnName} | |||
| idx={idx} | |||
| item={item} | |||
| checkboxIds={checkboxIds} | |||
| /> | |||
| ); | |||
| })} | |||
| </TableRow> | |||
| ); | |||
| })} | |||
| </TableBody> | |||
| </Table> | |||
| </TableContainer> | |||
| @@ -255,8 +304,8 @@ function SearchResults<T extends ResultWithId>({ | |||
| rowsPerPageOptions={[10, 25, 100]} | |||
| component="div" | |||
| count={!totalCount || totalCount == 0 | |||
| ? items.length | |||
| : totalCount | |||
| ? items.length | |||
| : totalCount | |||
| } | |||
| // count={ | |||
| // !pagingController || pagingController.totalCount == 0 | |||
| @@ -280,6 +329,7 @@ interface TableCellsProps<T extends ResultWithId> { | |||
| columnName: keyof T; | |||
| idx: number; | |||
| item: T; | |||
| checkboxIds: (string | number)[]; | |||
| } | |||
| function TabelCells<T extends ResultWithId>({ | |||
| @@ -287,7 +337,10 @@ function TabelCells<T extends ResultWithId>({ | |||
| columnName, | |||
| idx, | |||
| item, | |||
| checkboxIds = [], | |||
| }: TableCellsProps<T>) { | |||
| const isItemSelected = checkboxIds.includes(item.id); | |||
| return ( | |||
| <TableCell | |||
| align={column.align} | |||
| @@ -309,6 +362,8 @@ function TabelCells<T extends ResultWithId>({ | |||
| <>{decimalFormatter.format(Number(item[columnName]))}</> | |||
| ) : isIntegerColumn(column) ? ( | |||
| <>{integerFormatter.format(Number(item[columnName]))}</> | |||
| ) : isCheckboxColumn(column) ? ( | |||
| <Checkbox disabled={column.disabled ? column.disabled(item) : undefined} checked={isItemSelected} /> | |||
| ) : column.renderCell ? ( | |||
| column.renderCell(item) | |||
| ) : ( | |||