From fd143285629882a667ffa0a24c9d0c4eba01e77c Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Wed, 3 Sep 2025 11:18:12 +0530 Subject: [PATCH] enable activating or deactivating existing documents --- src/components/Documents/Documents.jsx | 187 ++++++++++++--------- src/components/Documents/DocumentsList.jsx | 146 +++++++++------- src/hooks/useDocument.js | 7 +- src/repositories/DocumentRepository.jsx | 4 +- 4 files changed, 202 insertions(+), 142 deletions(-) diff --git a/src/components/Documents/Documents.jsx b/src/components/Documents/Documents.jsx index 85efe79c..513c6611 100644 --- a/src/components/Documents/Documents.jsx +++ b/src/components/Documents/Documents.jsx @@ -21,12 +21,13 @@ export const DocumentContext = createContext(); export const useDocumentContext = () => { const context = useContext(DocumentContext); if (!context) { - throw new Error("useDocumentContext must be used within an DocumentProvider"); + throw new Error( + "useDocumentContext must be used within an DocumentProvider" + ); } return context; }; - export const getDocuementsStatus = (status) => { switch (status) { case true: @@ -46,22 +47,22 @@ export const getDocuementsStatus = (status) => { }; const Documents = ({ Document_Entity, Entity }) => { const [searchText, setSearchText] = useState(""); + const [isActive, setIsActive] = useState(true); const [filters, setFilter] = useState(); const [isRefetching, setIsRefetching] = useState(false); const [refetchFn, setRefetchFn] = useState(null); - const [DocumentEntity,setDocumentEntity] = useState(Document_Entity) + const [DocumentEntity, setDocumentEntity] = useState(Document_Entity); const { employeeId } = useParams(); - const [OpenDocument,setOpenDocument] = useState(false) + const [OpenDocument, setOpenDocument] = useState(false); const [ManageDoc, setManageDoc] = useState({ document: null, isOpen: false, }); - const [viewDoc, setViewDoc] = useState({ + const [viewDoc, setViewDoc] = useState({ document: null, isOpen: false, }); - const { setOffcanvasContent, setShowTrigger } = useFab(); const methods = useForm({ @@ -95,34 +96,33 @@ const Documents = ({ Document_Entity, Entity }) => { viewDoc, setViewDoc, setOpenDocument, - OpenDocument - } + OpenDocument, + }; - useEffect(()=>{ - if(Document_Entity){ - setDocumentEntity(Document_Entity) + useEffect(() => { + if (Document_Entity) { + setDocumentEntity(Document_Entity); } - },[Document_Entity]) + }, [Document_Entity]); return ( +
+
+
+ {/* Search */} +
+ setSearchText(e.target.value)} + className="form-control form-control-sm" + placeholder="Search Document" + /> +
-
-
-
- {/* Search */} -
- setSearchText(e.target.value)} - className="form-control form-control-sm" - placeholder="Search Document" - /> -
- - {/* Actions */} -
- {/* + {/* { @@ -138,71 +138,96 @@ const Documents = ({ Document_Entity, Entity }) => { }`} > */} + - + +
+
- -
- {ManageDoc.isOpen && ( - - setManageDoc({ - document: null, - isOpen: false, - }) - } - > - setManageDoc({ document: null, isOpen: false, }) } - Document_Entity={DocumentEntity} - Entity={Entity} - /> - - )} + > + + setManageDoc({ + document: null, + isOpen: false, + }) + } + Document_Entity={DocumentEntity} + Entity={Entity} + /> + + )} - {viewDoc.isOpen && ( - setViewDoc({ - document:null, - isOpen:false - })}> - - - )} + {viewDoc.isOpen && ( + + setViewDoc({ + document: null, + isOpen: false, + }) + } + > + + + )} - {OpenDocument && ( - setOpenDocument(false)}> - - - )} - -
+ {OpenDocument && ( + setOpenDocument(false)} + > + + + )} +
- ); }; diff --git a/src/components/Documents/DocumentsList.jsx b/src/components/Documents/DocumentsList.jsx index 2a9b8879..656a9cdb 100644 --- a/src/components/Documents/DocumentsList.jsx +++ b/src/components/Documents/DocumentsList.jsx @@ -6,12 +6,12 @@ import { import { ITEMS_PER_PAGE } from "../../utils/constants"; import Avatar from "../common/Avatar"; import { formatUTCToLocalTime } from "../../utils/dateUtils"; -import Loader from "../common/Loader"; import { useDebounce } from "../../utils/appUtils"; import { DocumentTableSkeleton } from "./DocumentSkeleton"; import { getDocuementsStatus, useDocumentContext } from "./Documents"; import Pagination from "../common/Pagination"; import ConfirmModal from "../common/ConfirmModal"; +import { isPending } from "@reduxjs/toolkit"; const DocumentsList = ({ Document_Entity, @@ -20,11 +20,14 @@ const DocumentsList = ({ searchText, setIsRefetching, setRefetchFn, + isActive, }) => { const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [deletingId, setDeletingId] = useState(null); + const [restoringIds, setRestoringIds] = useState([]); const debouncedSearch = useDebounce(searchText, 500); const [currentPage, setCurrentPage] = useState(1); + const { data, isError, isLoading, error, refetch, isFetching } = useDocumentListByEntityId( Document_Entity, @@ -32,21 +35,21 @@ const DocumentsList = ({ ITEMS_PER_PAGE, currentPage, filters, - debouncedSearch + debouncedSearch, + isActive ); - // Pass the refetch function to parent when component mounts useEffect(() => { setRefetchFn(() => refetch); }, [setRefetchFn, refetch]); - // Sync fetching status with parent useEffect(() => { setIsRefetching(isFetching); }, [isFetching, setIsRefetching]); const { setManageDoc, setViewDoc } = useDocumentContext(); const { mutate: ActiveInActive, isPending } = useActiveInActiveDocument(); + const paginate = (page) => { if (page >= 1 && page <= (data?.totalPages ?? 1)) { setCurrentPage(page); @@ -66,9 +69,8 @@ const DocumentsList = ({ if (isFilterEmpty) return
No documents match your filter.
; const handleDelete = () => { - debugger; ActiveInActive( - { documentId: deletingId, isActive: false }, + { documentId: deletingId, isActive: !isActive }, { onSettled: () => { setDeletingId(null); @@ -77,6 +79,21 @@ const DocumentsList = ({ } ); }; + + const handleRestore = (docId) => { + setRestoringIds((prev) => [...prev, docId]); + + ActiveInActive( + { documentId: docId, isActive: true }, + { + onSettled: () => { + setRestoringIds((prev) => prev.filter((id) => id !== docId)); + refetch(); + }, + } + ); + }; + const DocumentColumns = [ { key: "name", @@ -94,10 +111,6 @@ const DocumentsList = ({ key: "uploadedBy", label: "Uploaded By", align: "text-start", - getValue: (e) => - `${e.uploadedBy?.firstName ?? ""} ${ - e.uploadedBy?.lastName ?? "" - }`.trim() || "N/A", customRender: (e) => (
- + {`${e.uploadedBy?.firstName ?? ""} ${ e.uploadedBy?.lastName ?? "" }`.trim() || "N/A"}
), + getValue: (e) => + `${e.uploadedBy?.firstName ?? ""} ${ + e.uploadedBy?.lastName ?? "" + }`.trim() || "N/A", }, { key: "uploadedAt", label: "Uploaded on", - getValue: (e) => formatUTCToLocalTime(e?.uploadedAt), - isAlwaysVisible: true, + getValue: (e) => formatUTCToLocalTime(e.uploadedAt), align: "text-center", + isAlwaysVisible: true, }, { key: "Status", - label: "status", + label: "Status", getValue: (e) => getDocuementsStatus(e.isVerified), - isAlwaysVisible: true, align: "text-center", + isAlwaysVisible: true, }, ]; @@ -134,13 +151,10 @@ const DocumentsList = ({ <> {IsDeleteModalOpen && (
setIsDeleteModalOpen(false)} - loading={isPending} + loading={!!isPending} paramData={deletingId} />
@@ -170,48 +184,66 @@ const DocumentsList = ({ - {data?.data?.map((doc) => ( - - {DocumentColumns.map((col) => ( - - {col.customRender - ? col.customRender(doc) - : col.getValue(doc)} + {data?.data?.map((doc) => { + const isRestoring = restoringIds.includes(doc.id); + + return ( + + {DocumentColumns.map((col) => ( + + {col.customRender + ? col.customRender(doc) + : col.getValue(doc)} + + ))} + + {doc.isActive ? ( +
+ + setViewDoc({ document: doc.id, isOpen: true }) + } + > + + + setManageDoc({ document: doc.id, isOpen: true }) + } + > + + { + setIsDeleteModalOpen(true); + setDeletingId(doc.id); + }} + > +
+ ) : isRestoring ? ( +
+ Loading... +
+ ) : ( + handleRestore(doc.id)} + > + )} - ))} - -
- - setViewDoc({ document: doc?.id, isOpen: true }) - } - > - - - setManageDoc({ document: doc?.id, isOpen: true }) - } - > - - { - setIsDeleteModalOpen(true); - setDeletingId(doc?.id); - }} - > -
- - - ))} + + ); + })} {data?.data?.length > 0 && ( )} diff --git a/src/hooks/useDocument.js b/src/hooks/useDocument.js index 15c1f304..c23f1d9b 100644 --- a/src/hooks/useDocument.js +++ b/src/hooks/useDocument.js @@ -31,7 +31,8 @@ export const useDocumentListByEntityId = ( pageSize, pageNumber, filter, - searchString = "" + searchString = "", + isActive ) => { return useQuery({ queryKey: [ @@ -42,6 +43,7 @@ export const useDocumentListByEntityId = ( pageNumber, filter, searchString, + isActive ], queryFn: async () => { const cleanedFilter = cleanFilter(filter); @@ -51,7 +53,8 @@ export const useDocumentListByEntityId = ( pageSize, pageNumber, cleanedFilter, - searchString + searchString, + isActive ); return resp.data diff --git a/src/repositories/DocumentRepository.jsx b/src/repositories/DocumentRepository.jsx index c7c78d57..0d6ab9d0 100644 --- a/src/repositories/DocumentRepository.jsx +++ b/src/repositories/DocumentRepository.jsx @@ -2,9 +2,9 @@ import { api } from "../utils/axiosClient"; export const DocumentRepository = { uploadDocument:(data)=> api.post(`/api/Document/upload`,data), - getDocumentList:(entityTypeId,entityId,pageSize, pageNumber, filter,searchString)=>{ + getDocumentList:(entityTypeId,entityId,pageSize, pageNumber, filter,searchString,isActive)=>{ const payloadJsonString = JSON.stringify(filter); - return api.get(`/api/Document/list/${entityTypeId}/entity/${entityId}/?pageSize=${pageSize}&pageNumber=${pageNumber}&filter=${payloadJsonString}&searchString=${searchString}`) + return api.get(`/api/Document/list/${entityTypeId}/entity/${entityId}/?pageSize=${pageSize}&pageNumber=${pageNumber}&filter=${payloadJsonString}&searchString=${searchString}&isActive=${isActive}`) }, getDocumentById:(id)=>api.get(`/api/Document/get/details/${id}`),