@@ -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) | |||
) : ( | |||