removed console and added none option for groupping for Expense list

This commit is contained in:
pramod.mahajan 2025-12-09 14:26:18 +05:30
parent 0643d3d0e1
commit 4a47b1d0fa
7 changed files with 398 additions and 355 deletions

View File

@ -37,7 +37,6 @@ const Dashboard = () => {
const canSelfAttendance = useHasUserPermission(SELF_ATTENDANCE); const canSelfAttendance = useHasUserPermission(SELF_ATTENDANCE);
const { data,isLoading,isError } = useGetCollectionOverview(); const { data,isLoading,isError } = useGetCollectionOverview();
console.log("data-->", data);
return ( return (
<div className="container-fluid mt-5"> <div className="container-fluid mt-5">
<div className="row gy-4"> <div className="row gy-4">

View File

@ -1,4 +1,10 @@
import React, { forwardRef, useEffect, useImperativeHandle, useState, useMemo } from "react"; import React, {
forwardRef,
useEffect,
useImperativeHandle,
useState,
useMemo,
} from "react";
import { FormProvider, useForm, Controller } from "react-hook-form"; import { FormProvider, useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { defaultFilter, SearchSchema } from "./ExpenseSchema"; import { defaultFilter, SearchSchema } from "./ExpenseSchema";
@ -15,7 +21,8 @@ import { useExpenseFilter } from "../../hooks/useExpense";
import { ExpenseFilterSkeleton } from "./ExpenseSkeleton"; import { ExpenseFilterSkeleton } from "./ExpenseSkeleton";
import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useLocation, useNavigate, useParams } from "react-router-dom";
const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }, ref) => { const ExpenseFilterPanel = forwardRef(
({ onApply, handleGroupBy, setFilterdata }, ref) => {
const { status } = useParams(); const { status } = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const selectedProjectId = useSelector( const selectedProjectId = useSelector(
@ -26,6 +33,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
const groupByList = useMemo(() => { const groupByList = useMemo(() => {
return [ return [
{ id: "none", name: "None" },
{ id: "transactionDate", name: "Transaction Date" }, { id: "transactionDate", name: "Transaction Date" },
{ id: "status", name: "Status" }, { id: "status", name: "Status" },
{ id: "submittedBy", name: "Submitted By" }, { id: "submittedBy", name: "Submitted By" },
@ -36,7 +44,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
].sort((a, b) => a.name.localeCompare(b.name)); ].sort((a, b) => a.name.localeCompare(b.name));
}, []); }, []);
const [selectedGroup, setSelectedGroup] = useState(groupByList[6]); const [selectedGroup, setSelectedGroup] = useState(groupByList[0]);
const [resetKey, setResetKey] = useState(0); const [resetKey, setResetKey] = useState(0);
const dynamicDefaultFilter = useMemo(() => { const dynamicDefaultFilter = useMemo(() => {
@ -124,12 +132,18 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
if (status !== appliedStatusId) { if (status !== appliedStatusId) {
const filterWithStatus = { const filterWithStatus = {
...dynamicDefaultFilter, ...dynamicDefaultFilter,
projectIds: selectedProjectId ? [selectedProjectId] : dynamicDefaultFilter.projectIds || [], projectIds: selectedProjectId
? [selectedProjectId]
: dynamicDefaultFilter.projectIds || [],
startDate: dynamicDefaultFilter.startDate startDate: dynamicDefaultFilter.startDate
? moment.utc(dynamicDefaultFilter.startDate, "DD-MM-YYYY").toISOString() ? moment
.utc(dynamicDefaultFilter.startDate, "DD-MM-YYYY")
.toISOString()
: undefined, : undefined,
endDate: dynamicDefaultFilter.endDate endDate: dynamicDefaultFilter.endDate
? moment.utc(dynamicDefaultFilter.endDate, "DD-MM-YYYY").toISOString() ? moment
.utc(dynamicDefaultFilter.endDate, "DD-MM-YYYY")
.toISOString()
: undefined, : undefined,
}; };
@ -152,8 +166,6 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
if (isError && isFetched) if (isError && isFetched)
return <div>Something went wrong Here- {error.message} </div>; return <div>Something went wrong Here- {error.message} </div>;
return ( return (
<> <>
<FormProvider {...methods}> <FormProvider {...methods}>
@ -164,7 +176,8 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
<div className="d-inline-flex border rounded-pill mb-1 overflow-hidden shadow-none"> <div className="d-inline-flex border rounded-pill mb-1 overflow-hidden shadow-none">
<button <button
type="button" type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${isTransactionDate ? "active btn-primary text-white" : "" className={`btn px-2 py-1 rounded-0 text-tiny ${
isTransactionDate ? "active btn-primary text-white" : ""
}`} }`}
onClick={() => setValue("isTransactionDate", true)} onClick={() => setValue("isTransactionDate", true)}
> >
@ -172,7 +185,8 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
</button> </button>
<button <button
type="button" type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${!isTransactionDate ? "active btn-primary text-white" : "" className={`btn px-2 py-1 rounded-0 text-tiny ${
!isTransactionDate ? "active btn-primary text-white" : ""
}`} }`}
onClick={() => setValue("isTransactionDate", false)} onClick={() => setValue("isTransactionDate", false)}
> >
@ -264,7 +278,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
<select <select
id="groupBySelect" id="groupBySelect"
className="form-select form-select-sm" className="form-select form-select-sm"
value={selectedGroup?.id || ""} value={selectedGroup?.id || "none"}
onChange={handleGroupChange} onChange={handleGroupChange}
> >
{groupByList.map((group) => ( {groupByList.map((group) => (
@ -291,6 +305,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata }
</FormProvider> </FormProvider>
</> </>
); );
}); }
);
export default ExpenseFilterPanel; export default ExpenseFilterPanel;

View File

@ -23,8 +23,15 @@ import { useSelector } from "react-redux";
import ExpenseFilterChips from "./ExpenseFilterChips"; import ExpenseFilterChips from "./ExpenseFilterChips";
import { defaultFilter } from "./ExpenseSchema"; import { defaultFilter } from "./ExpenseSchema";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { displayName } from "react-quill";
const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRef, onDataFiltered }) => { const ExpenseList = ({
filters,
groupBy,
searchText,
tableRef,
onDataFiltered,
}) => {
const [deletingId, setDeletingId] = useState(null); const [deletingId, setDeletingId] = useState(null);
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const { const {
@ -76,7 +83,17 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
} }
}; };
const groupByField = (items, field) => { const groupByField = (items, field) => {
if (!field || field === "none") {
return {
All: {
key: "All",
displayField: "All",
items: items || []
}
};
}
return items.reduce((acc, item) => { return items.reduce((acc, item) => {
let key; let key;
let displayField; let displayField;
@ -91,8 +108,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
displayField = "Status"; displayField = "Status";
break; break;
case "submittedBy": case "submittedBy":
key = `${item?.createdBy?.firstName ?? ""} ${item.createdBy?.lastName ?? "" key = `${item?.createdBy?.firstName ?? ""} ${item?.createdBy?.lastName ?? ""}`.trim();
}`.trim();
displayField = "Submitted By"; displayField = "Submitted By";
break; break;
case "project": case "project":
@ -116,7 +132,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
displayField = "Others"; displayField = "Others";
} }
const groupKey = `${field}_${key}`; // unique key for object property const groupKey = `${field}_${key}`;
if (!acc[groupKey]) { if (!acc[groupKey]) {
acc[groupKey] = { key, displayField, items: [] }; acc[groupKey] = { key, displayField, items: [] };
} }
@ -124,7 +140,8 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
acc[groupKey].items.push(item); acc[groupKey].items.push(item);
return acc; return acc;
}, {}); }, {});
}; };
const expenseColumns = [ const expenseColumns = [
{ {
@ -150,7 +167,8 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
label: "Submitted By", label: "Submitted By",
align: "text-start", align: "text-start",
getValue: (e) => getValue: (e) =>
`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" `${e.createdBy?.firstName ?? ""} ${
e.createdBy?.lastName ?? ""
}`.trim() || "N/A", }`.trim() || "N/A",
customRender: (e) => ( customRender: (e) => (
<div <div
@ -164,7 +182,8 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
lastName={e.createdBy?.lastName} lastName={e.createdBy?.lastName}
/> />
<span className="text-truncate"> <span className="text-truncate">
{`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" {`${e.createdBy?.firstName ?? ""} ${
e.createdBy?.lastName ?? ""
}`.trim() || "N/A"} }`.trim() || "N/A"}
</span> </span>
</div> </div>
@ -197,7 +216,8 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
align: "text-center", align: "text-center",
getValue: (e) => ( getValue: (e) => (
<span <span
className={`badge bg-label-${getColorNameFromHex(e?.status?.color) || "secondary" className={`badge bg-label-${
getColorNameFromHex(e?.status?.color) || "secondary"
}`} }`}
> >
{e.status?.name || "Unknown"} {e.status?.name || "Unknown"}
@ -218,12 +238,18 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
return <ExpenseTableSkeleton headers={headers} />; return <ExpenseTableSkeleton headers={headers} />;
if (isError) return <div>{error?.message}</div>; if (isError) return <div>{error?.message}</div>;
const grouped = groupBy const isNoGrouping = !groupBy || groupBy === "none";
? groupByField(data?.data ?? [], groupBy) const grouped = isNoGrouping
: { All: data?.data ?? [] }; ? { All: { key: "All", displayField: "All", items: data?.data ?? [] } }
: groupByField(data?.data ?? [], groupBy);
const IsGroupedByDate = [ const IsGroupedByDate = [
{key:"none",displayField:"None"},
{ key: "transactionDate", displayField: "Transaction Date" }, { key: "transactionDate", displayField: "Transaction Date" },
{ key: "createdAt", displayField: "created Date" }, { key: "createdAt", displayField: "created Date", },
]?.includes(groupBy); ]?.includes(groupBy);
const canEditExpense = (expense) => { const canEditExpense = (expense) => {
@ -264,7 +290,8 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
groupBy={groupBy} groupBy={groupBy}
/> />
<div <div
className="card-datatable table-responsive" ref={tableRef} className="card-datatable table-responsive"
ref={tableRef}
id="horizontal-example" id="horizontal-example"
> >
<div className="dataTables_wrapper no-footer px-2 "> <div className="dataTables_wrapper no-footer px-2 ">
@ -292,6 +319,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
{Object.keys(grouped).length > 0 ? ( {Object.keys(grouped).length > 0 ? (
Object.values(grouped).map(({ key, displayField, items }) => ( Object.values(grouped).map(({ key, displayField, items }) => (
<React.Fragment key={key}> <React.Fragment key={key}>
{!isNoGrouping && (
<tr className="tr-group text-dark"> <tr className="tr-group text-dark">
<td colSpan={8} className="text-start"> <td colSpan={8} className="text-start">
<div className="d-flex align-items-center px-2"> <div className="d-flex align-items-center px-2">
@ -307,6 +335,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
</div> </div>
</td> </td>
</tr> </tr>
)}
{items?.map((expense) => ( {items?.map((expense) => (
<tr key={expense.id}> <tr key={expense.id}>
{expenseColumns.map( {expenseColumns.map(
@ -314,19 +343,23 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText, tableRe
(col.isAlwaysVisible || groupBy !== col.key) && ( (col.isAlwaysVisible || groupBy !== col.key) && (
<td <td
key={col.key} key={col.key}
className={`d-table-cell ml-2 ${col.align ?? "" className={`d-table-cell ml-2 ${
col.align ?? ""
} `} } `}
> >
<div <div
className={`d-flex px-2 ${col.key === "status" className={`d-flex px-2 ${
col.key === "status"
? "justify-content-center" ? "justify-content-center"
: "" : ""
} }
${col.key === "amount" ${
col.key === "amount"
? "justify-content-end" ? "justify-content-end"
: "" : ""
} }
${col.key === "submitted" ${
col.key === "submitted"
? "justify-content-center" ? "justify-content-center"
: "" : ""
} }

View File

@ -57,7 +57,6 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
// onNext(); // onNext();
const tenantPayload = { ...data, onBoardingDate: moment.utc(data.onBoardingDate, "DD-MM-YYYY").toISOString() } const tenantPayload = { ...data, onBoardingDate: moment.utc(data.onBoardingDate, "DD-MM-YYYY").toISOString() }
// CreateTenant(tenantPayload); // CreateTenant(tenantPayload);
console.log(tenantPayload)
} }
}; };

View File

@ -1,7 +1,6 @@
import React from 'react' import React from 'react'
const Error = ({error,close}) => { const Error = ({error,close}) => {
console.log(error)
return ( return (
<div className="container text-center py-5"> <div className="container text-center py-5">
<h1 className="display-4 fw-bold text-danger">{error.statusCode || error?.response?.status <h1 className="display-4 fw-bold text-danger">{error.statusCode || error?.response?.status

View File

@ -124,7 +124,6 @@ export const useUploadDocument = (onSuccessCallBack) => {
if (onSuccessCallBack) onSuccessCallBack(); if (onSuccessCallBack) onSuccessCallBack();
}, },
onError: (error) => { onError: (error) => {
console.log(error);
showToast( showToast(
error.response.data.message || error.response.data.message ||
"Something went wrong please try again !", "Something went wrong please try again !",
@ -145,7 +144,6 @@ export const useUpdateDocument = (onSuccessCallBack) => {
if (onSuccessCallBack) onSuccessCallBack(); if (onSuccessCallBack) onSuccessCallBack();
}, },
onError: (error) => { onError: (error) => {
console.log(error);
showToast( showToast(
error.response.data.message || error.response.data.message ||
"Something went wrong please try again !", "Something went wrong please try again !",

View File

@ -50,7 +50,7 @@ const ExpensePage = () => {
); );
const [filters, setFilters] = useState(defaultFilter); const [filters, setFilters] = useState(defaultFilter);
const [groupBy, setGroupBy] = useState("transactionDate"); const [groupBy, setGroupBy] = useState("none");
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const filterPanelRef = useRef(); const filterPanelRef = useRef();
const [ManageExpenseModal, setManageExpenseModal] = useState({ const [ManageExpenseModal, setManageExpenseModal] = useState({