attachement display horizontically
This commit is contained in:
parent
a87d3fb20a
commit
3d7a8a1c94
@ -28,6 +28,7 @@
|
|||||||
<link rel="stylesheet" href="/assets/css/core-extend.css" />
|
<link rel="stylesheet" href="/assets/css/core-extend.css" />
|
||||||
<link rel="stylesheet" href="/assets/css/default.css" />
|
<link rel="stylesheet" href="/assets/css/default.css" />
|
||||||
<link rel="stylesheet" href="/assets/css/skeleton.css" />
|
<link rel="stylesheet" href="/assets/css/skeleton.css" />
|
||||||
|
<link rel="stylesheet" href="/assets/css/hover-utility.css" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
<link rel="stylesheet" href="/assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||||
|
|
||||||
|
86
public/assets/css/hover-utility.css
Normal file
86
public/assets/css/hover-utility.css
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* Hover background color */
|
||||||
|
.hover-bg-light:hover {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-bg-primary:hover {
|
||||||
|
background-color: var(--bs-primary) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-bg-danger:hover {
|
||||||
|
background-color: #dc3545 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-bg-success:hover {
|
||||||
|
background-color: var(--bg-success) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-bg-warning:hover {
|
||||||
|
background-color: #ffc107 !important;
|
||||||
|
color: #212529 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover text color */
|
||||||
|
.hover-text-primary:hover {
|
||||||
|
color: #0d6efd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-text-danger:hover {
|
||||||
|
color: #dc3545 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-text-success:hover {
|
||||||
|
color: #198754 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-text-muted:hover {
|
||||||
|
color: #6c757d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover shadow */
|
||||||
|
.hover-shadow-sm:hover {
|
||||||
|
box-shadow: 0 .125rem .25rem rgba(0, 0, 0, 0.075);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-shadow:hover {
|
||||||
|
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-shadow-lg:hover {
|
||||||
|
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover scale */
|
||||||
|
.hover-scale:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-scale-sm:hover {
|
||||||
|
transform: scale(1.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-scale-lg:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add smooth transition to hover effects */
|
||||||
|
.hover-transition {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover border color */
|
||||||
|
.hover-border-primary:hover {
|
||||||
|
border-color: #0d6efd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-border-danger:hover {
|
||||||
|
border-color: #dc3545 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thick-divider {
|
||||||
|
height: 3px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
@ -120,7 +120,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
|
|||||||
firstName={e.createdBy?.firstName}
|
firstName={e.createdBy?.firstName}
|
||||||
lastName={e.createdBy?.lastName}
|
lastName={e.createdBy?.lastName}
|
||||||
/>
|
/>
|
||||||
<span>
|
<span className="text-truncate">
|
||||||
{`${e.createdBy?.firstName ?? ""} ${
|
{`${e.createdBy?.firstName ?? ""} ${
|
||||||
e.createdBy?.lastName ?? ""
|
e.createdBy?.lastName ?? ""
|
||||||
}`.trim() || "N/A"}
|
}`.trim() || "N/A"}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
const SkeletonLine = ({ height = 20, width = "100%", className = "" }) => (
|
const SkeletonLine = ({ height = 20, width = "100%", className = "" }) => (
|
||||||
<div
|
<div
|
||||||
className={`skeleton mb-2 ${className}`}
|
className={`skeleton mb-2 ${className}`}
|
||||||
@ -11,13 +10,12 @@ const SkeletonLine = ({ height = 20, width = "100%", className = "" }) => (
|
|||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const ExpenseSkeleton = () => {
|
const ExpenseSkeleton = () => {
|
||||||
return (
|
return (
|
||||||
<div className="container p-3">
|
<div className="container p-3">
|
||||||
<div className="d-flex justify-content-center">
|
<div className="d-flex justify-content-center">
|
||||||
<SkeletonLine height={20} width="200px" />
|
<SkeletonLine height={20} width="200px" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{[...Array(5)].map((_, idx) => (
|
{[...Array(5)].map((_, idx) => (
|
||||||
<div className="row my-2" key={idx}>
|
<div className="row my-2" key={idx}>
|
||||||
@ -52,12 +50,9 @@ const ExpenseSkeleton = () => {
|
|||||||
|
|
||||||
export default ExpenseSkeleton;
|
export default ExpenseSkeleton;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const ExpenseDetailsSkeleton = () => {
|
export const ExpenseDetailsSkeleton = () => {
|
||||||
return (
|
return (
|
||||||
<div className="container px-3">
|
<div className="container px-3">
|
||||||
<div className="row mb-3">
|
<div className="row mb-3">
|
||||||
<div className="d-flex justify-content-center mb-3">
|
<div className="d-flex justify-content-center mb-3">
|
||||||
<SkeletonLine height={20} width="180px" className="mb-2" />
|
<SkeletonLine height={20} width="180px" className="mb-2" />
|
||||||
@ -65,7 +60,7 @@ export const ExpenseDetailsSkeleton = () => {
|
|||||||
|
|
||||||
{[...Array(3)].map((_, i) => (
|
{[...Array(3)].map((_, i) => (
|
||||||
<div className="col-12 col-md-4 mb-3" key={`row-1-${i}`}>
|
<div className="col-12 col-md-4 mb-3" key={`row-1-${i}`}>
|
||||||
<SkeletonLine height={14} className="mb-1" />
|
<SkeletonLine height={14} className="mb-1" />
|
||||||
<SkeletonLine />
|
<SkeletonLine />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@ -77,30 +72,38 @@ export const ExpenseDetailsSkeleton = () => {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
<div className="col-12 text-start">
|
||||||
|
<SkeletonLine height={14} width="150px" className="mb-1" />
|
||||||
|
|
||||||
<div className="col-12 my-2">
|
<div className="d-flex flex-wrap gap-2">
|
||||||
<SkeletonLine height={14} width="100px" className="mb-2" />
|
{[...Array(2)].map((_, i) => (
|
||||||
{[...Array(2)].map((_, i) => (
|
|
||||||
<div
|
|
||||||
className="list-group-item d-flex align-items-center mb-2"
|
|
||||||
key={i}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
className="rounded me-2"
|
key={i}
|
||||||
style={{
|
className="border rounded p-2 d-flex flex-column align-items-center"
|
||||||
height: "50px",
|
style={{ width: "80px" }}
|
||||||
width: "80px",
|
>
|
||||||
backgroundColor: "#dcdcdc",
|
{/* Icon placeholder */}
|
||||||
borderRadius: "4px",
|
<div
|
||||||
}}
|
style={{
|
||||||
/>
|
height: "30px",
|
||||||
<div className="w-100">
|
width: "30px",
|
||||||
<SkeletonLine height={14} width="60%" className="mb-1" />
|
|
||||||
<SkeletonLine height={14} width="20%" />
|
borderRadius: "4px",
|
||||||
|
marginBottom: "6px",
|
||||||
|
}}
|
||||||
|
className="skeleton"
|
||||||
|
/>
|
||||||
|
{/* Filename placeholder */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "10px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
className="skeleton"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr className="divider my-1" />
|
<hr className="divider my-1" />
|
||||||
@ -123,7 +126,12 @@ export const ExpenseDetailsSkeleton = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const SkeletonCell = ({ width = "100%", height = 20, className = "", style = {} }) => (
|
const SkeletonCell = ({
|
||||||
|
width = "100%",
|
||||||
|
height = 20,
|
||||||
|
className = "",
|
||||||
|
style = {},
|
||||||
|
}) => (
|
||||||
<div
|
<div
|
||||||
className={`skeleton ${className}`}
|
className={`skeleton ${className}`}
|
||||||
style={{
|
style={{
|
||||||
@ -137,93 +145,108 @@ const SkeletonCell = ({ width = "100%", height = 20, className = "", style = {}
|
|||||||
|
|
||||||
export const ExpenseTableSkeleton = ({ groups = 3, rowsPerGroup = 3 }) => {
|
export const ExpenseTableSkeleton = ({ groups = 3, rowsPerGroup = 3 }) => {
|
||||||
return (
|
return (
|
||||||
<div className="card px-2">
|
<div className="card px-2">
|
||||||
<table
|
<table
|
||||||
className="card-body table border-top dataTable no-footer dtr-column text-nowrap"
|
className="card-body table border-top dataTable no-footer dtr-column text-nowrap"
|
||||||
aria-describedby="DataTables_Table_0_info"
|
aria-describedby="DataTables_Table_0_info"
|
||||||
id="horizontal-example"
|
id="horizontal-example"
|
||||||
>
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="d-none d-sm-table-cell">
|
<th className="d-none d-sm-table-cell">
|
||||||
<div className="text-start ms-5">Expense Type</div>
|
<div className="text-start ms-5">Expense Type</div>
|
||||||
</th>
|
</th>
|
||||||
<th className="d-none d-sm-table-cell">
|
<th className="d-none d-sm-table-cell">
|
||||||
<div className="text-start ms-5">Payment Mode</div>
|
<div className="text-start ms-5">Payment Mode</div>
|
||||||
</th>
|
</th>
|
||||||
<th className="d-none d-sm-table-cell">Paid By</th>
|
<th className="d-none d-sm-table-cell">Submitted By</th>
|
||||||
<th className="d-none d-md-table-cell">Amount</th>
|
<th className="d-none d-sm-table-cell">Submitted</th>
|
||||||
<th>Status</th>
|
<th className="d-none d-md-table-cell">Amount</th>
|
||||||
<th>Action</th>
|
<th>Status</th>
|
||||||
</tr>
|
<th>Action</th>
|
||||||
</thead>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{[...Array(groups)].map((_, groupIdx) => (
|
{[...Array(groups)].map((_, groupIdx) => (
|
||||||
<React.Fragment key={`group-${groupIdx}`}>
|
<React.Fragment key={`group-${groupIdx}`}>
|
||||||
{/* Fake Date Group Header Row */}
|
{/* Fake Date Group Header Row */}
|
||||||
<tr className="bg-light">
|
<tr className="bg-light">
|
||||||
<td colSpan={8}>
|
<td colSpan={8}>
|
||||||
<SkeletonCell width="150px" height={20} />
|
<SkeletonCell width="150px" height={20} />
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{/* Rows under this group */}
|
|
||||||
{[...Array(rowsPerGroup)].map((__, rowIdx) => (
|
|
||||||
<tr key={`row-${groupIdx}-${rowIdx}`} className={rowIdx % 2 === 0 ? "odd" : "even"}>
|
|
||||||
{/* Expense Type */}
|
|
||||||
<td className="text-start d-none d-sm-table-cell ms-5">
|
|
||||||
<SkeletonCell width="90px" height={16} />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Payment Mode */}
|
|
||||||
<td className="text-start d-none d-sm-table-cell ms-5">
|
|
||||||
<SkeletonCell width="90px" height={16} />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Paid By (Avatar + name) */}
|
|
||||||
<td className="text-start d-none d-sm-table-cell ms-5">
|
|
||||||
<div className="d-flex align-items-center gap-2">
|
|
||||||
<SkeletonCell width="30px" height={30} className="rounded-circle" />
|
|
||||||
<SkeletonCell width="80px" height={16} />
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Amount */}
|
|
||||||
<td className="d-none d-md-table-cell text-end">
|
|
||||||
<SkeletonCell width="60px" height={16} />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Status */}
|
|
||||||
<td>
|
|
||||||
<SkeletonCell width="80px" height={22} className="rounded" />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Action */}
|
|
||||||
<td>
|
|
||||||
<div className="d-flex justify-content-center align-items-center gap-2">
|
|
||||||
{[...Array(3)].map((__, i) => (
|
|
||||||
<SkeletonCell
|
|
||||||
key={i}
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
className="rounded"
|
|
||||||
style={{ display: "inline-block" }}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
|
||||||
</React.Fragment>
|
{/* Rows under this group */}
|
||||||
))}
|
{[...Array(rowsPerGroup)].map((__, rowIdx) => (
|
||||||
</tbody>
|
<tr
|
||||||
</table>
|
key={`row-${groupIdx}-${rowIdx}`}
|
||||||
</div>
|
className={rowIdx % 2 === 0 ? "odd" : "even"}
|
||||||
|
>
|
||||||
|
{/* Expense Type */}
|
||||||
|
<td className="text-start d-none d-sm-table-cell ms-5">
|
||||||
|
<SkeletonCell width="90px" height={16} />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Payment Mode */}
|
||||||
|
<td className="text-start d-none d-sm-table-cell ms-5">
|
||||||
|
<SkeletonCell width="90px" height={16} />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Submitted By (Avatar + name) */}
|
||||||
|
<td className="text-start d-none d-sm-table-cell ms-5">
|
||||||
|
<div className="d-flex align-items-center gap-2">
|
||||||
|
<SkeletonCell
|
||||||
|
width="30px"
|
||||||
|
height={30}
|
||||||
|
className="rounded-circle"
|
||||||
|
/>
|
||||||
|
<SkeletonCell width="80px" height={16} />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{/* Submitted */}
|
||||||
|
<td className="d-none d-md-table-cell text-end">
|
||||||
|
<SkeletonCell width="70px" height={16} />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Amount */}
|
||||||
|
<td className="d-none d-md-table-cell text-end">
|
||||||
|
<SkeletonCell width="60px" height={16} />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Status */}
|
||||||
|
<td>
|
||||||
|
<SkeletonCell
|
||||||
|
width="80px"
|
||||||
|
height={22}
|
||||||
|
className="rounded"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Action */}
|
||||||
|
<td>
|
||||||
|
<div className="d-flex justify-content-center align-items-center gap-2">
|
||||||
|
{[...Array(3)].map((__, i) => (
|
||||||
|
<SkeletonCell
|
||||||
|
key={i}
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
className="rounded"
|
||||||
|
style={{ display: "inline-block" }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const ExpenseFilterSkeleton = () => {
|
export const ExpenseFilterSkeleton = () => {
|
||||||
return (
|
return (
|
||||||
<div className="p-3 text-start">
|
<div className="p-3 text-start">
|
||||||
|
@ -5,7 +5,10 @@ import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
|||||||
const ExpenseStatusLogs = ({ data }) => {
|
const ExpenseStatusLogs = ({ data }) => {
|
||||||
const [visibleCount, setVisibleCount] = useState(4);
|
const [visibleCount, setVisibleCount] = useState(4);
|
||||||
|
|
||||||
const logsToShow = data?.expenseLogs?.slice(0, visibleCount) || [];
|
const logsToShow = [...(data?.expenseLogs || [])]
|
||||||
|
.sort((a, b) => new Date(b.updateAt) - new Date(a.updateAt))
|
||||||
|
.slice(0, visibleCount);
|
||||||
|
|
||||||
|
|
||||||
const handleShowMore = () => {
|
const handleShowMore = () => {
|
||||||
setVisibleCount((prev) => prev + 4);
|
setVisibleCount((prev) => prev + 4);
|
||||||
|
@ -9,7 +9,7 @@ import { useForm } from "react-hook-form";
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { defaultActionValues, ExpenseActionScheam } from "./ExpenseSchema";
|
import { defaultActionValues, ExpenseActionScheam } from "./ExpenseSchema";
|
||||||
import { useExpenseContext } from "../../pages/Expense/ExpensePage";
|
import { useExpenseContext } from "../../pages/Expense/ExpensePage";
|
||||||
import { getColorNameFromHex } from "../../utils/appUtils";
|
import { getColorNameFromHex, getIconByFileType } from "../../utils/appUtils";
|
||||||
import { ExpenseDetailsSkeleton } from "./ExpenseSkeleton";
|
import { ExpenseDetailsSkeleton } from "./ExpenseSkeleton";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import {
|
import {
|
||||||
@ -271,37 +271,24 @@ const ViewExpense = ({ ExpenseId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-start">
|
|
||||||
<label className="form-label me-2 mb-0 fw-semibold">Attachment :</label>
|
|
||||||
|
|
||||||
{data?.documents?.map((doc) => {
|
<div className="col-12 text-start">
|
||||||
const getIconByType = (type) => {
|
<label className="form-label me-2 mb-2 fw-semibold">Attachment :</label>
|
||||||
if (!type) return "bx bx-file";
|
|
||||||
|
|
||||||
if (type.includes("pdf")) return "bxs-file-pdf";
|
<div className="d-flex flex-wrap gap-2">
|
||||||
if (type.includes("word")) return "bxs-file-doc";
|
{data?.documents?.map((doc) => {
|
||||||
if (type.includes("excel") || type.includes("spreadsheet"))
|
const isImage = doc.contentType?.includes("image");
|
||||||
return "bxs-file-xls";
|
|
||||||
if (type.includes("image")) return "bxs-file-image";
|
|
||||||
if (type.includes("zip") || type.includes("rar"))
|
|
||||||
return "bxs-file-archive";
|
|
||||||
|
|
||||||
return "bx bx-file";
|
return (
|
||||||
};
|
|
||||||
|
|
||||||
const isImage = doc.contentType?.includes("image");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="list-group-item list-group-item-action d-flex align-items-center"
|
|
||||||
key={doc.documentId}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
className="rounded me-1 d-flex align-items-center justify-content-center cursor-pointer"
|
key={doc.documentId}
|
||||||
style={{ height: "50px", width: "60px", position: "relative" }}
|
className="border rounded hover-scale p-2 d-flex flex-column align-items-center"
|
||||||
|
style={{
|
||||||
|
width: "80px",
|
||||||
|
cursor: isImage ? "pointer" : "default",
|
||||||
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isImage) {
|
if (isImage) {
|
||||||
setDocumentView({
|
setDocumentView({
|
||||||
@ -312,31 +299,22 @@ const ViewExpense = ({ ExpenseId }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className={`bx ${getIconByType(
|
className={`bx ${getIconByFileType(doc.contentType)}`}
|
||||||
doc.contentType
|
style={{ fontSize: "30px" }}
|
||||||
)} text-primary`}
|
|
||||||
style={{ fontSize: "35px" }}
|
|
||||||
></i>
|
></i>
|
||||||
|
<small
|
||||||
|
className="text-center text-tiny text-truncate w-100"
|
||||||
|
title={doc.fileName}
|
||||||
|
>
|
||||||
|
{doc.fileName}
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
<div className="w-100">
|
})}
|
||||||
<small className="mb-0 small">{doc.fileName}</small>
|
</div>
|
||||||
<div className="d">
|
|
||||||
<a
|
|
||||||
href={doc.preSignedUrl}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="bx bx-cloud-download cursor-pointer"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{data.expensesReimburse && (
|
||||||
{data.expensesReimburse && (
|
|
||||||
<div className="row text-start">
|
<div className="row text-start">
|
||||||
<div className="col-md-6 mb-sm-0 mb-2">
|
<div className="col-md-6 mb-sm-0 mb-2">
|
||||||
<label className="form-label me-2 mb-0 fw-semibold">
|
<label className="form-label me-2 mb-0 fw-semibold">
|
||||||
@ -371,7 +349,7 @@ const ViewExpense = ({ ExpenseId }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<hr className="divider my-1" />
|
<hr className="divider my-1 py-3 divider-primary" />
|
||||||
|
|
||||||
{Array.isArray(data?.nextStatus) && data.nextStatus.length > 0 && (
|
{Array.isArray(data?.nextStatus) && data.nextStatus.length > 0 && (
|
||||||
<>
|
<>
|
||||||
@ -457,11 +435,8 @@ const ViewExpense = ({ ExpenseId }) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ExpenseStatusLogs data={data}/>
|
<ExpenseStatusLogs data={data} />
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
// it important ------
|
// it important ------
|
||||||
export const mastersList = [ {id: 1, name: "Application Role"}, {id: 2, name: "Job Role"}, {id: 3, name: "Activity"},{id: 4, name:"Work Category"},{id:5,name:"Contact Category"},{id:6,name:"Contact Tag"}]
|
export const mastersList = [
|
||||||
|
{ id: 1, name: "Application Role" },
|
||||||
|
{ id: 2, name: "Job Role" },
|
||||||
|
{ id: 3, name: "Activity" },
|
||||||
|
{ id: 4, name: "Work Category" },
|
||||||
|
{ id: 5, name: "Contact Category" },
|
||||||
|
{ id: 6, name: "Contact Tag" },
|
||||||
|
{ id: 7, name: "Expense Type" },
|
||||||
|
{ id: 8, name: "Payment Mode" },
|
||||||
|
];
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
export const dailyTask = [
|
export const dailyTask = [
|
||||||
|
@ -180,7 +180,7 @@ const ExpensePage = () => {
|
|||||||
{ViewDocument.IsOpen && (
|
{ViewDocument.IsOpen && (
|
||||||
<GlobalModel
|
<GlobalModel
|
||||||
isOpen
|
isOpen
|
||||||
size="lg"
|
size="md"
|
||||||
key={ViewDocument.Image ?? "doc"}
|
key={ViewDocument.Image ?? "doc"}
|
||||||
closeModal={() => setDocumentView({ IsOpen: false, Image: null })}
|
closeModal={() => setDocumentView({ IsOpen: false, Image: null })}
|
||||||
>
|
>
|
||||||
|
@ -9,13 +9,18 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
|
|||||||
const selectedMaster = useSelector(
|
const selectedMaster = useSelector(
|
||||||
(store) => store.localVariables.selectedMaster
|
(store) => store.localVariables.selectedMaster
|
||||||
);
|
);
|
||||||
const hiddenColumns = [
|
const hiddenColumns = [
|
||||||
"id",
|
"id",
|
||||||
"featurePermission",
|
"featurePermission",
|
||||||
"tenant",
|
"tenant",
|
||||||
"tenantId",
|
"tenantId",
|
||||||
"checkLists",
|
"checkLists",
|
||||||
"isSystem",
|
"isSystem",
|
||||||
|
"isActive",
|
||||||
|
"noOfPersonsRequired",
|
||||||
|
"color",
|
||||||
|
"displayName",
|
||||||
|
"permissionIds"
|
||||||
];
|
];
|
||||||
|
|
||||||
const safeData = Array.isArray(data) ? data : [];
|
const safeData = Array.isArray(data) ? data : [];
|
||||||
|
@ -46,4 +46,18 @@ export const useDebounce = (value, delay = 500) => {
|
|||||||
}, [value, delay]);
|
}, [value, delay]);
|
||||||
|
|
||||||
return debouncedValue;
|
return debouncedValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getIconByFileType = (type = "") => {
|
||||||
|
const lower = type.toLowerCase();
|
||||||
|
|
||||||
|
if (lower === "application/pdf") return "bxs-file-pdf";
|
||||||
|
if (lower.includes("word")) return "bxs-file-doc";
|
||||||
|
if (lower.includes("excel") || lower.includes("spreadsheet"))
|
||||||
|
return "bxs-file-xls";
|
||||||
|
if (lower === "image/png") return "bxs-file-png";
|
||||||
|
if (lower === "image/jpeg" || lower === "image/jpg") return "bxs-file-jpg";
|
||||||
|
if (lower.includes("zip") || lower.includes("rar")) return "bxs-file-archive";
|
||||||
|
|
||||||
|
return "bx bx-file";
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user