Browse Source

[feature] update null check

create_edit_user
jason.lam 4 months ago
parent
commit
d2a81b9b72
2 changed files with 140 additions and 129 deletions
  1. +3
    -3
      src/components/ItemsSearch/ItemsSearch.tsx
  2. +137
    -126
      src/components/SearchResults/SearchResults.tsx

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

@@ -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 {fetchAllItemsByPage, ItemsResult} from "@/app/api/settings/item";
import { ItemsResult} 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";
@@ -11,7 +11,7 @@ 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 axiosInstance, {SetupAxiosInterceptors} from "@/app/(main)/axios/axiosInstance";
import axiosInstance from "@/app/(main)/axios/axiosInstance";


type Props = { type Props = {
items: ItemsResult[]; items: ItemsResult[];
@@ -23,7 +23,7 @@ const ItemsSearch: React.FC<Props> = ({ items }) => {
const [filteredItems, setFilteredItems] = useState<ItemsResult[]>(items); const [filteredItems, setFilteredItems] = useState<ItemsResult[]>(items);
const { t } = useTranslation("items"); const { t } = useTranslation("items");
const router = useRouter(); const router = useRouter();
const [filterObj, setFilterObj] = useState();
const [filterObj, setFilterObj] = useState({});
const [pagingController, setPagingController] = useState({ const [pagingController, setPagingController] = useState({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,


+ 137
- 126
src/components/SearchResults/SearchResults.tsx View File

@@ -8,160 +8,171 @@ import TableCell 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";


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


interface BaseColumn<T extends ResultWithId> { interface BaseColumn<T extends ResultWithId> {
name: keyof T;
label: string;
name: keyof T;
label: string;
} }


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


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


interface Props<T extends ResultWithId> { interface Props<T extends ResultWithId> {
items: T[];
columns: Column<T>[];
noWrapper?: boolean;
items: T[],
columns: Column<T>[],
noWrapper?: boolean,
setPagingController: (value: (((prevState: { pageNum: number; pageSize: number; totalCount: number }) => {
pageNum: number;
pageSize: number;
totalCount: number
}) | { pageNum: number; pageSize: number; totalCount: number })) => void,
pagingController: { pageNum: number; pageSize: number; totalCount: number },
isAutoPaging: boolean
} }


function isActionColumn<T extends ResultWithId>( function isActionColumn<T extends ResultWithId>(
column: Column<T>,
column: Column<T>,
): column is ColumnWithAction<T> { ): column is ColumnWithAction<T> {
return Boolean((column as ColumnWithAction<T>).onClick);
return Boolean((column as ColumnWithAction<T>).onClick);
} }


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


const handleChangePage: TablePaginationProps["onPageChange"] = (
_event,
newPage,
) => {
setPage(newPage);
setPagingController({
...pagingController,
pageNum: newPage+1,
})
};
const handleChangePage: TablePaginationProps["onPageChange"] = (
_event,
newPage,
) => {
setPage(newPage);
if (setPagingController) {
setPagingController({
...pagingController,
pageNum: newPage + 1,
})
}
};


const handleChangeRowsPerPage: TablePaginationProps["onRowsPerPageChange"] = (
event,
) => {
setRowsPerPage(+event.target.value);
setPage(0);
setPagingController({
...pagingController,
pageNum: +event.target.value,
})
};
const handleChangeRowsPerPage: TablePaginationProps["onRowsPerPageChange"] = (
event,
) => {
setRowsPerPage(+event.target.value);
setPage(0);
if (setPagingController) {
setPagingController({
...pagingController,
pageNum: +event.target.value,
})
}
};


const table = (
<>
<TableContainer sx={{ maxHeight: 440 }}>
<Table stickyHeader>
<TableHead>
<TableRow>
{columns.map((column, idx) => (
<TableCell key={`${column.name.toString()}${idx}`}>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<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;
const table = (
<>
<TableContainer sx={{maxHeight: 440}}>
<Table stickyHeader>
<TableHead>
<TableRow>
{columns.map((column, idx) => (
<TableCell key={`${column.name.toString()}${idx}`}>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<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 (
<TableCell key={`${columnName.toString()}-${idx}`}>
{isActionColumn(column) ? (
<IconButton
color={column.buttonColor ?? "primary"}
onClick={() => column.onClick(item)}
>
{column.buttonIcon}
</IconButton>
) : (
<>{item[columnName] as string}</>
)}
</TableCell>
);
})}
</TableRow>
);
})
:
items
.map((item) => {
return (
<TableRow hover tabIndex={-1} key={item.id}>
{columns.map((column, idx) => {
const columnName = column.name;
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>
);
})}
</TableRow>
);
})
:
items
.map((item) => {
return (
<TableRow hover tabIndex={-1} key={item.id}>
{columns.map((column, idx) => {
const columnName = column.name;


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>
);
})}
</TableRow>
);
})
}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={pagingController.totalCount == 0 ? items.length : pagingController.totalCount}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</>
);
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>
);
})}
</TableRow>
);
})
}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={pagingController.totalCount == 0 ? items.length : pagingController.totalCount}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</>
);


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


export default SearchResults; export default SearchResults;

Loading…
Cancel
Save