From cef2795ed3d1f1771e052d0343820e5036bd3315 Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Mon, 3 Jun 2024 03:58:34 +0530 Subject: [PATCH 01/11] fix button widths --- src/CAREUI/interactive/FiltersSlideover.tsx | 2 +- src/Components/Common/SortDropdown.tsx | 3 ++- src/Components/Patient/ManagePatients.tsx | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CAREUI/interactive/FiltersSlideover.tsx b/src/CAREUI/interactive/FiltersSlideover.tsx index 83f92e2bd90..496f1b3e516 100644 --- a/src/CAREUI/interactive/FiltersSlideover.tsx +++ b/src/CAREUI/interactive/FiltersSlideover.tsx @@ -58,7 +58,7 @@ export const AdvancedFilterButton = ({ onClick }: { onClick: () => void }) => { diff --git a/src/Components/Common/SortDropdown.tsx b/src/Components/Common/SortDropdown.tsx index b29662de0a7..8ffd09ba269 100644 --- a/src/Components/Common/SortDropdown.tsx +++ b/src/Components/Common/SortDropdown.tsx @@ -23,8 +23,9 @@ export default function SortDropdownMenu(props: Props) { } + containerClassName="w-full md:w-auto" > {props.options.map(({ isAscending, value }) => ( { selected={qParams.ordering} onSelect={updateQuery} /> -
+
{!isExportAllowed ? ( { From 339e2a63c68f7fd4546457c49f925ee9fcc47f73 Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:33:55 +0000 Subject: [PATCH 02/11] Support retries in Scribe --- src/Components/Scribe/Scribe.tsx | 115 ++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/src/Components/Scribe/Scribe.tsx b/src/Components/Scribe/Scribe.tsx index 6e876a4762c..b5149267e24 100644 --- a/src/Components/Scribe/Scribe.tsx +++ b/src/Components/Scribe/Scribe.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { Popover } from "@headlessui/react"; import ButtonV2 from "../Common/components/ButtonV2"; import CareIcon from "../../CAREUI/icons/CareIcon"; @@ -59,7 +59,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { const [open, setOpen] = useState(false); const [_progress, setProgress] = useState(0); const [stage, setStage] = useState("start"); - const [editableTranscript, setEditableTranscript] = useState(""); + const [_editableTranscript, setEditableTranscript] = useState(""); const [errors, setErrors] = useState([]); const [isTranscribing, setIsTranscribing] = useState(false); const [formFields, setFormFields] = useState<{ @@ -70,6 +70,13 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { const [isAudioUploading, setIsAudioUploading] = useState(false); const [updatedTranscript, setUpdatedTranscript] = useState(""); const [scribeID, setScribeID] = useState(""); + const stageRef = useRef(stage); + + useEffect(() => { + if (stageRef.current === "cancelled") { + setStage("start"); + } + }, [stage]); const { isRecording, @@ -81,6 +88,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { const uploadAudioData = (response: any, audioBlob: Blob) => { return new Promise((resolve, reject) => { + if (stageRef.current === "cancelled") resolve(); const url = response.data.signed_url; const internal_name = response.data.internal_name; const f = audioBlob; @@ -109,6 +117,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { const uploadAudio = async (audioBlob: Blob, associatingId: string) => { return new Promise((resolve, reject) => { + if (stageRef.current === "cancelled") resolve({}); const category = "AUDIO"; const name = "audio.mp3"; const filename = Date.now().toString(); @@ -127,6 +136,8 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { uploadAudioData(response, audioBlob) .then(() => { if (!response?.data?.id) throw Error("Error uploading audio"); + + if (stageRef.current === "cancelled") resolve({}); markUploadComplete(response?.data.id, associatingId).then(() => { resolve(response.data); }); @@ -145,12 +156,14 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { startRecording(); setProgress(25); setStage("recording"); + stageRef.current = "recording"; }; const handleStopRecordingClick = () => { stopRecording(); setProgress(50); setStage("recording-review"); + stageRef.current = "recording-end"; }; const handleEditChange = (e: { @@ -161,6 +174,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { const waitForTranscript = async (externalId: string): Promise => { return new Promise((resolve, reject) => { + if (stageRef.current === "cancelled") resolve(""); const interval = setInterval(async () => { try { const res = await request(routes.getScribe, { @@ -191,9 +205,29 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { }); }; + const reProcessTranscript = async () => { + setErrors([]); + setEditableTranscript(updatedTranscript); + setStage("review"); + const res = await request(routes.updateScribe, { + body: { + status: "READY", + transcript: updatedTranscript, + ai_response: null, + }, + pathParams: { + external_id: scribeID, + }, + }); + if (res.error || !res.data) throw Error("Error updating scribe instance"); + setStage("review"); + await handleSubmitTranscript(res.data.external_id); + }; + const waitForFormData = async (externalId: string): Promise => { return new Promise((resolve, reject) => { const interval = setInterval(async () => { + if (stageRef.current === "cancelled") resolve(""); try { const res = await request(routes.getScribe, { pathParams: { @@ -270,12 +304,14 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { }; const handleSubmitTranscript = async (external_id: string) => { + if (stageRef.current === "cancelled") return; setProgress(75); setIsGPTProcessing(true); try { const updatedFieldsResponse = await waitForFormData(external_id); setProgress(100); const parsedFormData = JSON.parse(updatedFieldsResponse ?? "{}"); + if (stageRef.current === "cancelled") return; setFormFields(parsedFormData); onFormUpdate(parsedFormData); setStage("final-review"); @@ -286,6 +322,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { }; const startTranscription = async (scribeID: string) => { + if (stageRef.current === "cancelled") return; setIsTranscribing(true); const errors = []; try { @@ -302,6 +339,7 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { //poll for transcript const transcriptResponse = await waitForTranscript(res.data.external_id); + if (stageRef.current === "cancelled") return; setEditableTranscript(transcriptResponse); setUpdatedTranscript(transcriptResponse); setStage("review"); @@ -329,6 +367,10 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { setFormFields({}); setEditableTranscript(""); setUpdatedTranscript(""); + setIsAudioUploading(false); + setScribeID(""); + setIsHoveringCancelRecord(false); + stageRef.current = "cancelled"; }; const processFormField = ( @@ -485,44 +527,47 @@ export const Scribe: React.FC = ({ fields, onFormUpdate }) => { src={URL.createObjectURL(blob)} /> ))} + { + handleRerecordClick(); + }} + className="w-full" + > + Restart Recording +
)} {(stage === "review" || stage === "final-review") && (
-

- Transcript -

+
+

+ Transcript +

+

+ (Edit if needed) +

+