From 430d8ec20c8da4c44c46f512c79bce0554e560b0 Mon Sep 17 00:00:00 2001
From: Ashesh3 <3626859+Ashesh3@users.noreply.github.com>
Date: Tue, 26 Dec 2023 14:47:33 +0530
Subject: [PATCH 1/6] Add edit option for doctor notes
---
.../ConsultationDoctorNotes/index.tsx | 4 +-
src/Components/Facility/DoctorNote.tsx | 10 +-
.../Facility/PatientConsultationNotesList.tsx | 8 +-
src/Components/Facility/PatientNoteCard.tsx | 218 +++++++++++++++---
src/Components/Facility/PatientNotesList.tsx | 4 +-
.../Facility/PatientNotesSlideover.tsx | 9 +-
src/Components/Facility/models.tsx | 11 +
.../Form/FormFields/TextFormField.tsx | 2 +
src/Redux/api.tsx | 5 +
src/Utils/utils.ts | 4 +-
10 files changed, 236 insertions(+), 39 deletions(-)
diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
index dd96ef9af1e..3853dc5decc 100644
--- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx
+++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
@@ -31,6 +31,8 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
notes: [],
cPage: 1,
totalPages: 1,
+ facilityId: facilityId,
+ patientId: patientId,
};
const [state, setState] = useState(initialData);
@@ -98,8 +100,6 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
diff --git a/src/Components/Facility/DoctorNote.tsx b/src/Components/Facility/DoctorNote.tsx
index 85703a1e3d8..5777f9e3fb1 100644
--- a/src/Components/Facility/DoctorNote.tsx
+++ b/src/Components/Facility/DoctorNote.tsx
@@ -5,11 +5,12 @@ import { PatientNoteStateType } from "./models";
interface DoctorNoteProps {
state: PatientNoteStateType;
+ setReload: any;
handleNext: () => void;
}
const DoctorNote = (props: DoctorNoteProps) => {
- const { state, handleNext } = props;
+ const { state, handleNext, setReload } = props;
return (
{
scrollableTarget="patient-notes-list"
>
{state.notes.map((note: any) => (
-
+
))}
) : (
diff --git a/src/Components/Facility/PatientConsultationNotesList.tsx b/src/Components/Facility/PatientConsultationNotesList.tsx
index f38de51110b..86aa99abc3d 100644
--- a/src/Components/Facility/PatientConsultationNotesList.tsx
+++ b/src/Components/Facility/PatientConsultationNotesList.tsx
@@ -10,8 +10,6 @@ import request from "../../Utils/request/request";
interface PatientNotesProps {
state: PatientNoteStateType;
setState: any;
- patientId: string;
- facilityId: string;
reload?: boolean;
setReload?: any;
}
@@ -28,7 +26,7 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
setIsLoading(true);
const { data }: any = await request(routes.getPatientNotes, {
pathParams: {
- patientId: props.patientId,
+ patientId: props.state.patientId,
},
query: {
consultation: consultationId,
@@ -81,7 +79,9 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
);
}
- return
;
+ return (
+
+ );
};
export default PatientConsultationNotesList;
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 2f07702504a..88c64914321 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -1,36 +1,202 @@
import { relativeDate, formatDateTime, classNames } from "../../Utils/utils";
import { USER_TYPES_MAP } from "../../Common/constants";
-import { PatientNotesModel } from "./models";
+import { PatientNoteStateType, PatientNotesModel } from "./models";
+import ButtonV2 from "../Common/components/ButtonV2";
+import CareIcon from "../../CAREUI/icons/CareIcon";
+import { useState } from "react";
+import { Error, Success } from "../../Utils/Notifications";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import DialogModal from "../Common/Dialog";
+import { t } from "i18next";
+
+const PatientNoteCard = ({
+ state,
+ note,
+ setReload,
+}: {
+ state: PatientNoteStateType;
+ note: PatientNotesModel;
+ setReload: any;
+}) => {
+ const [isEditing, setIsEditing] = useState(false);
+ const [noteField, setNoteField] = useState(note.note);
+ const [showEditHistory, setShowEditHistory] = useState(false);
+
+ const onUpdateNote = async () => {
+ if (noteField === note.note) {
+ setIsEditing(false);
+ return;
+ }
+ const payload = {
+ note: noteField,
+ };
+ if (!/\S+/.test(noteField)) {
+ Error({
+ msg: "Note Should Contain At Least 1 Character",
+ });
+ return;
+ }
+
+ const { res } = await request(routes.updatePatientNote, {
+ pathParams: { patientId: state.patientId, noteId: note.id },
+ body: payload,
+ });
+ if (res?.status === 200) {
+ Success({ msg: "Note updated successfully" });
+ setIsEditing(false);
+ setReload(true);
+ }
+ };
-const PatientNoteCard = ({ note }: { note: PatientNotesModel }) => {
return (
-
-
-
- {note.created_by_object?.first_name || "Unknown"}{" "}
- {note.created_by_object?.last_name}
-
- {note.user_type && (
-
- {`(${USER_TYPES_MAP[note.user_type]})`}
-
+ <>
+ {" "}
+
-
{note.note}
-
-
-
- {formatDateTime(note.created_date)}
-
- {relativeDate(note.created_date)}
+ >
+
+
+
+
+ {note.created_by_object?.first_name || "Unknown"}{" "}
+ {note.created_by_object?.last_name}
+
+ {note.user_type && (
+
+ {`(${USER_TYPES_MAP[note.user_type]})`}
+
+ )}
+
+
+
+
+ {formatDateTime(note.created_date)}
+
+ Created {relativeDate(note.created_date, true)}
+
+
+ {note.edits.length > 1 && (
+
+
{
+ setShowEditHistory(true);
+ }}
+ >
+
+
+ {formatDateTime(note.edits[0].edited_on)}
+
+ Edited {relativeDate(note.edits[0].edited_on, true)}
+
+
+
+
+ )}
+
+
+
{
+ if (!isEditing) setIsEditing(true);
+ }}
+ >
+ {isEditing ? (
+
+ ) : (
+
+ )}
+
+ {
+
+ {isEditing ? (
+
+ ) : (
+
{noteField}
+ )}
+
+ }
-
+ {showEditHistory && (
+
setShowEditHistory(false)}
+ title={t("edit_history")}
+ >
+
+
+
+ Edit History for note
+ {note.id}
+
+
+
+ {note.edits.map((edit, index) => {
+ const isLast = index === note.edits.length - 1;
+ return (
+
+
+
+
+ {isLast ? "Created" : "Edited"} On
+
+
+ {formatDateTime(edit.edited_on)}
+
+
+
+
+ {isLast ? "Created" : "Edited"} By
+
+
+ {edit.edited_by.username}
+
+
+
+
+
+ );
+ })}
+
+
+ {
+ setShowEditHistory(false);
+ }}
+ >
+ {t("close")}
+
+
+
+
+ )}
+ >
);
};
diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 96f9dcad871..a36762072b9 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -74,7 +74,9 @@ const PatientNotesList = (props: PatientNotesProps) => {
);
}
- return
;
+ return (
+
+ );
};
export default PatientNotesList;
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 8b08d9767db..9b2674ec84a 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -29,6 +29,8 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
notes: [],
cPage: 1,
totalPages: 1,
+ patientId: props.patientId,
+ facilityId: props.facilityId,
};
const [state, setState] = useState(initialData);
@@ -141,8 +143,6 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
@@ -157,6 +157,11 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
errorClassName="hidden"
placeholder="Type your Note"
disabled={!patientActive}
+ onKeyDown={(e) => {
+ if (e.key === "Enter") {
+ onAddNote();
+ }
+ }}
/>
& {
leadingPadding?: string | undefined;
min?: string | number;
max?: string | number;
+ onKeyDown?: (event: React.KeyboardEvent) => void;
onFocus?: (event: React.FocusEvent) => void;
onBlur?: (event: React.FocusEvent) => void;
};
@@ -62,6 +63,7 @@ const TextFormField = forwardRef((props: TextFormFieldProps, ref) => {
onFocus={props.onFocus}
onBlur={props.onBlur}
onChange={(e) => field.handleChange(e.target.value)}
+ onKeyDown={props.onKeyDown}
/>
);
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 9634036e6c4..09c682261e5 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -624,6 +624,11 @@ const routes = {
method: "POST",
TRes: Type(),
},
+ updatePatientNote: {
+ path: "/api/v1/patient/{patientId}/notes/{noteId}/",
+ method: "PUT",
+ TRes: Type(),
+ },
sampleTestList: {
path: "/api/v1/patient/{patientId}/test_sample/",
},
diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts
index df6bd46d131..23f07fae5a0 100644
--- a/src/Utils/utils.ts
+++ b/src/Utils/utils.ts
@@ -99,9 +99,9 @@ export const formatDate = (date: DateLike, format = DATE_FORMAT) =>
export const formatTime = (date: DateLike, format = TIME_FORMAT) =>
formatDateTime(date, format);
-export const relativeDate = (date: DateLike) => {
+export const relativeDate = (date: DateLike, withoutSuffix = false) => {
const obj = dayjs(date);
- return `${obj.fromNow()} at ${obj.format(TIME_FORMAT)}`;
+ return `${obj.fromNow(withoutSuffix)} at ${obj.format(TIME_FORMAT)}`;
};
export const formatName = (user: { first_name: string; last_name: string }) => {
From 1220789bcd261b5445863fafdbfe19a8f9245e24 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Wed, 27 Dec 2023 14:17:43 +0530
Subject: [PATCH 2/6] use edited_date
---
src/Components/Facility/PatientNoteCard.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 88c64914321..02a1d7df845 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -89,9 +89,9 @@ const PatientNoteCard = ({
>
- {formatDateTime(note.edits[0].edited_on)}
+ {formatDateTime(note.edits[0].edited_date)}
- Edited {relativeDate(note.edits[0].edited_on, true)}
+ Edited {relativeDate(note.edits[0].edited_date, true)}
- {formatDateTime(edit.edited_on)}
+ {formatDateTime(edit.edited_date)}
From d80144a2c255ff252e5561c7aeba4cd512db856e Mon Sep 17 00:00:00 2001
From: Ashesh3 <3626859+Ashesh3@users.noreply.github.com>
Date: Thu, 18 Jan 2024 13:16:45 +0530
Subject: [PATCH 3/6] Update PatientNoteCard component and models
---
src/Components/Facility/PatientNoteCard.tsx | 118 ++++++++++++--------
src/Components/Facility/models.tsx | 5 +-
src/Redux/api.tsx | 6 +
3 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 02a1d7df845..8c53a5701d4 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -1,6 +1,10 @@
import { relativeDate, formatDateTime, classNames } from "../../Utils/utils";
import { USER_TYPES_MAP } from "../../Common/constants";
-import { PatientNoteStateType, PatientNotesModel } from "./models";
+import {
+ PatientNoteStateType,
+ PatientNotesEditModel,
+ PatientNotesModel,
+} from "./models";
import ButtonV2 from "../Common/components/ButtonV2";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { useState } from "react";
@@ -9,6 +13,9 @@ import request from "../../Utils/request/request";
import routes from "../../Redux/api";
import DialogModal from "../Common/Dialog";
import { t } from "i18next";
+import dayjs from "dayjs";
+import Spinner from "../Common/Spinner";
+import useAuthUser from "../../Common/hooks/useAuthUser";
const PatientNoteCard = ({
state,
@@ -22,6 +29,17 @@ const PatientNoteCard = ({
const [isEditing, setIsEditing] = useState(false);
const [noteField, setNoteField] = useState(note.note);
const [showEditHistory, setShowEditHistory] = useState(false);
+ const [editHistory, setEditHistory] = useState
([]);
+ const authUser = useAuthUser();
+
+ const fetchEditHistory = async () => {
+ const { res, data } = await request(routes.getPatientNoteEditHistory, {
+ pathParams: { patientId: state.patientId, noteId: note.id },
+ });
+ if (res?.status === 200) {
+ setEditHistory(data?.results ?? []);
+ }
+ };
const onUpdateNote = async () => {
if (noteField === note.note) {
@@ -79,46 +97,55 @@ const PatientNoteCard = ({
Created {relativeDate(note.created_date, true)}
- {note.edits.length > 1 && (
-
-
{
- setShowEditHistory(true);
- }}
- >
-
-
- {formatDateTime(note.edits[0].edited_date)}
-
- Edited {relativeDate(note.edits[0].edited_date, true)}
+ {
+ // If last edited date is same as created date, then it is not edited
+ !dayjs(note.last_edited_date).isSame(
+ note.created_date,
+ "second"
+ ) && (
+
+
{
+ fetchEditHistory();
+ setShowEditHistory(true);
+ }}
+ >
+
+
+ {formatDateTime(note.last_edited_date)}
+
+ Edited {relativeDate(note.last_edited_date, true)}
+
+
-
-
- )}
+ )
+ }
-
{
- if (!isEditing) setIsEditing(true);
- }}
- >
- {isEditing ? (
-
- ) : (
-
- )}
-
+ {note.created_by_object.id === authUser.id && (
+
{
+ if (!isEditing) setIsEditing(true);
+ }}
+ >
+ {isEditing ? (
+
+ ) : (
+
+ )}
+
+ )}
{
@@ -149,8 +176,13 @@ const PatientNoteCard = ({
- {note.edits.map((edit, index) => {
- const isLast = index === note.edits.length - 1;
+ {editHistory.length === 0 && (
+
+
+
+ )}
+ {editHistory?.map((edit, index) => {
+ const isLast = index === editHistory.length - 1;
return (
-
-
- {isLast ? "Created" : "Edited"} By
-
-
- {edit.edited_by.username}
-
-
Note
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index b774d13f525..ea33a36fa00 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -490,7 +490,7 @@ export interface BaseUserModel {
export interface PatientNotesEditModel {
id: string;
edited_by: BaseUserModel;
- edited_on: string;
+ edited_date: string;
note: string;
}
@@ -501,7 +501,8 @@ export interface PatientNotesModel {
created_by_object: BaseUserModel;
user_type?: string;
created_date: string;
- edits: PatientNotesEditModel[];
+ last_edited_by?: BaseUserModel;
+ last_edited_date?: string;
}
export interface PatientNoteStateType {
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 09c682261e5..f9a31cc4f21 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -46,6 +46,7 @@ import {
LocationModel,
StateModel,
PatientNotesModel,
+ PatientNotesEditModel,
} from "../Components/Facility/models";
import {
IDeleteExternalResult,
@@ -629,6 +630,11 @@ const routes = {
method: "PUT",
TRes: Type
(),
},
+ getPatientNoteEditHistory: {
+ path: "/api/v1/patient/{patientId}/notes/{noteId}/edits/",
+ method: "GET",
+ TRes: Type>(),
+ },
sampleTestList: {
path: "/api/v1/patient/{patientId}/test_sample/",
},
From c378683c134928138f19671c8aee5cbdfbca74a7 Mon Sep 17 00:00:00 2001
From: Ashesh3 <3626859+Ashesh3@users.noreply.github.com>
Date: Thu, 18 Jan 2024 13:35:53 +0530
Subject: [PATCH 4/6] disableEdit for inactive patient
---
src/Components/Facility/DoctorNote.tsx | 4 +++-
.../Facility/PatientConsultationNotesList.tsx | 10 ++++++++--
src/Components/Facility/PatientNoteCard.tsx | 4 +++-
src/Components/Facility/PatientNotesSlideover.tsx | 1 +
4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/src/Components/Facility/DoctorNote.tsx b/src/Components/Facility/DoctorNote.tsx
index 5777f9e3fb1..1fe28ba38d0 100644
--- a/src/Components/Facility/DoctorNote.tsx
+++ b/src/Components/Facility/DoctorNote.tsx
@@ -7,10 +7,11 @@ interface DoctorNoteProps {
state: PatientNoteStateType;
setReload: any;
handleNext: () => void;
+ disableEdit?: boolean;
}
const DoctorNote = (props: DoctorNoteProps) => {
- const { state, handleNext, setReload } = props;
+ const { state, handleNext, setReload, disableEdit } = props;
return (
{
note={note}
key={note.id}
setReload={setReload}
+ disableEdit={disableEdit}
/>
))}
diff --git a/src/Components/Facility/PatientConsultationNotesList.tsx b/src/Components/Facility/PatientConsultationNotesList.tsx
index 86aa99abc3d..2b9df8c3902 100644
--- a/src/Components/Facility/PatientConsultationNotesList.tsx
+++ b/src/Components/Facility/PatientConsultationNotesList.tsx
@@ -12,12 +12,13 @@ interface PatientNotesProps {
setState: any;
reload?: boolean;
setReload?: any;
+ disableEdit?: boolean;
}
const pageSize = RESULTS_PER_PAGE_LIMIT;
const PatientConsultationNotesList = (props: PatientNotesProps) => {
- const { state, setState, reload, setReload } = props;
+ const { state, setState, reload, setReload, disableEdit } = props;
const consultationId = useSlug("consultation") ?? "";
const [isLoading, setIsLoading] = useState(true);
@@ -80,7 +81,12 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
}
return (
-
+
);
};
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 8c53a5701d4..8f98e621573 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -21,10 +21,12 @@ const PatientNoteCard = ({
state,
note,
setReload,
+ disableEdit,
}: {
state: PatientNoteStateType;
note: PatientNotesModel;
setReload: any;
+ disableEdit?: boolean;
}) => {
const [isEditing, setIsEditing] = useState(false);
const [noteField, setNoteField] = useState(note.note);
@@ -127,7 +129,7 @@ const PatientNoteCard = ({
}
- {note.created_by_object.id === authUser.id && (
+ {!disableEdit && note.created_by_object.id === authUser.id && (
Date: Tue, 13 Feb 2024 15:20:09 +0530
Subject: [PATCH 5/6] Make editing more intuitive
---
src/Components/Facility/PatientNoteCard.tsx | 65 +++++++++++++--------
1 file changed, 41 insertions(+), 24 deletions(-)
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 8f98e621573..c97527f5070 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -129,35 +129,52 @@ const PatientNoteCard = ({
}
- {!disableEdit && note.created_by_object.id === authUser.id && (
- {
- if (!isEditing) setIsEditing(true);
- }}
- >
- {isEditing ? (
-
- ) : (
+ {!disableEdit &&
+ note.created_by_object.id === authUser.id &&
+ !isEditing && (
+ {
+ setIsEditing(true);
+ }}
+ >
- )}
-
- )}
+
+ )}
{
{isEditing ? (
-
+
+
+
+
+
+ Update Note
+
+ {
+ setIsEditing(false);
+ setNoteField(note.note);
+ }}
+ id="cancel-update-note-button"
+ >
+
+
+
+
) : (
{noteField}
)}
From 8650c240bab2bb1c6d00bc7c2ffc0a7fb1bc2c9a Mon Sep 17 00:00:00 2001
From: Ashesh3 <3626859+Ashesh3@users.noreply.github.com>
Date: Tue, 13 Feb 2024 18:10:46 +0530
Subject: [PATCH 6/6] Refactor PatientNoteCard component buttons
---
src/Components/Facility/PatientNoteCard.tsx | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index c97527f5070..671c1744acf 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -152,17 +152,9 @@ const PatientNoteCard = ({
value={noteField}
onChange={(e) => setNoteField(e.target.value)}
>
-
+
-
- Update Note
-
- {
@@ -172,6 +164,15 @@ const PatientNoteCard = ({
id="cancel-update-note-button"
>
+ Cancel
+
+
+
+ Update Note