| @@ -7,6 +7,7 @@ import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig"; | |||||
| import Stack from "@mui/material/Stack"; | import Stack from "@mui/material/Stack"; | ||||
| import Breadcrumb from "@/components/Breadcrumb"; | import Breadcrumb from "@/components/Breadcrumb"; | ||||
| import {AxiosProvider} from "@/app/(main)/axios/AxiosProvider"; | import {AxiosProvider} from "@/app/(main)/axios/AxiosProvider"; | ||||
| import {SetupAxiosInterceptors} from "@/app/(main)/axios/axiosInstance"; | |||||
| export default async function MainLayout({ | export default async function MainLayout({ | ||||
| children, | children, | ||||
| @@ -19,6 +20,10 @@ export default async function MainLayout({ | |||||
| redirect("/login"); | redirect("/login"); | ||||
| } | } | ||||
| if(session){ | |||||
| SetupAxiosInterceptors(session?.accessToken); | |||||
| } | |||||
| return ( | return ( | ||||
| <AxiosProvider> | <AxiosProvider> | ||||
| <> | <> | ||||
| @@ -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 from "@/app/(main)/axios/axiosInstance"; | |||||
| import axiosInstance, {SetupAxiosInterceptors} from "@/app/(main)/axios/axiosInstance"; | |||||
| type Props = { | type Props = { | ||||
| items: ItemsResult[]; | items: ItemsResult[]; | ||||
| @@ -27,6 +27,7 @@ const ItemsSearch: React.FC<Props> = ({ items }) => { | |||||
| const [pagingController, setPagingController] = useState({ | const [pagingController, setPagingController] = useState({ | ||||
| pageNum: 1, | pageNum: 1, | ||||
| pageSize: 10, | pageSize: 10, | ||||
| totalCount: 0, | |||||
| }) | }) | ||||
| const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | ||||
| @@ -79,10 +80,9 @@ const ItemsSearch: React.FC<Props> = ({ items }) => { | |||||
| ); | ); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (filterObj) { | |||||
| refetchData(filterObj); | |||||
| } | |||||
| }, [filterObj, pagingController]); | |||||
| refetchData(filterObj); | |||||
| }, [filterObj, pagingController.pageNum, pagingController.pageSize]); | |||||
| const refetchData = async (filterObj: SearchQuery) => { | const refetchData = async (filterObj: SearchQuery) => { | ||||
| // Make sure the API endpoint is correct | // Make sure the API endpoint is correct | ||||
| @@ -96,6 +96,10 @@ const ItemsSearch: React.FC<Props> = ({ items }) => { | |||||
| const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { params }); | const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { params }); | ||||
| console.log("[debug] resposne", response) | console.log("[debug] resposne", response) | ||||
| setFilteredItems(response.data.records); | setFilteredItems(response.data.records); | ||||
| setPagingController({ | |||||
| ...pagingController, | |||||
| totalCount: response.data.total | |||||
| }) | |||||
| return response; // Return the data from the response | return response; // Return the data from the response | ||||
| } catch (error) { | } catch (error) { | ||||
| console.error('Error fetching items:', error); | console.error('Error fetching items:', error); | ||||
| @@ -132,6 +136,7 @@ const ItemsSearch: React.FC<Props> = ({ items }) => { | |||||
| columns={columns} | columns={columns} | ||||
| setPagingController={setPagingController} | setPagingController={setPagingController} | ||||
| pagingController={pagingController} | pagingController={pagingController} | ||||
| isAutoPaging={false} | |||||
| /> | /> | ||||
| </> | </> | ||||
| ); | ); | ||||
| @@ -49,7 +49,8 @@ function SearchResults<T extends ResultWithId>({ | |||||
| columns, | columns, | ||||
| noWrapper, | noWrapper, | ||||
| pagingController, | pagingController, | ||||
| setPagingController | |||||
| setPagingController, | |||||
| isAutoPaging = true, | |||||
| }: Props<T>) { | }: 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); | ||||
| @@ -61,7 +62,7 @@ function SearchResults<T extends ResultWithId>({ | |||||
| setPage(newPage); | setPage(newPage); | ||||
| setPagingController({ | setPagingController({ | ||||
| ...pagingController, | ...pagingController, | ||||
| pageNum: newPage, | |||||
| pageNum: newPage+1, | |||||
| }) | }) | ||||
| }; | }; | ||||
| @@ -90,39 +91,68 @@ function SearchResults<T extends ResultWithId>({ | |||||
| </TableRow> | </TableRow> | ||||
| </TableHead> | </TableHead> | ||||
| <TableBody> | <TableBody> | ||||
| {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; | |||||
| { | |||||
| 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> | |||||
| ); | |||||
| })} | |||||
| 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> | </TableBody> | ||||
| </Table> | </Table> | ||||
| </TableContainer> | </TableContainer> | ||||
| <TablePagination | <TablePagination | ||||
| rowsPerPageOptions={[10, 25, 100]} | rowsPerPageOptions={[10, 25, 100]} | ||||
| component="div" | component="div" | ||||
| count={items.length} | |||||
| count={pagingController.totalCount == 0 ? items.length : pagingController.totalCount} | |||||
| rowsPerPage={rowsPerPage} | rowsPerPage={rowsPerPage} | ||||
| page={page} | page={page} | ||||
| onPageChange={handleChangePage} | onPageChange={handleChangePage} | ||||