|
- "use client";
-
- import { DoResult } from "@/app/api/do";
- import { DoSearchAll, DoSearchLiteResponse, fetchDoSearch, fetchAllDoSearch, fetchDoSearchList, releaseDo ,startBatchReleaseAsync, getBatchReleaseProgress} from "@/app/api/do/actions";
- import {
- startWorkbenchBatchReleaseAsyncV2,
- getWorkbenchBatchReleaseProgress,
- } from "@/app/api/doworkbench/actions";
-
- import { useRouter } from "next/navigation";
- import React, { ForwardedRef, useCallback, useEffect, useMemo, useState } from "react";
- import { useTranslation } from "react-i18next";
- import { Criterion } from "../SearchBox";
- import { isEmpty, sortBy, uniqBy } from "lodash";
- import { arrayToDateString, arrayToDayjs } from "@/app/utils/formatUtil";
- import SearchBox from "../SearchBox/SearchBox";
- import { EditNote } from "@mui/icons-material";
- import InputDataGrid from "../InputDataGrid";
- import { CreateConsoDoInput } from "@/app/api/do/actions";
- import { TableRow } from "../InputDataGrid/InputDataGrid";
- import {
- FooterPropsOverrides,
- GridColDef,
- GridRowModel,
- GridToolbarContainer,
- useGridApiRef,
- } from "@mui/x-data-grid";
- import {
- FormProvider,
- SubmitErrorHandler,
- SubmitHandler,
- useForm,
- } from "react-hook-form";
- import { Box, Button, Paper, Stack, Tab, Tabs, TablePagination, Typography } from "@mui/material";
- import StyledDataGrid from "../StyledDataGrid";
- import Swal from "sweetalert2";
- import { useSession } from "next-auth/react";
- import { SessionWithTokens } from "@/config/authConfig";
- import { useDoSearchRowSelection } from "./useDoSearchRowSelection";
- import DoReplenishmentTab from "./DoReplenishmentTab";
-
- type Props = {
- filterArgs?: Record<string, any>;
- searchQuery?: Record<string, any>;
- onDeliveryOrderSearch?: () => void;
- };
- type SearchBoxInputs = Record<"code" | "status" | "estimatedArrivalDate" | "orderDate" | "supplierName" | "shopName" | "deliveryOrderLines" | "truckLanceCode" | "codeTo" | "statusTo" | "estimatedArrivalDateTo" | "orderDateTo" | "supplierNameTo" | "shopNameTo" | "deliveryOrderLinesTo" | "truckLanceCodeTo", string>;
- type SearchParamNames = keyof SearchBoxInputs;
- type DoSearchTab = "2F" | "4F" | "TRUCK_X" | "ETRA" | "REPLENISH";
- type TabFilter = { floor: "2F" | "4F" | null; isExtra: boolean; forceTruckKeyword?: string };
-
- // put all this into a new component
- // ConsoDoForm
- type EntryError =
- | {
- [field in keyof DoResult]?: string;
- }
- | undefined;
- type DoRow = TableRow<Partial<DoResult>, EntryError>;
-
- /** 已填車線但未選預計送貨日:後端會掃全量再篩,需擋下。 */
- function isTruckLaneSearchMissingEta(truckLanceCode: string, estimatedArrivalDate: string): boolean {
- return truckLanceCode.trim() !== "" && estimatedArrivalDate.trim() === "";
- }
-
- const DoSearch: React.FC<Props> = ({ filterArgs, searchQuery, onDeliveryOrderSearch }) => {
- const apiRef = useGridApiRef();
-
- const formProps = useForm<CreateConsoDoInput>({
- defaultValues: {},
- });
- const { setValue } = formProps;
- const errors = formProps.formState.errors;
-
-
- const { t } = useTranslation("do");
- const router = useRouter();
- const { data: session } = useSession() as { data: SessionWithTokens | null };
- const currentUserId = session?.id ? parseInt(session.id) : undefined;
- //console.log("🔍 DoSearch - session:", session);
- //console.log("🔍 DoSearch - currentUserId:", currentUserId);
- const [searchTimeout, setSearchTimeout] = useState<NodeJS.Timeout | null>(null);
-
- const [searchAllDos, setSearchAllDos] = useState<DoSearchAll[]>([]);
- const [totalCount, setTotalCount] = useState(0);
- const [isWorkbench, setIsWorkbench] = useState(false);
- const [activeTab, setActiveTab] = useState<DoSearchTab>("2F");
- const [searchBoxResetKey, setSearchBoxResetKey] = useState(0);
- const [pagingController, setPagingController] = useState({
- pageNum: 1,
- pageSize: 10,
- });
-
- const [currentSearchParams, setCurrentSearchParams] = useState<SearchBoxInputs>({
- code: "",
- status: "",
- estimatedArrivalDate: "",
- orderDate: "",
- supplierName: "",
- shopName: "",
- deliveryOrderLines: "",
- truckLanceCode: "",
- codeTo: "",
- statusTo: "",
- estimatedArrivalDateTo: "",
- orderDateTo: "",
- supplierNameTo: "",
- shopNameTo: "",
- deliveryOrderLinesTo: "",
- truckLanceCodeTo: "",
- });
- const createClearedSearchParams = useCallback(
- (source: SearchBoxInputs): SearchBoxInputs => ({
- code: "",
- status: "",
- estimatedArrivalDate: source.estimatedArrivalDate || "",
- orderDate: "",
- supplierName: "",
- shopName: "",
- deliveryOrderLines: "",
- truckLanceCode: "",
- codeTo: "",
- statusTo: "",
- estimatedArrivalDateTo: source.estimatedArrivalDateTo || "",
- orderDateTo: "",
- supplierNameTo: "",
- shopNameTo: "",
- deliveryOrderLinesTo: "",
- truckLanceCodeTo: "",
- }),
- [],
- );
-
- const [hasSearched, setHasSearched] = useState(false);
- const [hasResults, setHasResults] = useState(false);
-
- const {
- rowSelectionModel,
- applyRowSelectionChange,
- resetSelection,
- resolveIdsForBatchRelease,
- } = useDoSearchRowSelection(searchAllDos, setValue);
-
- // 当搜索条件变化时,重置到第一页
- useEffect(() => {
- setPagingController(p => ({
- ...p,
- pageNum: 1,
- }));
- }, [
- currentSearchParams.code,
- currentSearchParams.shopName,
- currentSearchParams.status,
- currentSearchParams.estimatedArrivalDate,
- currentSearchParams.truckLanceCode,
- ]);
-
-
- const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
- () => [
- { label: t("Code"), paramName: "code", type: "text" },
- { label: t("Shop Name"), paramName: "shopName", type: "text" },
- { label: t("Truck Lance Code"), paramName: "truckLanceCode", type: "text" },
- {
- label: t("Estimated Arrival"),
- paramName: "estimatedArrivalDate",
- type: "date",
- preFilledValue: currentSearchParams.estimatedArrivalDate || "",
- },
- {
- label: t("Status"),
- paramName: "status",
- type: "autocomplete",
- options:[
- {label: t('Pending'), value: 'pending'},
- {label: t('Receiving'), value: 'receiving'},
- {label: t('Completed'), value: 'completed'}
- ]
- }
- ],
- [t, currentSearchParams.estimatedArrivalDate],
- );
-
- const onReset = useCallback(async () => {
- try {
- setSearchAllDos([]);
- setTotalCount(0);
- setHasSearched(false);
- setHasResults(false);
- resetSelection();
- setPagingController({ pageNum: 1, pageSize: 10 });
- }
- catch (error) {
- console.error("Error: ", error);
- setSearchAllDos([]);
- setTotalCount(0);
- }
- }, [resetSelection]);
-
- const onDetailClick = useCallback(
- (doResult: DoResult) => {
- if (typeof window !== 'undefined') {
- sessionStorage.setItem('doSearchParams', JSON.stringify(currentSearchParams));
- }
- router.push(`/do/edit?id=${doResult.id}`);
- },
- [router, currentSearchParams],
- );
-
- const validationTest = useCallback(
- (
- newRow: GridRowModel<DoRow>,
- ): EntryError => {
- const error: EntryError = {};
- console.log(newRow);
- return Object.keys(error).length > 0 ? error : undefined;
- },
- [],
- );
-
- const columns = useMemo<GridColDef[]>(
- () => [
- {
- field: "id",
- headerName: t("Details"),
- width: 100,
- renderCell: (params) => (
- <Button
- variant="outlined"
- size="small"
- startIcon={<EditNote />}
- onClick={() => onDetailClick(params.row)}
- >
- {t("Details")}
- </Button>
- ),
- },
- {
- field: "code",
- headerName: t("code"),
- flex: 1.5,
- },
- {
- field: "shopName",
- headerName: t("Shop Name"),
- flex: 1,
- },
- {
- field: "supplierName",
- headerName: t("Supplier Name"),
- flex: 1,
- },
- {
- field: "truckLanceCode",
- headerName: t("Truck Lance Code"),
- flex: 1,
- renderCell: (params) => {
- const v = params.row.truckLanceCode;
- if (v == null) return "車線-X";
- if (typeof v === "string" && v.trim() === "") return "車線-X";
- return v;
- }
- },
- {
- field: "orderDate",
- headerName: t("Order Date"),
- flex: 1,
- renderCell: (params) => {
- return params.row.orderDate
- ? arrayToDateString(params.row.orderDate)
- : "N/A";
- },
- },
- {
- field: "estimatedArrivalDate",
- headerName: t("Estimated Arrival"),
- flex: 1,
- renderCell: (params) => {
- return params.row.estimatedArrivalDate
- ? arrayToDateString(params.row.estimatedArrivalDate)
- : "N/A";
- },
- },
- {
- field: "status",
- headerName: t("Status"),
- flex: 1,
- renderCell: (params) => {
- return t(params.row.status);
- },
- },
- ],
- [t, arrayToDateString, onDetailClick],
- );
-
- const onSubmit = useCallback<SubmitHandler<CreateConsoDoInput>>(
- async (data, event) => {
- const hasErrors = false;
- console.log(errors);
- },
- [errors],
- );
- const onSubmitError = useCallback<SubmitErrorHandler<CreateConsoDoInput>>(
- (errors) => {},
- [],
- );
-
- const resolveTabFilter = useCallback((tab: DoSearchTab): TabFilter => {
- switch (tab) {
- case "2F":
- return { floor: "2F", isExtra: false };
- case "4F":
- return { floor: "4F", isExtra: false };
- case "TRUCK_X":
- return { floor: null, isExtra: false, forceTruckKeyword: "x" };
- case "ETRA":
- return { floor: null, isExtra: true };
- case "REPLENISH":
- default:
- return { floor: null, isExtra: false };
- }
- }, []);
-
- const performSearch = useCallback(
- async (
- query: SearchBoxInputs,
- pageNum: number,
- pageSize: number,
- options?: { resetExcludedRows?: boolean; markSearched?: boolean; tabOverride?: DoSearchTab },
- ) => {
- const effectiveTab = options?.tabOverride ?? activeTab;
- const tabFilter = resolveTabFilter(effectiveTab);
- const tabTruckKeyword = tabFilter.forceTruckKeyword ?? "";
- const effectiveTruckLanceCode = tabTruckKeyword || query.truckLanceCode || "";
- const shouldValidateTruckLane = effectiveTab !== "TRUCK_X";
-
- if (
- shouldValidateTruckLane &&
- isTruckLaneSearchMissingEta(effectiveTruckLanceCode, query.estimatedArrivalDate ?? "")
- ) {
- await Swal.fire({
- icon: "warning",
- title: t("Truck lane search requires date title"),
- text: t("Truck lane search requires date message"),
- confirmButtonText: t("Confirm"),
- });
- return false;
- }
-
- let estArrStartDate = query.estimatedArrivalDate;
- const time = "T00:00:00";
- if (estArrStartDate !== "") {
- estArrStartDate = `${query.estimatedArrivalDate}${time}`;
- }
-
- const status = query.status === "All" ? "" : query.status;
-
- const response = await fetchDoSearch(
- query.code || "",
- query.shopName || "",
- status,
- "",
- "",
- estArrStartDate,
- "",
- pageNum,
- pageSize,
- effectiveTruckLanceCode,
- tabFilter.floor,
- tabFilter.isExtra,
- );
-
- setSearchAllDos(response.records);
- setTotalCount(response.total);
- if (options?.markSearched ?? false) {
- setHasSearched(true);
- setHasResults(response.records.length > 0);
- }
- if (options?.resetExcludedRows ?? false) {
- resetSelection();
- }
- return true;
- },
- [activeTab, resolveTabFilter, t, resetSelection],
- );
-
- //SEARCH FUNCTION
- const handleSearch = useCallback(
- async (query: SearchBoxInputs) => {
- try {
- setCurrentSearchParams(query);
- await performSearch(query, pagingController.pageNum, pagingController.pageSize, {
- resetExcludedRows: true,
- markSearched: true,
- });
- } catch (error) {
- console.error("Error: ", error);
- setSearchAllDos([]);
- setTotalCount(0);
- setHasSearched(true);
- setHasResults(false);
- resetSelection();
- }
- },
- [pagingController.pageNum, pagingController.pageSize, performSearch, resetSelection],
- );
-
- useEffect(() => {
- if (typeof window !== 'undefined') {
- const savedSearchParams = sessionStorage.getItem('doSearchParams');
-
- if (savedSearchParams) {
- try {
- const params = JSON.parse(savedSearchParams);
- setCurrentSearchParams(params);
-
- // 自动使用保存的搜索条件重新搜索,获取最新数据
- const timer = setTimeout(async () => {
- await handleSearch(params);
- // 搜索完成后,清除 sessionStorage
- if (typeof window !== 'undefined') {
- sessionStorage.removeItem('doSearchParams');
- sessionStorage.removeItem('doSearchResults');
- sessionStorage.removeItem('doSearchHasSearched');
- }
- }, 100);
-
- return () => clearTimeout(timer);
- } catch (e) {
- console.error('Error restoring search state:', e);
- // 如果出错,也清除 sessionStorage
- if (typeof window !== 'undefined') {
- sessionStorage.removeItem('doSearchParams');
- sessionStorage.removeItem('doSearchResults');
- sessionStorage.removeItem('doSearchHasSearched');
- }
- }
- }
- }
- }, [handleSearch]);
-
- const debouncedSearch = useCallback((query: SearchBoxInputs) => {
- if (searchTimeout) {
- clearTimeout(searchTimeout);
- }
-
- const timeout = setTimeout(() => {
- handleSearch(query);
- }, 300);
-
- setSearchTimeout(timeout);
- }, [handleSearch, searchTimeout]);
-
- // 分页变化时重新搜索
- const handlePageChange = useCallback(
- (event: unknown, newPage: number) => {
- const newPagingController = {
- ...pagingController,
- pageNum: newPage + 1,
- };
- setPagingController(newPagingController);
- if (hasSearched && currentSearchParams) {
- void performSearch(
- currentSearchParams,
- newPagingController.pageNum,
- newPagingController.pageSize,
- ).catch((error) => {
- console.error("Error: ", error);
- });
- }
- },
- [pagingController, hasSearched, currentSearchParams, performSearch],
- );
-
- const handlePageSizeChange = useCallback(
- (event: React.ChangeEvent<HTMLInputElement>) => {
- const newPageSize = parseInt(event.target.value, 10);
- const newPagingController = {
- pageNum: 1,
- pageSize: newPageSize,
- };
- setPagingController(newPagingController);
- if (hasSearched && currentSearchParams) {
- void performSearch(currentSearchParams, 1, newPageSize).catch((error) => {
- console.error("Error: ", error);
- });
- }
- },
- [hasSearched, currentSearchParams, performSearch],
- );
-
- const handleBatchRelease = useCallback(async (isWorkbench: boolean) => {
- try {
- const tabFilter = resolveTabFilter(activeTab);
- const tabTruckKeyword = tabFilter.forceTruckKeyword ?? "";
- const effectiveTruckLanceCode = tabTruckKeyword || currentSearchParams.truckLanceCode || "";
- const shouldValidateTruckLane = activeTab !== "TRUCK_X";
- if (
- shouldValidateTruckLane &&
- isTruckLaneSearchMissingEta(
- effectiveTruckLanceCode,
- currentSearchParams.estimatedArrivalDate ?? "",
- )
- ) {
- await Swal.fire({
- icon: "warning",
- title: t("Truck lane search requires date title"),
- text: t("Truck lane search requires date message"),
- confirmButtonText: t("Confirm"),
- });
- return;
- }
- // 根据当前搜索条件获取所有匹配的记录(不分页)
- let estArrStartDate = currentSearchParams.estimatedArrivalDate;
- const time = "T00:00:00";
-
- if(estArrStartDate != ""){
- estArrStartDate = currentSearchParams.estimatedArrivalDate + time;
- }
-
- let status = "";
- if(currentSearchParams.status == "All"){
- status = "";
- }
- else{
- status = currentSearchParams.status;
- }
-
- // 显示加载提示
- const loadingSwal = Swal.fire({
- title: t("Loading"),
- text: t("Fetching all matching records..."),
- allowOutsideClick: false,
- allowEscapeKey: false,
- showConfirmButton: false,
- didOpen: () => {
- Swal.showLoading();
- }
- });
-
- // 获取所有匹配的记录
- const allMatchingDos = await fetchAllDoSearch(
- currentSearchParams.code || "",
- currentSearchParams.shopName || "",
- status,
- estArrStartDate,
- effectiveTruckLanceCode,
- tabFilter.floor,
- tabFilter.isExtra,
- );
-
- Swal.close();
-
- if (allMatchingDos.length === 0) {
- await Swal.fire({
- icon: "warning",
- title: t("No Records"),
- text: t("No matching records found for batch release."),
- confirmButtonText: t("OK")
- });
- return;
- }
-
- const idsToRelease = resolveIdsForBatchRelease(
- allMatchingDos.map((d) => d.id),
- );
-
- if (idsToRelease.length === 0) {
- await Swal.fire({
- icon: "warning",
- title: t("No Records"),
- text: t("No delivery orders selected for batch release. Uncheck orders you want to exclude, or search again to reset selection."),
- confirmButtonText: t("OK"),
- });
- return;
- }
-
- const showMergeExtraOption = isWorkbench && activeTab === "ETRA";
-
- const result = await Swal.fire({
- icon: "question",
- title: t("Batch Release"),
- html: `
- <div style="text-align: left;">
- <p>${t("Selected Shop(s): ")}${idsToRelease.length}</p>
- <p style="font-size: 0.9em; color: #666; margin-top: 8px;">
-
- ${currentSearchParams.code ? `${t("Code")}: ${currentSearchParams.code} ` : ""}
- ${currentSearchParams.shopName ? `${t("Shop Name")}: ${currentSearchParams.shopName} ` : ""}
- ${currentSearchParams.estimatedArrivalDate ? `${t("Estimated Arrival")}: ${currentSearchParams.estimatedArrivalDate} ` : ""}
- ${status ? `${t("Status")}: ${t(status)} ` : ""}
- </p>
- ${
- showMergeExtraOption
- ? `<p style="font-size:0.95em;color:#666;margin-top:16px;">${t("Merge extra orders into lane batch ticket")}</p>`
- : ""
- }
- </div>
- `,
- showCancelButton: true,
- showDenyButton: showMergeExtraOption,
- confirmButtonText: showMergeExtraOption ? t("Confirm merge release") : t("Confirm"),
- denyButtonText: t("Confirm release without merge"),
- cancelButtonText: t("Cancel"),
- confirmButtonColor: "#8dba00",
- denyButtonColor: "#6366f1",
- cancelButtonColor: "#F04438",
- });
-
- if (result.isDismissed) return;
- if (!result.isConfirmed && !result.isDenied) return;
-
- const mergeExtraIntoLaneTicket = showMergeExtraOption ? result.isConfirmed : true;
-
- try {
- let startRes ;
- if(isWorkbench){
- startRes = await startWorkbenchBatchReleaseAsyncV2({
- ids: idsToRelease,
- userId: currentUserId ?? 1,
- mergeExtraIntoLaneTicket,
- });
- }
- else{
- startRes = await startBatchReleaseAsync({ ids: idsToRelease, userId: currentUserId ?? 1 });
- }
- //await startBatchReleaseAsync({ ids: idsToRelease, userId: currentUserId ?? 1 });
- const jobId = startRes?.entity?.jobId;
-
- if (!jobId) {
- await Swal.fire({ icon: "error", title: t("Error"), text: t("Failed to start batch release") });
- return;
- }
-
- const progressSwal = Swal.fire({
- title: t("Releasing"),
- text: "0% (0 / 0)",
- allowOutsideClick: false,
- allowEscapeKey: false,
- showConfirmButton: false,
- didOpen: () => {
- Swal.showLoading();
- }
- });
-
- const timer = setInterval(async () => {
- try {
- const p = isWorkbench
- ? await getWorkbenchBatchReleaseProgress(jobId)
- : await getBatchReleaseProgress(jobId);
-
- const e = p?.entity || {};
- const total = e.total ?? 0;
- const finished = e.finished ?? 0;
- const percentage = total > 0 ? Math.round((finished / total) * 100) : 0;
-
- const textContent = document.querySelector('.swal2-html-container');
- if (textContent) {
- textContent.textContent = `${percentage}% (${finished} / ${total})`;
- }
-
- if (p.code === "FINISHED" || e.running === false) {
- clearInterval(timer);
- await new Promise(resolve => setTimeout(resolve, 500));
- Swal.close();
-
- await Swal.fire({
- icon: "success",
- title: t("Completed"),
- text: t("Batch release completed successfully."),
- confirmButtonText: t("Confirm"),
- confirmButtonColor: "#8dba00"
- });
-
- if (currentSearchParams && Object.keys(currentSearchParams).length > 0) {
- await handleSearch(currentSearchParams);
- }
- }
- } catch (err) {
- console.error("progress poll error:", err);
- }
- }, 800);
- } catch (error) {
- console.error("Batch release error:", error);
- await Swal.fire({
- icon: "error",
- title: t("Error"),
- text: t("An error occurred during batch release"),
- confirmButtonText: t("OK")
- });
- }
- } catch (error) {
- console.error("Error fetching all matching records:", error);
- await Swal.fire({
- icon: "error",
- title: t("Error"),
- text: t("Failed to fetch matching records"),
- confirmButtonText: t("OK")
- });
- }
- }, [t, currentUserId, currentSearchParams, handleSearch, resolveIdsForBatchRelease, activeTab, resolveTabFilter]);
-
- const handleTabChange = useCallback(
- (_: React.SyntheticEvent, nextTab: DoSearchTab) => {
- if (nextTab === activeTab) return;
- const nextSearchParams = createClearedSearchParams(currentSearchParams);
- setActiveTab(nextTab);
- setCurrentSearchParams(nextSearchParams);
- setSearchBoxResetKey((prev) => prev + 1);
- setPagingController((prev) => ({ ...prev, pageNum: 1 }));
- resetSelection();
- // 切換 tab 僅重置搜索條件與結果;由使用者再次按「搜索」後才查詢。
- setSearchAllDos([]);
- setTotalCount(0);
- setHasSearched(false);
- setHasResults(false);
- },
- [
- activeTab,
- currentSearchParams,
- createClearedSearchParams,
- resetSelection,
- ],
- );
-
- return (
- <>
- <FormProvider {...formProps}>
- <Stack
- spacing={2}
- component="form"
- onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
- >
-
-
- <Paper variant="outlined" sx={{ px: 2, pt: 1 }}>
- <Box display="flex" justifyContent="space-between" alignItems="center">
- <Tabs
- value={activeTab}
- onChange={handleTabChange}
- variant="scrollable"
- >
- <Tab value="2F" label="2/F" />
- <Tab value="4F" label="4/F" />
- <Tab value="TRUCK_X" label={t("Truck X")} />
- <Tab value="ETRA" label={t("Etra")} />
- <Tab value="REPLENISH" label={t("Replenishment")} />
- </Tabs>
-
- {activeTab !== "REPLENISH" && hasSearched && hasResults && (
- <Button
- name="batch_release"
- variant="contained"
- onClick={() => handleBatchRelease(true)}
- >
- {t("Workbench Batch Release")}
- </Button>
- )}
- </Box>
- </Paper>
-
-
- {activeTab === "REPLENISH" ? (
- <DoReplenishmentTab />
- ) : (
- <>
- <SearchBox
- key={`tab-reset-${searchBoxResetKey}`}
- criteria={searchCriteria}
- onSearch={handleSearch}
- onReset={onReset}
- />
-
- <Paper variant="outlined" sx={{ overflow: "hidden" }}>
- <StyledDataGrid
- rows={searchAllDos}
- columns={columns}
- checkboxSelection
- rowSelectionModel={rowSelectionModel}
- onRowSelectionModelChange={applyRowSelectionChange}
- slots={{
- footer: FooterToolbar,
- noRowsOverlay: NoRowsOverlay,
- }}
- />
- <TablePagination
- component="div"
- count={totalCount}
- page={(pagingController.pageNum - 1)}
- rowsPerPage={pagingController.pageSize}
- onPageChange={handlePageChange}
- onRowsPerPageChange={handlePageSizeChange}
- rowsPerPageOptions={[10, 25, 50]}
- />
- </Paper>
- </>
- )}
-
- </Stack>
- </FormProvider>
- </>
- );
- };
-
-
- const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
- return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
- };
- const NoRowsOverlay: React.FC = () => {
- const { t } = useTranslation("home");
- return (
- <Box
- display="flex"
- justifyContent="center"
- alignItems="center"
- height="100%"
- >
- <Typography variant="caption">{t("Add some entries!")}</Typography>
- </Box>
- );
- };
-
- export default DoSearch;
|