added created, fetch and edit operration
This commit is contained in:
parent
5c1b14bd38
commit
1bba9ab68a
@ -1,6 +1,10 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { formatNumber, getDateDifferenceInDays } from "../../utils/dateUtils";
|
import {
|
||||||
|
formatNumber,
|
||||||
|
formatUTCToLocalTime,
|
||||||
|
getDateDifferenceInDays,
|
||||||
|
} from "../../utils/dateUtils";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useProjectDetails, useUpdateProject } from "../../hooks/useProjects";
|
import { useProjectDetails, useUpdateProject } from "../../hooks/useProjects";
|
||||||
import ManageProjectInfo from "./ManageProjectInfo";
|
import ManageProjectInfo from "./ManageProjectInfo";
|
||||||
@ -22,7 +26,7 @@ const ProjectCard = ({ project, isCore = true }) => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
const { setMangeProject } = useProjectContext();
|
const { setMangeProject, setManageServiceProject } = useProjectContext();
|
||||||
|
|
||||||
const getProgress = (planned, completed) => {
|
const getProgress = (planned, completed) => {
|
||||||
return (completed * 100) / planned + "%";
|
return (completed * 100) / planned + "%";
|
||||||
@ -54,7 +58,7 @@ const ProjectCard = ({ project, isCore = true }) => {
|
|||||||
} else {
|
} else {
|
||||||
setManageServiceProject({
|
setManageServiceProject({
|
||||||
isOpen: true,
|
isOpen: true,
|
||||||
Project: project.id,
|
project: project.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -138,14 +142,21 @@ const ProjectCard = ({ project, isCore = true }) => {
|
|||||||
<span className="text-heading fw-medium">
|
<span className="text-heading fw-medium">
|
||||||
Contact Person:{" "}
|
Contact Person:{" "}
|
||||||
</span>
|
</span>
|
||||||
{project?.contactPerson ? project.contactPerson : "NA"}
|
{isCore
|
||||||
|
? project?.contactPerson
|
||||||
|
? project.contactPerson
|
||||||
|
: "NA"
|
||||||
|
: project.contactName}
|
||||||
</p>
|
</p>
|
||||||
<p className="mb-1">
|
<p className="mb-1">
|
||||||
<span className="text-heading fw-medium">Start Date: </span>
|
<span className="text-heading fw-medium">
|
||||||
{project.startDate
|
{isCore ? "Start Date:" : "Assigned Date"}{" "}
|
||||||
? moment(project?.startDate).format("DD-MMM-YYYY")
|
</span>
|
||||||
: "NA"}
|
{formatUTCToLocalTime(
|
||||||
|
isCore ? project?.startDate : project.assignedDate
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
{isCore && (
|
||||||
<p className="mb-1">
|
<p className="mb-1">
|
||||||
<span className="text-heading fw-medium">Deadline: </span>
|
<span className="text-heading fw-medium">Deadline: </span>
|
||||||
|
|
||||||
@ -153,6 +164,7 @@ const ProjectCard = ({ project, isCore = true }) => {
|
|||||||
? moment(project?.endDate).format("DD-MMM-YYYY")
|
? moment(project?.endDate).format("DD-MMM-YYYY")
|
||||||
: "NA"}
|
: "NA"}
|
||||||
</p>
|
</p>
|
||||||
|
)}
|
||||||
<p className="mb-0">{project?.projectAddress}</p>
|
<p className="mb-0">{project?.projectAddress}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { defaultProjectValues } from "./ServiceProjectSchema";
|
import { defaultProjectValues } from "./ServiceProjectSchema";
|
||||||
import Label from "../common/Label";
|
import Label from "../common/Label";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
import { useGlobalServices } from "../../hooks/masterHook/useMaster";
|
import {
|
||||||
|
useGlobalServices,
|
||||||
|
useServices,
|
||||||
|
} from "../../hooks/masterHook/useMaster";
|
||||||
import { ITEMS_PER_PAGE, PROJECT_STATUS } from "../../utils/constants";
|
import { ITEMS_PER_PAGE, PROJECT_STATUS } from "../../utils/constants";
|
||||||
import DatePicker from "../common/DatePicker";
|
import DatePicker from "../common/DatePicker";
|
||||||
|
|
||||||
@ -14,10 +17,18 @@ import {
|
|||||||
useOrganizationsList,
|
useOrganizationsList,
|
||||||
} from "../../hooks/useOrganization";
|
} from "../../hooks/useOrganization";
|
||||||
import { error } from "pdf-lib";
|
import { error } from "pdf-lib";
|
||||||
import { useCreateServiceProject } from "../../hooks/useServiceProject";
|
import {
|
||||||
|
useCreateServiceProject,
|
||||||
|
useServiceProject,
|
||||||
|
useUpdateServiceProject,
|
||||||
|
} from "../../hooks/useServiceProject";
|
||||||
|
|
||||||
const ManageServiceProject = ({ servieceProjectId }) => {
|
const ManageServiceProject = ({ serviceProjectId, onClose }) => {
|
||||||
console.log(servieceProjectId)
|
const {
|
||||||
|
data: projectdata,
|
||||||
|
isLoading: isProjectLoading,
|
||||||
|
isProjectError,
|
||||||
|
} = useServiceProject(serviceProjectId);
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const methods = useForm({
|
const methods = useForm({
|
||||||
resolver: zodResolver(projectSchema),
|
resolver: zodResolver(projectSchema),
|
||||||
@ -27,22 +38,79 @@ const ManageServiceProject = ({ servieceProjectId }) => {
|
|||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
|
reset,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = methods;
|
} = methods;
|
||||||
const { data, isError, isLoading } = useGlobalServices();
|
const { data, isError, isLoading } = useServices();
|
||||||
const { data: organization, isLoading: isLoadingOrganization } =
|
const { data: organization, isLoading: isLoadingOrganization } =
|
||||||
useOrganizationsList(ITEMS_PER_PAGE, 1, true);
|
useOrganizationsList(ITEMS_PER_PAGE, 1, true);
|
||||||
|
|
||||||
const { mutate: CreateServiceProject, isPending } = useCreateServiceProject();
|
const { mutate: CreateServiceProject, isPending } = useCreateServiceProject(
|
||||||
|
() => {
|
||||||
|
reset();
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const { mutate: UpdateServiceProject, isPending: isUpdating } =
|
||||||
|
useUpdateServiceProject(() => {
|
||||||
|
reset();
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
formData.services = formData.services.filter((s) => s.serviceId);
|
|
||||||
|
if (serviceProjectId) {
|
||||||
|
let existingServiceIds = projectdata?.services?.map((s) => s.id) || [];
|
||||||
|
|
||||||
|
const oldServices = projectdata.services.map((service) => ({
|
||||||
|
serviceId: service.id,
|
||||||
|
isActive: formData.services.includes(service.id),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const newServices = formData.services
|
||||||
|
.filter((s) => !existingServiceIds.includes(s))
|
||||||
|
.map((service) => ({ serviceId: service, isActive: true }));
|
||||||
|
|
||||||
|
formData.services = [...oldServices, ...newServices];
|
||||||
|
} else {
|
||||||
|
formData.services = formData.services.map((service) => ({
|
||||||
|
serviceId: service,
|
||||||
|
isActive: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceProjectId) {
|
||||||
|
let payload = { ...formData, id: serviceProjectId };
|
||||||
|
|
||||||
|
UpdateServiceProject({ id: serviceProjectId, payload });
|
||||||
|
} else {
|
||||||
CreateServiceProject(formData);
|
CreateServiceProject(formData);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (projectdata) {
|
||||||
|
const activeServiceIds = (projectdata.services || [])
|
||||||
|
.map((s) => s.serviceId || s.id)
|
||||||
|
.filter(Boolean);
|
||||||
|
reset({
|
||||||
|
name: projectdata.name,
|
||||||
|
shortName: projectdata.shortName,
|
||||||
|
clientId: projectdata.client.id,
|
||||||
|
assignedDate: projectdata.assignedDate,
|
||||||
|
address: projectdata.address,
|
||||||
|
statusId: projectdata.status.id,
|
||||||
|
contactEmail: projectdata.contactEmail,
|
||||||
|
contactPhone: projectdata.contactPhone,
|
||||||
|
contactName: projectdata.contactName,
|
||||||
|
services: activeServiceIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [projectdata]);
|
||||||
return (
|
return (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<form className="px-3 py-2" onSubmit={handleSubmit(onSubmit)}>
|
<form className="px-3 py-2" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className=" text-center">
|
<div className=" text-center">
|
||||||
<h5>Create Project</h5>
|
<h5>{serviceProjectId ? "Update Project":"Create Project"}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div className="row text-start">
|
<div className="row text-start">
|
||||||
<div className="col-12 mb-2">
|
<div className="col-12 mb-2">
|
||||||
@ -105,10 +173,13 @@ const ManageServiceProject = ({ servieceProjectId }) => {
|
|||||||
options={data?.data}
|
options={data?.data}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
name="services"
|
name="services"
|
||||||
valueKey="id"
|
|
||||||
labelKey="name"
|
labelKey="name"
|
||||||
label="Select Cient"
|
valueKey="id"
|
||||||
|
label="Select Service"
|
||||||
/>
|
/>
|
||||||
|
{errors?.services && (
|
||||||
|
<span className="danger-text">{errors.services.message}</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mb-2">
|
<div className="col-12 mb-2">
|
||||||
<Label htmlFor="name" required>
|
<Label htmlFor="name" required>
|
||||||
@ -205,16 +276,21 @@ const ManageServiceProject = ({ servieceProjectId }) => {
|
|||||||
<div className="d-flex justify-content-end gap-4">
|
<div className="d-flex justify-content-end gap-4">
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-outline-secondary"
|
className="btn btn-sm btn-outline-secondary"
|
||||||
disabled={isPending}
|
disabled={isPending || isUpdating}
|
||||||
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-sm btn-primary"
|
className="btn btn-sm btn-primary"
|
||||||
disabled={isPending}
|
disabled={isPending || isUpdating}
|
||||||
>
|
>
|
||||||
{isPending ? "Please wait..." : "Submit"}
|
{isPending || isUpdating
|
||||||
|
? "Please wait..."
|
||||||
|
: serviceProjectId
|
||||||
|
? "Update"
|
||||||
|
: "Submit"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -4,25 +4,7 @@ export const projectSchema = z.object({
|
|||||||
name: z.string().min(1, "Name is required"),
|
name: z.string().min(1, "Name is required"),
|
||||||
shortName: z.string().min(1, "Short name is required"),
|
shortName: z.string().min(1, "Short name is required"),
|
||||||
clientId: z.string().min(1, { message: "Client is required" }),
|
clientId: z.string().min(1, { message: "Client is required" }),
|
||||||
services: z
|
services:z.array(z.string()).min(1,{message:"At least one service required"}),
|
||||||
.any() // accept anything, then sanitize below
|
|
||||||
.transform((val) => {
|
|
||||||
if (!Array.isArray(val)) return [];
|
|
||||||
return val
|
|
||||||
.map((item) => {
|
|
||||||
if (typeof item === "string") {
|
|
||||||
return { serviceId: item, isActive: true };
|
|
||||||
}
|
|
||||||
if (item && typeof item === "object" && "serviceId" in item) {
|
|
||||||
return { serviceId: item.serviceId, isActive: !!item.isActive };
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
})
|
|
||||||
.refine((arr) => arr.length > 0, {
|
|
||||||
message: "At least one service is required",
|
|
||||||
}),
|
|
||||||
address: z.string().min(1, "Address is required"),
|
address: z.string().min(1, "Address is required"),
|
||||||
assignedDate: z.string().min(1, { message: "Date is required" }),
|
assignedDate: z.string().min(1, { message: "Date is required" }),
|
||||||
statusId: z.string().min(1, "Status is required"),
|
statusId: z.string().min(1, "Status is required"),
|
||||||
@ -38,12 +20,7 @@ export const defaultProjectValues = {
|
|||||||
name: "",
|
name: "",
|
||||||
shortName: "",
|
shortName: "",
|
||||||
clientId: "",
|
clientId: "",
|
||||||
services: [
|
services: [],
|
||||||
{
|
|
||||||
serviceId:null,
|
|
||||||
isActive: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
address: "",
|
address: "",
|
||||||
assignedDate: "",
|
assignedDate: "",
|
||||||
statusId: "",
|
statusId: "",
|
||||||
|
|||||||
@ -1,32 +1,39 @@
|
|||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { ServiceProjectRepository } from "../repositories/ServiceProject";
|
import { ServiceProjectRepository } from "../repositories/ServiceProject";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const useServiceProjects = (pageSize, pageNumber) => {
|
export const useServiceProjects = (pageSize, pageNumber) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["serviceProjects", pageSize, pageNumber],
|
queryKey: ["serviceProjects", pageSize, pageNumber],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await ServiceProjectRepository.GetServiceProjects(pageSize,pageNumber);
|
const response = await ServiceProjectRepository.GetServiceProjects(
|
||||||
|
pageSize,
|
||||||
|
pageNumber
|
||||||
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
export const useServiceProject = (projectId) => {
|
export const useServiceProject = (projectId) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["serviceProject", projectId],
|
queryKey: ["serviceProject", projectId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await ServiceProjectRepository.GetServiceProject(projectId);
|
const response = await ServiceProjectRepository.GetServiceProject(
|
||||||
|
projectId
|
||||||
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
})
|
enabled: !!projectId,
|
||||||
}
|
});
|
||||||
|
};
|
||||||
export const useCreateServiceProject = (onSuccessCallback) => {
|
export const useCreateServiceProject = (onSuccessCallback) => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (playload) =>
|
mutationFn: async (playload) =>
|
||||||
await ServiceProjectRepository.CreateServiceProject(playload),
|
await ServiceProjectRepository.CreateServiceProject(playload),
|
||||||
onSuccess: (data, variables) => {
|
onSuccess: (data, variables) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
|
||||||
|
if (onSuccessCallback) onSuccessCallback();
|
||||||
showToast("Project created successfully", "success");
|
showToast("Project created successfully", "success");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@ -39,3 +46,52 @@ export const useCreateServiceProject = (onSuccessCallback) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
export const useUpdateServiceProject = (onSuccessCallback) => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ id, payload }) => {
|
||||||
|
return await ServiceProjectRepository.UpdateServiceProject(id, payload);
|
||||||
|
},
|
||||||
|
onSuccess: (data, variables) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["serviceProject", variables.id],
|
||||||
|
});
|
||||||
|
if (onSuccessCallback) onSuccessCallback();
|
||||||
|
showToast("Project updated successfully", "success");
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
showToast(
|
||||||
|
error?.response?.data?.message ||
|
||||||
|
error.message ||
|
||||||
|
"Failed to update project",
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useActiveInActiveServiceProject = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async (id, status) => {
|
||||||
|
return await ServiceProjectRepository.DeleteServiceProject(id, status);
|
||||||
|
},
|
||||||
|
onSuccess: (data, variables) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
|
||||||
|
if (onSuccessCallback) onSuccessCallback();
|
||||||
|
showToast(
|
||||||
|
`Project ${updated ? "restored" : "deleted"} successfully`,
|
||||||
|
"success"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
showToast(
|
||||||
|
error?.response?.data?.message ||
|
||||||
|
error.message ||
|
||||||
|
"Failed to update project",
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useProjectContext } from "../project/ProjectPage";
|
import { useProjectContext } from "../project/ProjectPage";
|
||||||
import { useServiceProjects } from "../../hooks/useServiceProject";
|
import { useActiveInActiveServiceProject, useServiceProjects } from "../../hooks/useServiceProject";
|
||||||
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||||
import ProjectCard from "../../components/Project/ProjectCard";
|
import ProjectCard from "../../components/Project/ProjectCard";
|
||||||
import Pagination from "../../components/common/Pagination";
|
import Pagination from "../../components/common/Pagination";
|
||||||
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
|
import ManageServiceProject from "../../components/ServiceProject/ManageServiceProject";
|
||||||
|
import { SpinnerLoader } from "../../components/common/Loader";
|
||||||
|
|
||||||
const ServiceProjectDisplay = ({ listView }) => {
|
const ServiceProjectDisplay = ({ listView }) => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -18,8 +21,41 @@ const ServiceProjectDisplay = ({ listView }) => {
|
|||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const {mutate:DeleteProject,isPending} = useActiveInActiveServiceProject()
|
||||||
|
const handleActiveInactive =(projectId)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoading)
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="page-min-h d-flex justify-content-center align-items-center"
|
||||||
|
style={{ minHeight: "80vh" }}
|
||||||
|
>
|
||||||
|
<SpinnerLoader />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isError)
|
||||||
|
return (
|
||||||
|
<div className="page-min-h d-flex justify-content-center align-items-center">
|
||||||
|
<p>{error.message}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|
||||||
|
{/* <ConfirmModal
|
||||||
|
type="delete"
|
||||||
|
header="Delete Project"
|
||||||
|
message="Are you sure you want delete?"
|
||||||
|
onSubmit={handleActiveInactive}
|
||||||
|
onClose={() => setDeleteContact({ contactId: null, Open: false })}
|
||||||
|
loading={isPending}
|
||||||
|
paramData={deleteContact.contactId}
|
||||||
|
isOpen={deleteContact.Open}
|
||||||
|
/> */}
|
||||||
|
|
||||||
{listView ? (
|
{listView ? (
|
||||||
<p>List</p>
|
<p>List</p>
|
||||||
) : (
|
) : (
|
||||||
@ -27,6 +63,9 @@ const ServiceProjectDisplay = ({ listView }) => {
|
|||||||
<ProjectCard project={project} isCore={false} />
|
<ProjectCard project={project} isCore={false} />
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-12 d-flex justify-content-start mt-3">
|
<div className="col-12 d-flex justify-content-start mt-3">
|
||||||
<Pagination
|
<Pagination
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
@ -34,6 +73,21 @@ const ServiceProjectDisplay = ({ listView }) => {
|
|||||||
onPageChange={paginate}
|
onPageChange={paginate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{manageServiceProject?.isOpen && (
|
||||||
|
<GlobalModel
|
||||||
|
size="md"
|
||||||
|
isOpen={manageServiceProject?.isOpen}
|
||||||
|
closeModal={() =>
|
||||||
|
setManageServiceProject({ isOpen: false, project: null })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ManageServiceProject
|
||||||
|
serviceProjectId={manageServiceProject?.project}
|
||||||
|
onClose={()=>setManageServiceProject({ isOpen: false, project: null })}
|
||||||
|
/>
|
||||||
|
</GlobalModel>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -40,7 +40,7 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul li {
|
||||||
padding: 10px 10px 10px 0;
|
/* padding: 10px 10px 10px 0; */
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import { ITEMS_PER_PAGE, MANAGE_PROJECT, PROJECT_STATUS } from "../../utils/constants";
|
import {
|
||||||
|
ITEMS_PER_PAGE,
|
||||||
|
MANAGE_PROJECT,
|
||||||
|
PROJECT_STATUS,
|
||||||
|
} from "../../utils/constants";
|
||||||
import ProjectListView from "../../components/Project/ProjectListView";
|
import ProjectListView from "../../components/Project/ProjectListView";
|
||||||
import GlobalModel from "../../components/common/GlobalModel";
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
||||||
@ -36,7 +40,10 @@ const ProjectPage = () => {
|
|||||||
const [projectList, setProjectList] = useState([]);
|
const [projectList, setProjectList] = useState([]);
|
||||||
const [listView, setListView] = useState(false);
|
const [listView, setListView] = useState(false);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [coreProjects, setCoreProjects] = useState(true);
|
const [coreProjects, setCoreProjects] = useState(() => {
|
||||||
|
const storedValue = sessionStorage.getItem('whichProjectDisplay');
|
||||||
|
return storedValue === 'true';
|
||||||
|
});
|
||||||
const HasManageProject = useHasUserPermission(MANAGE_PROJECT);
|
const HasManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
|
|
||||||
const [selectedStatuses, setSelectedStatuses] = useState(
|
const [selectedStatuses, setSelectedStatuses] = useState(
|
||||||
@ -47,9 +54,16 @@ const ProjectPage = () => {
|
|||||||
setMangeProject,
|
setMangeProject,
|
||||||
setManageServiceProject,
|
setManageServiceProject,
|
||||||
manageProject,
|
manageProject,
|
||||||
manageServiceProject
|
manageServiceProject,
|
||||||
};
|
};
|
||||||
const handleToggleProject = (e) => setCoreProjects(e.target.checked);
|
|
||||||
|
|
||||||
|
const handleToggleProject = (e) => {
|
||||||
|
const checked = e.target.checked;
|
||||||
|
setCoreProjects(checked);
|
||||||
|
sessionStorage.setItem('whichProjectDisplay', String(checked));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProjectContext.Provider value={contextDispatcher}>
|
<ProjectContext.Provider value={contextDispatcher}>
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@ -80,7 +94,8 @@ const ProjectPage = () => {
|
|||||||
<div className="d-flex gap-2 mb-2">
|
<div className="d-flex gap-2 mb-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn btn-sm p-1 ${!listView ? "btn-primary" : "btn-outline-primary"
|
className={`btn btn-sm p-1 ${
|
||||||
|
!listView ? "btn-primary" : "btn-outline-primary"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setListView(false)}
|
onClick={() => setListView(false)}
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@ -91,7 +106,8 @@ const ProjectPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn btn-sm p-1 ${listView ? "btn-primary" : "btn-outline-primary"
|
className={`btn btn-sm p-1 ${
|
||||||
|
listView ? "btn-primary" : "btn-outline-primary"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setListView(true)}
|
onClick={() => setListView(true)}
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@ -146,18 +162,18 @@ const ProjectPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{HasManageProject && (
|
{HasManageProject && (
|
||||||
<div className="ms-auto">
|
<div class="btn-group">
|
||||||
|
<button type="button" className="btn btn-primary">
|
||||||
|
<i className="bx bx-plus-circle me-2"></i> New Project
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-primary"
|
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
class="btn btn-primary dropdown-toggle dropdown-toggle-split"
|
||||||
setMangeProject({ isOpen: true, Project: null })
|
data-bs-toggle="dropdown"
|
||||||
}
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus-circle me-2"></i>
|
<span class="visually-hidden">Toggle Dropdown</span>
|
||||||
<span className="d-none d-md-inline-block">
|
|
||||||
Add New Project
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li
|
<li
|
||||||
|
|||||||
@ -132,20 +132,6 @@ const ProjectsDisplay = ({ listView, searchTerm }) => {
|
|||||||
</GlobalModel>
|
</GlobalModel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Service Project */}
|
|
||||||
{manageServiceProject?.isOpen && (
|
|
||||||
<GlobalModel
|
|
||||||
size="md"
|
|
||||||
isOpen={manageServiceProject?.isOpen}
|
|
||||||
closeModal={() =>
|
|
||||||
setManageServiceProject({ isOpen: false, Project: null })
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ManageServiceProject
|
|
||||||
serviceProjectId={manageServiceProject?.Project}
|
|
||||||
/>
|
|
||||||
</GlobalModel>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,5 +6,5 @@ export const ServiceProjectRepository = {
|
|||||||
GetServiceProject: (id) => api.get(`/api/ServiceProject/details/${id}`),
|
GetServiceProject: (id) => api.get(`/api/ServiceProject/details/${id}`),
|
||||||
UpdateServiceProject: (id, data) =>
|
UpdateServiceProject: (id, data) =>
|
||||||
api.put(`/api/ServiceProject/edit/${id}`, data),
|
api.put(`/api/ServiceProject/edit/${id}`, data),
|
||||||
DeleteServiceProject: (id) => api.delete(`/api/ServiceProject/delete/{id}`),
|
DeleteServiceProject: (id,isActive=false) => api.delete(`/api/ServiceProject/delete/${id}?isActive=${isActive}`,),
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user