Skip to content

Commit

Permalink
Merge branch 'develop' into improve-login-flow
Browse files Browse the repository at this point in the history
  • Loading branch information
rithviknishad authored Dec 13, 2023
2 parents f64151f + 9967dae commit 6d2bd16
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 27 deletions.
2 changes: 2 additions & 0 deletions cypress/e2e/facility_spec/locations.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe("Location Management Section", () => {
cy.contains("Add New Location").click();
cy.get("[name='name']").type("Test Location");
cy.get("textarea[name='description']").type("Test Description");
cy.get("#location-type").click();
cy.get("#location-type-option-ICU").click();
cy.intercept(/\/api\/v1\/facility\/[\w-]+\/asset_location\//).as(
"addLocation"
);
Expand Down
7 changes: 7 additions & 0 deletions src/Components/Assets/AssetTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import { BedModel } from "../Facility/models";
import { PerformedByModel } from "../HCX/misc";
import { PatientModel } from "../Patient/models";

export enum AssetLocationType {
OTHER = "OTHER",
WARD = "WARD",
ICU = "ICU",
}

export interface AssetLocationObject {
id: string;
name: string;
description: string;
created_date?: string;
modified_date?: string;
location_type: AssetLocationType;
middleware_address?: string;
facility: {
id: string;
Expand Down
33 changes: 33 additions & 0 deletions src/Components/Facility/AddLocationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { Submit, Cancel } from "../Common/components/ButtonV2";
import TextFormField from "../Form/FormFields/TextFormField";
import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
import Page from "../Common/components/Page";
import { SelectFormField } from "../Form/FormFields/SelectFormField";
import { AssetLocationType } from "../Assets/AssetTypes";

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

Expand All @@ -29,10 +31,12 @@ export const AddLocationForm = (props: LocationFormProps) => {
const [description, setDescription] = useState("");
const [facilityName, setFacilityName] = useState("");
const [locationName, setLocationName] = useState("");
const [locationType, setLocationType] = useState("");
const [errors, setErrors] = useState<any>({
name: "",
description: "",
middlewareAddress: "",
locationType: "",
});
const headerText = !locationId ? "Add Location" : "Update Location";
const buttonText = !locationId ? "Add Location" : "Update Location";
Expand All @@ -53,6 +57,7 @@ export const AddLocationForm = (props: LocationFormProps) => {
setName(res?.data?.name || "");
setLocationName(res?.data?.name || "");
setDescription(res?.data?.description || "");
setLocationType(res?.data?.location_type || "");
setMiddlewareAddress(res?.data?.middleware_address || "");
}
setIsLoading(false);
Expand All @@ -66,13 +71,19 @@ export const AddLocationForm = (props: LocationFormProps) => {
name: "",
description: "",
middlewareAddress: "",
locationType: "",
};

if (name.trim().length === 0) {
error.name = "Name is required";
formValid = false;
}

if (locationType.trim().length === 0) {
error.locationType = "Location Type is required";
formValid = false;
}

if (
middlewareAddress &&
middlewareAddress.match(
Expand All @@ -98,6 +109,7 @@ export const AddLocationForm = (props: LocationFormProps) => {
name,
description,
middleware_address: middlewareAddress,
location_type: locationType,
};

const res = await dispatchAction(
Expand Down Expand Up @@ -172,6 +184,27 @@ export const AddLocationForm = (props: LocationFormProps) => {
error={errors.description}
/>
</div>
<div>
<SelectFormField
id="location-type"
name="location_type"
label="Location Type"
options={[
{ title: "ICU", value: AssetLocationType.ICU },
{
title: "WARD",
value: AssetLocationType.WARD,
},
{ title: "OTHER", value: AssetLocationType.OTHER },
]}
optionLabel={({ title }) => title}
optionValue={({ value }) => value}
value={locationType}
required
onChange={({ value }) => setLocationType(value)}
error={errors.locationType}
/>
</div>
<div>
<TextFormField
name="Location Middleware Address"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => {
? formatDate(
props.consultationData.discharge_date
)
: "--/--/----"}
: "--/--/---- --:-- --"}
</span>
</div>
<div>
Expand Down Expand Up @@ -294,10 +294,10 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => {
Discharge Date {" - "}
<span className="font-semibold">
{props.consultationData.discharge_date
? formatDate(
? formatDateTime(
props.consultationData.discharge_date
)
: "--/--/----"}
: "--/--/---- --:-- --"}
</span>
</div>
<div>
Expand Down
6 changes: 4 additions & 2 deletions src/Components/Facility/ConsultationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,9 @@ export const ConsultationForm = (props: any) => {
cause_of_death: res.data?.discharge_notes || "",
death_datetime: res.data?.death_datetime || "",
death_confirmed_doctor: res.data?.death_confirmed_doctor || "",
InvestigationAdvice: res.data.investigation,
InvestigationAdvice: Array.isArray(res.data.investigation)
? res.data.investigation
: [],
diagnoses: res.data.diagnoses.sort(
(a: ConsultationDiagnosis, b: ConsultationDiagnosis) =>
ConditionVerificationStatuses.indexOf(a.verification_status) -
Expand All @@ -410,7 +412,7 @@ export const ConsultationForm = (props: any) => {
dispatch({ type: "set_form", form: { ...state.form, ...formData } });
setBed(formData.bed);

if (res.data.last_daily_round) {
if (res.data.last_daily_round && state.form.category) {
setDisabledFields((fields) => [...fields, "category"]);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/Components/Facility/FacilityCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => {
<div className="flex w-full flex-wrap justify-between gap-2 py-2">
<div className="flex flex-wrap gap-2">
<div
className={`tooltip ml-auto flex h-[38px] w-fit items-center justify-center rounded-md px-2 text-xl ${
className={`tooltip button-size-default ml-auto flex w-fit items-center justify-center rounded-md px-2 ${
facility.patient_count / facility.bed_count > 0.85
? "button-danger-border bg-red-500"
: "button-primary-border bg-primary-100"
Expand All @@ -178,7 +178,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => {
)}
/>{" "}
<dt
className={`my-1 text-sm font-semibold ${
className={`text-sm font-semibold ${
facility.patient_count / facility.bed_count > 0.85
? "text-white"
: "text-gray-700"
Expand Down
12 changes: 9 additions & 3 deletions src/Components/Facility/FacilityUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import CountBlock from "../../CAREUI/display/Count";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
import * as Notification from "../../Utils/Notifications.js";
import { classNames, isUserOnline, relativeTime } from "../../Utils/utils";
import {
classNames,
isUserOnline,
relativeTime,
showUserDelete,
} from "../../Utils/utils";
import Pagination from "../Common/Pagination";
import UserDetails from "../Common/UserDetails";
import ButtonV2 from "../Common/components/ButtonV2";
Expand All @@ -16,6 +21,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser";
import request from "../../Utils/request/request";
import routes from "../../Redux/api";
import useQuery from "../../Utils/request/useQuery";
import { UserModel } from "../Users/models";

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

Expand Down Expand Up @@ -256,7 +262,7 @@ export default function FacilityUsers(props: any) {
facilityUserData &&
facilityUserData.results &&
facilityUserData.results.length &&
(userList = facilityUserData.results.map((user: any) => {
(userList = facilityUserData.results.map((user: UserModel) => {
return (
<div
key={`usr_${user.id}`}
Expand Down Expand Up @@ -299,7 +305,7 @@ export default function FacilityUsers(props: any) {
aria-label="Online"
></i>
) : null}
{authUser.user_type === "StateAdmin" && (
{showUserDelete(authUser, user) && (
<button
type="button"
className="focus:ring-blue m-3 w-20 self-end rounded-md border border-red-500 bg-white px-3 py-2 text-center text-sm font-medium leading-4 text-red-700 transition duration-150 ease-in-out hover:text-red-500 hover:shadow focus:border-red-300 focus:outline-none active:bg-gray-50 active:text-red-800"
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Patient/ManagePatients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -589,10 +589,10 @@ export const PatientManager = () => {
)}
</div>
<div className="flex w-full flex-col gap-2 pl-2 md:block md:flex-row">
<div className="flex w-full justify-between gap-2">
<div className="font-semibold">
<div className="flex w-full items-center justify-between gap-2">
<div className="flex flex-wrap gap-2 font-semibold">
<span className="text-xl capitalize">{patient.name}</span>
<span className="ml-4 text-gray-800">
<span className="text-gray-800">
{formatAge(patient.age, patient.date_of_birth, true)}
</span>
</div>
Expand Down
20 changes: 7 additions & 13 deletions src/Components/Users/ManageUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import UnlinkFacilityDialog from "./UnlinkFacilityDialog";
import UserDeleteDialog from "./UserDeleteDialog";
import UserDetails from "../Common/UserDetails";
import UserFilter from "./UserFilter";
import { classNames, isUserOnline, relativeTime } from "../../Utils/utils";
import {
classNames,
isUserOnline,
relativeTime,
showUserDelete,
} from "../../Utils/utils";
import { navigate } from "raviger";
import useFilters from "../../Common/hooks/useFilters";
import useWindowDimensions from "../../Common/hooks/useWindowDimensions";
Expand Down Expand Up @@ -159,17 +164,6 @@ export default function ManageUsers() {
});
};

const showDelete = (user: any) => {
if (user.is_superuser) return true;

if (
USER_TYPES.indexOf(authUser.user_type) >= USER_TYPES.indexOf("StateAdmin")
)
return user.state_object?.id === authUser.state;

return false;
};

let userList: any[] = [];

userListData?.results &&
Expand Down Expand Up @@ -233,7 +227,7 @@ export default function ManageUsers() {
aria-label="Online"
></i>
) : null}
{showDelete(user) && (
{showUserDelete(authUser, user) && (
<ButtonV2
variant="danger"
ghost
Expand Down
27 changes: 26 additions & 1 deletion src/Utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { AREACODES, IN_LANDLINE_AREA_CODES } from "../Common/constants";
import { navigate } from "raviger";

Check failure on line 1 in src/Utils/utils.ts

View workflow job for this annotation

GitHub Actions / lint

'navigate' is defined but never used. Allowed unused vars must match /^_/u
import { AREACODES, IN_LANDLINE_AREA_CODES, USER_TYPES } from "../Common/constants";

Check failure on line 2 in src/Utils/utils.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·AREACODES,·IN_LANDLINE_AREA_CODES,·USER_TYPES·` with `⏎··AREACODES,⏎··IN_LANDLINE_AREA_CODES,⏎··USER_TYPES,⏎`
import phoneCodesJson from "../Common/static/countryPhoneAndFlags.json";
import dayjs from "./dayjs";
import { UserModel } from "../Components/Users/models";

interface ApacheParams {
age: number;
Expand Down Expand Up @@ -420,6 +422,29 @@ export const scrollTo = (id: string | boolean) => {
element?.scrollIntoView({ behavior: "smooth", block: "center" });
};

export const showUserDelete = (authUser: UserModel, targetUser: UserModel) => {
// Auth user should be higher in hierarchy than target user
if (
USER_TYPES.indexOf(authUser.user_type) <=
USER_TYPES.indexOf(targetUser.user_type)
)
return false;

if (
authUser.user_type === "StateAdmin" &&
targetUser.state_object?.id === authUser.state
)
return true;

if (
authUser.user_type === "DistrictAdmin" &&
targetUser.district_object?.id === authUser.district
)
return true;

return false;
};

export const invalidateFiltersCache = () => {
for (const key in localStorage) {
if (key.startsWith("filters--")) {
Expand Down

0 comments on commit 6d2bd16

Please sign in to comment.