Skip to content

Commit

Permalink
fix(users): added pagination in linked facility list (#7257)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeswibon committed Mar 4, 2024
1 parent de5d7ce commit 51530fc
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 105 deletions.
227 changes: 131 additions & 96 deletions src/Components/Users/ManageUsers.tsx
@@ -1,42 +1,45 @@
import * as Notification from "../../Utils/Notifications.js";
import dayjs from "dayjs";
import { navigate } from "raviger";
import { lazy, useState } from "react";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import ButtonV2, { Submit } from "../Common/components/ButtonV2";
import CareIcon from "../../CAREUI/icons/CareIcon";
import ConfirmHomeFacilityUpdateDialog from "./ConfirmHomeFacilityUpdateDialog";
import { useTranslation } from "react-i18next";
import CountBlock from "../../CAREUI/display/Count";
import { FacilityModel } from "../Facility/models";
import { FacilitySelect } from "../Common/FacilitySelect";
import SearchInput from "../Form/SearchInput";
import SkillsSlideOver from "./SkillsSlideOver";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import SlideOverCustom from "../../CAREUI/interactive/SlideOver";
import { USER_TYPES } from "../../Common/constants";
import UnlinkFacilityDialog from "./UnlinkFacilityDialog";
import UserDeleteDialog from "./UserDeleteDialog";
import UserDetails from "../Common/UserDetails";
import UserDetailComponent from "../Common/UserDetailsComponet.js";
import UserFilter from "./UserFilter";
import useAuthUser from "../../Common/hooks/useAuthUser.js";
import useFilters from "../../Common/hooks/useFilters";
import useWindowDimensions from "../../Common/hooks/useWindowDimensions";
import routes from "../../Redux/api.js";
import * as Notification from "../../Utils/Notifications.js";
import request from "../../Utils/request/request.js";
import useQuery from "../../Utils/request/useQuery.js";
import {
classNames,
isUserOnline,
relativeTime,
showUserDelete,
} from "../../Utils/utils";
import { navigate } from "raviger";
import useFilters from "../../Common/hooks/useFilters";
import useWindowDimensions from "../../Common/hooks/useWindowDimensions";
import { FacilitySelect } from "../Common/FacilitySelect";
import Pagination from "../Common/Pagination";
import UserDetails from "../Common/UserDetails";
import UserDetailComponent from "../Common/UserDetailsComponet.js";
import ButtonV2, { Submit } from "../Common/components/ButtonV2";
import CircularProgress from "../Common/components/CircularProgress.js";
import Page from "../Common/components/Page.js";
import dayjs from "dayjs";
import { FacilityModel } from "../Facility/models";
import TextFormField from "../Form/FormFields/TextFormField.js";
import useAuthUser from "../../Common/hooks/useAuthUser.js";
import routes from "../../Redux/api.js";
import useQuery from "../../Utils/request/useQuery.js";
import request from "../../Utils/request/request.js";
import SearchInput from "../Form/SearchInput";
import ConfirmHomeFacilityUpdateDialog from "./ConfirmHomeFacilityUpdateDialog";
import SkillsSlideOver from "./SkillsSlideOver";
import UnlinkFacilityDialog from "./UnlinkFacilityDialog";
import UserDeleteDialog from "./UserDeleteDialog";
import UserFilter from "./UserFilter";

const Loading = lazy(() => import("../Common/Loading"));

export default function ManageUsers() {
const { t } = useTranslation();
const { width } = useWindowDimensions();
const {
qParams,
Expand Down Expand Up @@ -108,7 +111,7 @@ export default function ManageUsers() {
onClick={() => navigate("/users/add")}
>
<CareIcon icon="l-plus" className="text-lg" />
<p>Add New User</p>
<p>{t("add_new_user")}</p>
</ButtonV2>
);

Expand Down Expand Up @@ -434,13 +437,13 @@ export default function ManageUsers() {
} else if (userListData?.results && userListData?.results.length === 0) {
manageUsers = (
<div>
<h5> No Users Found</h5>
<h5> {t("no_users_found")}</h5>
</div>
);
}

return (
<Page title="User Management" hideBack={true} breadcrumbs={false}>
<Page title={t("user_management")} hideBack={true} breadcrumbs={false}>
{expandSkillList && (
<SkillsSlideOver
show={expandSkillList}
Expand All @@ -452,11 +455,8 @@ export default function ManageUsers() {
open={expandFacilityList}
setOpen={setExpandFacilityList}
slideFrom="right"
title="Facilities"
title={t("facilities")}
dialogClass="md:w-[400px]"
onCloseClick={() => {
//fetchData({ aborted: false });
}}
>
<UserFacilities user={selectedUser} />
</SlideOverCustom>
Expand All @@ -468,12 +468,12 @@ export default function ManageUsers() {
setWeeklyHoursError("");
}}
slideFrom="right"
title="Average weekly working hours"
title={t("average_weekly_working_hours")}
dialogClass="md:w-[400px]"
>
<div className="px-2">
<dt className="mb-3 text-sm font-medium leading-5 text-black">
Set Average weekly working hours for {selectedUser}
{t("set_average_weekly_working_hours_for")} {selectedUser}
</dt>
<TextFormField
name="weekly_working_hours"
Expand All @@ -490,7 +490,7 @@ export default function ManageUsers() {
max={168}
/>
<div className="mt-2 text-right">
<Submit onClick={handleWorkingHourSubmit} label="Update" />
<Submit onClick={handleWorkingHourSubmit} label={t("update")} />
</div>
</div>
</SlideOverCustom>
Expand All @@ -510,7 +510,7 @@ export default function ManageUsers() {
name="username"
onChange={(e) => updateQuery({ [e.name]: e.value })}
value={qParams.username}
placeholder="Search by username"
placeholder={t("search_by_username")}
/>
</div>
<div className="flex flex-col gap-2">
Expand Down Expand Up @@ -557,9 +557,14 @@ export default function ManageUsers() {
}

function UserFacilities(props: { user: any }) {
const { t } = useTranslation();
const { user } = props;
const username = user.username;
const limit = 20;
const [isLoading, setIsLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [offset, setOffset] = useState(0);
const [totalCount, setTotalCount] = useState(0);
const [facility, setFacility] = useState<any>(null);
const [unlinkFacilityData, setUnlinkFacilityData] = useState<{
show: boolean;
Expand Down Expand Up @@ -602,8 +607,23 @@ function UserFacilities(props: { user: any }) {
refetch: refetchUserFacilities,
} = useQuery(routes.userListFacility, {
pathParams: { username },
query: {
limit,
offset,
},
onResponse: ({ res, data }) => {
if (res?.status === 200 && data) {
setTotalCount(data.count);
}
},
});

const handlePagination = (page: number, limit: number) => {
const offset = (page - 1) * limit;
setCurrentPage(page);
setOffset(offset);
};

const updateHomeFacility = async (username: string, facility: any) => {
setIsLoading(true);
const { res } = await request(routes.partialUpdateUser, {
Expand Down Expand Up @@ -678,7 +698,7 @@ function UserFacilities(props: { user: any }) {
className="mt-1 h-[45px] w-[74px] text-base"
onClick={() => addFacility(username, facility)}
>
Add
{t("add")}
</ButtonV2>
</div>
{isLoading || userFacilitiesLoading ? (
Expand All @@ -690,7 +710,9 @@ function UserFacilities(props: { user: any }) {
{/* Home Facility section */}
{user?.home_facility_object && (
<div className="mt-2" id="home-facility">
<div className="mb-2 ml-2 text-lg font-bold">Home Facility</div>
<div className="mb-2 ml-2 text-lg font-bold">
{t("home_facility")}
</div>
<div className="relative rounded p-2 transition hover:bg-gray-200 focus:bg-gray-200 md:rounded-lg">
<div className="flex items-center justify-between">
<span>{user?.home_facility_object?.name}</span>
Expand All @@ -708,7 +730,7 @@ function UserFacilities(props: { user: any }) {
>
<CareIcon className="care-l-link-broken" />
<span className="tooltip-text tooltip-left">
Clear Home Facility
{t("clear_home_facility")}
</span>
</button>
</div>
Expand All @@ -719,77 +741,90 @@ function UserFacilities(props: { user: any }) {
)}

{/* Linked Facilities section */}
{!!userFacilities?.length && (
{!!userFacilities?.results.length && (
<div className="mt-2" id="linked-facility-list">
<div className="mb-2 ml-2 text-lg font-bold">
Linked Facilities
{t("linked_facilities")}
</div>
<div className="flex flex-col">
{userFacilities.map((facility: any, i: number) => {
if (user?.home_facility_object?.id === facility.id) {
// skip if it's a home facility
return null;
}
return (
<div
id={`facility_${i}`}
key={`facility_${i}`}
className={classNames(
"relative rounded p-2 transition hover:bg-gray-200 focus:bg-gray-200 md:rounded-lg"
)}
>
<div className="flex items-center justify-between">
<span>{facility.name}</span>
<div className="flex items-center gap-2">
<button
className="tooltip text-lg hover:text-primary-500"
id="home-facility-icon"
onClick={() => {
if (user?.home_facility_object) {
// has previous home facility
setReplaceHomeFacility({
{userFacilities.results.map(
(facility: FacilityModel, i: number) => {
if (user?.home_facility_object?.id === facility.id) {
// skip if it's a home facility
return null;
}
return (
<div
id={`facility_${i}`}
key={`facility_${i}`}
className={classNames(
"relative rounded p-2 transition hover:bg-gray-200 focus:bg-gray-200 md:rounded-lg"
)}
>
<div className="flex items-center justify-between">
<span>{facility.name}</span>
<div className="flex items-center gap-2">
<button
className="tooltip text-lg hover:text-primary-500"
id="home-facility-icon"
onClick={() => {
if (user?.home_facility_object) {
// has previous home facility
setReplaceHomeFacility({
show: true,
userName: username,
previousFacility:
user?.home_facility_object,
newFacility: facility,
});
} else {
// no previous home facility
updateHomeFacility(username, facility);
}
}}
>
<CareIcon className="care-l-estate" />
<span className="tooltip-text tooltip-left">
Set as home facility
</span>
</button>
<button
id="unlink-facility-button"
className="tooltip text-lg text-red-600"
onClick={() =>
setUnlinkFacilityData({
show: true,
facility: facility,
userName: username,
previousFacility: user?.home_facility_object,
newFacility: facility,
});
} else {
// no previous home facility
updateHomeFacility(username, facility);
isHomeFacility: false,
})
}
}}
>
<CareIcon className="care-l-estate" />
<span className="tooltip-text tooltip-left">
Set as home facility
</span>
</button>
<button
id="unlink-facility-button"
className="tooltip text-lg text-red-600"
onClick={() =>
setUnlinkFacilityData({
show: true,
facility: facility,
userName: username,
isHomeFacility: false,
})
}
>
<CareIcon className="care-l-link-broken" />
<span className="tooltip-text tooltip-left">
Unlink Facility
</span>
</button>
>
<CareIcon className="care-l-link-broken" />
<span className="tooltip-text tooltip-left">
Unlink Facility
</span>
</button>
</div>
</div>
</div>
</div>
);
})}
);
}
)}
</div>
{totalCount > limit && (
<div className="mt-4 flex w-full justify-center">
<Pagination
cPage={currentPage}
defaultPerPage={limit}
data={{ totalCount }}
onChange={handlePagination}
/>
</div>
)}
</div>
)}
{!user?.home_facility_object && !userFacilities?.length && (
{!user?.home_facility_object && !userFacilities?.results.length && (
<div className="my-2 flex h-96 flex-col content-center justify-center align-middle">
<div className="w-full">
<img
Expand All @@ -799,7 +834,7 @@ function UserFacilities(props: { user: any }) {
/>
</div>
<p className="pt-4 text-center text-lg font-semibold text-primary">
No Linked Facilities
{t("no_linked_facilities")}
</p>
</div>
)}
Expand Down
13 changes: 13 additions & 0 deletions src/Locale/en/Users.json
@@ -0,0 +1,13 @@
{
"user_management": "User Management",
"facilities": "Facilities",
"add_new_user": "Add New User",
"no_users_found": "No Users Found",
"home_facility": "Home Facility",
"clear_home_facility": "Clear Home Facility",
"linked_facilities": "Linked Facilities",
"no_linked_facilities": "No Linked Facilities",
"average_weekly_working_hours": "Average weekly working hours",
"set_average_weekly_working_hours_for": "Set Average weekly working hours for",
"search_by_username": "Search by username"
}

0 comments on commit 51530fc

Please sign in to comment.