diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0e4c9005787..8964b0c8e57 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,9 +13,9 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-label: "stale" stale-pr-label: "stale" - stale-issue-message: "Hi, @gigincg, @nihal467, @khavinshankar, @mathew-alex, @aparnacoronasafe, This issue has been automatically marked as stale because it has not had any recent activity." + stale-issue-message: "Hi, @coronasafe/care-frontend-maintainers, This issue has been automatically marked as stale because it has not had any recent activity." stale-pr-message: "Hi, This pr has been automatically marked as stale because it has not had any recent activity. It will be automatically closed if no further activity occurs for 7 more days. Thank you for your contributions." - close-pr-message: "Hi, @gigincg, @nihal467, @khavinshankar, @mathew-alex, This pr has been automatically closed because it has not had any recent activity. Thank you for your contributions. Feel free to repopen the pr." + close-pr-message: "Hi, @coronasafe/care-frontend-maintainers, This PR has been automatically closed due to inactivity. Thank you for your contributions. Feel free to re-open the PR." exempt-issue-labels: "blocked,waiting for related PR,waiting for back end,help wanted,work-in-progress,In Progress,wishlist,EPIC" exempt-pr-labels: "tested,needs testing,need Review,waiting for related PR,waiting for back end,help wanted,blocked,work-in-progress,In Progress" days-before-issue-stale: 14 diff --git a/cypress/e2e/users_spec/user_manage.cy.ts b/cypress/e2e/users_spec/user_manage.cy.ts index af3b9149b2f..0ff66fba27a 100644 --- a/cypress/e2e/users_spec/user_manage.cy.ts +++ b/cypress/e2e/users_spec/user_manage.cy.ts @@ -33,7 +33,7 @@ describe("Manage User", () => { cy.awaitUrl("/users"); }); - it("linking skills for a users and verify its reflection in profile", () => { + it("linking skills for users and verify its reflection in profile", () => { // select the district user and select one skill link and verify its profile reflection userPage.typeInSearchInput(usernameforworkinghour); userPage.checkUsernameText(usernameforworkinghour); @@ -49,7 +49,7 @@ describe("Manage User", () => { manageUserPage.navigateToProfile(); userCreationPage.verifyElementContainsText( "username-profile-details", - usernameforworkinghour + usernameforworkinghour, ); manageUserPage.assertSkillInAlreadyLinkedSkills(linkedskill); }); diff --git a/src/Components/Facility/DoctorVideoSlideover.tsx b/src/Components/Facility/DoctorVideoSlideover.tsx index 9e1e64bb610..1eadf89af46 100644 --- a/src/Components/Facility/DoctorVideoSlideover.tsx +++ b/src/Components/Facility/DoctorVideoSlideover.tsx @@ -1,22 +1,23 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import SlideOver from "../../CAREUI/interactive/SlideOver"; import { UserAssignedModel } from "../Users/models"; import { SkillObjectModel } from "../Users/models"; import CareIcon, { IconName } from "../../CAREUI/icons/CareIcon"; -import { relativeTime } from "../../Utils/utils"; +import { classNames, relativeTime } from "../../Utils/utils"; import useAuthUser from "../../Common/hooks/useAuthUser"; import { triggerGoal } from "../../Integrations/Plausible"; import { Warn } from "../../Utils/Notifications"; import Switch from "../../CAREUI/interactive/Switch"; import useQuery from "../../Utils/request/useQuery"; import routes from "../../Redux/api"; +import Loading from "../Common/Loading"; -enum FilterTypes { - ALL = "All", - DOCTOR = "Doctor", - NURSE = "Nurse", - TELEICU = "TeleICU Hub", -} +const UserGroups = { + ALL: "All", + DOCTOR: "Doctor", + NURSE: "Nurse", + TELEICU: "TeleICU Doctor", +}; const courtesyTitle = (user: UserAssignedModel) => { /* TODO: Discuss courtesy title for gender number 2 appropirately */ @@ -30,57 +31,39 @@ interface DoctorDetails { type: FilterTypes.DOCTOR | FilterTypes.NURSE | FilterTypes.TELEICU; } +type UserGroup = keyof typeof UserGroups; + +type UserAnnotatedWithGroup = UserAssignedModel & { group?: UserGroup }; + const isHomeUser = (user: UserAssignedModel, facilityId: string) => user.home_facility_object?.id === facilityId; - export default function DoctorVideoSlideover(props: { show: boolean; facilityId: string; setShow: (show: boolean) => void; }) { const { show, facilityId, setShow } = props; - const [filteredDoctors, setFilteredDoctors] = useState([]); - const [filter, setFilter] = useState(FilterTypes.ALL); + const [filter, setFilter] = useState("ALL"); - const { data: users, loading } = useQuery(routes.getFacilityUsers, { + const { data } = useQuery(routes.getFacilityUsers, { prefetch: show, pathParams: { facility_id: facilityId }, query: { limit: 50 }, }); - useEffect(() => { - const filterDoctors = (users: UserAssignedModel[]) => { - const filteredusers = users - .filter((user: UserAssignedModel) => { - return user.alt_phone_number || user.video_connect_link; - }) - .sort((a: UserAssignedModel, b: UserAssignedModel) => { - const aIsHomeUser = isHomeUser(a, facilityId); - const bIsHomeUser = isHomeUser(b, facilityId); - return aIsHomeUser === bIsHomeUser ? 0 : aIsHomeUser ? -1 : 1; - }); - const Doctors = filteredusers.filter((user: UserAssignedModel) => { - return user.user_type === "Doctor" && isHomeUser(user, facilityId); - }); - const Nurses = filteredusers.filter((user: UserAssignedModel) => { - return user.user_type === "Nurse" && isHomeUser(user, facilityId); - }); - const TeleICU = filteredusers.filter((user: UserAssignedModel) => { - return ( - (user.user_type === "Doctor" || user.user_type === "Nurse") && - !isHomeUser(user, facilityId) - ); - }); - setFilteredDoctors([ - { users: Doctors, type: FilterTypes.DOCTOR }, - { users: Nurses, type: FilterTypes.NURSE }, - { users: TeleICU, type: FilterTypes.TELEICU }, - ]); - }; - if (users?.results && !loading) { - filterDoctors(users?.results); + const getUserGroup = (user: UserAssignedModel) => { + if (isHomeUser(user, facilityId)) { + if (user.user_type === "Doctor") return "DOCTOR"; + if (user.user_type === "Nurse") return "NURSE"; } - }, [facilityId, filter, loading, users?.results]); + + if (user.user_type === "Doctor") return "TELEICU"; + }; + + const annotatedUsers: UserAnnotatedWithGroup[] | undefined = data?.results + .filter((user) => user.alt_phone_number || user.video_connect_link) + .map((user) => ({ ...user, group: getUserGroup(user) })) + .filter((user) => !!user.group) as UserAnnotatedWithGroup[]; return (
({ ...acc, [type]: type }), - {}, - ) as Record - } + tabs={UserGroups} selected={filter} onChange={(tab) => setFilter(tab)} size="md" />
- {filteredDoctors.map((doctor) => { - return ( - (filter === FilterTypes.ALL || filter === doctor.type) && ( -
-

{doctor.type}

- {doctor.users.map((user, i) => { - return ( -
-
    - -
-
- ); - })} -
- ) - ); - })} + + {!annotatedUsers ? ( + + ) : filter === "ALL" ? ( +
+ + + + + +
+ ) : ( +
+ +
+ )}
); } +const UserGroupList = (props: { + users: UserAnnotatedWithGroup[]; + group: UserGroup; + showGroupHeading?: boolean; +}) => { + const users = props.users.filter((user) => user.group === props.group); + + return ( +
+ {props.showGroupHeading && ( +
+ + {UserGroups[props.group]} + +
+
+ )} + + {!users.length && ( + + No users in this category + + )} + + {!!users.length && ( +
    + {users.map((user) => ( +
  • + +
  • + ))} +
+ )} +
+ ); +}; + type MSLaunchURI = ( uri: string, successCB?: null | (() => void), noHandlerCB?: null | (() => void), ) => void; -function UserListItem(props: { user: UserAssignedModel; facilityId: string }) { - const user = props.user; - const facilityId = props.facilityId; +function UserListItem({ user }: { user: UserAnnotatedWithGroup }) { const icon: IconName = user.user_type === "Doctor" ? "l-user-md" : "l-user-nurse"; @@ -214,17 +229,13 @@ function UserListItem(props: { user: UserAssignedModel; facilityId: string }) { } return ( -
  • @@ -239,16 +250,11 @@ function UserListItem(props: { user: UserAssignedModel; facilityId: string }) { }
  • +
    ); } diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 51baa4d1a28..35a5bbfea02 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -105,7 +105,6 @@ export const PatientManager = () => { const [diagnoses, setDiagnoses] = useState([]); const [showDialog, setShowDialog] = useState<"create" | "list-discharged">(); const [showDoctors, setShowDoctors] = useState(false); - const [showDoctorConnect, setShowDoctorConnect] = useState(false); const [phone_number, setPhoneNumber] = useState(""); const [phoneNumberError, setPhoneNumberError] = useState(""); const [emergency_phone_number, setEmergencyPhoneNumber] = useState(""); @@ -248,12 +247,6 @@ export const PatientManager = () => { qParams.diagnoses_differential, ]); - useEffect(() => { - if (params.facility) { - setShowDoctorConnect(true); - } - }, [qParams.facility]); - const date_range_fields = [ [params.created_date_before, params.created_date_after], [params.modified_date_before, params.modified_date_after], @@ -785,7 +778,7 @@ export const PatientManager = () => { }} isTab2Active={!!tabValue} /> - {showDoctorConnect && ( + {!!params.facility && ( {