Merge pull request 'Adding ImageGallery Chips.' (#517) from Image_Gallery_FilterChips into Purchase_Invoice_Management

Reviewed-on: #517
merged
This commit is contained in:
pramod.mahajan 2025-12-03 06:55:13 +00:00
commit 8dfc8e4336
11 changed files with 204 additions and 100 deletions

View File

@ -96,11 +96,11 @@ const AssignOrg = ({ setStep }) => {
<div className="d-flex justify-content-between align-items-center text-start mb-1"> <div className="d-flex justify-content-between align-items-center text-start mb-1">
<div className="d-flex flex-row gap-2 align-items-center text-wrap"> <div className="d-flex flex-row gap-2 align-items-center text-wrap">
<img <img
src="/public/assets/img/orgLogo.png" src="/public/assets/img/orgLogo.png"
alt="logo" alt="logo"
width={40} width={40}
height={40} height={40}
/> <p className="fw-semibold fs-6 m-0">{orgData.name}</p> /> <p className="fw-semibold fs-5 mt-2 m-0">{orgData.name}</p>
</div> </div>
<div className="text-end"> <div className="text-end">
<button <button
@ -113,60 +113,60 @@ const AssignOrg = ({ setStep }) => {
</div> </div>
</div> </div>
</div> </div>
<div className="d-flex text-secondary mb-2"> <i className="bx bx-sm bx-info-circle me-1" /> Organization Info</div> <div className="d-flex text-secondary mb-3"> <i className="bx bx-sm bx-info-circle me-2" /> Organization Info</div>
{/* Contact Info */} {/* Contact Info */}
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-4">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "130px" }}
> >
<i className="bx bx-sm bx-user me-1" /> Contact Person : <i className="bx bx-sm bx-user me-1" /> Contact Person :
</label> </label>
<div className="text-muted">{orgData.contactPerson}</div> <div className="text-muted">{orgData.contactPerson}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-4">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "130px" }}
> >
<i className='bx bx-sm me-1 bx-phone'></i> Contact Number : <i className='bx bx-sm me-1 bx-phone'></i> Contact Number :
</label> </label>
<div className="text-muted">{orgData.contactNumber}</div> <div className="text-muted">{orgData.contactNumber}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-4">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "130px" }}
> >
<i className='bx bx-sm me-1 bx-envelope'></i> Email Address : <i className='bx bx-sm me-1 bx-envelope'></i> Email Address :
</label> </label>
<div className="text-muted">{orgData.email}</div> <div className="text-muted text-wrap">{orgData.email}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3"> <div className="col-12 mb-4">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ maxWidth: "130px" }} style={{ maxWidth: "130px" }}
> >
<i className="bx bx-sm me-1 bx-barcode"></i> <i className="bx bx-sm me-2 bx-barcode"></i>
Service Provider Id (SPRID) : Service Provider Id (SPRID) :
</label> </label>
<div className="text-muted">{orgData.sprid}</div> <div className="text-muted">{orgData.sprid}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3"> <div className="col-12 mb-4">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-1 mb-0 fw-semibold" className="form-label me-1 mb-0 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "130px" }}
> >
<i className='bx bx-sm me-1 bx-map'></i> Address : <i className='bx bx-sm me-1 bx-map'></i> Address :
</label> </label>
<div className="text-muted text-start">{orgData.address}</div> <div className="text-muted text-start">{orgData.address}</div>
</div> </div>

View File

@ -189,7 +189,7 @@ const ManagOrg = () => {
)} )}
</div> </div>
<div className="d-flex justify-content-between gap-2 my-2"> <div className="d-flex justify-content-between gap-2 my-5">
<button <button
type="button" type="button"
className="btn btn-sm btn-outline-secondary" className="btn btn-sm btn-outline-secondary"

View File

@ -45,7 +45,7 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
return ( return (
<div className="d-block mt-4"> <div className="d-block mt-4">
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className="row align-items-center g-2"> <div className="row align-items-center g-2 mb-3">
{/* Input Section */} {/* Input Section */}
<div className="col-12 col-md-8 d-block d-md-flex align-items-center gap-2 m-0 text-start"> <div className="col-12 col-md-8 d-block d-md-flex align-items-center gap-2 m-0 text-start">
<Label className="text-nowrap mb-1 mb-md-0" required> <Label className="text-nowrap mb-1 mb-md-0" required>
@ -88,7 +88,7 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
<div className="py-2 text-tiny text-center"> <div className="py-2 text-tiny text-center">
<div className="d-flex flex-column gap-2 border-0 bg-none"> <div className="d-flex flex-column gap-2 border-0 bg-none">
{data.data.map((org) => ( {data.data.map((org) => (
<div className="d-flex flex-row gap-2 text-start text-black "> <div className="d-flex flex-row gap-2 text-start text-black mt-3">
<div className="mt-1"> <div className="mt-1">
<img <img
src="/public/assets/img/orgLogo.png" src="/public/assets/img/orgLogo.png"
@ -97,19 +97,19 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
height={50} height={50}
/> />
</div> </div>
<div className="d-flex flex-column p-0 m-0 cursor-pointer"> <div className="d-flex flex-column p-0 m-0 cursor-pointer mb-3">
<span className="fs-6 fw-semibold">{org.name}</span> <span className="fs-6 fw-semibold mb-2">{org.name}</span>
<div className="d-flex gap-2"> <div className="d-flex gap-2">
<small <small
className=" fw-semibold text-uppercase" className=" fw-semibold text-uppercase mb-2"
style={{ letterSpacing: "1px" }} style={{ letterSpacing: "1px" }}
> >
SPRID :{" "} SPRID :{" "}
</small> </small>
<small className="fs-6">{org.sprid}</small> <small className="fs-6">{org.sprid}</small>
</div> </div>
<div className="d-flex flex-row gap-2"> <div className="d-flex flex-row gap-2 mb-4">
<small className="text-small fw-semibold">Address:</small> <small className="text-small fw-semibold ">Address:</small>
<div className="d-flex text-wrap">{org.address}</div> <div className="d-flex text-wrap">{org.address}</div>
</div> </div>
<div className="m-0 p-0"> <div className="m-0 p-0">

View File

@ -122,6 +122,7 @@ const OrganizationsList = ({searchText}) => {
{organizationsColumns.map((col) => ( {organizationsColumns.map((col) => (
<td <td
key={col.key} key={col.key}
style={{ height: "50px" }}
className={`d-table-cell ${col.align ?? ""}`} className={`d-table-cell ${col.align ?? ""}`}
> >
{col.customRender {col.customRender

View File

@ -9,7 +9,7 @@ const VieworgDataanization = ({ orgId }) => {
return ( return (
<div className="row text-black text-black text-start "> <div className="row text-black text-black text-start ">
{/* Header */} {/* Header */}
<div className="col-12 mb-3"> <div className="col-12 mb-5">
<div className="d-flex justify-content-between align-items-center text-start mb-1"> <div className="d-flex justify-content-between align-items-center text-start mb-1">
<div className="d-flex flex-row gap-2 align-items-center text-wrap"> <div className="d-flex flex-row gap-2 align-items-center text-wrap">
<img <img
@ -18,7 +18,7 @@ const VieworgDataanization = ({ orgId }) => {
width={40} width={40}
height={40} height={40}
/>{" "} />{" "}
<p className="fw-semibold fs-6 m-0">{data?.name}</p> <p className="fw-semibold fs-5 mt-2 m-0">{data?.name}</p>
</div> </div>
<div className="text-end"> <div className="text-end">
<span <span
@ -30,12 +30,12 @@ const VieworgDataanization = ({ orgId }) => {
</div> </div>
</div> </div>
</div> </div>
<div className="d-flex text-secondary mb-2"> <div className="d-flex text-secondary mb-5">
{" "} {" "}
<i className="bx bx-sm bx-info-circle me-1" /> Organization Info <i className="bx bx-sm bx-info-circle me-1" /> Organization Info
</div> </div>
{/* Contact Info */} {/* Contact Info */}
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
@ -46,7 +46,7 @@ const VieworgDataanization = ({ orgId }) => {
<div className="text-muted">{data?.contactPerson}</div> <div className="text-muted">{data?.contactPerson}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
@ -57,7 +57,7 @@ const VieworgDataanization = ({ orgId }) => {
<div className="text-muted">{data?.contactNumber}</div> <div className="text-muted">{data?.contactNumber}</div>
</div> </div>
</div> </div>
<div className="col-md-12 mb-3"> <div className="col-md-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
@ -68,32 +68,32 @@ const VieworgDataanization = ({ orgId }) => {
<div className="text-muted">{data?.email}</div> <div className="text-muted">{data?.email}</div>
</div> </div>
</div> </div>
<div className="col-6 mb-3"> <div className="col-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ maxWidth: "130px" }} style={{ maxWidth: "130px" }}
> >
<i className="bx bx-sm me-1 bx-barcode"></i> <i className="bx bx-sm me-2 bx-barcode"></i>
Service Provider Id (SPRID) : Service Provider Id (SPRID) :
</label> </label>
<div className="text-muted">{data?.sprid}</div> <div className="text-muted">{data?.sprid}</div>
</div> </div>
</div> </div>
<div className="col-6 mb-3"> <div className="col-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-0 fw-semibold"
style={{ maxWidth: "130px" }} style={{ maxWidth: "130px" }}
> >
<i className="bx bx-sm me-1 bx-group"></i> <i className="bx bx-sm me-2 bx-group"></i>
Employees : Employees :
</label> </label>
<div className="text-muted">{data?.activeEmployeeCount}</div> <div className="text-muted">{data?.activeEmployeeCount}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3"> <div className="col-12 mb-5">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-1 mb-0 fw-semibold" className="form-label me-1 mb-0 fw-semibold"
@ -104,7 +104,7 @@ const VieworgDataanization = ({ orgId }) => {
<div className="text-muted text-start">{data?.address}</div> <div className="text-muted text-start">{data?.address}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3"> <div className="col-12 mb-5">
<div <div
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer" className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
data-bs-toggle="collapse" data-bs-toggle="collapse"
@ -162,7 +162,7 @@ const VieworgDataanization = ({ orgId }) => {
</div> </div>
{/* Services Section */} {/* Services Section */}
<div className="col-12 mb-3"> <div className="col-12 mb-5">
<div <div
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer" className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
data-bs-toggle="collapse" data-bs-toggle="collapse"
@ -180,7 +180,7 @@ const VieworgDataanization = ({ orgId }) => {
{data?.services && data.services.length > 0 ? ( {data?.services && data.services.length > 0 ? (
<div className="row"> <div className="row">
{data.services.map((service) => ( {data.services.map((service) => (
<div key={service.id} className="col-md-12 mb-3"> <div key={service.id} className="col-md-12 mb-5">
<div className="card h-100 shadow-sm border-0"> <div className="card h-100 shadow-sm border-0">
<div className="card-body"> <div className="card-body">
<h6 className="fw-semibold mb-1"> <h6 className="fw-semibold mb-1">

View File

@ -0,0 +1,59 @@
import React, { useMemo } from "react";
const GalleryFilterChips = ({ filter, filterData, removeFilterChip, clearFilter }) => {
const data = filterData?.data || filterData || {};
const filterChips = useMemo(() => {
const chips = [];
const addGroup = (ids, list, label, key) => {
if (!ids?.length) return;
const items = ids.map((id) => ({
id,
name: list?.find((i) => i.id === id)?.name || id,
}));
chips.push({ key, label, items });
};
addGroup(filter.buildingIds, data.buildings, "Building", "buildingIds");
addGroup(filter.floorIds, data.floors, "Floor", "floorIds");
addGroup(filter.workAreaIds, data.workAreas, "Work Area", "workAreaIds");
addGroup(filter.activityIds, data.activities, "Activity", "activityIds");
addGroup(filter.workCategoryIds, data.workCategories, "Work Category", "workCategoryIds");
addGroup(filter.uploadedByIds, data.uploadedBy, "Uploaded By", "uploadedByIds");
addGroup(filter.serviceIds, data.services, "Service", "serviceIds");
return chips;
}, [filter, filterData]);
if (!filterChips.length) return null;
return (
<div className="d-flex flex-wrap align-items-center gap-2">
{filterChips.map((chipGroup) => (
<div key={chipGroup.key} className="d-flex align-items-center flex-wrap">
<span className="fw-semibold me-2">{chipGroup.label}:</span>
{chipGroup.items.map((item) => (
<span
key={item.id}
className="d-flex align-items-center bg-light rounded px-2 py-1 me-1"
>
<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(chipGroup.key, item.id)}
/>
</span>
))}
</div>
))}
</div>
);
};
export default GalleryFilterChips;

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react";
import { useImageGalleryFilter } from "../../hooks/useImageGallery"; import { useImageGalleryFilter } from "../../hooks/useImageGallery";
import { useSelectedProject } from "../../slices/apiDataManager"; import { useSelectedProject } from "../../slices/apiDataManager";
import { FormProvider, useForm } from "react-hook-form"; import { FormProvider, useForm } from "react-hook-form";
@ -10,19 +10,52 @@ import SelectMultiple from "../common/SelectMultiple";
import { localToUtc } from "../../utils/appUtils"; import { localToUtc } from "../../utils/appUtils";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
const GalleryFilterPanel = ({ onApply }) => { const GalleryFilterPanel = forwardRef(({ onApply, setFilterdata, clearFilter }, ref) => {
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const [resetKey, setResetKey] = useState(0); const [resetKey, setResetKey] = useState(0);
const { data, isLoading, isError, error } = const { data, isLoading, isError, error } =
useImageGalleryFilter(selectedProject); useImageGalleryFilter(selectedProject);
const dynamicDefaultFilter = useMemo(() => {
return {
...defaultGalleryFilterValue,
buildingIds: defaultGalleryFilterValue.buildingIds || [],
floorIds: defaultGalleryFilterValue.floorIds || [],
workAreaIds: defaultGalleryFilterValue.workAreaIds || [],
activityIds: defaultGalleryFilterValue.activityIds || [],
workCategoryIds: defaultGalleryFilterValue.workCategoryIds || [],
startDate: defaultGalleryFilterValue.startDate,
endDate: defaultGalleryFilterValue.endDate,
uploadedByIds: defaultGalleryFilterValue.uploadedByIds || [],
serviceIds: defaultGalleryFilterValue.serviceIds || [],
};
}, [selectedProject]);
useImperativeHandle(ref, () => ({
resetFieldValue: (name, value) => {
// Reset specific field
if (value !== undefined) {
setValue(name, value);
} else {
reset({ ...methods.getValues(), [name]: defaultFilter[name] });
}
},
getValues: methods.getValues, // optional, to read current filter state
}));
useEffect(() => {
if (data && setFilterdata) {
setFilterdata(data);
}
}, [data, setFilterdata]);
const closePanel = () => { const closePanel = () => {
document.querySelector(".offcanvas.show .btn-close")?.click(); document.querySelector(".offcanvas.show .btn-close")?.click();
}; };
const methods = useForm({ const methods = useForm({
resolver: zodResolver(gallerySchema), resolver: zodResolver(gallerySchema),
defaultValues: defaultGalleryFilterValue, defaultValues: dynamicDefaultFilter,
}); });
const { const {
@ -144,6 +177,6 @@ const GalleryFilterPanel = ({ onApply }) => {
</FormProvider> </FormProvider>
</div> </div>
); );
}; });
export default GalleryFilterPanel; export default GalleryFilterPanel;

View File

@ -8,7 +8,8 @@ import { ITEMS_PER_PAGE } from "../../utils/constants";
import Pagination from "../common/Pagination"; import Pagination from "../common/Pagination";
import { formatUTCToLocalTime } from "../../utils/dateUtils"; import { formatUTCToLocalTime } from "../../utils/dateUtils";
import { SpinnerLoader } from "../common/Loader"; import { SpinnerLoader } from "../common/Loader";
const ImageGalleryListView = ({filter}) => { import GalleryFilterChips from "./GalleryFilterChips";
const ImageGalleryListView = ({ filter, filterData, removeFilterChip, clearFilter }) => {
const [hoveredImage, setHoveredImage] = useState(null); const [hoveredImage, setHoveredImage] = useState(null);
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
@ -27,23 +28,23 @@ const ImageGalleryListView = ({filter}) => {
} }
}; };
if (!data?.data?.length && !isLoading) { if (!data?.data?.length && !isLoading) {
return ( return (
<div <div
className="d-flex justify-content-center align-items-center text-muted" className="d-flex justify-content-center align-items-center text-muted"
style={{ minHeight: "50vh" }} style={{ minHeight: "50vh" }}
> >
<span style={{ fontSize: "0.9rem" }}> <span style={{ fontSize: "0.9rem" }}>
{selectedProject {selectedProject
? "No images match the selected filters." ? "No images match the selected filters."
: "Please Select Project!"} : "Please Select Project!"}
</span> </span>
</div> </div>
); );
} }
if (isLoading) { if (isLoading) {
return ( return (
<div className="page-min-h d-flex justify-content-center align-items-center"> <div className="page-min-h d-flex justify-content-center align-items-center">
<SpinnerLoader /> <SpinnerLoader />
@ -51,16 +52,26 @@ const ImageGalleryListView = ({filter}) => {
); );
} }
return ( return (
<div className="main-content"> <div className="main-content">
<div className="col-12 mb-2 mt-2 px-4">
<GalleryFilterChips
filter={filter}
filterData={filterData}
removeFilterChip={removeFilterChip}
clearFilter={clearFilter}
/>
</div>
<div className="activity-section"> <div className="activity-section">
{data?.data?.map((batch) => { {data?.data?.map((batch) => {
if (!batch.documents?.length) return null; if (!batch.documents?.length) return null;
const doc = batch.documents[0]; const doc = batch.documents[0];
const userName = `${doc.uploadedBy?.firstName || ""} ${ const userName = `${doc.uploadedBy?.firstName || ""} ${doc.uploadedBy?.lastName || ""
doc.uploadedBy?.lastName || "" }`.trim();
}`.trim();
const date = formatUTCToLocalTime(doc.uploadedAt); const date = formatUTCToLocalTime(doc.uploadedAt);
// const hasArrows = batch.documents.length > scrollThreshold; // const hasArrows = batch.documents.length > scrollThreshold;
@ -112,7 +123,7 @@ const ImageGalleryListView = ({filter}) => {
)} */} )} */}
<div <div
className="image-group-horizontal" className="image-group-horizontal"
// ref={(el) => (imageGroupRefs.current[batch.batchId] = el)} // ref={(el) => (imageGroupRefs.current[batch.batchId] = el)}
> >
{batch.documents.map((d, i) => { {batch.documents.map((d, i) => {
const hoverDate = moment().format("DD MMMM, YYYY"); const hoverDate = moment().format("DD MMMM, YYYY");

View File

@ -47,6 +47,7 @@ export const useImageGalleryFilter = (project)=>{
const response = await ImageGalleryRepository.getImageGalleryFilter(project); const response = await ImageGalleryRepository.getImageGalleryFilter(project);
return response.data; return response.data;
}, },
enabled:!!project
}) })
} }

View File

@ -23,6 +23,7 @@ import GlobalModel from "../../components/common/GlobalModel";
import ViewGallery from "../../components/gallary/ViewGallery"; import ViewGallery from "../../components/gallary/ViewGallery";
import { useFab } from "../../Context/FabContext"; import { useFab } from "../../Context/FabContext";
import GalleryFilterPanel from "../../components/gallary/GalleryFilterPanel"; import GalleryFilterPanel from "../../components/gallary/GalleryFilterPanel";
import { defaultGalleryFilterValue } from "../../components/gallary/GallerySchema";
const GalleryContext = createContext(); const GalleryContext = createContext();
@ -36,12 +37,12 @@ export const useGalleryContext = () => {
}; };
const ImageGalleryPage = () => { const ImageGalleryPage = () => {
const [filter, setFilter] = useState(); const [filter, setFilter] = useState(defaultGalleryFilterValue);
const selectedProjectId = useSelectedProject(); const selectedProjectId = useSelectedProject();
const { projectNames } = useProjectName(); const { projectNames } = useProjectName();
const [filterData, setFilterdata] = useState(null);
const updatedRef = useRef();
const [openGallery, setOpenGallery] = useState({ isOpen: false, data: null }); const [openGallery, setOpenGallery] = useState({ isOpen: false, data: null });
const { data: assignedServices = [], isLoading } = const { data: assignedServices = [], isLoading } =
useProjectAssignedServices(selectedProjectId); useProjectAssignedServices(selectedProjectId);
@ -55,13 +56,18 @@ const ImageGalleryPage = () => {
setOpenGallery, setOpenGallery,
}; };
const clearFilter = () => setFilter(defaultGalleryFilterValue);
const { setOffcanvasContent, setShowTrigger } = useFab(); const { setOffcanvasContent, setShowTrigger } = useFab();
useEffect(() => { useEffect(() => {
setShowTrigger(true); setShowTrigger(true);
setOffcanvasContent( setOffcanvasContent(
"Gallery Filter", "Gallery Filter",
<GalleryFilterPanel onApply={setFilter} /> <GalleryFilterPanel
onApply={setFilter}
ref={updatedRef}
clearFilter={clearFilter}
setFilterdata={setFilterdata} />
); );
return () => { return () => {
@ -70,6 +76,22 @@ const ImageGalleryPage = () => {
}; };
}, []); }, []);
const handleRemoveChip = (key, id) => {
setFilter((prev) => {
const updated = { ...prev };
if (Array.isArray(updated[key])) {
updated[key] = updated[key].filter((v) => v !== id);
setTimeout(() => updatedRef.current?.resetFieldValue(key, updated[key]), 0);
} else {
updated[key] = null;
setTimeout(() => updatedRef.current?.resetFieldValue(key, null), 0);
}
return updated;
});
};
return ( return (
<GalleryContext.Provider value={contextMessager}> <GalleryContext.Provider value={contextMessager}>
<div className="container-fluid"> <div className="container-fluid">
@ -78,34 +100,11 @@ const ImageGalleryPage = () => {
/> />
<div className="card page-min-h p-2"> <div className="card page-min-h p-2">
{/* {selectedProjectId && ( <ImageGalleryListView
<div className="d-flex flex-row w-20 pb-2"> filter={filter}
{!isLoading && assignedServices?.length === 0 ? ( filterData={filterData}
<span className="badge bg-label-secondary"> removeFilterChip={handleRemoveChip}
Not service assiged yet clearFilter={clearFilter} />
</span>
) : (
<select className="form-select form-select-sm">
<option>Select Service</option>
{isLoading ? (
<option>Loading...</option>
) : assignedServices.length === 1 ? (
<span className="badge bg-label-secondary">
{assignedServices[0].name}
</span>
) : (
assignedServices?.map((service) => (
<option key={service.id} value={service?.id}>
{service?.name}
</option>
))
)}
</select>
)}
</div>
)} */}
<ImageGalleryListView filter={filter} />
</div> </div>
{openGallery?.isOpen && ( {openGallery?.isOpen && (

View File

@ -140,13 +140,13 @@ const CollectionPage = () => {
</div> </div>
</div> </div>
<div className="col-12 col-sm-8 d-block d-sm-flex justify-content-end ga-2 align-items-center gap-2"> <div className="col-12 col-sm-8 d-block d-sm-flex justify-content-end ga-2 align-items-center gap-2">
<input <input
type="search" type="search"
value={searchText} value={searchText}
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}
placeholder="Search Collection" placeholder="Search Collection"
className="form-control form-control-sm mt-2 mt-sm-0" className="form-control form-control-sm w-25 mt-2 mt-sm-0"
/> />
<div className="d-flex justify-content-between justify-content-sm-between mt-2 mt-sm-0"> <div className="d-flex justify-content-between justify-content-sm-between mt-2 mt-sm-0">
<FormProvider {...methods} className="me-3"> <FormProvider {...methods} className="me-3">