From ea24a51115363362b40062201d081299fb788165 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Wed, 22 Jan 2025 15:38:39 +0530 Subject: [PATCH 1/2] Appointment Token UI mobile fix (#10096) --- src/pages/Appointments/components/AppointmentTokenCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Appointments/components/AppointmentTokenCard.tsx b/src/pages/Appointments/components/AppointmentTokenCard.tsx index 7dc65f84c3f..eeba2a98116 100644 --- a/src/pages/Appointments/components/AppointmentTokenCard.tsx +++ b/src/pages/Appointments/components/AppointmentTokenCard.tsx @@ -23,7 +23,7 @@ const AppointmentTokenCard = ({ id, appointment, facility }: Props) => { return (
From 5a566b3468f56e4b9d820beb972c4fa36fc80d11 Mon Sep 17 00:00:00 2001 From: Aditya Jindal Date: Wed, 22 Jan 2025 15:41:20 +0530 Subject: [PATCH 2/2] Move all the Skeletons to seperate file (#9982) --- public/locale/en.json | 3 + src/components/Common/SkeletonLoading.tsx | 111 ++++++++++++++++++ .../QuestionnaireResponsesList.tsx | 20 +--- src/components/Facility/FacilityUsers.tsx | 111 ++---------------- .../PatientDetailsTab/patientUpdates.tsx | 18 +-- src/pages/Encounters/EncounterList.tsx | 41 +------ .../Encounters/tabs/EncounterNotesTab.tsx | 27 ++--- .../FacilityOrganizationIndex.tsx | 15 +-- .../FacilityOrganizationUsers.tsx | 23 ++-- .../FacilityOrganizationView.tsx | 15 +-- .../components/FacilityOrganizationLayout.tsx | 13 +- .../Organization/OrganizationFacilities.tsx | 27 +---- src/pages/Organization/OrganizationIndex.tsx | 28 ++--- .../Organization/OrganizationPatients.tsx | 31 +---- src/pages/Organization/OrganizationUsers.tsx | 17 +-- src/pages/Organization/OrganizationView.tsx | 15 +-- .../components/OrganizationLayout.tsx | 37 +----- .../components/OrganizationLayoutSkeleton.tsx | 23 ++++ 18 files changed, 210 insertions(+), 365 deletions(-) create mode 100644 src/components/Common/SkeletonLoading.tsx create mode 100644 src/pages/Organization/components/OrganizationLayoutSkeleton.tsx diff --git a/public/locale/en.json b/public/locale/en.json index 42547268ec5..4ccb09513f2 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -381,6 +381,7 @@ "all_patients": "All Patients", "allergen": "Allergen", "allergies": "Allergies", + "allergies_empty_message": "No allergies recorded", "allow_transfer": "Allow Transfer", "allowed_formats_are": "Allowed formats are {{formats}}.", "already_a_member": "Already a member?", @@ -767,6 +768,7 @@ "diagnosis__unconfirmed": "Unconfirmed", "diagnosis_already_added": "This diagnosis was already added", "diagnosis_at_discharge": "Diagnosis at Discharge", + "diagnosis_empty_message": "No diagnoses recorded", "diastolic": "Diastolic", "didnt_receive_a_message": "Didn't receive a message?", "diet_preference": "Diet Preference", @@ -2024,6 +2026,7 @@ "switch_bed": "Switch Bed", "switch_camera_is_not_available": "Switch camera is not available.", "symptoms": "Symptoms", + "symptoms_empty_message": "No symptoms recorded", "systolic": "Systolic", "tachycardia": "Tachycardia", "tag_name": "Tag Name", diff --git a/src/components/Common/SkeletonLoading.tsx b/src/components/Common/SkeletonLoading.tsx new file mode 100644 index 00000000000..9200b38095f --- /dev/null +++ b/src/components/Common/SkeletonLoading.tsx @@ -0,0 +1,111 @@ +import { Card, CardContent } from "@/components/ui/card"; +import { Skeleton } from "@/components/ui/skeleton"; + +export const TableSkeleton = ({ count }: { count: number }) => ( +
+ + {/* Header Skeleton */} + + + + + + + + + + {/* Body Skeleton */} + + {Array.from({ length: count }).map((_, i) => ( + + + + + + + + ))} + +
+ + + + + + + + + +
+
+ +
+ + +
+
+
+ + + + + + + +
+
+); + +export const CardListSkeleton = ({ count }: { count: number }) => + Array.from({ length: count }, (_, index) => ( +
+
+
+
+
+ + +
+
+
+
+ )); + +export const CardGridSkeleton = ({ count }: { count: number }) => + Array.from({ length: count }, (_, index) => ( +
+ + +
+
+ +
+
+ +
+ + +
+
+
+
+ +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+
+
+ )); diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index 3cbad3a75c6..8d701f09393 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -5,6 +5,8 @@ import PaginatedList from "@/CAREUI/misc/PaginatedList"; import { Card } from "@/components/ui/card"; +import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; + import routes from "@/Utils/request/api"; import { formatDateTime, properCase } from "@/Utils/utils"; import { Encounter } from "@/types/emr/encounter"; @@ -147,22 +149,8 @@ export default function QuestionnaireResponsesList({ encounter }: Props) { -
- {[1, 2, 3].map((i) => ( - -
-
-
-
-
-
-
-
- - ))} +
+
diff --git a/src/components/Facility/FacilityUsers.tsx b/src/components/Facility/FacilityUsers.tsx index 696e1d06b9b..f2fe0e61e12 100644 --- a/src/components/Facility/FacilityUsers.tsx +++ b/src/components/Facility/FacilityUsers.tsx @@ -5,12 +5,14 @@ import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; import { Badge } from "@/components/ui/badge"; -import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; -import { Skeleton } from "@/components/ui/skeleton"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import Page from "@/components/Common/Page"; +import { + CardGridSkeleton, + TableSkeleton, +} from "@/components/Common/SkeletonLoading"; import UserListAndCardView from "@/components/Users/UserListAndCard"; import useFilters from "@/hooks/useFilters"; @@ -18,103 +20,6 @@ import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; -const UserCardSkeleton = () => ( -
-
- {Array.from({ length: 6 }).map((_, i) => ( - - -
-
- -
-
- -
- - -
-
-
-
- -
-
- - -
-
- - -
-
- -
- -
-
-
-
- ))} -
-
-); - -const UserListSkeleton = () => ( -
- - {/* Header Skeleton */} - - - - - - - - - - {/* Body Skeleton */} - - {Array.from({ length: 7 }).map((_, i) => ( - - - - - - - - ))} - -
- - - - - - - - - -
-
- -
- - -
-
-
- - - - - - - -
-
-); - export default function FacilityUsers(props: { facilityId: string }) { const { t } = useTranslation(); const { qParams, updateQuery, Pagination } = useFilters({ @@ -141,7 +46,13 @@ export default function FacilityUsers(props: { facilityId: string }) { if (userListLoading || !userListData) { usersList = - activeTab === "card" ? : ; + activeTab === "card" ? ( +
+ +
+ ) : ( + + ); } else { usersList = (
diff --git a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx index b4a2447d841..72cc2509391 100644 --- a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx +++ b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx @@ -7,6 +7,8 @@ import PaginatedList from "@/CAREUI/misc/PaginatedList"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; +import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; + import routes from "@/Utils/request/api"; import { formatDateTime, properCase } from "@/Utils/utils"; import { QuestionnaireResponse } from "@/types/questionnaire/questionnaireResponse"; @@ -48,21 +50,7 @@ export const Updates = (props: PatientProps) => {
- {[1, 2, 3].map((i) => ( - -
-
-
-
-
-
-
-
- - ))} +
diff --git a/src/pages/Encounters/EncounterList.tsx b/src/pages/Encounters/EncounterList.tsx index b7195f4b115..59dbbadfed8 100644 --- a/src/pages/Encounters/EncounterList.tsx +++ b/src/pages/Encounters/EncounterList.tsx @@ -30,11 +30,11 @@ import { SelectValue, } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; -import { Skeleton } from "@/components/ui/skeleton"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import Page from "@/components/Common/Page"; import SearchByMultipleFields from "@/components/Common/SearchByMultipleFields"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import useFilters from "@/hooks/useFilters"; @@ -100,36 +100,6 @@ const buildQueryParams = ( return params; }; -function EncounterCardSkeleton() { - return ( - - -
- - -
- -
- -
-
- - -
-
- - -
- -
- -
-
-
-
- ); -} - function EmptyState() { return ( @@ -690,14 +660,7 @@ export function EncounterList({
{isLoading ? ( - <> - - - - - - - + ) : encounters.length === 0 ? (
diff --git a/src/pages/Encounters/tabs/EncounterNotesTab.tsx b/src/pages/Encounters/tabs/EncounterNotesTab.tsx index d10fa051d24..9a898de5ba6 100644 --- a/src/pages/Encounters/tabs/EncounterNotesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterNotesTab.tsx @@ -34,7 +34,6 @@ import { Input } from "@/components/ui/input"; import { Markdown } from "@/components/ui/markdown"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Sheet, SheetContent } from "@/components/ui/sheet"; -import { Skeleton } from "@/components/ui/skeleton"; import { Textarea } from "@/components/ui/textarea"; import { Tooltip, @@ -45,6 +44,7 @@ import { import { Avatar } from "@/components/Common/Avatar"; import Loading from "@/components/Common/Loading"; +import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; import useAuthUser from "@/hooks/useAuthUser"; @@ -69,23 +69,6 @@ const threadTemplates = [ "Lab Results Discussion", ] as const; -// Component to display loading skeleton for messages -const MessageSkeleton = () => ( -
- {[1, 2, 3].map((i) => ( -
-
-
-
- - -
-
-
- ))} -
-); - // Info tooltip component for help text const InfoTooltip = ({ content }: { content: string }) => ( @@ -568,7 +551,9 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { <> {messagesLoading ? (
- +
+ +
) : ( <> @@ -593,7 +578,9 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { )} {isFetchingNextPage && (
- +
+ +
)}
diff --git a/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx b/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx index 81a3dc4042a..9f81df9b8f0 100644 --- a/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx +++ b/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx @@ -16,6 +16,7 @@ import { import { Skeleton } from "@/components/ui/skeleton"; import Page from "@/components/Common/Page"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; @@ -41,19 +42,9 @@ export default function FacilityOrganizationIndex({ return (
- +
- {Array.from({ length: 6 }).map((_, i) => ( - - - - - - - - - - ))} +
); diff --git a/src/pages/FacilityOrganization/FacilityOrganizationUsers.tsx b/src/pages/FacilityOrganization/FacilityOrganizationUsers.tsx index f467018fe08..ba50a278d52 100644 --- a/src/pages/FacilityOrganization/FacilityOrganizationUsers.tsx +++ b/src/pages/FacilityOrganization/FacilityOrganizationUsers.tsx @@ -8,6 +8,10 @@ import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Avatar } from "@/components/Common/Avatar"; +import { + CardGridSkeleton, + CardListSkeleton, +} from "@/components/Common/SkeletonLoading"; import { UserStatusIndicator } from "@/components/Users/UserListAndCard"; import routes from "@/Utils/request/api"; @@ -49,20 +53,11 @@ export default function FacilityOrganizationUsers({ id, facilityId }: Props) { if (isLoadingUsers) { return ( -
- {Array.from({ length: 3 }).map((_, i) => ( - - -
-
-
-
-
-
-
- - - ))} +
+ +
+ +
); diff --git a/src/pages/FacilityOrganization/FacilityOrganizationView.tsx b/src/pages/FacilityOrganization/FacilityOrganizationView.tsx index c49087ef6f4..83e34e5df7a 100644 --- a/src/pages/FacilityOrganization/FacilityOrganizationView.tsx +++ b/src/pages/FacilityOrganization/FacilityOrganizationView.tsx @@ -11,6 +11,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import Pagination from "@/components/Common/Pagination"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; @@ -79,19 +80,7 @@ export default function FacilityOrganizationView({ id, facilityId }: Props) { {isLoading ? (
- {Array.from({ length: 6 }).map((_, i) => ( - - -
-
-
-
-
-
-
- - - ))} +
) : (
diff --git a/src/pages/FacilityOrganization/components/FacilityOrganizationLayout.tsx b/src/pages/FacilityOrganization/components/FacilityOrganizationLayout.tsx index f975d5e2cdd..914429d74fe 100644 --- a/src/pages/FacilityOrganization/components/FacilityOrganizationLayout.tsx +++ b/src/pages/FacilityOrganization/components/FacilityOrganizationLayout.tsx @@ -11,8 +11,10 @@ import { BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Menubar, MenubarMenu, MenubarTrigger } from "@/components/ui/menubar"; +import { Skeleton } from "@/components/ui/skeleton"; import Page from "@/components/Common/Page"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; @@ -61,7 +63,16 @@ export default function FacilityOrganizationLayout({ }); if (isLoading) { - return
Loading...
; + return ( +
+ + + +
+ +
+
+ ); } // add loading state if (!org) { diff --git a/src/pages/Organization/OrganizationFacilities.tsx b/src/pages/Organization/OrganizationFacilities.tsx index bfc2389a1d6..ff55fa2fc04 100644 --- a/src/pages/Organization/OrganizationFacilities.tsx +++ b/src/pages/Organization/OrganizationFacilities.tsx @@ -9,6 +9,7 @@ import { Card, CardContent, CardFooter } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Avatar } from "@/components/Common/Avatar"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import useFilters from "@/hooks/useFilters"; @@ -82,31 +83,7 @@ export default function OrganizationFacilities({ data-cy="facility-cards" > {isLoading ? ( - Array.from({ length: 6 }).map((_, i) => ( - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - )) + ) : facilities?.results?.length === 0 ? ( diff --git a/src/pages/Organization/OrganizationIndex.tsx b/src/pages/Organization/OrganizationIndex.tsx index 1719b70caab..3cfbb299460 100644 --- a/src/pages/Organization/OrganizationIndex.tsx +++ b/src/pages/Organization/OrganizationIndex.tsx @@ -1,5 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; +import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -12,9 +13,9 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Skeleton } from "@/components/ui/skeleton"; import Page from "@/components/Common/Page"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import query from "@/Utils/request/query"; import { @@ -29,25 +30,12 @@ export default function OrganizationIndex() { queryFn: query(organizationApi.listMine), }); + const { t } = useTranslation(); if (isLoading) { return ( - -
- {Array.from({ length: 3 }).map((_, i) => ( - - - - - - - - - - - - - - ))} + +
+
); @@ -55,7 +43,7 @@ export default function OrganizationIndex() { if (!data?.results?.length) { return ( - + @@ -80,7 +68,7 @@ export default function OrganizationIndex() { } return ( - +
{data.results.map((org: Organization) => ( diff --git a/src/pages/Organization/OrganizationPatients.tsx b/src/pages/Organization/OrganizationPatients.tsx index 1148ef144f5..98cca56915a 100644 --- a/src/pages/Organization/OrganizationPatients.tsx +++ b/src/pages/Organization/OrganizationPatients.tsx @@ -11,6 +11,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { Avatar } from "@/components/Common/Avatar"; import SearchByMultipleFields from "@/components/Common/SearchByMultipleFields"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import useFilters from "@/hooks/useFilters"; @@ -112,35 +113,7 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) {
{isLoading ? ( - Array.from({ length: 6 }).map((_, i) => ( - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - )) + ) : patients?.results?.length === 0 ? ( diff --git a/src/pages/Organization/OrganizationUsers.tsx b/src/pages/Organization/OrganizationUsers.tsx index 96a03e780d7..db9f846d8d5 100644 --- a/src/pages/Organization/OrganizationUsers.tsx +++ b/src/pages/Organization/OrganizationUsers.tsx @@ -8,6 +8,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Avatar } from "@/components/Common/Avatar"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import { UserStatusIndicator } from "@/components/Users/UserListAndCard"; import useFilters from "@/hooks/useFilters"; @@ -92,19 +93,9 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) { />
{isLoadingUsers ? ( - Array.from({ length: 3 }).map((_, i) => ( - - -
-
-
-
-
-
-
- - - )) +
+ +
) : (
{users?.results?.length === 0 ? ( diff --git a/src/pages/Organization/OrganizationView.tsx b/src/pages/Organization/OrganizationView.tsx index cedf500fe33..faea49a5993 100644 --- a/src/pages/Organization/OrganizationView.tsx +++ b/src/pages/Organization/OrganizationView.tsx @@ -11,6 +11,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import Pagination from "@/components/Common/Pagination"; +import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import query from "@/Utils/request/query"; import { Organization, getOrgLabel } from "@/types/organization/organization"; @@ -67,19 +68,7 @@ export default function OrganizationView({ id, navOrganizationId }: Props) { {isLoading ? (
- {Array.from({ length: 6 }).map((_, i) => ( - - -
-
-
-
-
-
-
- - - ))} +
) : (
diff --git a/src/pages/Organization/components/OrganizationLayout.tsx b/src/pages/Organization/components/OrganizationLayout.tsx index 0ea786aec15..e10168c8257 100644 --- a/src/pages/Organization/components/OrganizationLayout.tsx +++ b/src/pages/Organization/components/OrganizationLayout.tsx @@ -12,14 +12,13 @@ import { BreadcrumbList, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; -import { Card, CardContent } from "@/components/ui/card"; import { Menubar, MenubarMenu, MenubarTrigger } from "@/components/ui/menubar"; -import { Skeleton } from "@/components/ui/skeleton"; import Page from "@/components/Common/Page"; import query from "@/Utils/request/query"; import { usePermissions } from "@/context/PermissionContext"; +import OrganizationLayoutSkeleton from "@/pages/Organization/components/OrganizationLayoutSkeleton"; import { Organization, OrganizationParent, @@ -70,39 +69,7 @@ export default function OrganizationLayout({ }, [org, setOrganization]); if (isLoading) { - return ( -
- - -
- {[...Array(4)].map((_, index) => ( - - ))} -
- - -
- {Array.from({ length: 6 }).map((_, i) => ( - - -
-
- -
- - -
-
-
- -
-
-
-
- ))} -
-
- ); + return ; } // add loading state if (!org) { diff --git a/src/pages/Organization/components/OrganizationLayoutSkeleton.tsx b/src/pages/Organization/components/OrganizationLayoutSkeleton.tsx new file mode 100644 index 00000000000..7d9955a7367 --- /dev/null +++ b/src/pages/Organization/components/OrganizationLayoutSkeleton.tsx @@ -0,0 +1,23 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +import { + CardGridSkeleton, + CardListSkeleton, +} from "@/components/Common/SkeletonLoading"; + +export default function OrganizationLayoutSkeleton() { + return ( +
+ + +
+ +
+ + +
+ +
+
+ ); +}