Organization_Management : Organization Hierarchy #443
149
src/components/Organization/OrganizationsList.jsx
Normal file
149
src/components/Organization/OrganizationsList.jsx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useOrganizationsList } from "../../hooks/useOrganization";
|
||||||
|
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||||
|
import Avatar from "../common/Avatar";
|
||||||
|
import { useDebounce } from "../../utils/appUtils";
|
||||||
|
|
||||||
|
const OrganizationsList = ({searchText}) => {
|
||||||
|
const searchString = useDebounce(searchText,500)
|
||||||
|
const {
|
||||||
|
data = [],
|
||||||
|
isLoading,
|
||||||
|
isFetching,
|
||||||
|
isError,
|
||||||
|
error,
|
||||||
|
} = useOrganizationsList(ITEMS_PER_PAGE, 1, true,null,searchString);
|
||||||
|
|
||||||
|
const organizationsColumns = [
|
||||||
|
{
|
||||||
|
key: "name",
|
||||||
|
label: "Organization Name",
|
||||||
|
getValue: (org) => (
|
||||||
|
<div className="d-flex gap-2 py-1 ">
|
||||||
|
<i class="bx bx-buildings"></i>
|
||||||
|
<span
|
||||||
|
className="text-truncate d-inline-block "
|
||||||
|
style={{ maxWidth: "150px" }}
|
||||||
|
>
|
||||||
|
{org?.name || "N/A"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "contactPerson",
|
||||||
|
label: "Contact Person",
|
||||||
|
getValue: (org) => (
|
||||||
|
(
|
||||||
|
<div className="d-flex align-items-center ps-1">
|
||||||
|
<Avatar
|
||||||
|
size="xs"
|
||||||
|
classAvatar="m-0"
|
||||||
|
firstName={(org?.name || "").trim().split(" ")[0] || ""}
|
||||||
|
lastName={(org?.name || "").trim().split(" ")[1] || ""}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="text-truncate d-inline-block "
|
||||||
|
style={{ maxWidth: "150px" }}
|
||||||
|
>
|
||||||
|
{org?.name || "N/A"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
),
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "contactNumber",
|
||||||
|
label: "Phone Number",
|
||||||
|
getValue: (org) => org.contactNumber || "N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "email",
|
||||||
|
label: "Email",
|
||||||
|
getValue: (org) => (
|
||||||
|
<span
|
||||||
|
className="text-truncate d-inline-block"
|
||||||
|
style={{ maxWidth: "200px" }}
|
||||||
|
>
|
||||||
|
{org?.email || "N/A"}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "sprid",
|
||||||
|
label: "SPRID Id",
|
||||||
|
getValue: (org) => org.sprid || "N/A",
|
||||||
|
align: "text-center",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isFetching && !isFetching) return <div>Loading...</div>;
|
||||||
|
if (isError) return <div>{error?.message || "Something went wrong"}</div>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="card px-0 px-sm-4">
|
||||||
|
<div className="card-datatable table-responsive" id="horizontal-example">
|
||||||
|
<div className="dataTables_wrapper no-footer px-2">
|
||||||
|
<table className="table border-top dataTable text-nowrap">
|
||||||
|
<thead>
|
||||||
|
<tr className="table_header_border">
|
||||||
|
{organizationsColumns.map((col) => (
|
||||||
|
<th
|
||||||
|
key={col.key}
|
||||||
|
className="sorting d-table-cell"
|
||||||
|
aria-sort="descending"
|
||||||
|
>
|
||||||
|
<div className={`${col.align}`}>{col.label}</div>
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
<th className="sticky-action-column bg-white text-center">
|
||||||
|
Action
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{data.length > 0 ? (
|
||||||
|
data.map((org) => (
|
||||||
|
<tr key={org.id}>
|
||||||
|
{organizationsColumns.map((col) => (
|
||||||
|
<td
|
||||||
|
key={col.key}
|
||||||
|
className={`d-table-cell ${col.align ?? ""}`}
|
||||||
|
>
|
||||||
|
{col.customRender
|
||||||
|
? col.customRender(org)
|
||||||
|
: col.getValue(org)}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
<td className="sticky-action-column ">
|
||||||
|
<div className="d-flex justify-content-center gap-2 ">
|
||||||
|
<i className="bx bx-show text-primary cursor-pointer"></i>
|
||||||
|
<i className="bx bx-edit text-secondary cursor-pointer"></i>
|
||||||
|
<i className="bx bx-trash text-danger cursor-pointer"></i>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
colSpan={organizationsColumns.length + 1}
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
<p className="fw-semibold">Not Found</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OrganizationsList;
|
||||||
@ -4,7 +4,7 @@ import {
|
|||||||
openOrgModal,
|
openOrgModal,
|
||||||
closeOrgModal,
|
closeOrgModal,
|
||||||
} from "../slices/localVariablesSlice";
|
} from "../slices/localVariablesSlice";
|
||||||
import { useMutation } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import OrganizationRepository from "../repositories/OrganizationRespository";
|
import OrganizationRepository from "../repositories/OrganizationRespository";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
|
|
||||||
@ -22,11 +22,24 @@ export const useOrganizationModal = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useOrganizationsList = (pageSize, pageNumber, active, sprid, searchString="") => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["organizationList", pageSize, pageNumber, active, sprid, searchString],
|
||||||
|
queryFn: async() => {
|
||||||
|
const resp = await OrganizationRepository.getOrganizationList(pageSize, pageNumber, active, sprid, searchString);
|
||||||
|
return resp.data;
|
||||||
|
},
|
||||||
|
keepPreviousData: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useCreateOrganization = (onSuccessCallback) => {
|
export const useCreateOrganization = (onSuccessCallback) => {
|
||||||
|
const useClient = useQueryClient()
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (OrgPayload) =>
|
mutationFn: async (OrgPayload) =>
|
||||||
await OrganizationRepository.createOrganization(OrgPayload),
|
await OrganizationRepository.createOrganization(OrgPayload),
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
|
useClient.invalidateQueries({queryKey:["organizationList"]})
|
||||||
showToast("Organization created successfully", "success");
|
showToast("Organization created successfully", "success");
|
||||||
if (onSuccessCallback) onSuccessCallback();
|
if (onSuccessCallback) onSuccessCallback();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import { useOrganizationModal } from "../../hooks/useOrganization";
|
import { useOrganizationModal } from "../../hooks/useOrganization";
|
||||||
|
import OrganizationsList from "../../components/Organization/OrganizationsList";
|
||||||
|
|
||||||
const OrganizationPage = () => {
|
const OrganizationPage = () => {
|
||||||
const orgModal = useOrganizationModal()
|
const orgModal = useOrganizationModal()
|
||||||
|
const [searchText,setSearchText] = useState("")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
@ -12,10 +15,12 @@ const OrganizationPage = () => {
|
|||||||
<div className="card my-3 px-sm-2 px-0">
|
<div className="card my-3 px-sm-2 px-0">
|
||||||
<div className="card-body py-2 px-3">
|
<div className="card-body py-2 px-3">
|
||||||
<div className="row align-items-center">
|
<div className="row align-items-center">
|
||||||
<div className="col-6 ">
|
<div className="col-6 d-flex ">
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
|
value={searchText}
|
||||||
|
onChange={(e)=>setSearchText(e.target.value)}
|
||||||
className="form-control form-control-sm w-auto"
|
className="form-control form-control-sm w-auto"
|
||||||
placeholder="Search Organization"
|
placeholder="Search Organization"
|
||||||
aria-describedby="search-label"
|
aria-describedby="search-label"
|
||||||
@ -36,6 +41,8 @@ const OrganizationPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<OrganizationsList searchText={searchText}/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
import { api } from "../utils/axiosClient";
|
import { api } from "../utils/axiosClient";
|
||||||
|
|
||||||
|
const OrganizationRepository = {
|
||||||
const OrganizationRepository = {
|
createOrganization: (data) => api.post("/api/Organization/create", data),
|
||||||
createOrganization:(data)=>api.post('/api/Organization/create',data)
|
getOrganizationList: (pageSize, pageNumber, active, sprid, searchString) => {
|
||||||
}
|
return api.get(
|
||||||
|
`/api/Organization/list?pageSize=${pageSize}&pageNumber=${pageNumber}&active=${active}&${
|
||||||
|
sprid ? `sprid=${sprid}&` : ""
|
||||||
|
}searchString=${searchString}`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default OrganizationRepository;
|
export default OrganizationRepository;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user