Adding Chips in Document.
This commit is contained in:
parent
cbb52087c3
commit
c686b388f4
@ -124,7 +124,7 @@ const AttendLogs = ({ Id }) => {
|
||||
return (
|
||||
<div className="table-responsive">
|
||||
<div className="mb-3">
|
||||
<h5 className="fw-bold mb-2">Attendance Logs</h5>
|
||||
<h5 className="fw-bold mb-4">Attendance Logs</h5>
|
||||
{logs && !loading && (
|
||||
<p className="mb-0 text-start">
|
||||
Showing logs for{" "}
|
||||
@ -146,9 +146,9 @@ const AttendLogs = ({ Id }) => {
|
||||
<table className="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Activity</th>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Activity</th>
|
||||
<th>Location</th>
|
||||
<th>Recored By</th>
|
||||
<th>Description</th>
|
||||
@ -160,15 +160,16 @@ const AttendLogs = ({ Id }) => {
|
||||
.sort((a, b) => b.id - a.id)
|
||||
.map((log, index) => (
|
||||
<tr key={index}>
|
||||
<td>
|
||||
{whichActivityPerform(log.activity, log.activityTime)}
|
||||
</td>
|
||||
<td>
|
||||
<div className="py-2">
|
||||
{formatUTCToLocalTime(log.activityTime)}
|
||||
</div>
|
||||
</td>
|
||||
<td>{convertShortTime(log.activityTime)}</td>
|
||||
<td>
|
||||
{whichActivityPerform(log.activity, log.activityTime)}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{log?.latitude != 0 ? (
|
||||
<i
|
||||
|
@ -2,80 +2,93 @@ import React, { useMemo } from "react";
|
||||
import moment from "moment";
|
||||
|
||||
const DocumentFilterChips = ({ filters, filterData, removeFilterChip }) => {
|
||||
const filterChips = useMemo(() => {
|
||||
const chips = [];
|
||||
// Normalize structure: handle both "filterData.data" and plain "filterData"
|
||||
const data = filterData?.data || filterData || {};
|
||||
|
||||
const buildGroup = (ids, list, label, key) => {
|
||||
if (!ids?.length) return;
|
||||
const items = ids.map((id) => ({
|
||||
id,
|
||||
name: list.find((item) => item.id === id)?.name || id,
|
||||
}));
|
||||
chips.push({ key, label, items });
|
||||
};
|
||||
const filterChips = useMemo(() => {
|
||||
const chips = [];
|
||||
|
||||
// Build chips from document filters
|
||||
buildGroup(filters.uploadedByIds, filterData.data.uploadedBy || [], "Uploaded By", "uploadedByIds");
|
||||
buildGroup(filters.documentCategoryIds, filterData.data.documentCategory || [], "Category", "documentCategoryIds");
|
||||
buildGroup(filters.documentTypeIds, filterData.data.documentType || [], "Type", "documentTypeIds");
|
||||
buildGroup(filters.documentTagIds, filterData.data.documentTag || [], "Tags", "documentTagIds");
|
||||
const buildGroup = (ids, list, label, key) => {
|
||||
if (!ids?.length) return;
|
||||
const items = ids.map((id) => ({
|
||||
id,
|
||||
name: list?.find((item) => item.id === id)?.name || id,
|
||||
}));
|
||||
chips.push({ key, label, items });
|
||||
};
|
||||
|
||||
if (filters.statusIds?.length) {
|
||||
const items = filters.statusIds.map((status) => ({
|
||||
id: status,
|
||||
name:
|
||||
status === true
|
||||
? "Verified"
|
||||
: status === false
|
||||
? "Rejected"
|
||||
: "Pending",
|
||||
}));
|
||||
chips.push({ key: "statusIds", label: "Status", items });
|
||||
}
|
||||
// Build chips using normalized data
|
||||
buildGroup(filters.uploadedByIds, data.uploadedBy || [], "Uploaded By", "uploadedByIds");
|
||||
buildGroup(filters.documentCategoryIds, data.documentCategory || [], "Category", "documentCategoryIds");
|
||||
buildGroup(filters.documentTypeIds, data.documentType || [], "Type", "documentTypeIds");
|
||||
buildGroup(filters.documentTagIds, data.documentTag || [], "Tags", "documentTagIds");
|
||||
|
||||
if (filters.startDate || filters.endDate) {
|
||||
const start = filters.startDate ? moment(filters.startDate).format("DD-MM-YYYY") : "";
|
||||
const end = filters.endDate ? moment(filters.endDate).format("DD-MM-YYYY") : "";
|
||||
chips.push({
|
||||
key: "dateRange",
|
||||
label: "Date Range",
|
||||
items: [{ id: "dateRange", name: `${start} - ${end}` }],
|
||||
});
|
||||
}
|
||||
if (filters.statusIds?.length) {
|
||||
const items = filters.statusIds.map((status) => ({
|
||||
id: status,
|
||||
name:
|
||||
status === true
|
||||
? "Verified"
|
||||
: status === false
|
||||
? "Rejected"
|
||||
: "Pending",
|
||||
}));
|
||||
chips.push({ key: "statusIds", label: "Status", items });
|
||||
}
|
||||
|
||||
return chips;
|
||||
}, [filters, filterData]);
|
||||
if (filters.startDate || filters.endDate) {
|
||||
const start = filters.startDate ? moment(filters.startDate).format("DD-MM-YYYY") : "";
|
||||
const end = filters.endDate ? moment(filters.endDate).format("DD-MM-YYYY") : "";
|
||||
chips.push({
|
||||
key: "dateRange",
|
||||
label: "Date Range",
|
||||
items: [{ id: "dateRange", name: `${start} - ${end}` }],
|
||||
});
|
||||
}
|
||||
|
||||
if (!filterChips.length) return null;
|
||||
return chips;
|
||||
}, [filters, filterData]);
|
||||
|
||||
console.log("Kartik", filterData.uploadedBy)
|
||||
if (!filterChips.length) return null;
|
||||
|
||||
return (
|
||||
<div className="row my-2">
|
||||
<div className="col-12">
|
||||
<div className="d-flex flex-wrap align-items-start gap-1">
|
||||
{filterChips.map((chip) => (
|
||||
<div key={chip.key} className="d-flex align-items-center flex-wrap px-2 py-1" style={{ fontSize: "0.9rem" }}>
|
||||
<span className="fw-semibold me-2">{chip.label}:</span>
|
||||
<div className="d-flex flex-wrap align-items-center gap-1">
|
||||
{chip.items.map((item) => (
|
||||
<span key={item.id} className="d-flex align-items-center bg-light rounded px-2 py-1 text-xs">
|
||||
<span>{item.name}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close btn-close-white btn-sm ms-2"
|
||||
style={{ filter: "invert(1) grayscale(1)", opacity: 0.7, fontSize: "0.6rem" }}
|
||||
onClick={() => removeFilterChip(chip.key, item.id)}
|
||||
/>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
return (
|
||||
<div className="row my-2">
|
||||
<div className="col-12">
|
||||
<div className="d-flex flex-wrap align-items-start gap-1">
|
||||
{filterChips.map((chip) => (
|
||||
<div
|
||||
key={chip.key}
|
||||
className="d-flex align-items-center flex-wrap px-2 py-1"
|
||||
style={{ fontSize: "0.9rem" }}
|
||||
>
|
||||
<span className="fw-semibold me-2">{chip.label}:</span>
|
||||
<div className="d-flex flex-wrap align-items-center gap-1">
|
||||
{chip.items.map((item) => (
|
||||
<span
|
||||
key={item.id}
|
||||
className="d-flex align-items-center bg-light rounded px-2 py-1 text-xs"
|
||||
>
|
||||
<span>{item.name}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close btn-close-white btn-sm ms-2"
|
||||
style={{
|
||||
filter: "invert(1) grayscale(1)",
|
||||
opacity: 0.7,
|
||||
fontSize: "0.6rem",
|
||||
}}
|
||||
onClick={() => removeFilterChip(chip.key, item.id)}
|
||||
/>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentFilterChips;
|
||||
export default DocumentFilterChips;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState,useMemo } from "react";
|
||||
import React, { useEffect, useState, useMemo, useImperativeHandle, forwardRef } from "react";
|
||||
import { useDocumentFilterEntities } from "../../hooks/useDocument";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
@ -11,16 +11,16 @@ import SelectMultiple from "../common/SelectMultiple";
|
||||
import moment from "moment";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
const DocumentFilterPanel = ({ entityTypeId, onApply,setFilterdata }) => {
|
||||
const DocumentFilterPanel = forwardRef(({ entityTypeId, onApply, setFilterdata }, ref) => {
|
||||
const [resetKey, setResetKey] = useState(0);
|
||||
const { status } = useParams();
|
||||
|
||||
const { data, isError, isLoading, error } =
|
||||
useDocumentFilterEntities(entityTypeId);
|
||||
|
||||
//changes
|
||||
//changes
|
||||
|
||||
const dynamicDocumentFilterDefaultValues = useMemo(() => {
|
||||
const dynamicDocumentFilterDefaultValues = useMemo(() => {
|
||||
return {
|
||||
...DocumentFilterDefaultValues,
|
||||
uploadedByIds: DocumentFilterDefaultValues.uploadedByIds || [],
|
||||
@ -49,13 +49,24 @@ const DocumentFilterPanel = ({ entityTypeId, onApply,setFilterdata }) => {
|
||||
document.querySelector(".offcanvas.show .btn-close")?.click();
|
||||
};
|
||||
|
||||
//changes
|
||||
useEffect(() => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
resetFieldValue: (name, value) => {
|
||||
// Reset specific field
|
||||
if (value !== undefined) {
|
||||
setValue(name, value);
|
||||
} else {
|
||||
reset({ ...methods.getValues(), [name]: DocumentFilterDefaultValues[name] });
|
||||
}
|
||||
},
|
||||
getValues: methods.getValues, // optional, to read current filter state
|
||||
}));
|
||||
|
||||
//changes
|
||||
useEffect(() => {
|
||||
if (data && setFilterdata) {
|
||||
setFilterdata(data);
|
||||
}
|
||||
}, [data, setFilterdata]);
|
||||
console.log("Veer",data)
|
||||
|
||||
const onSubmit = (values) => {
|
||||
onApply({
|
||||
@ -88,7 +99,7 @@ const DocumentFilterPanel = ({ entityTypeId, onApply,setFilterdata }) => {
|
||||
documentTag = [],
|
||||
} = data?.data || {};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
@ -100,18 +111,16 @@ const DocumentFilterPanel = ({ entityTypeId, onApply,setFilterdata }) => {
|
||||
<div className="d-inline-flex border rounded-pill overflow-hidden shadow-none">
|
||||
<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)}
|
||||
>
|
||||
Uploaded On
|
||||
</button>
|
||||
<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)}
|
||||
>
|
||||
Updated On
|
||||
@ -228,6 +237,6 @@ const DocumentFilterPanel = ({ entityTypeId, onApply,setFilterdata }) => {
|
||||
</form>
|
||||
</FormProvider>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default DocumentFilterPanel;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||
import React, { createContext, useContext, useEffect, useRef, useState } from "react";
|
||||
import GlobalModel from "../common/GlobalModel";
|
||||
import NewDocument from "./ManageDocument";
|
||||
import { DOCUMENTS_ENTITIES, UPLOAD_DOCUMENT } from "../../utils/constants";
|
||||
@ -59,6 +59,7 @@ const Documents = ({ Document_Entity, Entity }) => {
|
||||
const { employeeId } = useParams();
|
||||
const [OpenDocument, setOpenDocument] = useState(false);
|
||||
const [filterData, setFilterdata] = useState(DocumentFilterDefaultValues);
|
||||
const updatedFilters = useRef();
|
||||
const [ManageDoc, setManageDoc] = useState({
|
||||
document: null,
|
||||
isOpen: false,
|
||||
@ -94,7 +95,7 @@ const Documents = ({ Document_Entity, Entity }) => {
|
||||
setShowTrigger(true);
|
||||
setOffcanvasContent(
|
||||
"Document Filters",
|
||||
<DocumentFilterPanel entityTypeId={DocumentEntity} onApply={setFilter} setFilterdata={setFilterdata} />
|
||||
<DocumentFilterPanel entityTypeId={DocumentEntity} onApply={setFilter} setFilterdata={setFilterdata} ref={updatedFilters} />
|
||||
);
|
||||
|
||||
return () => {
|
||||
@ -102,7 +103,7 @@ const Documents = ({ Document_Entity, Entity }) => {
|
||||
setOffcanvasContent("", null);
|
||||
};
|
||||
}, []);
|
||||
console.log("Testing",filterData)
|
||||
|
||||
const contextValues = {
|
||||
ManageDoc,
|
||||
setManageDoc,
|
||||
@ -110,6 +111,7 @@ console.log("Testing",filterData)
|
||||
setViewDoc,
|
||||
setOpenDocument,
|
||||
OpenDocument,
|
||||
// removeFilterChip
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -118,22 +120,38 @@ console.log("Testing",filterData)
|
||||
}
|
||||
}, [Document_Entity]);
|
||||
|
||||
|
||||
|
||||
const removeFilterChip = (key, id) => {
|
||||
const updatedFilters = { ...filters };
|
||||
|
||||
if (Array.isArray(updatedFilters[key])) {
|
||||
updatedFilters[key] = updatedFilters[key].filter((v) => v !== id);
|
||||
} else {
|
||||
}
|
||||
else if (key === "dateRange") {
|
||||
updatedFilters.startDate = null;
|
||||
updatedFilters.endDate = null;
|
||||
}
|
||||
else {
|
||||
updatedFilters[key] = null;
|
||||
}
|
||||
|
||||
setFilter(updatedFilters);
|
||||
|
||||
methods.setValue(key, updatedFilters[key] ?? DocumentFilterDefaultValues[key]);
|
||||
|
||||
if (key === "dateRange") {
|
||||
methods.setValue("startDate", null);
|
||||
methods.setValue("endDate", null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<DocumentContext.Provider value={contextValues}>
|
||||
<div className="mt-2">
|
||||
<div className="card page-min-h d-flex p-2">
|
||||
<DocumentFilterChips filters={filters} filterData={filterData} removeFilterChip={removeFilterChip} />
|
||||
<DocumentFilterChips filters={filters} filterData={filterData} removeFilterChip={removeFilterChip} />
|
||||
<div className="row align-items-center">
|
||||
{/* Search */}
|
||||
<div className="d-flex col-8 col-md-8 col-lg-4 mb-md-0 align-items-center">
|
||||
|
@ -65,7 +65,7 @@ const DocumentsList = ({
|
||||
setIsRefetching(isFetching);
|
||||
}, [isFetching, setIsRefetching]);
|
||||
|
||||
const { setManageDoc, setViewDoc } = useDocumentContext();
|
||||
const { setManageDoc, setViewDoc,removeFilterChip } = useDocumentContext();
|
||||
const { mutate: ActiveInActive, isPending } = useActiveInActiveDocument();
|
||||
|
||||
const paginate = (page) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user