Skip to content

Commit

Permalink
Feat: Display total no. of entities with heading in Organization (#10092
Browse files Browse the repository at this point in the history
)
  • Loading branch information
AdityaJ2305 authored Jan 29, 2025
1 parent d9689df commit 9b6dcbd
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 22 deletions.
6 changes: 4 additions & 2 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,8 @@
"enter_year_of_birth_to_verify": "Enter year of birth to verify",
"entered_in_error": "Entered in Error",
"entered_in_error_warning": "This action cannot be undone. The appointment will be marked as entered in error and removed from the system.",
"entity_count_one": "{{count}} {{entity}}",
"entity_count_other": "{{count}} {{entity}}s",
"environment": "Environment",
"error_404": "Error 404",
"error_deleting_shifting": "Error while deleting Shifting record",
Expand Down Expand Up @@ -948,6 +950,8 @@
"facility": "Facility",
"facility_added_successfully": "Facility created successfully",
"facility_consent_requests_page_title": "Patient Consent List",
"facility_count_one": "{{count}} Facility",
"facility_count_other": "{{count}} Facilities ",
"facility_district_name": "Facility/District Name",
"facility_district_pincode": "Facility/District/Pincode",
"facility_for_care_support": "Facility for Care Support",
Expand Down Expand Up @@ -2108,8 +2112,6 @@
"use_phone_number_for_emergency": "Use this phone number for emergency contact",
"user_add_error": "Error while adding User",
"user_added_successfully": "User added successfully",
"user_count_one": "{{count}} user",
"user_count_other": "{{count}} users",
"user_delete_error": "Error while deleting User",
"user_deleted_successfully": "User Deleted Successfully",
"user_deleted_successfuly": "User Deleted Successfully",
Expand Down
13 changes: 9 additions & 4 deletions src/components/Facility/FacilityUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function FacilityUsers(props: { facilityId: string }) {

let usersList: JSX.Element = <></>;

const { data: userListData, isLoading: userListLoading } = useQuery({
const { data: userListData, isFetching: userListFetching } = useQuery({
queryKey: ["facilityUsers", facilityId, qParams],
queryFn: query.debounced(routes.facility.getUsers, {
pathParams: { facility_id: facilityId },
Expand All @@ -45,7 +45,7 @@ export default function FacilityUsers(props: { facilityId: string }) {
enabled: !!facilityId,
});

if (userListLoading || !userListData) {
if (userListFetching || !userListData) {
usersList =
activeTab === "card" ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
Expand All @@ -71,10 +71,15 @@ export default function FacilityUsers(props: { facilityId: string }) {
title={t("users_management")}
componentRight={
<Badge
className="bg-purple-50 text-purple-700 ml-2 text-sm font-medium rounded-xl px-3 m-3"
className="bg-purple-50 text-purple-700 ml-2 text-sm font-medium rounded-xl px-3 m-3 w-max"
variant="outline"
>
{t("user_count", { count: userListData?.count ?? 0 })}
{userListFetching
? t("loading")
: t("entity_count", {
count: userListData?.count ?? 0,
entity: "User",
})}
</Badge>
}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Questionnaire/QuestionnaireSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function QuestionnaireSearch({
icon="l-spinner"
className="mr-2 h-4 w-4 animate-spin"
/>
Loading...
{t("loading")}
</>
) : (
<span>{t("add_questionnaire")}</span>
Expand Down
16 changes: 12 additions & 4 deletions src/pages/Organization/OrganizationFacilities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { BaseFacility } from "@/types/facility/facility";

import AddFacilitySheet from "./components/AddFacilitySheet";
import EditFacilitySheet from "./components/EditFacilitySheet";
import EntityBadge from "./components/EntityBadge";
import OrganizationLayout from "./components/OrganizationLayout";

interface Props {
Expand All @@ -35,13 +36,13 @@ export default function OrganizationFacilities({
const { qParams, Pagination, advancedFilter, resultsPerPage, updateQuery } =
useFilters({ limit: 15, cacheBlacklist: ["name"] });

const { data: facilities, isLoading } = useQuery({
const { data: facilities, isFetching } = useQuery({
queryKey: ["organizationFacilities", id, qParams],
queryFn: query.debounced(routes.facility.list, {
queryParams: {
page: qParams.page,
limit: resultsPerPage,
offset: (qParams.page - 1) * resultsPerPage,
offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
organization: id,
name: qParams.name,
...advancedFilter.filter,
Expand All @@ -58,7 +59,14 @@ export default function OrganizationFacilities({
<OrganizationLayout id={id} navOrganizationId={navOrganizationId}>
<div className="space-y-6">
<div className="flex justify-between items-center">
<h2 className="text-lg font-semibold">{t("facilities")}</h2>
<div className="mt-1 flex flex-col justify-start space-y-2 md:flex-row md:justify-between md:space-y-0">
<EntityBadge
title={t("facilities")}
count={facilities?.count}
isFetching={isFetching}
customTranslation="facility_count"
/>
</div>
<AddFacilitySheet organizationId={id} />
</div>

Expand All @@ -82,7 +90,7 @@ export default function OrganizationFacilities({
className="grid gap-4 md:grid-cols-2 lg:grid-cols-3"
data-cy="facility-cards"
>
{isLoading ? (
{isFetching ? (
<CardGridSkeleton count={6} />
) : facilities?.results?.length === 0 ? (
<Card className="col-span-full">
Expand Down
16 changes: 12 additions & 4 deletions src/pages/Organization/OrganizationPatients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Patient } from "@/types/emr/newPatient";
import { Organization } from "@/types/organization/organization";
import organizationApi from "@/types/organization/organizationApi";

import EntityBadge from "./components/EntityBadge";
import OrganizationLayout from "./components/OrganizationLayout";

interface Props {
Expand Down Expand Up @@ -70,15 +71,15 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) {
});
};

const { data: patients, isLoading } = useQuery({
const { data: patients, isFetching } = useQuery({
queryKey: ["organizationPatients", id, qParams],
queryFn: query.debounced(organizationApi.listPatients, {
pathParams: { id },
queryParams: {
...(organization?.org_type === "govt" && { organization: id }),
page: qParams.page,
limit: resultsPerPage,
offset: (qParams.page - 1) * resultsPerPage,
offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
...advancedFilter.filter,
},
}),
Expand All @@ -97,7 +98,14 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) {
>
<div className="space-y-6">
<div className="flex justify-between items-center">
<h2 className="text-lg font-semibold">{t("patients")}</h2>
<div className="mt-1 flex flex-col justify-start space-y-2 md:flex-row md:justify-between md:space-y-0">
<EntityBadge
title={t("patients")}
count={patients?.count}
isFetching={isFetching}
translationParams={{ entity: "Patient" }}
/>
</div>
</div>

<SearchByMultipleFields
Expand All @@ -112,7 +120,7 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) {
/>

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{isLoading ? (
{isFetching ? (
<CardGridSkeleton count={6} />
) : patients?.results?.length === 0 ? (
<Card className="col-span-full">
Expand Down
16 changes: 12 additions & 4 deletions src/pages/Organization/OrganizationUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import organizationApi from "@/types/organization/organizationApi";

import AddUserSheet from "./components/AddUserSheet";
import EditUserRoleSheet from "./components/EditUserRoleSheet";
import EntityBadge from "./components/EntityBadge";
import LinkUserSheet from "./components/LinkUserSheet";
import OrganizationLayout from "./components/OrganizationLayout";

Expand All @@ -36,14 +37,14 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) {
const openAddUserSheet = qParams.sheet === "add";
const openLinkUserSheet = qParams.sheet === "link";

const { data: users, isLoading: isLoadingUsers } = useQuery({
const { data: users, isFetching: isFetchingUsers } = useQuery({
queryKey: ["organizationUsers", id, qParams.search, qParams.page],
queryFn: query.debounced(organizationApi.listUsers, {
pathParams: { id },
queryParams: {
username: qParams.search,
limit: resultsPerPage,
offset: (qParams.page - 1) * resultsPerPage,
offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
},
}),
enabled: !!id,
Expand All @@ -57,7 +58,14 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) {
<OrganizationLayout id={id} navOrganizationId={navOrganizationId}>
<div className="space-y-6">
<div className="flex justify-between items-center">
<h2 className="text-lg font-semibold">{t("users")}</h2>
<div className="mt-1 flex flex-col justify-start space-y-2 md:flex-row md:justify-between md:space-y-0">
<EntityBadge
title={t("users")}
count={users?.count}
isFetching={isFetchingUsers}
translationParams={{ entity: "User" }}
/>
</div>
<div className="flex gap-2">
<AddUserSheet
open={openAddUserSheet}
Expand Down Expand Up @@ -93,7 +101,7 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) {
data-cy="search-user"
/>
</div>
{isLoadingUsers ? (
{isFetchingUsers ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<CardGridSkeleton count={6} />
</div>
Expand Down
14 changes: 11 additions & 3 deletions src/pages/Organization/OrganizationView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import query from "@/Utils/request/query";
import { Organization, getOrgLabel } from "@/types/organization/organization";
import organizationApi from "@/types/organization/organizationApi";

import EntityBadge from "./components/EntityBadge";
import OrganizationLayout from "./components/OrganizationLayout";

interface Props {
Expand All @@ -31,7 +32,7 @@ export default function OrganizationView({ id, navOrganizationId }: Props) {
const [searchQuery, setSearchQuery] = useState("");
const limit = 12; // 3x4 grid

const { data: children, isLoading } = useQuery({
const { data: children, isFetching } = useQuery({
queryKey: ["organization", id, "children", page, limit, searchQuery],
queryFn: query.debounced(organizationApi.list, {
queryParams: {
Expand All @@ -52,7 +53,14 @@ export default function OrganizationView({ id, navOrganizationId }: Props) {
<OrganizationLayout id={id} navOrganizationId={navOrganizationId}>
<div className="space-y-6">
<div className="flex flex-col justify-between items-start gap-4">
<h2 className="text-lg font-semibold">{t("organizations")}</h2>
<div className="mt-1 flex flex-col justify-start space-y-2 md:flex-row md:justify-between md:space-y-0">
<EntityBadge
title={t("organizations")}
count={children?.count}
isFetching={isFetching}
translationParams={{ entity: "Organization" }}
/>
</div>
<div className="w-72">
<Input
placeholder="Search by name..."
Expand All @@ -66,7 +74,7 @@ export default function OrganizationView({ id, navOrganizationId }: Props) {
</div>
</div>

{isLoading ? (
{isFetching ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<CardGridSkeleton count={6} />
</div>
Expand Down
41 changes: 41 additions & 0 deletions src/pages/Organization/components/EntityBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";
import { useTranslation } from "react-i18next";

import { Badge } from "@/components/ui/badge";

interface EntityBadgeProps {
title: string;
count?: number | null | undefined;
isFetching: boolean;
translationParams?: Record<string, string>;
customTranslation?: string;
}

const EntityBadge: React.FC<EntityBadgeProps> = ({
title,
count,
isFetching,
translationParams,
customTranslation,
}) => {
const { t } = useTranslation();

return (
<div className="flex items-center">
<h2 className="text-lg font-semibold">{title}</h2>
<Badge
className="bg-purple-50 text-purple-700 ml-2 text-sm font-medium rounded-xl px-3 m-3 w-max"
variant="outline"
>
{isFetching
? t("loading")
: t(customTranslation || "entity_count", {
count: count ?? 0,
...translationParams,
})}
</Badge>
</div>
);
};

export default EntityBadge;

0 comments on commit 9b6dcbd

Please sign in to comment.