dynamically set group by filed
This commit is contained in:
parent
81712a0695
commit
6fbc0411db
@ -11,6 +11,8 @@ import ConfirmModal from "../common/ConfirmModal";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
||||||
const [deletingId, setDeletingId] = useState(null);
|
const [deletingId, setDeletingId] = useState(null);
|
||||||
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
@ -81,11 +83,74 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
}, {});
|
}, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const expenseColumns = [
|
||||||
|
{
|
||||||
|
key: "expensesType",
|
||||||
|
label: "Expense Type",
|
||||||
|
getValue: (e) => e.expensesType?.name || "N/A",
|
||||||
|
align:"text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "paymentMode",
|
||||||
|
label: "Payment Mode",
|
||||||
|
getValue: (e) => e.paymentMode?.name || "N/A",
|
||||||
|
align:"text-start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "paidBy",
|
||||||
|
label: "Paid By",
|
||||||
|
align:"text-start",
|
||||||
|
getValue: (e) =>
|
||||||
|
`${e.paidBy?.firstName ?? ""} ${e.paidBy?.lastName ?? ""}`.trim() || "N/A",
|
||||||
|
customRender: (e) => (
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<Avatar
|
||||||
|
size="xs"
|
||||||
|
classAvatar="m-0"
|
||||||
|
firstName={e.paidBy?.firstName}
|
||||||
|
lastName={e.paidBy?.lastName}
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
{`${e.paidBy?.firstName ?? ""} ${e.paidBy?.lastName ?? ""}`.trim() || "N/A"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "submitted",
|
||||||
|
label: "Submitted",
|
||||||
|
getValue: (e) => formatUTCToLocalTime(e?.createdAt),
|
||||||
|
isAlwaysVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "amount",
|
||||||
|
label: "Amount",
|
||||||
|
getValue: (e) => (
|
||||||
|
<>
|
||||||
|
<i className="bx bx-rupee b-xs"></i> {e?.amount}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
isAlwaysVisible: true,
|
||||||
|
align: "text-end"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "status",
|
||||||
|
label: "Status",
|
||||||
|
align:"text-center",
|
||||||
|
getValue: (e) => (
|
||||||
|
<span className={`badge bg-label-${getColorNameFromHex(e?.status?.color) || "secondary"}`}>
|
||||||
|
{e.status?.name || "Unknown"}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
if (isInitialLoading) return <ExpenseTableSkeleton />;
|
if (isInitialLoading) return <ExpenseTableSkeleton />;
|
||||||
if (isError) return <div>{error}</div>;
|
if (isError) return <div>{error}</div>;
|
||||||
|
|
||||||
const grouped = groupBy ? groupByField(data?.data ?? [], groupBy) : { All: data?.data ?? [] };
|
const grouped = groupBy ? groupByField(data?.data ?? [], groupBy) : { All: data?.data ?? [] };
|
||||||
const IsGroupedByDate = ["transactionDate","createdAt"].includes(groupBy)
|
const IsGroupedByDate = ["transactionDate", "createdAt"].includes(groupBy);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{IsDeleteModalOpen && (
|
{IsDeleteModalOpen && (
|
||||||
@ -95,7 +160,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
role="dialog"
|
role="dialog"
|
||||||
style={{
|
style={{
|
||||||
display: "block",
|
display: "block",
|
||||||
backgroundColor: "rgba(0,0,0,0.5)",
|
backgroundColor: "rgba(0,0,0,0.5)"
|
||||||
}}
|
}}
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
>
|
>
|
||||||
@ -117,48 +182,18 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
<table className="table border-top dataTable text-nowrap">
|
<table className="table border-top dataTable text-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{![ groupBy].includes("expensesType") && (
|
{expenseColumns.map(
|
||||||
<th
|
(col) =>
|
||||||
className="sorting sorting_desc d-none d-sm-table-cell"
|
(col.isAlwaysVisible || groupBy !== col.key) && (
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
aria-label="Expense Type: activate to sort column ascending"
|
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ms-5">Expense Type</div>
|
|
||||||
</th>
|
|
||||||
)}
|
|
||||||
{![groupBy].includes("paymentMode") && (
|
|
||||||
<th
|
|
||||||
className="sorting sorting_desc d-table-cell"
|
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
aria-label="Payment Mode: activate to sort column ascending"
|
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ">Payment Mode</div>
|
|
||||||
</th>
|
|
||||||
)}
|
|
||||||
{![groupBy].includes("paidBy") && (
|
|
||||||
<th
|
<th
|
||||||
className="sorting sorting_desc d-table-cell"
|
key={col.key}
|
||||||
tabIndex="0"
|
className={`sorting d-table-cell`}
|
||||||
aria-controls="DataTables_Table_0"
|
aria-sort="descending"
|
||||||
rowSpan="1"
|
>
|
||||||
colSpan="1"
|
<div className={`${col.align}`}>{col.label}</div>
|
||||||
aria-label="Paid By: activate to sort column ascending"
|
</th>
|
||||||
aria-sort="descending"
|
)
|
||||||
>
|
|
||||||
<div className="text-start ms-5">Paid By</div>
|
|
||||||
</th>
|
|
||||||
)}
|
)}
|
||||||
<th><div className="text-center">Submitted</div></th>
|
|
||||||
<th className="text-end">Amount</th>
|
|
||||||
{![groupBy].includes("status") && <th>Status</th>}
|
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -166,51 +201,21 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
{Object.entries(grouped).map(([group, expenses]) => (
|
{Object.entries(grouped).map(([group, expenses]) => (
|
||||||
<React.Fragment key={group}>
|
<React.Fragment key={group}>
|
||||||
<tr className="tr-group text-dark">
|
<tr className="tr-group text-dark">
|
||||||
<td colSpan={7} className="text-start">
|
<td colSpan={8} className="text-start">
|
||||||
<strong>{IsGroupedByDate ? formatUTCToLocalTime(group) : group}</strong>
|
<strong>{IsGroupedByDate ? formatUTCToLocalTime(group) : group}</strong>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{expenses.map((expense) => (
|
{expenses.map((expense) => (
|
||||||
<tr key={expense.id}>
|
<tr key={expense.id}>
|
||||||
{![groupBy].includes("expensesType") && (
|
{expenseColumns.map(
|
||||||
<td className="text-start d-table-cell ">{expense.expensesType?.name || "N/A"}</td>
|
(col) =>
|
||||||
)}
|
(col.isAlwaysVisible || groupBy !== col.key) && (
|
||||||
{![groupBy].includes("paymentMode") && (
|
<td key={col.key} className={`d-table-cell ${col.align ?? ""}`}>
|
||||||
<td className="text-start d-table-cell ">{expense.paymentMode?.name || "N/A"}</td>
|
{col.customRender
|
||||||
)}
|
? col.customRender(expense)
|
||||||
{![ groupBy].includes("paidBy") && (
|
: col.getValue(expense)}
|
||||||
<td className="text-start d-table-cell ">
|
</td>
|
||||||
<div className="d-flex align-items-center">
|
)
|
||||||
<Avatar
|
|
||||||
size="xs"
|
|
||||||
classAvatar="m-0"
|
|
||||||
firstName={expense.paidBy?.firstName}
|
|
||||||
lastName={expense.paidBy?.lastName}
|
|
||||||
/>
|
|
||||||
<span>
|
|
||||||
{`${expense.paidBy?.firstName ?? ""} ${
|
|
||||||
expense.paidBy?.lastName ?? ""
|
|
||||||
}`.trim() || "N/A"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
)}
|
|
||||||
<td className="d-table-cell text-center">{formatUTCToLocalTime(expense?.createdAt)}</td>
|
|
||||||
<td className="d-table-cell text-end">
|
|
||||||
<i className="bx bx-rupee b-xs"></i>
|
|
||||||
{expense?.amount}
|
|
||||||
</td>
|
|
||||||
{![ groupBy].includes("status") && (
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
className={`badge bg-label-${
|
|
||||||
getColorNameFromHex(expense?.status?.color) ||
|
|
||||||
"secondary"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{expense.status?.name || "Unknown"}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
)}
|
)}
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex justify-content-center gap-2">
|
<div className="d-flex justify-content-center gap-2">
|
||||||
@ -228,7 +233,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
setManageExpenseModal({
|
setManageExpenseModal({
|
||||||
IsOpen: true,
|
IsOpen: true,
|
||||||
expenseId: expense.id,
|
expenseId: expense.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
></i>
|
></i>
|
||||||
@ -273,3 +278,4 @@ const ExpenseList = ({ filters, groupBy = "transactionDate" }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default ExpenseList;
|
export default ExpenseList;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user