From a02a33a24781d0439e4051c8410d852ef4392d0e Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 1 Jul 2025 13:23:16 +0530 Subject: [PATCH] partially implementation of masters in react query hooks --- .../Project/Infrastructure/TaskModel.jsx | 1 - src/components/master/CreateActivity.jsx | 162 ++-- .../master/CreateContactCategory.jsx | 88 +- src/components/master/CreateContactTag.jsx | 91 +- src/components/master/CreateJobRole.jsx | 112 ++- src/components/master/CreateRole.jsx | 182 ++-- src/components/master/CreateWorkCategory.jsx | 103 ++- src/components/master/EditActivity.jsx | 191 ++-- src/components/master/EditContactCategory.jsx | 110 +-- src/components/master/EditContactTag.jsx | 110 +-- src/components/master/EditJobRole.jsx | 129 +-- src/components/master/EditRole.jsx | 230 ++--- src/components/master/EditWorkCategory.jsx | 111 +-- src/components/master/MasterModal.jsx | 112 ++- src/hooks/masterHook/useMaster.js | 843 ++++++++++++++---- src/pages/master/MasterPage.jsx | 148 ++- src/repositories/MastersRepository.jsx | 2 +- 17 files changed, 1651 insertions(+), 1074 deletions(-) diff --git a/src/components/Project/Infrastructure/TaskModel.jsx b/src/components/Project/Infrastructure/TaskModel.jsx index 8c46fa03..3ae39077 100644 --- a/src/components/Project/Infrastructure/TaskModel.jsx +++ b/src/components/Project/Infrastructure/TaskModel.jsx @@ -49,7 +49,6 @@ const TaskModel = ({ const { activities, loading, error } = useActivitiesMaster(); const { categories, categoryLoading, categoryError } = useWorkCategoriesMaster(); - const { register, handleSubmit, diff --git a/src/components/master/CreateActivity.jsx b/src/components/master/CreateActivity.jsx index 62cca207..039a3775 100644 --- a/src/components/master/CreateActivity.jsx +++ b/src/components/master/CreateActivity.jsx @@ -7,6 +7,7 @@ import { MasterRespository } from "../../repositories/MastersRepository"; import { clearApiCacheKey } from "../../slices/apiCacheSlice"; import { getCachedData, cacheData } from "../../slices/apiDataManager"; import showToast from "../../services/toastService"; +import {useCreateActivity} from "../../hooks/masterHook/useMaster"; const schema = z.object({ activityName: z.string().min(1, { message: "Activity Name is required" }), @@ -23,101 +24,96 @@ const schema = z.object({ }); const CreateActivity = ({ onClose }) => { - const [isLoading, setIsLoading] = useState(false); +const maxDescriptionLength = 255; +const { mutate: createActivity, isPending: isLoading } = useCreateActivity(() => onClose?.()); - const { - register, - handleSubmit, - control, - setValue, - clearErrors, - setError, - getValues, - reset, - formState: { errors }, - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - activityName: "", - unitOfMeasurement: "", - checkList: [], - }, - }); +const { + register, + handleSubmit, + control, + setValue, + clearErrors, + setError, + getValues, + reset, + formState: { errors }, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + activityName: "", + unitOfMeasurement: "", + checkList: [], + }, +}); +const { + fields: checkListItems, + append, + remove, +} = useFieldArray({ + control, + name: "checkList", +}); - const { - fields: checkListItems, - append, - remove, - } = useFieldArray({ - control, - name: "checkList", - }); +const addChecklistItem = useCallback(() => { + const values = getValues("checkList"); + const lastIndex = checkListItems.length - 1; - // Form submission handler - const onSubmit = (data) => { - setIsLoading(true); - - MasterRespository.createActivity(data) - .then( ( resp ) => - { - - const cachedData = getCachedData("Activity"); - const updatedData = [ ...cachedData, resp?.data ]; - cacheData("Activity", updatedData); - showToast("Activity Successfully Added.", "success"); - setIsLoading(false); - handleClose() - }) - .catch((error) => { - showToast(error.message, "error"); - setIsLoading(false); - }); - }; - - - const addChecklistItem = () => { - const values = getValues("checkList"); - const lastIndex = checkListItems.length - 1; - if ( - checkListItems.length > 0 && - (!values?.[lastIndex] || values[lastIndex].description.trim() === "") - ) { - setError(`checkList.${lastIndex}.description`, { - type: "manual", - message: "Please fill this checklist item before adding another.", - }); - return; - } - clearErrors(`checkList.${lastIndex}.description`); - append({ - id: null, - description: "", - isMandatory: false, + if ( + checkListItems.length > 0 && + (!values?.[lastIndex] || values[lastIndex].description.trim() === "") + ) { + setError(`checkList.${lastIndex}.description`, { + type: "manual", + message: "Please fill this checklist item before adding another.", }); - }; + return; + } - const removeChecklistItem = (index) => { - remove(index); - }; + clearErrors(`checkList.${lastIndex}.description`); + append({ id: null, description: "", isMandatory: false }); +}, [checkListItems, getValues, append, setError, clearErrors]); +const removeChecklistItem = useCallback((index) => { + remove(index); +}, [remove]); - const handleChecklistChange = (index, value) => { - setValue(`checkList.${index}`, value); - }; +const handleChecklistChange = useCallback((index, value) => { + setValue(`checkList.${index}`, value); +}, [setValue]); - const handleClose = () => { - reset(); - onClose(); - }; +const onSubmit = (formData) => { + createActivity(formData); +}; + // const onSubmit = (data) => { + // setIsLoading(true); + // MasterRespository.createActivity(data) + // .then( ( resp ) => + // { + + // const cachedData = getCachedData("Activity"); + // const updatedData = [ ...cachedData, resp?.data ]; + // cacheData("Activity", updatedData); + // showToast("Activity Successfully Added.", "success"); + // setIsLoading(false); + // handleClose() + // }) + // .catch((error) => { + // showToast(error.message, "error"); + // setIsLoading(false); + // }); + // }; +const handleClose = useCallback(() => { + reset(); + onClose(); +}, [reset, onClose]); +useEffect(() => { + const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); +}, []); - // for tooltip - useEffect(() => { - const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')); - tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); - }, []); return (
{/*
Create Activity
*/} diff --git a/src/components/master/CreateContactCategory.jsx b/src/components/master/CreateContactCategory.jsx index 5bce4171..e5923c91 100644 --- a/src/components/master/CreateContactCategory.jsx +++ b/src/components/master/CreateContactCategory.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useCreateContactCategory} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -16,51 +17,52 @@ const schema = z.object({ const CreateContactCategory = ({onClose}) => { - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: "", - description: "", - - }, - }); - - const onSubmit = (data) => { - setIsLoading(true) - MasterRespository.createContactCategory(data).then((resp)=>{ - setIsLoading(false) - resetForm() - const cachedData = getCachedData("Contact Category"); - const updatedData = [...cachedData, resp?.data]; - cacheData("Contact Category", updatedData); - showToast("Contact Category Added successfully.", "success"); +const { + register, + handleSubmit, + formState: { errors }, + reset, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: "", + description: "", + }, +}); - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error"); - setIsLoading(false) - }) - }; - const resetForm = () => { - reset({ - name: "", - description: "" - }); - setDescriptionLength(0); - } +const [descriptionLength, setDescriptionLength] = useState(0); +const maxDescriptionLength = 255; - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; +const { mutate: createContactCategory, isPending: isLoading } = useCreateContactCategory(() => onClose?.()); + +const onSubmit = (payload) => { + createContactCategory(payload); +}; + // const onSubmit = (data) => { + // setIsLoading(true) + // MasterRespository.createContactCategory(data).then((resp)=>{ + // setIsLoading(false) + // resetForm() + // const cachedData = getCachedData("Contact Category"); + // const updatedData = [...cachedData, resp?.data]; + // cacheData("Contact Category", updatedData); + // showToast("Contact Category Added successfully.", "success"); + + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error"); + // setIsLoading(false) + // }) + // }; +const resetForm = () => { + reset({ name: "", description: "" }); + setDescriptionLength(0); +}; + +useEffect(() => { + return () => resetForm(); +}, []); + return (<>
diff --git a/src/components/master/CreateContactTag.jsx b/src/components/master/CreateContactTag.jsx index dc92b789..28fe9ab3 100644 --- a/src/components/master/CreateContactTag.jsx +++ b/src/components/master/CreateContactTag.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useCreateContactTag} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -15,53 +16,53 @@ const schema = z.object({ }); const CreateContactTag = ({onClose}) => { +const { + register, + handleSubmit, + formState: { errors }, + reset, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: "", + description: "", + }, +}); - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: "", - description: "", - - }, - }); - - const onSubmit = (data) => { - setIsLoading(true) - MasterRespository.createContactTag(data).then((resp)=>{ - setIsLoading(false) - resetForm() - debugger - const cachedData = getCachedData("Contact Tag"); - const updatedData = [...cachedData, resp?.data]; - cacheData("Contact Tag", updatedData); - showToast("Contact Tag Added successfully.", "success"); - console.log(getCachedData("Contact Tag")) - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error"); - setIsLoading(false) - }) - }; - const resetForm = () => { - reset({ - name: "", - description: "" - }); - setDescriptionLength(0); - } +const [descriptionLength, setDescriptionLength] = useState(0); +const maxDescriptionLength = 255; - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; +const { mutate: createContactTag, isPending: isLoading } = useCreateContactTag(() => onClose?.()); + +const onSubmit = (payload) => { + createContactTag(payload); +}; + // const onSubmit = (data) => { + // setIsLoading(true) + // MasterRespository.createContactTag(data).then((resp)=>{ + // setIsLoading(false) + // resetForm() + // debugger + // const cachedData = getCachedData("Contact Tag"); + // const updatedData = [...cachedData, resp?.data]; + // cacheData("Contact Tag", updatedData); + // showToast("Contact Tag Added successfully.", "success"); + // console.log(getCachedData("Contact Tag")) + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error"); + // setIsLoading(false) + // }) + // }; +const resetForm = () => { + reset({ name: "", description: "" }); + setDescriptionLength(0); +}; + +useEffect(() => { + return () => resetForm(); +}, []); + return (<>
diff --git a/src/components/master/CreateJobRole.jsx b/src/components/master/CreateJobRole.jsx index 50e81851..97f22ee2 100644 --- a/src/components/master/CreateJobRole.jsx +++ b/src/components/master/CreateJobRole.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useCreateJobRole} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -16,58 +17,75 @@ const schema = z.object({ const CreateJobRole = ({onClose}) => { - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - role: "", - description: "", - - }, - }); - - const onSubmit = (data) => { - setIsLoading(true) - const result = { - name: data.role, - description: data.description, - }; - - MasterRespository.createJobRole(result).then((resp)=>{ - setIsLoading(false) - resetForm() - const cachedData = getCachedData("Job Role"); - const updatedData = [...cachedData, resp?.data]; - cacheData("Job Role", updatedData); - showToast("JobRole Added successfully.", "success"); + const maxDescriptionLength = 255; + const [descriptionLength, setDescriptionLength] = useState(0); - onClose() - }).catch((error)=>{ - showToast(error.message, "error"); - setIsLoading(false) - }) + const { + register, + handleSubmit, + formState: { errors }, + reset, + watch, + } = useForm({ + resolver: zodResolver(schema), + defaultValues: { + role: "", + description: "", + }, + }); + + const resetForm = () => { + reset({ role: "", description: "" }); + setDescriptionLength(0); + }; + + const { mutate: createJobRole, isPending:isLoading } = useCreateJobRole(() => { + onClose?.(); + } ); + + + // const onSubmit = (data) => { + // setIsLoading(true) + // const result = { + // name: data.role, + // description: data.description, + // }; + + // MasterRespository.createJobRole(result).then((resp)=>{ + // setIsLoading(false) + // resetForm() + // const cachedData = getCachedData("Job Role"); + // const updatedData = [...cachedData, resp?.data]; + // cacheData("Job Role", updatedData); + // showToast("JobRole Added successfully.", "success"); + + // onClose() + // }).catch((error)=>{ + // showToast(error.message, "error"); + // setIsLoading(false) + // }) + // }; + const onSubmit = (data) => { + const payload = { + name: data.role, + description: data.description, }; - const resetForm = () => { - reset({ - role: "", - description: "" - }); - setDescriptionLength(0); - } + createJobRole(payload); + }; + + useEffect(() => { + const sub = watch((values) => { + setDescriptionLength(values.description?.length || 0); + }); + return () => sub.unsubscribe(); + }, [watch]); + + useEffect(() => { + return () => resetForm(); + }, []); - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; return (<> {/*
diff --git a/src/components/master/CreateRole.jsx b/src/components/master/CreateRole.jsx index 03ccf297..9f314612 100644 --- a/src/components/master/CreateRole.jsx +++ b/src/components/master/CreateRole.jsx @@ -1,21 +1,19 @@ import React, { useEffect, useState, useRef } from "react"; import { useFeatures } from "../../hooks/useMasterRole"; -import { useForm } from 'react-hook-form'; -import { set, z } from 'zod'; -import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from "react-hook-form"; +import { set, z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; import { MasterRespository } from "../../repositories/MastersRepository"; import { cacheData, getCachedData } from "../../slices/apiDataManager"; import showToast from "../../services/toastService"; - - - - - +import { useCreateApplicationRole } from "../../hooks/masterHook/useMaster"; const schema = z.object({ role: z.string().min(1, { message: "Role is required" }), - description: z.string().min(1, { message: "Description is required" }) + description: z + .string() + .min(1, { message: "Description is required" }) .max(255, { message: "Description cannot exceed 255 characters" }), selectedPermissions: z @@ -23,21 +21,22 @@ const schema = z.object({ .min(1, { message: "Please select at least one permission" }), }); - - - const CreateRole = ({ modalType, onClose }) => { - - const [isLoading, setIsLoading] = useState(false) + const maxDescriptionLength = 255; + const [descriptionLength, setDescriptionLength] = useState(0); const popoverRefs = useRef([]); - const { masterFeatures } = useFeatures() + const { masterFeatures } = useFeatures(); + const { mutate: submitNewApplicationRole, isPending: isLoading } = + useCreateApplicationRole(() => { + onClose?.(); + }); const { register, handleSubmit, formState: { errors }, - + reset, } = useForm({ resolver: zodResolver(schema), defaultValues: { @@ -48,9 +47,7 @@ const CreateRole = ({ modalType, onClose }) => { }); const onSubmit = (values) => { - setIsLoading(true) - const result = { - + const payload = { role: values.role, description: values.description, featuresPermission: values.selectedPermissions.map((id) => ({ @@ -59,27 +56,40 @@ const CreateRole = ({ modalType, onClose }) => { })), }; - MasterRespository.createRole(result).then((resp) => { - setIsLoading(false) - const cachedData = getCachedData("Application Role"); - const updatedData = [...cachedData, resp.data]; - cacheData("Application Role", updatedData); - showToast("Application Role Added successfully.", "success"); - onClose() - }).catch((err) => { - - showToast(err?.response?.data?.message, "error"); - setIsLoading(false) - onClose() - }) - - + submitNewApplicationRole(payload); }; - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; + + // const onSubmit = (values) => { + // setIsLoading(true) + // const result = { + + // role: values.role, + // description: values.description, + // featuresPermission: values.selectedPermissions.map((id) => ({ + // id, + // isEnabled: true, + // })), + // }; + + // MasterRespository.createRole(result).then((resp) => { + // setIsLoading(false) + // const cachedData = getCachedData("Application Role"); + // const updatedData = [...cachedData, resp.data]; + // cacheData("Application Role", updatedData); + // showToast("Application Role Added successfully.", "success"); + // onClose() + // }).catch((err) => { + + // showToast(err?.response?.data?.message, "error"); + // setIsLoading(false) + // onClose() + // }) + + // }; useEffect(() => { setDescriptionLength(0); }, []); + useEffect(() => { popoverRefs.current.forEach((el) => { if (el) { @@ -87,14 +97,13 @@ const CreateRole = ({ modalType, onClose }) => { trigger: "focus", placement: "right", html: true, - content: el.getAttribute("data-bs-content"), // use inline content from attribute + content: el.getAttribute("data-bs-content"), }); } }); }, [masterFeatures]); return ( - {/*
@@ -102,23 +111,24 @@ const CreateRole = ({ modalType, onClose }) => {
*/}
- {errors.role &&

{errors.role.message}

}
-
- + @@ -131,26 +141,26 @@ const CreateRole = ({ modalType, onClose }) => { )}
-
- - {masterFeatures.map((feature, featureIndex) => ( - -
- - -
+
+
{feature.name}
-
{feature.featurePermissions.map((perm, permIndex) => { - const refIndex = (featureIndex * 10) + permIndex; + const refIndex = featureIndex * 10 + permIndex; return (
-
+
- (popoverRefs.current[refIndex] = el) - } + ref={(el) => (popoverRefs.current[refIndex] = el)} tabIndex="0" className="d-flex align-items-center avatar-group justify-content-center" - data-bs-toggle="popover" refIndex + data-bs-toggle="popover" + refIndex data-bs-trigger="focus" data-bs-placement="right" data-bs-html="true" @@ -182,23 +191,26 @@ const CreateRole = ({ modalType, onClose }) => { `} >   - - +
- - ) + ); })}
-

- ))} {errors.selectedPermissions && (

{errors.selectedPermissions.message}

@@ -206,33 +218,23 @@ const CreateRole = ({ modalType, onClose }) => { {!masterFeatures &&

Loading...

}
- - { - masterFeatures && ( - -
- - -
- ) - } - + {masterFeatures && ( +
+ + +
+ )} ); }; export default CreateRole; - - - - - diff --git a/src/components/master/CreateWorkCategory.jsx b/src/components/master/CreateWorkCategory.jsx index 0a7bc31b..81b2eab9 100644 --- a/src/components/master/CreateWorkCategory.jsx +++ b/src/components/master/CreateWorkCategory.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useCreateWorkCategory} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -16,58 +17,64 @@ const schema = z.object({ const CreateWorkCategory = ({onClose}) => { - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: "", - description: "", - - }, - }); - - const onSubmit = (data) => { - setIsLoading(true) - // const result = { - // name: data.name, - // description: data.description, - // }; - - MasterRespository.createWorkCategory(data).then((resp)=>{ - setIsLoading(false) - resetForm() - const cachedData = getCachedData("Work Category"); - const updatedData = [...cachedData, resp?.data]; - cacheData("Work Category", updatedData); - showToast("Work Category Added successfully.", "success"); + const { + register, + handleSubmit, + formState: { errors }, + reset, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: "", + description: "", + }, +}); - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error"); - setIsLoading(false) - }) +const [descriptionLength, setDescriptionLength] = useState(0); +const maxDescriptionLength = 255; + +const { mutate: createWorkCategory, isPending: isLoading } = useCreateWorkCategory(() => { + resetForm(); + onClose?.(); +}); + +const onSubmit = (payload) => { + createWorkCategory(payload) + }; + + // const onSubmit = (data) => { + // setIsLoading(true) + + + // MasterRespository.createWorkCategory(data).then((resp)=>{ + // setIsLoading(false) + // resetForm() + // const cachedData = getCachedData("Work Category"); + // const updatedData = [...cachedData, resp?.data]; + // cacheData("Work Category", updatedData); + // showToast("Work Category Added successfully.", "success"); + + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error"); + // setIsLoading(false) + // }) - }; - const resetForm = () => { - reset({ - name: "", - description: "" - }); - setDescriptionLength(0); - } + // }; - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; +const resetForm = () => { + reset({ + name: "", + description: "", + }); + setDescriptionLength(0); +}; + +useEffect(() => { + return () => resetForm(); +}, []); + return (<>
diff --git a/src/components/master/EditActivity.jsx b/src/components/master/EditActivity.jsx index 503bf8c0..cba8dad5 100644 --- a/src/components/master/EditActivity.jsx +++ b/src/components/master/EditActivity.jsx @@ -5,6 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import {MasterRespository} from "../../repositories/MastersRepository"; import showToast from "../../services/toastService"; import {getCachedData,cacheData} from "../../slices/apiDataManager"; +import {useUpdateActivity} from "../../hooks/masterHook/useMaster"; const schema = z.object({ @@ -23,111 +24,107 @@ const schema = z.object({ const UpdateActivity = ({ activityData, onClose }) => { - const [isLoading, setIsLoading] = useState(false); + const { mutate: updateActivity, isPending: isLoading } = useUpdateActivity(() => onClose?.()); - const { - register, - handleSubmit, - control, - setValue, - reset, - setError, - clearErrors, - getValues, - formState: { errors }, - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - id:activityData.id, - activityName: activityData.activityName, - unitOfMeasurement: activityData.unitOfMeasurement, - checkLists: activityData.checkLists || [], - }, - }); +const { + register, + handleSubmit, + control, + setValue, + reset, + setError, + clearErrors, + getValues, + formState: { errors }, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + id: activityData?.id, + activityName: activityData?.activityName, + unitOfMeasurement: activityData?.unitOfMeasurement, + checkList: activityData?.checkLists || [], + }, +}); - const { fields: checkListItems, append, remove } = useFieldArray({ - control, - name: "checkList", - }); +const { fields: checkListItems, append, remove } = useFieldArray({ + control, + name: "checkList", +}); - // Load initial data - useEffect(() => { - if (activityData) { - reset( { - id:activityData.id, - activityName: activityData.activityName, - unitOfMeasurement: activityData.unitOfMeasurement, - checkList: activityData.checkLists || [], - }); - } - }, [activityData]); +useEffect(() => { + if (activityData) { + reset({ + id: activityData.id, + activityName: activityData.activityName, + unitOfMeasurement: activityData.unitOfMeasurement, + checkList: activityData.checkLists || [], + }); + } +}, [activityData, reset]); - - const handleChecklistChange = (index, value) => { - setValue(`checkList.${index}`, value); +const addChecklistItem = () => { + const values = getValues("checkList"); + const lastIndex = checkListItems.length - 1; + + if ( + checkListItems.length > 0 && + (!values?.[lastIndex] || values[lastIndex].description.trim() === "") + ) { + setError(`checkList.${lastIndex}.description`, { + type: "manual", + message: "Please fill this checklist item before adding another.", + }); + return; + } + + clearErrors(`checkList.${lastIndex}.description`); + append({ id: null, description: "", isMandatory: false }); +}; + +const removeChecklistItem = (index) => { + remove(index); +}; + +const handleChecklistChange = (index, value) => { + setValue(`checkList.${index}`, value); +}; + +const onSubmit = (formData) => { + const payload = { ...formData, id: activityData.id }; + updateActivity({ id: activityData.id, payload }); }; - - // Submit handler - const onSubmit = async(data) => { - setIsLoading(true); +// const onSubmit = async(data) => { + // setIsLoading(true); - const Activity = {...data, id:activityData.id} - try - { - const response = await MasterRespository.updateActivity( activityData?.id, Activity ); - const updatedActivity = response.data; - const cachedData = getCachedData("Activity") + // const Activity = {...data, id:activityData.id} + // try + // { + // const response = await MasterRespository.updateActivity( activityData?.id, Activity ); + // const updatedActivity = response.data; + // const cachedData = getCachedData("Activity") - if (cachedData) { - const updatedActivities = cachedData.map((activity) => - activity.id === updatedActivity.id ? { ...activity, ...updatedActivity } : activity - ); + // if (cachedData) { + // const updatedActivities = cachedData.map((activity) => + // activity.id === updatedActivity.id ? { ...activity, ...updatedActivity } : activity + // ); - cacheData( "Activity", updatedActivities ); - onClose() - } - setIsLoading( false ) - showToast("Activity Successfully Updated", "success"); - } catch ( err ) - { - setIsLoading( false ) + // cacheData( "Activity", updatedActivities ); + // onClose() + // } + // setIsLoading( false ) + // showToast("Activity Successfully Updated", "success"); + // } catch ( err ) + // { + // setIsLoading( false ) - showToast("error.message", "error"); - } - }; + // showToast("error.message", "error"); + // } + // }; - - - // Add new checklist item - const addChecklistItem = () => { - const values = getValues("checkList"); - const lastIndex = checkListItems.length - 1; - - if ( - checkListItems.length > 0 && - (!values?.[lastIndex] || values[lastIndex].description.trim() === "") - ) { - setError(`checkList.${lastIndex}.description`, { - type: "manual", - message: "Please fill this checklist item before adding another.", - }); - return; - } - - clearErrors(`checkList.${lastIndex}.description`); - append({ id: null, description: "", isMandatory: false }); - }; - - const removeChecklistItem = (index) => { - remove(index); - }; - - - // for tooltip - useEffect(() => { - const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')); - tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); - }, []); +useEffect(() => { + const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); +}, []); return ( @@ -232,7 +229,7 @@ const UpdateActivity = ({ activityData, onClose }) => { className="btn btn-xs btn-primary mt-2" onClick={addChecklistItem} > - @@ -256,4 +253,4 @@ const UpdateActivity = ({ activityData, onClose }) => { ); }; -export default UpdateActivity; +export default UpdateActivity; \ No newline at end of file diff --git a/src/components/master/EditContactCategory.jsx b/src/components/master/EditContactCategory.jsx index 331802d6..f8a403ae 100644 --- a/src/components/master/EditContactCategory.jsx +++ b/src/components/master/EditContactCategory.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useUpdateContactCategory} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -15,65 +16,72 @@ const schema = z.object({ }); const EditContactCategory= ({data,onClose}) => { +const { + register, + handleSubmit, + formState: { errors }, + reset, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: data?.name || "", + description: data?.description || "", + }, +}); - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: data?.name || "", - description:data?.description || "", - - }, - }); - - const onSubmit = (formdata) => { - setIsLoading(true) - const result = { - id:data?.id, - name: formdata?.name, - description: formdata.description, - }; +const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); +const maxDescriptionLength = 255; + +const { mutate: updateContactCategory, isPending: isLoading } = useUpdateContactCategory(() => onClose?.()); + +const onSubmit = (formData) => { + const payload = { + id: data?.id, + name: formData.name, + description: formData.description, + }; + + updateContactCategory({id:data?.id,payload}); + }; + // const onSubmit = (formdata) => { + // setIsLoading(true) + // const result = { + // id:data?.id, + // name: formdata?.name, + // description: formdata.description, + // }; - MasterRespository.updateContactCategory(data?.id,result).then((resp)=>{ - setIsLoading(false) - showToast("Contact Category Updated successfully.", "success"); - const cachedData = getCachedData("Contact Category"); - if (cachedData) { + // MasterRespository.updateContactCategory(data?.id,result).then((resp)=>{ + // setIsLoading(false) + // showToast("Contact Category Updated successfully.", "success"); + // const cachedData = getCachedData("Contact Category"); + // if (cachedData) { - const updatedData = cachedData.map((category) => - category.id === data?.id ? { ...category, ...resp.data } : category - ); - cacheData("Contact Category", updatedData); - } + // const updatedData = cachedData.map((category) => + // category.id === data?.id ? { ...category, ...resp.data } : category + // ); + // cacheData("Contact Category", updatedData); + // } - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error") - setIsLoading(false) - }) + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error") + // setIsLoading(false) + // }) - }; - const resetForm = () => { - reset({ - name: "", - description: "" - }); - setDescriptionLength(0); - } + // }; - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; +const resetForm = () => { + reset({ name: "", description: "" }); + setDescriptionLength(0); +}; + +useEffect(() => { + return () => resetForm(); +}, []); + return (<>
diff --git a/src/components/master/EditContactTag.jsx b/src/components/master/EditContactTag.jsx index 1c0f71d1..70ab0794 100644 --- a/src/components/master/EditContactTag.jsx +++ b/src/components/master/EditContactTag.jsx @@ -6,6 +6,7 @@ import { MasterRespository } from '../../repositories/MastersRepository'; import { clearApiCacheKey } from '../../slices/apiCacheSlice'; import { getCachedData,cacheData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useUpdateContactTag} from '../../hooks/masterHook/useMaster'; const schema = z.object({ @@ -15,65 +16,72 @@ const schema = z.object({ }); const EditContactTag= ({data,onClose}) => { +const { + register, + handleSubmit, + formState: { errors }, + reset +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: data?.name || "", + description: data?.description || "", + }, +}); - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors },reset - - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: data?.name || "", - description:data?.description || "", - - }, - }); - - const onSubmit = (formdata) => { - setIsLoading(true) - const result = { - id:data?.id, - name: formdata?.name, - description: formdata.description, - }; +const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); +const maxDescriptionLength = 255; + +const { mutate: updateContactTag, isPending: isLoading } = useUpdateContactTag(() => onClose?.()); + +const onSubmit = (formData) => { + const payload = { + id: data?.id, + name: formData.name, + description: formData.description, + }; + debugger + updateContactTag({ id: data?.id, payload} ); + } + // const onSubmit = (formdata) => { + // setIsLoading(true) + // const result = { + // id:data?.id, + // name: formdata?.name, + // description: formdata.description, + // }; - MasterRespository.updateContactTag(data?.id,result).then((resp)=>{ - setIsLoading(false) - showToast("Contact Tag Updated successfully.", "success"); - const cachedData = getCachedData("Contact Tag"); - if (cachedData) { + // MasterRespository.updateContactTag(data?.id,result).then((resp)=>{ + // setIsLoading(false) + // showToast("Contact Tag Updated successfully.", "success"); + // const cachedData = getCachedData("Contact Tag"); + // if (cachedData) { - const updatedData = cachedData.map((category) => - category.id === data?.id ? { ...category, ...resp.data } : category - ); - cacheData("Contact Tag", updatedData); - } + // const updatedData = cachedData.map((category) => + // category.id === data?.id ? { ...category, ...resp.data } : category + // ); + // cacheData("Contact Tag", updatedData); + // } - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error") - setIsLoading(false) - }) + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error") + // setIsLoading(false) + // }) - }; - const resetForm = () => { - reset({ - name: "", - description: "" - }); - setDescriptionLength(0); - } + // }; - useEffect(()=>{ - return ()=>resetForm() - },[]) - - const [descriptionLength, setDescriptionLength] = useState(0); - const maxDescriptionLength = 255; +const resetForm = () => { + reset({ name: "", description: "" }); + setDescriptionLength(0); +}; + +useEffect(() => { + return () => resetForm(); +}, []); + return (<>
diff --git a/src/components/master/EditJobRole.jsx b/src/components/master/EditJobRole.jsx index 93d9ce79..c10cd457 100644 --- a/src/components/master/EditJobRole.jsx +++ b/src/components/master/EditJobRole.jsx @@ -5,6 +5,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { MasterRespository } from '../../repositories/MastersRepository'; import { cacheData,getCachedData } from '../../slices/apiDataManager'; import showToast from '../../services/toastService'; +import {useUpdateJobRole} from '../../hooks/masterHook/useMaster'; @@ -17,63 +18,81 @@ const schema = z.object({ const EditJobRole = ({data,onClose}) => { - - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors } ,reset - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - role: data?.name || "", - description:data?.description || "", - - }, - }); - - const onSubmit = (formdata) => { - setIsLoading(true) - const result = { - id:data?.id, - name: formdata?.role, - description: formdata.description, - }; - - - - MasterRespository.updateJobRole(data?.id,result).then((resp)=>{ - setIsLoading(false) - showToast("JobRole Update successfully.", "success"); - const cachedData = getCachedData("Job Role"); - if (cachedData) { - - const updatedData = cachedData.map((role) => - role.id === data?.id ? { ...role, ...resp.data } : role - ); - cacheData("Job Role", updatedData); - } - - onClose() - }).catch((error)=>{ - showToast(error.message, "error") - setIsLoading(false) - }) - - }; - - - useEffect(() => { - reset({ - role: data?.name, - description: data?.description - }); - setDescriptionLength(data?.description?.length || 0); - }, [data, reset]); - - const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); +const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); const maxDescriptionLength = 255; + const { + register, + handleSubmit, + formState: { errors }, + reset, + watch, + } = useForm({ + resolver: zodResolver(schema), + defaultValues: { + role: data?.name || "", + description: data?.description || "", + }, + }); + + const { mutate: updateJobRole, isPendin:isLoading } = useUpdateJobRole(() => { + onClose?.(); + }); +// const onSubmit = (formdata) => { + // setIsLoading(true) + // const result = { + // id:data?.id, + // name: formdata?.role, + // description: formdata.description, + // }; + + + + // MasterRespository.updateJobRole(data?.id,result).then((resp)=>{ + // setIsLoading(false) + // showToast("JobRole Update successfully.", "success"); + // const cachedData = getCachedData("Job Role"); + // if (cachedData) { + + // const updatedData = cachedData.map((role) => + // role.id === data?.id ? { ...role, ...resp.data } : role + // ); + // cacheData("Job Role", updatedData); + // } + + // onClose() + // }).catch((error)=>{ + // showToast(error.message, "error") + // setIsLoading(false) + // }) + + // }; + + const onSubmit = (formData) => { + updateJobRole({ + id: data?.id, + payload: { + id: data?.id, + name: formData.role, + description: formData.description, + }, + }); + }; + + useEffect(() => { + reset({ + role: data?.name || "", + description: data?.description || "", + }); + setDescriptionLength(data?.description?.length || 0); + }, [data, reset]); + + useEffect(() => { + const sub = watch((values) => { + setDescriptionLength(values.description?.length || 0); + }); + return () => sub.unsubscribe(); + }, [watch]); return (<> diff --git a/src/components/master/EditRole.jsx b/src/components/master/EditRole.jsx index 51e483f8..a5861f3b 100644 --- a/src/components/master/EditRole.jsx +++ b/src/components/master/EditRole.jsx @@ -7,6 +7,7 @@ import { useFeatures } from "../../hooks/useMasterRole"; import { MasterRespository } from "../../repositories/MastersRepository"; import { cacheData, getCachedData } from "../../slices/apiDataManager"; import showToast from "../../services/toastService"; +import {useUpdateApplicationRole} from "../../hooks/masterHook/useMaster"; @@ -27,128 +28,149 @@ const updateSchema = z.object({ const EditMaster = ({ master, onClose }) => { - const [isLoading, setIsLoading] = useState(false) - const { masterFeatures } = useFeatures() - const popoverRefs = useRef([]); +const maxDescriptionLength = 255; +const popoverRefs = useRef([]); +const { masterFeatures } = useFeatures(); +const { mutate: updateApplicationRole, isPending: isLoading } = useUpdateApplicationRole(() => onClose?.()); - const buildDefaultPermissions = () => { - const defaults = {}; - masterFeatures.forEach((feature) => { - feature.featurePermissions.forEach((perm) => { - const existing = master?.item?.featurePermission?.find( - (p) => p.id === perm.id - ); - defaults[perm.id] = existing ? existing.isEnabled : false; - }); +const buildDefaultPermissions = () => { + const defaults = {}; + masterFeatures.forEach((feature) => { + feature.featurePermissions.forEach((perm) => { + const existing = master?.item?.featurePermission?.find(p => p.id === perm.id); + defaults[perm.id] = existing?.isEnabled || false; }); - return defaults; - - }; - - - const initialPermissions = buildDefaultPermissions(); - const { - register, - handleSubmit, - formState: { errors, dirtyFields }, - setError, reset - } = useForm({ - resolver: zodResolver(updateSchema), - defaultValues: { - role: master?.item?.role, - description: master?.item?.description, - permissions: initialPermissions, - }, }); + return defaults; +}; - const onSubmit = (data) => { - setIsLoading(true) - const existingIds = new Set( - master?.item?.featurePermission?.map((p) => p.id) - ); +const initialPermissions = buildDefaultPermissions(); +const { + register, + handleSubmit, + formState: { errors, dirtyFields }, + setError, + reset, +} = useForm({ + resolver: zodResolver(updateSchema), + defaultValues: { + role: master?.item?.role || "", + description: master?.item?.description || "", + permissions: initialPermissions, + }, +}); - const updatedPermissions = Object.entries(data.permissions) - .filter(([id, value]) => { - if (existingIds.has(id)) return true; +const [descriptionLength, setDescriptionLength] = useState(master?.item?.description?.length || 0); - return ( - value === true || - (dirtyFields.permissions && dirtyFields.permissions[id]) - ); - }) - .map(([id, value]) => ({ id, isEnabled: value })); +const onSubmit = (data) => { + const existingIds = new Set(master?.item?.featurePermission?.map(p => p.id)); - - if (updatedPermissions.length === 0) { - setError("permissions", { - type: "manual", - message: "At least one permission must be selected.", - }); - return; - } - - const updatedRole = { - id: master?.item?.id, - role: data.role, - description: data.description, - featuresPermission: updatedPermissions, - }; - MasterRespository.updateRoles(master?.item?.id, updatedRole).then((resp) => { - setIsLoading(false) - - - const cachedData = getCachedData("Application Role"); - - if (cachedData) { - - const updatedData = cachedData.map((role) => - role.id === resp.data?.id ? { ...role, ...resp.data } : role - ); - - cacheData("Application Role", updatedData); - } - showToast("Application Role Updated successfully.", "success"); - setIsLoading(false) - onClose() - }).catch((Err) => { - showToast(Err.message, "error"); - setIsLoading(false) + const updatedPermissions = Object.entries(data.permissions) + .filter(([id, value]) => { + return existingIds.has(id) || value === true || (dirtyFields.permissions?.[id]); }) + .map(([id, value]) => ({ id, isEnabled: value })); + if (updatedPermissions.length === 0) { + setError("permissions", { + type: "manual", + message: "At least one permission must be selected.", + }); + return; + } + + const payload = { + id: master?.item?.id, + role: data.role, + description: data.description, + featuresPermission: updatedPermissions, }; - useEffect(() => { - reset({ - role: master?.item?.role, - description: master?.item?.description, - permissions: initialPermissions, - }); - setDescriptionLength(master?.item?.description?.length || 0); - }, [master, reset]); + updateApplicationRole({ id: payload.id, payload }); +}; +// const onSubmit = (data) => { +// setIsLoading(true) +// const existingIds = new Set( +// master?.item?.featurePermission?.map((p) => p.id) +// ); - const [descriptionLength, setDescriptionLength] = useState(master?.item?.description?.length || 0); - const maxDescriptionLength = 255; - useEffect(() => { - popoverRefs.current.forEach((el) => { - if (el) { - new bootstrap.Popover(el, { - trigger: "focus", - placement: "right", - html: true, - content: el.getAttribute("data-bs-content"), // use inline content from attribute - }); - } - }); - }, [masterFeatures]); +// const updatedPermissions = Object.entries(data.permissions) +// .filter(([id, value]) => { +// if (existingIds.has(id)) return true; + +// return ( +// value === true || +// (dirtyFields.permissions && dirtyFields.permissions[id]) +// ); +// }) +// .map(([id, value]) => ({ id, isEnabled: value })); + + +// if (updatedPermissions.length === 0) { +// setError("permissions", { +// type: "manual", +// message: "At least one permission must be selected.", +// }); +// return; +// } + +// const updatedRole = { +// id: master?.item?.id, +// role: data.role, +// description: data.description, +// featuresPermission: updatedPermissions, +// }; +// MasterRespository.updateRoles(master?.item?.id, updatedRole).then((resp) => { +// setIsLoading(false) + + +// const cachedData = getCachedData("Application Role"); + +// if (cachedData) { + +// const updatedData = cachedData.map((role) => +// role.id === resp.data?.id ? { ...role, ...resp.data } : role +// ); + +// cacheData("Application Role", updatedData); +// } +// showToast("Application Role Updated successfully.", "success"); +// setIsLoading(false) +// onClose() +// }).catch((Err) => { +// showToast(Err.message, "error"); +// setIsLoading(false) +// }) + +// }; +useEffect(() => { + reset({ + role: master?.item?.role || "", + description: master?.item?.description || "", + permissions: buildDefaultPermissions(), + }); + setDescriptionLength(master?.item?.description?.length || 0); +}, [master, reset]); + +useEffect(() => { + popoverRefs.current.forEach((el) => { + if (el) { + new bootstrap.Popover(el, { + trigger: "focus", + placement: "right", + html: true, + content: el.getAttribute("data-bs-content"), + }); + } + }); +}, [masterFeatures]); + return ( - {/*
- -
*/}
{ - const[isLoading,setIsLoading] = useState(false) - const { - register, - handleSubmit, - formState: { errors } ,reset - } = useForm({ - resolver: zodResolver(schema), - defaultValues: { - name: data?.name || "", - description:data?.description || "", - - }, - }); - - const onSubmit = (formdata) => { - setIsLoading(true) - const result = { - id:data?.id, - name: formdata?.name, - description: formdata.description, - }; +const { + register, + handleSubmit, + formState: { errors }, + reset, +} = useForm({ + resolver: zodResolver(schema), + defaultValues: { + name: data?.name || "", + description: data?.description || "", + }, +}); + +const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); +const maxDescriptionLength = 255; + +const { mutate: updateWorkCategory, isPending: isLoading } = useUpdateWorkCategory(() => onClose?.()); + +const onSubmit = (formdata) => { + const payload = { + id: data?.id, + name: formdata.name, + description: formdata.description, + }; + + updateWorkCategory({id:data?.id,payload}); +}; + + // const onSubmit = (formdata) => { + // setIsLoading(true) + // const result = { + // id:data?.id, + // name: formdata?.name, + // description: formdata.description, + // }; - MasterRespository.updateWorkCategory(data?.id,result).then((resp)=>{ - setIsLoading(false) - showToast("Work Category Update successfully.", "success"); - const cachedData = getCachedData("Work Category"); - if (cachedData) { + // MasterRespository.updateWorkCategory(data?.id,result).then((resp)=>{ + // setIsLoading(false) + // showToast("Work Category Update successfully.", "success"); + // const cachedData = getCachedData("Work Category"); + // if (cachedData) { - const updatedData = cachedData.map((category) => - category.id === data?.id ? { ...category, ...resp.data } : category - ); - cacheData("Work Category", updatedData); - } + // const updatedData = cachedData.map((category) => + // category.id === data?.id ? { ...category, ...resp.data } : category + // ); + // cacheData("Work Category", updatedData); + // } - onClose() - }).catch((error)=>{ - showToast(error?.response?.data?.message, "error") - setIsLoading(false) - }) + // onClose() + // }).catch((error)=>{ + // showToast(error?.response?.data?.message, "error") + // setIsLoading(false) + // }) - }; + // }; +useEffect(() => { + reset({ + name: data?.name || "", + description: data?.description || "", + }); + setDescriptionLength(data?.description?.length || 0); +}, [data, reset]); - - useEffect(() => { - reset({ - name: data?.name, - description: data?.description - }); - setDescriptionLength(data?.description?.length || 0); - }, [data, reset]); - - const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0); - const maxDescriptionLength = 255; return (<> - {/*
- -
- */}
{ - const [ isDeleteModalOpen, setIsDeleteModalOpen ] = useState( false ); + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const { mutate: deleteMasterItem, isPending } = useDeleteMasterItem(); - const handleSelectedMasterDeleted = async () => - { - const deleteFn = MasterRespository[modaldata.masterType]; - if (!deleteFn) { - showToast(`No delete strategy defined for master type`,"error"); - return false; + // const handleSelectedMasterDeleted = async () => + // { + // debugger + // const deleteFn = MasterRespository[modaldata.masterType]; + // if (!deleteFn) { + // showToast(`No delete strategy defined for master type`,"error"); + // return false; + // } + // try + // { + // const response = await deleteFn( modaldata?.item?.id ); + // const selected_cachedData = getCachedData( modaldata?.masterType ); + // const updated_master = selected_cachedData?.filter(item => item.id !== modaldata?.item.id); + // cacheData( modaldata?.masterType, updated_master ) + + // showToast(`${modaldata?.masterType} is deleted successfully`, "success"); + // handleCloseDeleteModal() + + // } catch ( error ) + // { + // const message = error.response.data.message || error.message || "Error occured api during call" + // showToast(message, "success"); + // } + // } + + const handleSelectedMasterDeleted = () => { + if (!modaldata?.masterType || !modaldata?.item?.id) { + showToast("Missing master type or item", "error"); + return; } - try - { - const response = await deleteFn( modaldata?.item?.id ); - const selected_cachedData = getCachedData( modaldata?.masterType ); - const updated_master = selected_cachedData?.filter(item => item.id !== modaldata?.item.id); - cacheData( modaldata?.masterType, updated_master ) - - showToast(`${modaldata?.masterType} is deleted successfully`, "success"); - handleCloseDeleteModal() - - } catch ( error ) - { - const message = error.response.data.message || error.message || "Error occured api during call" - showToast(message, "success"); - } - } - + deleteMasterItem( + { + masterType: modaldata.masterType, + item: modaldata.item, + validateFn: modaldata.validateFn, // optional + }, + { + onSuccess: () => { + handleCloseDeleteModal(); + }, + } + ); + }; useEffect(() => { if (modaldata?.modalType === "delete") { @@ -55,7 +75,7 @@ const MasterModal = ({ modaldata, closeModal }) => { const handleCloseDeleteModal = () => { setIsDeleteModalOpen(false); - closeModal(); + closeModal(); }; if (modaldata?.modalType === "delete" && isDeleteModalOpen) { @@ -88,7 +108,9 @@ const MasterModal = ({ modaldata, closeModal }) => { >
{
-
{ `${modaldata?.modalType} `}
- -
+
{`${modaldata?.modalType} `}
+ +
{modaldata.modalType === "Application Role" && ( - + )} {modaldata.modalType === "Edit-Application Role" && ( @@ -122,7 +147,10 @@ const MasterModal = ({ modaldata, closeModal }) => { )} {modaldata.modalType === "Edit-Activity" && ( - + )} {modaldata.modalType === "Work Category" && ( @@ -133,10 +161,10 @@ const MasterModal = ({ modaldata, closeModal }) => { {modaldata.modalType === "Contact Category" && ( )} - {modaldata.modalType === "Edit-Contact Category" && ( + {modaldata.modalType === "Edit-Contact Category" && ( )} - {modaldata.modalType === "Contact Tag" && ( + {modaldata.modalType === "Contact Tag" && ( )} {modaldata.modalType === "Edit-Contact Tag" && ( diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js index a5c43a51..74c84eec 100644 --- a/src/hooks/masterHook/useMaster.js +++ b/src/hooks/masterHook/useMaster.js @@ -2,6 +2,8 @@ import {useState,useEffect} from "react" import { MasterRespository } from "../../repositories/MastersRepository"; import { cacheData,getCachedData } from "../../slices/apiDataManager"; import { useSelector } from "react-redux"; +import {useMutation, useQueries, useQuery, useQueryClient} from "@tanstack/react-query"; +import showToast from "../../services/toastService"; @@ -9,214 +11,687 @@ import { useSelector } from "react-redux"; -export const useFeatures = () => - useMasterData("masterFeatures", MasterRespository.getFeatures); -export const useMasterRole = () => - useMasterData("masterRole", MasterRespository.getRoles); +// const useMaster = () => { - -const useMaster = (isMa) => { - - const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster); - const [data, setData] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(""); - useEffect(() => { - const fetchData = async () => { - if (!selectedMaster) return; - setLoading(true); - try { - const cachedData = getCachedData(selectedMaster); - if (cachedData) { +// const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster); +// const [data, setData] = useState([]); +// const [loading, setLoading] = useState(true); +// const [error, setError] = useState(""); +// useEffect(() => { +// const fetchData = async () => { +// if (!selectedMaster) return; +// setLoading(true); +// try { +// const cachedData = getCachedData(selectedMaster); +// if (cachedData) { - setData(cachedData); +// setData(cachedData); - } else { - let response; - switch (selectedMaster) { - case "Application Role": - response = await MasterRespository.getRoles(); - response = response.data; - break; - case "Job Role": - response = await MasterRespository.getJobRole(); - response = response.data - break; - case "Activity": - response = await MasterRespository.getActivites(); - response = response.data - break; - case "Work Category": - response = await MasterRespository.getWorkCategory(); - response = response.data - break; - case "Contact Category": - response = await MasterRespository.getContactCategory(); - response = response.data - break; - case "Contact Tag": - response = await MasterRespository.getContactTag(); - response = response.data - break; - case "Status": - response = [{description: null,featurePermission: null,id: "02dd4761-363c-49ed-8851-3d2489a3e98d",status:"status 1"},{description: null,featurePermission: null,id: "03dy9761-363c-49ed-8851-3d2489a3e98d",status:"status 2"},{description: null,featurePermission: null,id: "03dy7761-263c-49ed-8851-3d2489a3e98d",status:"Status 3"}]; - break; - default: - response = []; - } +// } else { +// let response; +// switch (selectedMaster) { +// case "Application Role": +// response = await MasterRespository.getRoles(); +// response = response.data; +// break; +// case "Job Role": +// response = await MasterRespository.getJobRole(); +// response = response.data +// break; +// case "Activity": +// response = await MasterRespository.getActivites(); +// response = response.data +// break; +// case "Work Category": +// response = await MasterRespository.getWorkCategory(); +// response = response.data +// break; +// case "Contact Category": +// response = await MasterRespository.getContactCategory(); +// response = response.data +// break; +// case "Contact Tag": +// response = await MasterRespository.getContactTag(); +// response = response.data +// break; +// case "Status": +// response = [{description: null,featurePermission: null,id: "02dd4761-363c-49ed-8851-3d2489a3e98d",status:"status 1"},{description: null,featurePermission: null,id: "03dy9761-363c-49ed-8851-3d2489a3e98d",status:"status 2"},{description: null,featurePermission: null,id: "03dy7761-263c-49ed-8851-3d2489a3e98d",status:"Status 3"}]; +// break; +// default: +// response = []; +// } - if (response) { - setData(response); - cacheData(selectedMaster, response); - } - } - } catch (err) { - setError("Failed to fetch data."); - } finally { - setLoading(false); - } - }; +// if (response) { +// setData(response); +// cacheData(selectedMaster, response); +// } +// } +// } catch (err) { +// setError("Failed to fetch data."); +// } finally { +// setLoading(false); +// } +// }; - if ( selectedMaster ) - { +// if ( selectedMaster ) +// { - fetchData(); - } +// fetchData(); +// } - }, [selectedMaster]); +// }, [selectedMaster]); - return { data, loading, error } +// return { data, loading, error } +// }; + + + + +// export const useActivitiesMaster = () => +// { +// const [ activities, setActivites ] = useState( [] ) +// const [ loading, setloading ] = useState( false ); +// const [ error, setError ] = useState() +// const fetchActivities =async () => { +// setloading(true); +// try { +// const response = await MasterRespository.getActivites(); +// setActivites(response.data); +// cacheData( "ActivityMaster", response.data ); +// setloading(false); +// } catch (err) { +// setError(err); +// setloading(false); +// } +// } +// useEffect( () => +// { +// const cacheddata = getCachedData( "ActivityMaster" ); +// if ( !cacheddata ) +// { +// fetchActivities() +// } else +// { +// setActivites(cacheddata); +// } +// }, [] ) + +// return {activities,loading,error} +// } + +// export const useWorkCategoriesMaster = () => +// { +// const [ categories, setCategories ] = useState( [] ) +// const [ categoryLoading, setloading ] = useState( false ); +// const [ categoryError, setError ] = useState( "" ) + +// const fetchCategories =async () => { +// const cacheddata = getCachedData("Work Category"); + +// if (!cacheddata) { +// setloading(true); +// try { +// const response = await MasterRespository.getWorkCategory(); +// setCategories(response.data); +// cacheData("Work Category", response.data); +// } catch (err) { +// setError(err); +// console.log(err); +// } finally { +// setloading(false); +// } +// } else { +// setCategories(cacheddata); +// } +// } +// useEffect( () => +// { +// fetchCategories() +// }, [] ) + +// return {categories,categoryLoading,categoryError} +// } + +// export const useContactCategory = () => +// { +// const [ contactCategory, setContactCategory ] = useState( [] ) +// const [ loading, setLoading ] = useState( false ) +// const [ Error, setError ] = useState() + +// const fetchConatctCategory = async() => +// { +// const cache_Category = getCachedData( "Contact Category" ); +// if ( !cache_Category ) +// { +// try +// { +// let resp = await MasterRespository.getContactCategory(); +// setContactCategory( resp.data ); +// cacheData("Contact Category",resp.data) +// } catch ( error ) +// { +// setError(error) +// } +// } else +// { +// setContactCategory(cache_Category) +// } +// } + +// useEffect( () => +// { +// fetchConatctCategory() +// }, [] ) +// return { contactCategory,loading,Error} +// } +// export const useContactTags = () => { +// const [contactTags, setContactTags] = useState([]); +// const [loading, setLoading] = useState(false); +// const [error, setError] = useState(null); + +// useEffect(() => { +// const fetchContactTag = async () => { +// const cache_Tags = getCachedData("Contact Tag"); + +// if (!cache_Tags) { +// setLoading(true); +// try { +// const resp = await MasterRespository.getContactTag(); +// setContactTags(resp.data); +// cacheData("Contact Tag", resp.data); +// } catch (err) { +// setError(err); +// } finally { +// setLoading(false); +// } +// } else { +// setContactTags(cache_Tags); +// } +// }; + +// fetchContactTag(); +// }, []); + +// return { contactTags, loading, error }; +// }; + +// Separate matser------------- + +export const useActivitiesMaster = () => +{ + const { data:activities=[],isLoading:loading,error} = useQuery( { + queryKey: [ "ActivityMaster" ], + queryFn: async() => + { + const response = await MasterRespository.getActivites(); + return response.data + }, + onError: (error) => { + showToast(error?.response?.data?.message || error.message || "Failed to fetch ActivityMasters", "error"); + }, + } ) + return {activities,loading,error} +} +export const useWorkCategoriesMaster = () => { + const { + data: categories = [], + isLoading: categoryLoading, + error: categoryError, + } = useQuery({ + queryKey: ["Work Category"], + queryFn: async () => { + const response = await MasterRespository.getWorkCategory(); + return response.data; + }, + onError: (error) => { + showToast( + error?.response?.data?.message || + error.message || + "Failed to fetch work categories", + "error" + ); + }, + }); + + return { categories, categoryLoading, categoryError }; +}; + + +export const useContactCategory = () => +{ + const {data:contactCategory=[],isLoading:loading,error:Error } = useQuery( { + queryKey: [ "Contact Category" ], + queryFn: async () => + { + let resp = await MasterRespository.getContactCategory(); + return resp.data + }, + onError: (error) => { + showToast(error?.response?.data?.message || error.message || "Failed to fetch Contact categories", "error"); + }, + } ) + return { contactCategory,loading,Error} +} + +export const useContactTags = () => { + const { + data: contactTags = [], + isLoading: loading, + error, + } = useQuery({ + queryKey: ["Contact Tag"], + queryFn: async () => { + const res = await MasterRespository.getContactTag(); + return res.data; + }, + onError: (error) => { + showToast( + error?.response?.data?.message || + error.message || + "Failed to fetch Contact Tag", + "error" + ); + }, + }); + + return { contactTags, loading, error }; +}; + +// ===Application Masters Query================================================= + +const fetchMasterData = async (masterType) => { + switch (masterType) { + case "Application Role": + return (await MasterRespository.getRoles()).data; + case "Job Role": + return (await MasterRespository.getJobRole()).data; + case "Activity": + return (await MasterRespository.getActivites()).data; + case "Work Category": + return (await MasterRespository.getWorkCategory()).data; + case "Contact Category": + return (await MasterRespository.getContactCategory()).data; + case "Contact Tag": + return (await MasterRespository.getContactTag()).data; + case "Status": + return [ + { + description: null, + featurePermission: null, + id: "02dd4761-363c-49ed-8851-3d2489a3e98d", + status: "status 1", + }, + { + description: null, + featurePermission: null, + id: "03dy9761-363c-49ed-8851-3d2489a3e98d", + status: "status 2", + }, + { + description: null, + featurePermission: null, + id: "03dy7761-263c-49ed-8851-3d2489a3e98d", + status: "Status 3", + }, + ]; + default: + return []; + } +}; + +const useMaster = () => { + const selectedMaster = useSelector((store) => store.localVariables.selectedMaster); + + const { + data = [], + isLoading, + error, + } = useQuery({ + queryKey: ["masterData", selectedMaster], + queryFn: () => fetchMasterData(selectedMaster), + enabled: !!selectedMaster, + staleTime: 1000 * 60 * 10, + refetchOnWindowFocus: false, + onError: (error) => { + showToast(error?.response?.data?.message || error.message || `Failed to fetch ${selectedMaster} Maseter`, "error"); + }, + }); + + return { data, loading: isLoading, error }; }; export default useMaster; -export const useActivitiesMaster = () => - { - const [ activities, setActivites ] = useState( [] ) - const [ loading, setloading ] = useState( false ); - const [ error, setError ] = useState() - const fetchActivities =async () => { - setloading(true); - try { - const response = await MasterRespository.getActivites(); - setActivites(response.data); - cacheData( "ActivityMaster", response.data ); - setloading(false); - } catch (err) { - setError(err); - setloading(false); - } - } - useEffect( () => - { - const cacheddata = getCachedData( "ActivityMaster" ); - if ( !cacheddata ) - { - fetchActivities() - } else - { - setActivites(cacheddata); - } - }, [] ) - - return {activities,loading,error} - } +// ================================Mutation==================================== - export const useWorkCategoriesMaster = () => - { - const [ categories, setCategories ] = useState( [] ) - const [ categoryLoading, setloading ] = useState( false ); - const [ categoryError, setError ] = useState( "" ) - - const fetchCategories =async () => { - const cacheddata = getCachedData("Work Category"); - - if (!cacheddata) { - setloading(true); - try { - const response = await MasterRespository.getWorkCategory(); - setCategories(response.data); - cacheData("Work Category", response.data); - } catch (err) { - setError(err); - console.log(err); - } finally { - setloading(false); - } - } else { - setCategories(cacheddata); - } - } - useEffect( () => - { - fetchCategories() - }, [] ) - - return {categories,categoryLoading,categoryError} -} - -export const useContactCategory = () => +// Job Role----------------------------------- +export const useUpdateJobRole = (onSuccessCallback, onErrorCallback) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ({ id, payload }) => { + const response = await MasterRespository.updateJobRole(id, payload); + return response.data; + }, + onSuccess: (data, variables) => { + showToast("JobRole updated successfully.", "success"); + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Job Role"], + }); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + if (onErrorCallback) onErrorCallback(error); + }, + }); +}; + +export const useCreateJobRole = (onSuccessCallback) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (payload) => { + const response = await MasterRespository.createJobRole(payload); + return response.data; + }, + onSuccess: (data) => { + showToast("JobRole added successfully.", "success"); + + queryClient.invalidateQueries(["masterData", "Job Role"]); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +}; + +// Application Role------------------------------------------- + +export const useCreateApplicationRole = (onSuccessCallback) => { - const [ contactCategory, setContactCategory ] = useState( [] ) - const [ loading, setLoading ] = useState( false ) - const [ Error, setError ] = useState() - - const fetchConatctCategory = async() => - { - const cache_Category = getCachedData( "Contact Category" ); - if ( !cache_Category ) + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( payload ) => { - try - { - let resp = await MasterRespository.getContactCategory(); - setContactCategory( resp.data ); - cacheData("Contact Category",resp.data) - } catch ( error ) - { - setError(error) - } - } else + const resp = await MasterRespository.createRole( payload ); + return resp.data; + }, + onSuccess: ( data ) => { - setContactCategory(cache_Category) + queryClient.invalidateQueries( [ "masterData", "Application Role" ] ) + showToast( "Application Role added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); } - } - - useEffect( () => - { - fetchConatctCategory() - }, [] ) - return { contactCategory,loading,Error} + }) } -export const useContactTags = () => { - const [contactTags, setContactTags] = useState([]); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - useEffect(() => { - const fetchContactTag = async () => { - const cache_Tags = getCachedData("Contact Tag"); +export const useUpdateApplicationRole = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); - if (!cache_Tags) { - setLoading(true); - try { - const resp = await MasterRespository.getContactTag(); - setContactTags(resp.data); - cacheData("Contact Tag", resp.data); - } catch (err) { - setError(err); - } finally { - setLoading(false); - } - } else { - setContactTags(cache_Tags); + return useMutation({ + mutationFn: async ( {id, payload} ) => + { + const response = await MasterRespository.updateRoles(id,payload); + return response.data; + }, + onSuccess: (data, variables) => { + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Application Role"], + }); + showToast("Application Role updated successfully.", "success"); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +} + +// Activity------------------------------ +export const useCreateActivity = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( payload ) => + { + const resp = await MasterRespository.createActivity(payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( [ "masterData", "Activity" ] ) + showToast( "Activity added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} + +export const useUpdateActivity = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ( {id, payload} ) => + { + const response = await MasterRespository.updateActivity(id,payload); + return response.data; + }, + onSuccess: (data, variables) => { + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Activity"], + }); + showToast("Activity updated successfully.", "success"); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +} + + +//-----Create work Category------------------------------- +export const useCreateWorkCategory = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( payload ) => + { + const resp = await MasterRespository.createWorkCategory(payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( [ "masterData", "Work Category" ] ) + showToast( "Work Category added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} + +export const useUpdateWorkCategory = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ( {id, payload} ) => + { + const response = await MasterRespository.updateWorkCategory(id,payload); + return response.data; + }, + onSuccess: (data, variables) => { + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Work Category"], + }); + showToast("Work Category updated successfully.", "success"); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +} + +//-- Contact Category--------------------------- + + +export const useCreateContactCategory = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( payload ) => + { + const resp = await MasterRespository.createContactCategory(payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( [ "masterData", "Contact Category" ] ) + showToast( "Contact Category added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} + + +export const useUpdateContactCategory = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ( {id, payload} ) => + { + const response = await MasterRespository.updateContactCategory(id,payload); + return response.data; + }, + onSuccess: (data, variables) => { + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Contact Category"], + }); + showToast("Contact Category updated successfully.", "success"); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +} + +// ---------Contact Tag------------------- + +export const useCreateContactTag = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( payload ) => + { + const resp = await MasterRespository.createContactTag(payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( [ "masterData", "Contact Tag" ] ) + showToast( "Contact Tag added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} + + +export const useUpdateContactTag = (onSuccessCallback) => +{ + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ( {id, payload} ) => + { + debugger + const response = await MasterRespository.updateContactTag(id,payload); + return response.data; + }, + onSuccess: (data, variables) => { + + queryClient.invalidateQueries({ + queryKey: ["masterData", "Contact Tag"], + }); + showToast("Contact Tag updated successfully.", "success"); + + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +} + +// -Delete Master -------- +export const useDeleteMasterItem = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ( {masterType, item} ) => + { + const deleteFn = MasterRespository[masterType]; + if (!deleteFn) { + throw new Error(`No delete strategy defined for master type: ${masterType}`); } - }; - fetchContactTag(); - }, []); + await deleteFn(item.id); + return { masterType }; + }, - return { contactTags, loading, error }; + onSuccess: ({ masterType }) => { + queryClient.invalidateQueries({ queryKey: ["masterData", masterType] }); + + showToast(`${masterType} deleted successfully.`, "success"); + }, + + onError: (error) => { + const message = + error?.response?.data?.message || error?.message || "Error occurred during deletion"; + showToast(message, "error"); + }, + }); }; \ No newline at end of file diff --git a/src/pages/master/MasterPage.jsx b/src/pages/master/MasterPage.jsx index 3852f7d3..68d790b6 100644 --- a/src/pages/master/MasterPage.jsx +++ b/src/pages/master/MasterPage.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useMemo } from "react"; import Breadcrumb from "../../components/common/Breadcrumb"; import MasterModal from "../../components/master/MasterModal"; import { mastersList} from "../../data/masters"; @@ -9,92 +9,80 @@ import MasterTable from "./MasterTable"; import { getCachedData } from "../../slices/apiDataManager"; import {useHasUserPermission} from "../../hooks/useHasUserPermission"; import { MANAGE_MASTER } from "../../utils/constants"; +import {useQueryClient} from "@tanstack/react-query"; const MasterPage = () => { +const [modalConfig, setModalConfig] = useState({ modalType: "", item: null, masterType: null }); +const [searchTerm, setSearchTerm] = useState(''); +const [filteredResults, setFilteredResults] = useState([]); +const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); - const [modalConfig, setmodalConfig] = useState({modalType: "", item: null, masterType:null }); - const [searchTerm, setSearchTerm] = useState(''); - const [ filteredResults, setFilteredResults ] = useState( [] ); - const hasMasterPermission = useHasUserPermission( MANAGE_MASTER ) - const dispatch = useDispatch(); - const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster) - - const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); - - const openModal = () => { - setIsCreateModalOpen(true); +const hasMasterPermission = useHasUserPermission(MANAGE_MASTER); +const dispatch = useDispatch(); +const selectedMaster = useSelector((store) => store.localVariables.selectedMaster); +const queryClient = useQueryClient(); +const { data: masterData = [], loading, error, RecallApi } = useMaster(); + +const openModal = () => setIsCreateModalOpen(true); + +const closeModal = () => { + setIsCreateModalOpen(false); + setModalConfig(null); + + // Clean up Bootstrap modal manually + const modalEl = document.getElementById('master-modal'); + modalEl?.classList.remove('show'); + if (modalEl) modalEl.style.display = 'none'; + + document.body.classList.remove('modal-open'); + document.body.style.overflow = 'auto'; + + document.querySelectorAll('.modal-backdrop').forEach((el) => el.remove()); +}; + +const handleModalData = (modalType, item, masterType = selectedMaster) => { + setModalConfig({ modalType, item, masterType }); +}; + +const handleSearch = (e) => { + const value = e.target.value.toLowerCase(); + setSearchTerm(value); + + if (!masterData?.length) return; + + const results = masterData.filter((item) => + Object.values(item).some( + (field) => field?.toString().toLowerCase().includes(value) + ) + ); + setFilteredResults(results); +}; +const displayData = useMemo(() => { + if (searchTerm) return filteredResults; + return queryClient.getQueryData(["masterData", selectedMaster]) || masterData; +}, [searchTerm, filteredResults, selectedMaster, masterData]); + +const columns = useMemo(() => { + if (!displayData?.length) return []; + return Object.keys(displayData[0]).map((key) => ({ + key, + label: key.toUpperCase(), + })); +}, [displayData]); + +useEffect(() => { + if (modalConfig) openModal(); +}, [modalConfig]); + +useEffect(() => { + return () => { + setIsCreateModalOpen(false); + closeModal(); }; +}, []); - const closeModal = () => { - setIsCreateModalOpen(false); - setmodalConfig(null); - - - const modalElement = document.getElementById('master-modal'); - if (modalElement) { - modalElement.classList.remove('show'); - modalElement.style.display = 'none'; - document.body.classList.remove('modal-open'); - - - const backdropElement = document.querySelector('.modal-backdrop'); - if (backdropElement) { - backdropElement.classList.remove('modal-backdrop'); - backdropElement.style.display = 'none'; - } - } - const modalBackdropElement = document.querySelector('.modal-backdrop'); - if (modalBackdropElement) { - modalBackdropElement.remove(); - } - document.body.style.overflow = 'auto'; - - }; - - const {data:masterData, loading,error , RecallApi} = useMaster(); - - - const handleSearch = (e) => { - const value = e.target.value.toLowerCase(); - setSearchTerm(value); - - if (!masterData.length) return; - - const results = masterData.filter((item) => - Object.values(item).some((field) => - field && field.toString().toLowerCase().includes(value) - ) - ); - - setFilteredResults(results); - }; - - const displayData = searchTerm ? filteredResults : getCachedData(selectedMaster) ? getCachedData(selectedMaster) : masterData - - const columns = displayData?.length - ? Object.keys(displayData[0]).map((key) => ({ key, label: key.toUpperCase() })) - : []; - - const handleModalData =(modalType,item,masterType = selectedMaster)=>{ - setmodalConfig({ modalType: modalType, item:item,masterType:masterType }); - } - - useEffect(() => { - if (modalConfig !== null) { - openModal(); - } - - }, [ modalConfig, isCreateModalOpen ] ); - - - useEffect(() => { - return () => { - setIsCreateModalOpen(false) - closeModal(); - }; - }, []) return ( <> diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx index a2557574..aebfc157 100644 --- a/src/repositories/MastersRepository.jsx +++ b/src/repositories/MastersRepository.jsx @@ -41,7 +41,7 @@ export const MasterRespository = { "Activity": ( id ) => api.delete( `/api/master/activity/delete/${ id }` ), "Application Role":(id)=>api.delete(`/api/roles/${id}`), "Work Category": ( id ) => api.delete( `api/master/work-category/${ id }` ), - "Contact Category": ( id ) => api.delete( `/api/master/contact-category` ), + "Contact Category": ( id ) => api.delete( `/api/master/contact-category/${id}` ), "Contact Tag" :(id)=>api.delete(`/api/master/contact-tag/${id}`), getWorkCategory:() => api.get(`/api/master/work-categories`),