Browse Source

Add Inventory

create_edit_user
cyril.tsui 2 months ago
parent
commit
144533e804
12 changed files with 392 additions and 63 deletions
  1. +34
    -0
      src/app/(main)/inventory/page.tsx
  2. +5
    -16
      src/app/(main)/scheduling/detail/page.tsx
  3. +0
    -0
      src/app/api/inventory/actions.ts
  4. +30
    -0
      src/app/api/inventory/index.ts
  5. +1
    -0
      src/components/Breadcrumb/Breadcrumb.tsx
  6. +12
    -4
      src/components/DetailScheduleDetail/ViewByFGDetails.tsx
  7. +139
    -0
      src/components/InventorySearch/InventorySearch.tsx
  8. +24
    -0
      src/components/InventorySearch/InventorySearchWrapper.tsx
  9. +1
    -0
      src/components/InventorySearch/index.ts
  10. +2
    -2
      src/components/NavigationContent/NavigationContent.tsx
  11. +3
    -3
      src/components/SearchBox/SearchBox.tsx
  12. +141
    -38
      src/components/SearchResults/SearchResults.tsx

+ 34
- 0
src/app/(main)/inventory/page.tsx View File

@@ -0,0 +1,34 @@
import { preloadInventory } from "@/app/api/inventory";
import InventorySearch from "@/components/InventorySearch";
import { getServerI18n } from "@/i18n";
import { Stack, Typography } from "@mui/material";
import { Metadata } from "next";
import { Suspense } from "react";

export const metadata: Metadata = {
title: "Inventory"
}

const Inventory: React.FC = async () => {
const { t } = await getServerI18n("inventory")

preloadInventory()

return <>
<Stack
direction="row"
justifyContent={"space-between"}
flexWrap={"wrap"}
rowGap={2}
>
<Typography variant="h4" marginInlineEnd={2}>
{t("Inventory")}
</Typography>
</Stack>
<Suspense fallback={<InventorySearch.Loading />}>
<InventorySearch />
</Suspense>
</>;
}

export default Inventory;

+ 5
- 16
src/app/(main)/scheduling/detail/page.tsx View File

@@ -1,19 +1,16 @@
import { TypeEnum } from "@/app/utils/typeEnum"; import { TypeEnum } from "@/app/utils/typeEnum";
import ItemsSearch from "@/components/ItemsSearch";
import DetailSchedule from "@/components/DetailSchedule";
import { getServerI18n } from "@/i18n"; import { getServerI18n } from "@/i18n";
import Add from "@mui/icons-material/Add";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack"; import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import { Metadata } from "next"; import { Metadata } from "next";
import Link from "next/link";
import { Suspense } from "react"; import { Suspense } from "react";


export const metadata: Metadata = { export const metadata: Metadata = {
title: "Detail Scheduling", title: "Detail Scheduling",
}; };


const detailScheduling: React.FC = async () => {
const DetailScheduling: React.FC = async () => {
const project = TypeEnum.PRODUCT const project = TypeEnum.PRODUCT
const { t } = await getServerI18n(project); const { t } = await getServerI18n(project);
// preloadClaims(); // preloadClaims();
@@ -29,20 +26,12 @@ const detailScheduling: React.FC = async () => {
<Typography variant="h4" marginInlineEnd={2}> <Typography variant="h4" marginInlineEnd={2}>
{t("Detail Scheduling")} {t("Detail Scheduling")}
</Typography> </Typography>
{/* <Button
variant="contained"
startIcon={<Add />}
LinkComponent={Link}
href="product/create"
>
{t("Create product")}
</Button> */}
</Stack> </Stack>
<Suspense fallback={<ItemsSearch.Loading />}>
<ItemsSearch />
<Suspense fallback={<DetailSchedule.Loading />}>
<DetailSchedule />
</Suspense> </Suspense>
</> </>
); );
}; };


export default detailScheduling;
export default DetailScheduling;

+ 0
- 0
src/app/api/inventory/actions.ts View File


+ 30
- 0
src/app/api/inventory/index.ts View File

@@ -0,0 +1,30 @@
import { serverFetchJson } from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";
import { cache } from "react";
import "server-only";

export interface InventoryResult {
id: number;
code: string;
name: string;
type: string;
qty: number;
uomCode: string;
uomUdfudesc: string;
germPerSmallestUnit: number;
qtyPerSmallestUnit: number;
smallestUnit: string;
price: number;
currencyName: string;
status: string;
}

export const preloadInventory = () => {
fetchInventories();
}

export const fetchInventories = cache(async() => {
return serverFetchJson<InventoryResult[]>(`${BASE_API_URL}/inventory/list`, {
next: { tags: ["inventories"]}
})
})

+ 1
- 0
src/components/Breadcrumb/Breadcrumb.tsx View File

@@ -18,6 +18,7 @@ const pathToLabelMap: { [path: string]: string } = {
"/scheduling/rough/edit": "FG & Material Demand Forecast Detail", "/scheduling/rough/edit": "FG & Material Demand Forecast Detail",
"/scheduling/detail": "Detail Scheduling", "/scheduling/detail": "Detail Scheduling",
"/scheduling/detail/edit": "FG Production Schedule", "/scheduling/detail/edit": "FG Production Schedule",
"/inventory": "Inventory",
}; };


const Breadcrumb = () => { const Breadcrumb = () => {


+ 12
- 4
src/components/DetailScheduleDetail/ViewByFGDetails.tsx View File

@@ -101,14 +101,14 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
() => [ () => [
[ [
{ {
id: 1, jobNo: "JO20250507001", priority: 85, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661,
id: 1, jobNo: "JO20250507001", estimatedProductionTime: "1 hr", priority: 85, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661,
lines: [ lines: [
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 100, purchaseQty: 20 }, { id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 100, purchaseQty: 20 },
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 80, purchaseQty: 10 } { id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 80, purchaseQty: 10 }
] ]
}, },
{ {
id: 2, jobNo: "JO20250507002", priority: 80, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520,
id: 2, jobNo: "JO20250507002", estimatedProductionTime: "2 hrs", priority: 80, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520,
lines: [ lines: [
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 1000, purchaseQty: 190.00 }, { id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 1000, purchaseQty: 190.00 },
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 1000, purchaseQty: 250.00 }, { id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 1000, purchaseQty: 250.00 },
@@ -116,7 +116,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
] ]
}, },
{ {
id: 3, jobNo: "JO20250507003", priority: 35, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0,
id: 3, jobNo: "JO20250507003", estimatedProductionTime: "5 hrs : 15 mins", priority: 35, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0,
lines: [ lines: [
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, { id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 },
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, { id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 },
@@ -132,7 +132,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
] ]
}, },
{ {
id: 4, jobNo: "JO20250507004", priority: 20, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1,
id: 4, jobNo: "JO20250507004", estimatedProductionTime: "3 hrs", priority: 20, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1,
lines: [ lines: [
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, { id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 },
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, { id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 },
@@ -525,6 +525,14 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
return row.productionQty return row.productionQty
} }
}, },
{
field: "estimatedProductionTime",
label: "Estimated Production Time",
type: "read-only",
style: {
textAlign: "right",
}
},
{ {
field: "priority", field: "priority",
label: "Production Priority", label: "Production Priority",


+ 139
- 0
src/components/InventorySearch/InventorySearch.tsx View File

@@ -0,0 +1,139 @@
"use client"
import { InventoryResult } from "@/app/api/inventory";
import { useTranslation } from "react-i18next";
import SearchBox, { Criterion } from "../SearchBox";
import { useCallback, useMemo, useState } from "react";
import { uniq } from "lodash";
import SearchResults, { Column } from "../SearchResults";
import { CheckCircleOutline, DoDisturb } from "@mui/icons-material";

interface Props {
inventories: InventoryResult[];
}

type SearchQuery = Partial<Omit<InventoryResult,
| "id"
| "qty"
| "uomCode"
| "uomUdfudesc"
| "germPerSmallestUnit"
| "qtyPerSmallestUnit"
| "itemSmallestUnit"
| "price"
| "description"
| "category">>;
type SearchParamNames = keyof SearchQuery;

const InventorySearch: React.FC<Props> = ({
inventories,
}) => {
const { t } = useTranslation("inventories");

const [filteredInventories, setFilteredInventories] = useState(inventories)

const searchCriteria: Criterion<SearchParamNames>[] = useMemo(() => [
{ label: t("Code"), paramName: "code", type: "text" },
{ label: t("Name"), paramName: "name", type: "text" },
{ label: t("Type"), paramName: "type", type: "select", options: uniq(inventories.map(i => i.type)) },
{ label: t("Status"), paramName: "status", type: "select", options: uniq(inventories.map(i => i.status)) },
], [t]
);

const onReset = useCallback(() => {
setFilteredInventories(inventories)
}, [inventories])

const columns = useMemo<Column<InventoryResult>[]>(
() => [
{
name: "code",
label: t("Code"),
},
{
name: "name",
label: t("Name"),
},
{
name: "type",
label: t("Type"),
},
{
name: "qty",
label: t("Qty"),
align: "right",
headerAlign: "right",
type: "integer"
},
{
name: "uomUdfudesc",
label: t("UoM"),
},
{
name: "qtyPerSmallestUnit",
label: t("Qty Per Smallest Unit"),
align: "right",
headerAlign: "right",
type: "decimal"
},
{
name: "smallestUnit",
label: t("Smallest Unit"),
},
// {
// name: "price",
// label: t("Price"),
// align: "right",
// sx: {
// alignItems: "right",
// justifyContent: "end",
// }
// },
// {
// name: "currencyName",
// label: t("Currency"),
// },
// {
// name: "status",
// label: t("Status"),
// type: "icon",
// icons: {
// available: <CheckCircleOutline fontSize="small"/>,
// unavailable: <DoDisturb fontSize="small"/>,
// },
// colors: {
// available: "success",
// unavailable: "error",
// }
// },
], [t]
)

return (
<>
<SearchBox
criteria={searchCriteria}
onSearch={(query) => {
console.log(query)
console.log(inventories)
setFilteredInventories(
inventories.filter(
(i) =>
i.code.toLowerCase().includes(query.code.toLowerCase()) &&
i.name.toLowerCase().includes(query.name.toLowerCase()) &&
(query.type == "All" || i.type.toLowerCase().includes(query.type.toLowerCase())) &&
(query.status == "All" || i.status.toLowerCase().includes(query.status.toLowerCase()))
)
)
}}
onReset={onReset}
/>
<SearchResults<InventoryResult> items={filteredInventories} columns={columns} pagingController={{
pageNum: 0,
pageSize: 0,
totalCount: 0,
}} />
</>
)
}

export default InventorySearch

+ 24
- 0
src/components/InventorySearch/InventorySearchWrapper.tsx View File

@@ -0,0 +1,24 @@
import React from "react";
import GeneralLoading from "../General/GeneralLoading"
import { fetchInventories } from "@/app/api/inventory";
import InventorySearch from "./InventorySearch";

interface SubComponents {
Loading: typeof GeneralLoading;
}

const InventorySearchWrapper: React.FC & SubComponents = async () => {
const [
inventories
] = await Promise.all([
fetchInventories()
])
return <InventorySearch inventories={inventories}/>
}


InventorySearchWrapper.Loading = GeneralLoading;

export default InventorySearchWrapper

+ 1
- 0
src/components/InventorySearch/index.ts View File

@@ -0,0 +1 @@
export { default } from "./InventorySearchWrapper"

+ 2
- 2
src/components/NavigationContent/NavigationContent.tsx View File

@@ -76,8 +76,8 @@ const NavigationContent: React.FC = () => {
}, },
{ {
icon: <RequestQuote />, icon: <RequestQuote />,
label: "View item In-out And invertory Ledger",
path: "",
label: "View item In-out And inventory Ledger",
path: "/inventory",
}, },
], ],
}, },


+ 3
- 3
src/components/SearchBox/SearchBox.tsx View File

@@ -28,7 +28,7 @@ interface BaseCriterion<T extends string> {
label2?: string; label2?: string;
paramName: T; paramName: T;
paramName2?: T; paramName2?: T;
options?: T[];
options?: T[] | string[];
filterObj?: T; filterObj?: T;
handleSelectionChange?: (selectedOptions: T[]) => void; handleSelectionChange?: (selectedOptions: T[]) => void;
} }
@@ -39,11 +39,11 @@ interface TextCriterion<T extends string> extends BaseCriterion<T> {


interface SelectCriterion<T extends string> extends BaseCriterion<T> { interface SelectCriterion<T extends string> extends BaseCriterion<T> {
type: "select"; type: "select";
options: T[];
options: string[];
} }


interface MultiSelectCriterion<T extends string> extends BaseCriterion<T> { interface MultiSelectCriterion<T extends string> extends BaseCriterion<T> {
type: "select";
type: "multi-select";
options: T[]; options: T[];
selectedOptions: T[]; selectedOptions: T[];
handleSelectionChange: (selectedOptions: T[]) => void; handleSelectionChange: (selectedOptions: T[]) => void;


+ 141
- 38
src/components/SearchResults/SearchResults.tsx View File

@@ -4,32 +4,62 @@ import React 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";
import TableCell from "@mui/material/TableCell";
import TableCell, { TableCellProps } from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer"; import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead"; import TableHead from "@mui/material/TableHead";
import TablePagination, { import TablePagination, {
TablePaginationProps, TablePaginationProps,
} from "@mui/material/TablePagination"; } from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow"; import TableRow from "@mui/material/TableRow";
import IconButton, {IconButtonOwnProps} from "@mui/material/IconButton";
import IconButton, { IconButtonOwnProps } from "@mui/material/IconButton";
import { ButtonOwnProps, Icon, IconOwnProps, SxProps, Theme } from "@mui/material";
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil";


export interface ResultWithId { export interface ResultWithId {
id: string | number; id: string | number;
} }


type ColumnType = "icon" | "decimal" | "integer";

interface BaseColumn<T extends ResultWithId> { interface BaseColumn<T extends ResultWithId> {
name: keyof T; name: keyof T;
label: string; label: string;
align?: TableCellProps["align"];
headerAlign?: TableCellProps["align"];
sx?: SxProps<Theme> | undefined;
style?: Partial<HTMLElement["style"]> & { [propName: string]: string };
type?: ColumnType;
}

interface IconColumn<T extends ResultWithId> extends BaseColumn<T> {
name: keyof T;
type: "icon";
icon?: React.ReactNode;
icons?: { [columnValue in keyof T]: React.ReactNode };
color?: IconOwnProps["color"];
colors?: { [columnValue in keyof T]: IconOwnProps["color"] };
}

interface DecimalColumn<T extends ResultWithId> extends BaseColumn<T> {
type: "decimal";
}

interface IntegerColumn<T extends ResultWithId> extends BaseColumn<T> {
type: "integer";
} }


interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> { interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> {
onClick: (item: T) => void; onClick: (item: T) => void;
buttonIcon: React.ReactNode; buttonIcon: React.ReactNode;
buttonIcons: { [columnValue in keyof T]: React.ReactNode };
buttonColor?: IconButtonOwnProps["color"]; buttonColor?: IconButtonOwnProps["color"];
} }


export type Column<T extends ResultWithId> = export type Column<T extends ResultWithId> =
| BaseColumn<T> | BaseColumn<T>
| IconColumn<T>
| DecimalColumn<T>
| ColumnWithAction<T>; | ColumnWithAction<T>;


interface Props<T extends ResultWithId> { interface Props<T extends ResultWithId> {
@@ -42,7 +72,7 @@ interface Props<T extends ResultWithId> {
totalCount: number totalCount: number
}) | { pageNum: number; pageSize: number; totalCount: number })) => void, }) | { pageNum: number; pageSize: number; totalCount: number })) => void,
pagingController: { pageNum: number; pageSize: number; totalCount: number }, pagingController: { pageNum: number; pageSize: number; totalCount: number },
isAutoPaging: boolean
isAutoPaging?: boolean
} }


function isActionColumn<T extends ResultWithId>( function isActionColumn<T extends ResultWithId>(
@@ -51,14 +81,67 @@ function isActionColumn<T extends ResultWithId>(
return Boolean((column as ColumnWithAction<T>).onClick); return Boolean((column as ColumnWithAction<T>).onClick);
} }


function isIconColumn<T extends ResultWithId>(
column: Column<T>,
): column is IconColumn<T> {
return column.type === "icon";
}

function isDecimalColumn<T extends ResultWithId>(
column: Column<T>,
): column is DecimalColumn<T> {
return column.type === "decimal";
}

function isIntegerColumn<T extends ResultWithId>(
column: Column<T>,
): column is IntegerColumn<T> {
return column.type === "integer";
}

// 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])
) : undefined;
}

function handleIconColors<T extends ResultWithId>(
column: IconColumn<T>,
value: T[keyof T],
): IconOwnProps["color"] {
const colors = convertObjectKeysToLowercase(column.colors ?? {});
const valueKey = String(value).toLowerCase() as keyof typeof colors;

if (colors && valueKey in colors) {
return colors[valueKey];
}

return column.color ?? "primary";
};

function handleIconIcons<T extends ResultWithId>(
column: IconColumn<T>,
value: T[keyof T],
): React.ReactNode {
const icons = convertObjectKeysToLowercase(column.icons ?? {});
const valueKey = String(value).toLowerCase() as keyof typeof icons;

if (icons && valueKey in icons) {
return icons[valueKey];
}

return column.icon ?? <CheckCircleOutlineIcon fontSize="small" />;
};

function SearchResults<T extends ResultWithId>({ function SearchResults<T extends ResultWithId>({
items,
columns,
noWrapper,
pagingController,
setPagingController,
isAutoPaging = true,
}: Props<T>) {
items,
columns,
noWrapper,
pagingController,
setPagingController,
isAutoPaging = true,
}: Props<T>) {
const [page, setPage] = React.useState(0); const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10); const [rowsPerPage, setRowsPerPage] = React.useState(10);


@@ -90,12 +173,12 @@ function SearchResults<T extends ResultWithId>({


const table = ( const table = (
<> <>
<TableContainer sx={{maxHeight: 440}}>
<TableContainer sx={{ maxHeight: 440 }}>
<Table stickyHeader> <Table stickyHeader>
<TableHead> <TableHead>
<TableRow> <TableRow>
{columns.map((column, idx) => ( {columns.map((column, idx) => (
<TableCell key={`${column.name.toString()}${idx}`}>
<TableCell align={column.headerAlign} sx={column.sx} key={`${column.name.toString()}${idx}`}>
{column.label} {column.label}
</TableCell> </TableCell>
))} ))}
@@ -113,18 +196,7 @@ function SearchResults<T extends ResultWithId>({
const columnName = column.name; const columnName = column.name;


return ( return (
<TableCell key={`${columnName.toString()}-${idx}`}>
{isActionColumn(column) ? (
<IconButton
color={column.buttonColor ?? "primary"}
onClick={() => column.onClick(item)}
>
{column.buttonIcon}
</IconButton>
) : (
<>{item[columnName] as string}</>
)}
</TableCell>
<TabelCells key={`${columnName.toString()}-${idx}`} column={column} columnName={columnName} idx={idx} item={item}/>
); );
})} })}
</TableRow> </TableRow>
@@ -139,19 +211,8 @@ function SearchResults<T extends ResultWithId>({
const columnName = column.name; const columnName = column.name;


return ( return (
<TableCell key={`${columnName.toString()}-${idx}`}>
{isActionColumn(column) ? (
<IconButton
color={column.buttonColor ?? "primary"}
onClick={() => column.onClick(item)}
>
{column.buttonIcon}
</IconButton>
) : (
<>{item[columnName] as string}</>
)}
</TableCell>
);
<TabelCells key={`${columnName.toString()}-${idx}`} column={column} columnName={columnName} idx={idx} item={item}/>
);
})} })}
</TableRow> </TableRow>
); );
@@ -172,7 +233,49 @@ function SearchResults<T extends ResultWithId>({
</> </>
); );


return noWrapper ? table : <Paper sx={{overflow: "hidden"}}>{table}</Paper>;
return noWrapper ? table : <Paper sx={{ overflow: "hidden" }}>{table}</Paper>;
}

// Table cells
interface TableCellsProps<T extends ResultWithId> {
column: Column<T>,
columnName: keyof T,
idx: number,
item: T,
}

function TabelCells<T extends ResultWithId>({
column,
columnName,
idx,
item
}: TableCellsProps<T>) {
return (
<TableCell align={column.align} sx={column.sx} key={`${columnName.toString()}-${idx}`}>
{isActionColumn(column) ? (
<IconButton
color={column.buttonColor ?? "primary"}
onClick={() => column.onClick(item)}
>
{column.buttonIcon}
</IconButton>
) :
isIconColumn(column) ? (
<Icon
color={handleIconColors(column, item[columnName])}
>
{handleIconIcons(column, item[columnName])}
</Icon>
) :
isDecimalColumn(column) ? (
<>{decimalFormatter.format(Number(item[columnName]))}</>
) :
isIntegerColumn(column) ? (
<>{integerFormatter.format(Number(item[columnName]))}</>
) : (
<>{item[columnName] as string}</>
)}
</TableCell>)
} }


export default SearchResults; export default SearchResults;

Loading…
Cancel
Save