From 00515e2445ec50b64a71214653e231f96d347142 Mon Sep 17 00:00:00 2001 From: "MSI\\derek" Date: Wed, 16 Apr 2025 11:05:07 +0800 Subject: [PATCH] update --- src/app/api/invoices/actions.ts | 4 +- .../InvoiceSearch/CreateInvoiceModal.tsx | 2 +- .../InvoiceSearch/InvoiceSearch.tsx | 16 +++-- .../SearchResults/SearchResults.tsx | 67 +++++++++++++++++-- 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/app/api/invoices/actions.ts b/src/app/api/invoices/actions.ts index d98c5e8..d40bb41 100644 --- a/src/app/api/invoices/actions.ts +++ b/src/app/api/invoices/actions.ts @@ -2,7 +2,7 @@ import { serverFetchJson, serverFetchString, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; import { BASE_API_URL } from "@/config/api"; -import { revalidateTag } from "next/cache"; +import { revalidatePath, revalidateTag } from "next/cache"; import { cache } from "react"; export interface InvoiceResult { @@ -145,8 +145,8 @@ export const updateInvoice = async (data: any) => { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, }); - revalidateTag("invoices") + revalidatePath("/(main)/invoice") return updateInvoice; } diff --git a/src/components/InvoiceSearch/CreateInvoiceModal.tsx b/src/components/InvoiceSearch/CreateInvoiceModal.tsx index 727ac98..7720673 100644 --- a/src/components/InvoiceSearch/CreateInvoiceModal.tsx +++ b/src/components/InvoiceSearch/CreateInvoiceModal.tsx @@ -69,7 +69,7 @@ const CreateInvoiceModal: React.FC = ({isOpen, onClose, projects, invoice if (response === "OK") { onClose() successDialog(t("Submit Success"), t).then(() => { - router.replace("/invoice"); + // router.replace("/invoice"); }) } }, t) diff --git a/src/components/InvoiceSearch/InvoiceSearch.tsx b/src/components/InvoiceSearch/InvoiceSearch.tsx index 1e2a517..cb098a9 100644 --- a/src/components/InvoiceSearch/InvoiceSearch.tsx +++ b/src/components/InvoiceSearch/InvoiceSearch.tsx @@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next"; import SearchResults, { Column } from "../SearchResults"; import EditNote from "@mui/icons-material/EditNote"; import { moneyFormatter } from "@/app/utils/formatUtil" -import { Button, ButtonGroup, Stack, Tab, Tabs, TabsProps, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, TextField, CardContent, Typography, Divider, Card } from "@mui/material"; +import { Button, ButtonGroup, Stack, Tab, Tabs, TabsProps, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, TextField, CardContent, Typography, Divider, Card, ThemeProvider } from "@mui/material"; import FileUploadIcon from '@mui/icons-material/FileUpload'; import AddIcon from '@mui/icons-material/Add'; import { deleteInvoice, importIssuedInovice, importReceivedInovice, updateInvoice } from "@/app/api/invoices/actions"; @@ -23,6 +23,8 @@ import { ProjectResult } from "@/app/api/projects"; import { IMPORT_INVOICE, IMPORT_RECEIPT } from "@/middleware"; import InvoiceSearchLoading from "./InvoiceSearchLoading"; import { NumberFormatValues, NumericFormat } from "react-number-format"; +import theme from "@/theme"; +import { SMALL_ROW_THEME } from "@/theme/colorConst"; interface CustomMoneyComponentProps { params: GridRenderEditCellParams; @@ -614,11 +616,13 @@ const InvoiceSearch: React.FC & SubComponents = ({ invoices, projects, ab { !loading && // tabIndex == 0 && - - items={filteredIvoices} - columns={combinedColumns} - autoRedirectToFirstPage - /> + + + items={filteredIvoices} + columns={combinedColumns} + autoRedirectToFirstPage + /> + } {t("Edit Invoice")} diff --git a/src/components/SearchResults/SearchResults.tsx b/src/components/SearchResults/SearchResults.tsx index 031bf44..0aee1ab 100644 --- a/src/components/SearchResults/SearchResults.tsx +++ b/src/components/SearchResults/SearchResults.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useEffect } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import Paper from "@mui/material/Paper"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; @@ -18,6 +18,9 @@ import { convertDateArrayToString, moneyFormatter } from "@/app/utils/formatUtil import DoneIcon from '@mui/icons-material/Done'; import CloseIcon from '@mui/icons-material/Close'; import { Button, Link, LinkOwnProps } from "@mui/material"; +import { orderBy, sortBy } from "lodash"; +import ArrowUp from '@mui/icons-material/KeyboardArrowUp'; +import ArrowDown from '@mui/icons-material/KeyboardArrowDown'; export interface ResultWithId { id: string | number; @@ -155,7 +158,50 @@ function SearchResults({ return column.underline ?? "always"; }; - + type OrderProps = Record + const [sortedItems, setSortedItems] = useState(items) + const [orderProps, setOrderProps] = useState(() => { + if (items.length === 0) { + return {} as OrderProps + } + return Object.keys(sortedItems[0]).reduce((acc, key) => { + if (key === "deleted" || key === "id") return acc + acc[key as keyof T] = false; + return acc; + }, {} as OrderProps); + }); + const changeOrder = useCallback((key: keyof T) => { + // preserve all column sorting + // setOrderProps( + // (prev) => ({ + // [...prev]: false, + // [key]: !prev[key] + // }) + // ) + // only sort 1 column + setOrderProps( + (prev) => { + const newOrderProps = Object.keys(prev).reduce((acc, currKey) => { + acc[currKey as keyof T] = currKey === key ? !prev[currKey as keyof T] : false; + return acc; + }, {} as OrderProps); + return newOrderProps; + } + ) + }, []) + const sortingItems = useCallback( + (key: keyof T) => { + // true === asc + // false === desc + console.log(orderProps) + if (orderProps[key]) { + return orderBy(sortedItems, key, 'asc') + } else { + return orderBy(sortedItems, key, 'desc') + } + } + , [sortedItems, orderProps] + ) const table = ( <> @@ -163,14 +209,25 @@ function SearchResults({ {columns.filter(item => item.isHidden !== true).map((column, idx) => ( - + { + changeOrder(column.name) + setSortedItems(sortingItems(column.name)) + }} + > {column?.type === "money" ?
{column.label}
: column.label} + {(() => { + const isAscending = orderProps[column.name]; + if (isAscending === undefined) return undefined; + return isAscending ? : ; + })()}
))}
- {items + {sortedItems .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((item) => { return ( @@ -223,7 +280,7 @@ function SearchResults({