Merge pull request 'Issues_Expense_2W Changes of Expense, Payment Request and Recurring Expense.' (#505) from Issues_Expense_2W into upgrade_Expense
Reviewed-on: #505 Merged
This commit is contained in:
commit
4cbac98986
@ -35,7 +35,7 @@ const ExpenseByProject = () => {
|
|||||||
|
|
||||||
const getSelectedTypeName = () => {
|
const getSelectedTypeName = () => {
|
||||||
if (!selectedType) return "All Types";
|
if (!selectedType) return "All Types";
|
||||||
const found = ExpenseTypes.find((t) => t.id === selectedType);
|
const found = ExpenseCategories.find((t) => t.id === selectedType);
|
||||||
return found ? found.name : "All Types";
|
return found ? found.name : "All Types";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,8 +69,8 @@ const ExpenseByProject = () => {
|
|||||||
|
|
||||||
|
|
||||||
const ExpenseCategoryType = [
|
const ExpenseCategoryType = [
|
||||||
{id:1,category:"Category",label:"Category"},
|
{ id: 1, category: "Category", label: "Category" },
|
||||||
{id:2,category:"Project",label:"Project"}
|
{ id: 2, category: "Project", label: "Project" }
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -91,19 +91,19 @@ const ExpenseByProject = () => {
|
|||||||
>
|
>
|
||||||
{viewMode}
|
{viewMode}
|
||||||
</button>
|
</button>
|
||||||
<ul className="dropdown-menu dropdown-menu-end ">
|
<ul className="dropdown-menu dropdown-menu-end ">
|
||||||
{ExpenseCategoryType.map((cat)=>(
|
{ExpenseCategoryType.map((cat) => (
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setViewMode(cat.category);
|
setViewMode(cat.category);
|
||||||
setSelectedType("");
|
setSelectedType("");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{cat.label}
|
{cat.label}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -115,8 +115,8 @@ const ExpenseByProject = () => {
|
|||||||
<button
|
<button
|
||||||
key={item}
|
key={item}
|
||||||
className={`border-0 px-2 py-1 text-sm rounded ${range === item
|
className={`border-0 px-2 py-1 text-sm rounded ${range === item
|
||||||
? "text-white bg-primary"
|
? "text-white bg-primary"
|
||||||
: "text-body bg-transparent"
|
: "text-body bg-transparent"
|
||||||
}`}
|
}`}
|
||||||
style={{ cursor: "pointer", transition: "all 0.2s ease" }}
|
style={{ cursor: "pointer", transition: "all 0.2s ease" }}
|
||||||
onClick={() => setRange(item)}
|
onClick={() => setRange(item)}
|
||||||
|
|||||||
@ -13,230 +13,236 @@ import { useParams } from "react-router-dom";
|
|||||||
|
|
||||||
const DocumentFilterPanel = forwardRef(
|
const DocumentFilterPanel = forwardRef(
|
||||||
({ entityTypeId, onApply, setFilterdata }, ref) => {
|
({ entityTypeId, onApply, setFilterdata }, ref) => {
|
||||||
const [resetKey, setResetKey] = useState(0);
|
const [resetKey, setResetKey] = useState(0);
|
||||||
const { status } = useParams();
|
const { status } = useParams();
|
||||||
|
|
||||||
const { data, isError, isLoading, error } =
|
const { data, isError, isLoading, error } =
|
||||||
useDocumentFilterEntities(entityTypeId);
|
useDocumentFilterEntities(entityTypeId);
|
||||||
|
|
||||||
//changes
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
closePanel();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const dynamicDocumentFilterDefaultValues = useMemo(() => {
|
//changes
|
||||||
return {
|
|
||||||
...DocumentFilterDefaultValues,
|
const dynamicDocumentFilterDefaultValues = useMemo(() => {
|
||||||
uploadedByIds: DocumentFilterDefaultValues.uploadedByIds || [],
|
return {
|
||||||
documentCategoryIds: DocumentFilterDefaultValues.documentCategoryIds || [],
|
...DocumentFilterDefaultValues,
|
||||||
documentTypeIds: DocumentFilterDefaultValues.documentTypeIds || [],
|
uploadedByIds: DocumentFilterDefaultValues.uploadedByIds || [],
|
||||||
documentTagIds: DocumentFilterDefaultValues.documentTagIds || [],
|
documentCategoryIds: DocumentFilterDefaultValues.documentCategoryIds || [],
|
||||||
startDate: DocumentFilterDefaultValues.startDate,
|
documentTypeIds: DocumentFilterDefaultValues.documentTypeIds || [],
|
||||||
endDate: DocumentFilterDefaultValues.endDate,
|
documentTagIds: DocumentFilterDefaultValues.documentTagIds || [],
|
||||||
|
startDate: DocumentFilterDefaultValues.startDate,
|
||||||
|
endDate: DocumentFilterDefaultValues.endDate,
|
||||||
|
};
|
||||||
|
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
|
const methods = useForm({
|
||||||
|
resolver: zodResolver(DocumentFilterSchema),
|
||||||
|
defaultValues: dynamicDocumentFilterDefaultValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { handleSubmit, reset, setValue, watch } = methods;
|
||||||
|
|
||||||
|
// Watch values from form
|
||||||
|
const isUploadedAt = watch("isUploadedAt");
|
||||||
|
const isVerified = watch("isVerified");
|
||||||
|
|
||||||
|
// Close the offcanvas (bootstrap specific)
|
||||||
|
const closePanel = () => {
|
||||||
|
document.querySelector(".offcanvas.show .btn-close")?.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
}, [status]);
|
useImperativeHandle(ref, () => ({
|
||||||
|
resetFieldValue: (name, value) => {
|
||||||
|
if (value !== undefined) {
|
||||||
|
setValue(name, value);
|
||||||
|
} else {
|
||||||
|
reset({ ...methods.getValues(), [name]: DocumentFilterDefaultValues[name] });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getValues: methods.getValues, // optional, to read current filter state
|
||||||
|
}));
|
||||||
|
|
||||||
const methods = useForm({
|
//changes
|
||||||
resolver: zodResolver(DocumentFilterSchema),
|
useEffect(() => {
|
||||||
defaultValues: dynamicDocumentFilterDefaultValues,
|
if (data && setFilterdata) {
|
||||||
});
|
setFilterdata(data);
|
||||||
|
|
||||||
const { handleSubmit, reset, setValue, watch } = methods;
|
|
||||||
|
|
||||||
// Watch values from form
|
|
||||||
const isUploadedAt = watch("isUploadedAt");
|
|
||||||
const isVerified = watch("isVerified");
|
|
||||||
|
|
||||||
// Close the offcanvas (bootstrap specific)
|
|
||||||
const closePanel = () => {
|
|
||||||
document.querySelector(".offcanvas.show .btn-close")?.click();
|
|
||||||
};
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
resetFieldValue: (name, value) => {
|
|
||||||
if (value !== undefined) {
|
|
||||||
setValue(name, value);
|
|
||||||
} else {
|
|
||||||
reset({ ...methods.getValues(), [name]: DocumentFilterDefaultValues[name] });
|
|
||||||
}
|
}
|
||||||
},
|
}, [data, setFilterdata]);
|
||||||
getValues: methods.getValues, // optional, to read current filter state
|
|
||||||
}));
|
|
||||||
|
|
||||||
//changes
|
const onSubmit = (values) => {
|
||||||
useEffect(() => {
|
onApply({
|
||||||
if (data && setFilterdata) {
|
...values,
|
||||||
setFilterdata(data);
|
startDate: values.startDate
|
||||||
}
|
? moment.utc(values.startDate, "DD-MM-YYYY").toISOString()
|
||||||
}, [data, setFilterdata]);
|
: null,
|
||||||
|
endDate: values.endDate
|
||||||
|
? moment.utc(values.endDate, "DD-MM-YYYY").toISOString()
|
||||||
|
: null,
|
||||||
|
});
|
||||||
|
// closePanel();
|
||||||
|
};
|
||||||
|
|
||||||
const onSubmit = (values) => {
|
const onClear = () => {
|
||||||
onApply({
|
reset(DocumentFilterDefaultValues);
|
||||||
...values,
|
setResetKey((prev) => prev + 1);
|
||||||
startDate: values.startDate
|
onApply(DocumentFilterDefaultValues);
|
||||||
? moment.utc(values.startDate, "DD-MM-YYYY").toISOString()
|
// closePanel();
|
||||||
: null,
|
};
|
||||||
endDate: values.endDate
|
|
||||||
? moment.utc(values.endDate, "DD-MM-YYYY").toISOString()
|
|
||||||
: null,
|
|
||||||
});
|
|
||||||
// closePanel();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClear = () => {
|
if (isLoading) return <div>Loading...</div>;
|
||||||
reset(DocumentFilterDefaultValues);
|
if (isError)
|
||||||
setResetKey((prev) => prev + 1);
|
return <div>Error: {error?.message || "Something went wrong!"}</div>;
|
||||||
onApply(DocumentFilterDefaultValues);
|
|
||||||
// closePanel();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isLoading) return <div>Loading...</div>;
|
const {
|
||||||
if (isError)
|
uploadedBy = [],
|
||||||
return <div>Error: {error?.message || "Something went wrong!"}</div>;
|
documentCategory = [],
|
||||||
|
documentType = [],
|
||||||
const {
|
documentTag = [],
|
||||||
uploadedBy = [],
|
} = data?.data || {};
|
||||||
documentCategory = [],
|
|
||||||
documentType = [],
|
|
||||||
documentTag = [],
|
|
||||||
} = data?.data || {};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
{/* Date Range Section */}
|
{/* Date Range Section */}
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="text-start d-flex align-items-center my-1">
|
<div className="text-start d-flex align-items-center my-1">
|
||||||
<label className="form-label me-2 my-0">Choose Date:</label>
|
<label className="form-label me-2 my-0">Choose Date:</label>
|
||||||
<div className="d-inline-flex border rounded-pill overflow-hidden shadow-none">
|
<div className="d-inline-flex border rounded-pill overflow-hidden shadow-none">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn px-2 py-1 rounded-0 text-tiny ${isUploadedAt ? "active btn-secondary text-white" : ""
|
className={`btn px-2 py-1 rounded-0 text-tiny ${isUploadedAt ? "active btn-secondary text-white" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setValue("isUploadedAt", true)}
|
onClick={() => setValue("isUploadedAt", true)}
|
||||||
>
|
>
|
||||||
Uploaded On
|
Uploaded On
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn px-2 py-1 rounded-0 text-tiny ${!isUploadedAt ? "active btn-secondary text-white" : ""
|
className={`btn px-2 py-1 rounded-0 text-tiny ${!isUploadedAt ? "active btn-secondary text-white" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setValue("isUploadedAt", false)}
|
onClick={() => setValue("isUploadedAt", false)}
|
||||||
>
|
>
|
||||||
Updated On
|
Updated On
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DateRangePicker1
|
||||||
|
placeholder="DD-MM-YYYY To DD-MM-YYYY"
|
||||||
|
startField="startDate"
|
||||||
|
endField="endDate"
|
||||||
|
defaultRange={false}
|
||||||
|
resetSignal={resetKey}
|
||||||
|
maxDate={new Date()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Dropdown Filters */}
|
||||||
|
<div className="row g-2 text-start">
|
||||||
|
<SelectMultiple
|
||||||
|
name="uploadedByIds"
|
||||||
|
label="Uploaded By:"
|
||||||
|
options={uploadedBy}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="documentCategoryIds"
|
||||||
|
label="Document Category:"
|
||||||
|
options={documentCategory}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="documentTypeIds"
|
||||||
|
label="Document Type:"
|
||||||
|
options={documentType}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="documentTagIds"
|
||||||
|
label="Tags:"
|
||||||
|
options={documentTag}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Status Filter */}
|
||||||
|
<div className="text-start my-2">
|
||||||
|
<label className="form-label d-block mb-2">Choose Status:</label>
|
||||||
|
<div className="d-flex gap-4">
|
||||||
|
<label className="switch switch-sm">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
className="switch-input"
|
||||||
|
name="isVerified"
|
||||||
|
checked={isVerified === null}
|
||||||
|
onChange={() => setValue("isVerified", null)}
|
||||||
|
/>
|
||||||
|
<span className="switch-toggle-slider">
|
||||||
|
<span className="switch-on"></span>
|
||||||
|
<span className="switch-off"></span>
|
||||||
|
</span>
|
||||||
|
<span className="switch-label">All</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className="switch switch-sm">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
className="switch-input"
|
||||||
|
name="isVerified"
|
||||||
|
checked={isVerified === true}
|
||||||
|
onChange={() => setValue("isVerified", true)}
|
||||||
|
/>
|
||||||
|
<span className="switch-toggle-slider">
|
||||||
|
<span className="switch-on"></span>
|
||||||
|
<span className="switch-off"></span>
|
||||||
|
</span>
|
||||||
|
<span className="switch-label">Verified</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className="switch switch-sm">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
className="switch-input"
|
||||||
|
name="isVerified"
|
||||||
|
checked={isVerified === false}
|
||||||
|
onChange={() => setValue("isVerified", false)}
|
||||||
|
/>
|
||||||
|
<span className="switch-toggle-slider">
|
||||||
|
<span className="switch-on"></span>
|
||||||
|
<span className="switch-off"></span>
|
||||||
|
</span>
|
||||||
|
<span className="switch-label">Rejected</span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DateRangePicker1
|
{/* Footer Buttons */}
|
||||||
placeholder="DD-MM-YYYY To DD-MM-YYYY"
|
<div className="d-flex justify-content-end py-3 gap-2">
|
||||||
startField="startDate"
|
<button
|
||||||
endField="endDate"
|
type="button"
|
||||||
defaultRange={false}
|
className="btn btn-label-secondary btn-sm"
|
||||||
resetSignal={resetKey}
|
onClick={onClear}
|
||||||
maxDate={new Date()}
|
>
|
||||||
/>
|
Clear
|
||||||
</div>
|
</button>
|
||||||
|
<button type="submit" className="btn btn-primary btn-sm">
|
||||||
{/* Dropdown Filters */}
|
Apply
|
||||||
<div className="row g-2 text-start">
|
</button>
|
||||||
<SelectMultiple
|
|
||||||
name="uploadedByIds"
|
|
||||||
label="Uploaded By:"
|
|
||||||
options={uploadedBy}
|
|
||||||
labelKey="name"
|
|
||||||
valueKey="id"
|
|
||||||
/>
|
|
||||||
<SelectMultiple
|
|
||||||
name="documentCategoryIds"
|
|
||||||
label="Document Category:"
|
|
||||||
options={documentCategory}
|
|
||||||
labelKey="name"
|
|
||||||
valueKey="id"
|
|
||||||
/>
|
|
||||||
<SelectMultiple
|
|
||||||
name="documentTypeIds"
|
|
||||||
label="Document Type:"
|
|
||||||
options={documentType}
|
|
||||||
labelKey="name"
|
|
||||||
valueKey="id"
|
|
||||||
/>
|
|
||||||
<SelectMultiple
|
|
||||||
name="documentTagIds"
|
|
||||||
label="Tags:"
|
|
||||||
options={documentTag}
|
|
||||||
labelKey="name"
|
|
||||||
valueKey="id"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Status Filter */}
|
|
||||||
<div className="text-start my-2">
|
|
||||||
<label className="form-label d-block mb-2">Choose Status:</label>
|
|
||||||
<div className="d-flex gap-4">
|
|
||||||
<label className="switch switch-sm">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="switch-input"
|
|
||||||
name="isVerified"
|
|
||||||
checked={isVerified === null}
|
|
||||||
onChange={() => setValue("isVerified", null)}
|
|
||||||
/>
|
|
||||||
<span className="switch-toggle-slider">
|
|
||||||
<span className="switch-on"></span>
|
|
||||||
<span className="switch-off"></span>
|
|
||||||
</span>
|
|
||||||
<span className="switch-label">All</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label className="switch switch-sm">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="switch-input"
|
|
||||||
name="isVerified"
|
|
||||||
checked={isVerified === true}
|
|
||||||
onChange={() => setValue("isVerified", true)}
|
|
||||||
/>
|
|
||||||
<span className="switch-toggle-slider">
|
|
||||||
<span className="switch-on"></span>
|
|
||||||
<span className="switch-off"></span>
|
|
||||||
</span>
|
|
||||||
<span className="switch-label">Verified</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label className="switch switch-sm">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="switch-input"
|
|
||||||
name="isVerified"
|
|
||||||
checked={isVerified === false}
|
|
||||||
onChange={() => setValue("isVerified", false)}
|
|
||||||
/>
|
|
||||||
<span className="switch-toggle-slider">
|
|
||||||
<span className="switch-on"></span>
|
|
||||||
<span className="switch-off"></span>
|
|
||||||
</span>
|
|
||||||
<span className="switch-label">Rejected</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
|
</FormProvider>
|
||||||
{/* Footer Buttons */}
|
);
|
||||||
<div className="d-flex justify-content-end py-3 gap-2">
|
});
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-label-secondary btn-sm"
|
|
||||||
onClick={onClear}
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</button>
|
|
||||||
<button type="submit" className="btn btn-primary btn-sm">
|
|
||||||
Apply
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</FormProvider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default DocumentFilterPanel;
|
export default DocumentFilterPanel;
|
||||||
|
|||||||
@ -519,7 +519,7 @@ function ManagePaymentRequest({ closeModal, requestToEdit = null }) {
|
|||||||
? "Please Wait..."
|
? "Please Wait..."
|
||||||
: requestToEdit
|
: requestToEdit
|
||||||
? "Update"
|
? "Update"
|
||||||
: "Save as Draft"}
|
: "Submit"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -43,9 +43,8 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
displayField = "Status";
|
displayField = "Status";
|
||||||
break;
|
break;
|
||||||
case "submittedBy":
|
case "submittedBy":
|
||||||
key = `${item?.createdBy?.firstName ?? ""} ${
|
key = `${item?.createdBy?.firstName ?? ""} ${item.createdBy?.lastName ?? ""
|
||||||
item.createdBy?.lastName ?? ""
|
}`.trim();
|
||||||
}`.trim();
|
|
||||||
displayField = "Submitted By";
|
displayField = "Submitted By";
|
||||||
break;
|
break;
|
||||||
case "project":
|
case "project":
|
||||||
@ -98,9 +97,8 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
label: "Submitted By",
|
label: "Submitted By",
|
||||||
align: "text-start",
|
align: "text-start",
|
||||||
getValue: (e) =>
|
getValue: (e) =>
|
||||||
`${e.createdBy?.firstName ?? ""} ${
|
`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? ""
|
||||||
e.createdBy?.lastName ?? ""
|
}`.trim() || "N/A",
|
||||||
}`.trim() || "N/A",
|
|
||||||
customRender: (e) => (
|
customRender: (e) => (
|
||||||
<div
|
<div
|
||||||
className="d-flex align-items-center cursor-pointer"
|
className="d-flex align-items-center cursor-pointer"
|
||||||
@ -113,9 +111,8 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
lastName={e.createdBy?.lastName}
|
lastName={e.createdBy?.lastName}
|
||||||
/>
|
/>
|
||||||
<span className="text-truncate">
|
<span className="text-truncate">
|
||||||
{`${e.createdBy?.firstName ?? ""} ${
|
{`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? ""
|
||||||
e.createdBy?.lastName ?? ""
|
}`.trim() || "N/A"}
|
||||||
}`.trim() || "N/A"}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
@ -128,15 +125,12 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "amount",
|
key: "amount",
|
||||||
label: " Amount",
|
label: "Amount",
|
||||||
align: "text-start",
|
align: "text-end",
|
||||||
getValue: (e) => (
|
getValue: (e) =>
|
||||||
<>
|
e?.amount
|
||||||
{formatCurrency(e?.amount)} {e.currency.currencyCode}
|
? `${e?.currency?.symbol ? e.currency.symbol + " " : ""}${e.amount.toLocaleString()}`
|
||||||
</>
|
: "N/A",
|
||||||
),
|
|
||||||
|
|
||||||
align: "text-end px-3",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "expenseStatus",
|
key: "expenseStatus",
|
||||||
@ -144,9 +138,8 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
align: "text-center",
|
align: "text-center",
|
||||||
getValue: (e) => (
|
getValue: (e) => (
|
||||||
<span
|
<span
|
||||||
className={`badge bg-label-${
|
className={`badge bg-label-${getColorNameFromHex(e?.expenseStatus?.color) || "secondary"
|
||||||
getColorNameFromHex(e?.expenseStatus?.color) || "secondary"
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{e?.expenseStatus?.name || "Unknown"}
|
{e?.expenseStatus?.name || "Unknown"}
|
||||||
</span>
|
</span>
|
||||||
@ -181,8 +174,13 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
|
|||||||
if (isLoading) return <ExpenseTableSkeleton headers={header} />;
|
if (isLoading) return <ExpenseTableSkeleton headers={header} />;
|
||||||
|
|
||||||
const grouped = groupBy
|
const grouped = groupBy
|
||||||
? groupByField(data?.data ?? [], groupBy)
|
? Object.fromEntries(
|
||||||
|
Object.entries(groupByField(data?.data ?? [], groupBy)).sort(([keyA], [keyB]) =>
|
||||||
|
keyA.localeCompare(keyB)
|
||||||
|
)
|
||||||
|
)
|
||||||
: { All: data?.data ?? [] };
|
: { All: data?.data ?? [] };
|
||||||
|
|
||||||
const IsGroupedByDate = [
|
const IsGroupedByDate = [
|
||||||
{ key: "transactionDate", displayField: "Transaction Date" },
|
{ key: "transactionDate", displayField: "Transaction Date" },
|
||||||
{ key: "createdAt", displayField: "created Date" },
|
{ key: "createdAt", displayField: "created Date" },
|
||||||
|
|||||||
@ -68,7 +68,7 @@ const RecurringExpenseList = ({ search, filterStatuses }) => {
|
|||||||
align: "text-end",
|
align: "text-end",
|
||||||
getValue: (e) =>
|
getValue: (e) =>
|
||||||
e?.amount
|
e?.amount
|
||||||
? `${e?.currency?.symbol || ""}${e.amount.toLocaleString()}`
|
? `${e?.currency?.symbol ? e.currency.symbol + " " : ""}${e.amount.toLocaleString()}`
|
||||||
: "N/A",
|
: "N/A",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -109,7 +109,7 @@ const RecurringExpenseList = ({ search, filterStatuses }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const paginate = (page) => {
|
const paginate = (page) => {
|
||||||
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
}
|
}
|
||||||
@ -277,11 +277,11 @@ const RecurringExpenseList = ({ search, filterStatuses }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Pagination */}
|
{/* Pagination */}
|
||||||
<Pagination
|
<Pagination
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
totalPages={data?.totalPages}
|
totalPages={data?.totalPages}
|
||||||
onPageChange={paginate}
|
onPageChange={paginate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user