From 7b294233b9f0b6b40d0909a37ca28b59deb795bf Mon Sep 17 00:00:00 2001 From: asherc Date: Sun, 18 May 2025 15:48:55 +0300 Subject: [PATCH 1/4] refactor can update functions --- .../src/components/molecules/SoapSection.tsx | 4 +- .../organisms/notes-tab/NotesSections.tsx | 66 +++++++----------- .../src/vimOs/useUpdateEncounter.ts | 69 ++++++++++--------- 3 files changed, 62 insertions(+), 77 deletions(-) diff --git a/vim--ai-scribe--react/src/components/molecules/SoapSection.tsx b/vim--ai-scribe--react/src/components/molecules/SoapSection.tsx index 7244a63..2617458 100644 --- a/vim--ai-scribe--react/src/components/molecules/SoapSection.tsx +++ b/vim--ai-scribe--react/src/components/molecules/SoapSection.tsx @@ -170,7 +170,9 @@ export const SoapSection = ({ fullWidth className="py-3 w-2/3 self-center" disabled={!isWriteAvailable} - tooltip={!isWriteAvailable ? "EHR write access missing" : "" } + tooltip={ + !isWriteAvailable ? "Can't write to EHR in current state" : "" + } > Push to EHR diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx index cba51f8..b7f7790 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx @@ -13,19 +13,15 @@ interface NotePanelProps { } const useUpdateSubjective = () => { - const encounterUpdates = useUpdateEncounterSubscription<"subjective">( - { - subjective: { - generalNotes: true, - chiefComplaintNotes: true, - historyOfPresentIllnessNotes: true, - reviewOfSystemsNotes: true, - }, - }, + const encounterUpdates = useUpdateEncounterSubscription( "subjective", { - subjective: ["chiefComplaintNotes", "reviewOfSystemsNotes"], - } + generalNotes: true, + chiefComplaintNotes: true, + historyOfPresentIllnessNotes: true, + reviewOfSystemsNotes: true, + }, + ["chiefComplaintNotes", "reviewOfSystemsNotes"] ); const { updateSubscriptionField, canUpdateSubscriptionParams } = @@ -47,17 +43,13 @@ const useUpdateSubjective = () => { }; const useUpdateObjective = () => { - const encounterUpdates = useUpdateEncounterSubscription<"objective">( - { - objective: { - generalNotes: true, - physicalExamNotes: true, - }, - }, + const encounterUpdates = useUpdateEncounterSubscription( "objective", { - objective: ["generalNotes", "physicalExamNotes"], - } + generalNotes: true, + physicalExamNotes: true, + }, + ["generalNotes", "physicalExamNotes"] ); const { updateSubscriptionField, canUpdateSubscriptionParams } = @@ -79,16 +71,12 @@ const useUpdateObjective = () => { }; const useUpdateAssessment = () => { - const encounterUpdates = useUpdateEncounterSubscription<"assessment">( - { - assessment: { - generalNotes: true, - }, - }, + const encounterUpdates = useUpdateEncounterSubscription( "assessment", { - assessment: ["generalNotes"], - } + generalNotes: true, + }, + ["generalNotes"] ); const { updateSubscriptionField, canUpdateSubscriptionParams } = @@ -110,16 +98,12 @@ const useUpdateAssessment = () => { }; const useUpdatePlan = () => { - const encounterUpdates = useUpdateEncounterSubscription<"plan">( - { - plan: { - generalNotes: true, - }, - }, + const encounterUpdates = useUpdateEncounterSubscription( "plan", { - plan: ["generalNotes"], - } + generalNotes: true, + }, + ["generalNotes"] ); const { updateSubscriptionField, canUpdateSubscriptionParams } = @@ -167,9 +151,7 @@ export const NotesSections = ({ isHighlighted={isHighlighted("subjective")} isWriteAvailable={canUpdateSubjectiveNote} renderHighlightedText={renderHighlightedText} - onPushToEHR={() => { - updateSubjectiveNote(); - }} + onPushToEHR={updateSubjectiveNote} /> updateObjectiveNote()} + onPushToEHR={updateObjectiveNote} /> updateAssessmentNote()} + onPushToEHR={updateAssessmentNote} /> updatePlanNote()} + onPushToEHR={updatePlanNote} /> ); diff --git a/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts b/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts index a6ec0f8..8ef2a0a 100644 --- a/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts +++ b/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts @@ -2,51 +2,52 @@ import { useEffect, useMemo, useState } from "react"; import type { EHR } from "vim-os-js-browser/types"; import { useVimOsContext } from "@/providers/VimOSContext"; -const calcIsUpdatable = ( - sectionName: keyof EHR.UpdateEncounterParams, - priorityList: Partial>, +type SectionField = + keyof NonNullable; + +type SectionFields = Array< + SectionField +>; + +const calcIsUpdatable = ( + sectionName: T, + priorityList: SectionFields, details: EHR.CanUpdateEncounterParams -) => { - if (sectionName && priorityList) { - const section = details[sectionName] || {}; - const priorities = priorityList[sectionName] || []; - const updatableField = priorities?.find( - (fieldName) => section[fieldName as keyof typeof section] === true - ); - - return updatableField; - } +): SectionFields => { + const section = details[sectionName] || {}; + const updatableFields = priorityList.filter( + (fieldName) => section[fieldName as keyof typeof section] === true + ); + + return updatableFields; }; export const useUpdateEncounterSubscription = < T extends keyof EHR.UpdateEncounterParams >( - subscriptionParams: EHR.CanUpdateEncounterParams, sectionName: T, - priorityList: Partial> // TODO Support Actual Fieldname // Partial>> + subscriptionParams: EHR.CanUpdateEncounterParams[T], + priorityList: SectionFields ) => { const vimOS = useVimOsContext(); const [canUpdateSubscriptionParams, setCanUpdateSubscriptionParams] = useState(false); - const [subscriptionUpdatableField, setSubscriptionUpdatableField] = - useState(); + const [subscriptionUpdatableFields, setSubscriptionUpdatableFields] = + useState>(); useEffect(() => { const onUpdate = () => { - if (subscriptionParams) { - const { details } = - vimOS.ehr.resourceUpdater.canUpdateEncounter(subscriptionParams); - if (sectionName && priorityList) { - const updatableField = calcIsUpdatable( - sectionName, - priorityList, - details - ); - const canUpdate = updatableField !== undefined; - setCanUpdateSubscriptionParams(canUpdate); - setSubscriptionUpdatableField(updatableField); - } - } + const { details } = vimOS.ehr.resourceUpdater.canUpdateEncounter({ + [sectionName]: subscriptionParams, + }); + const updatableFields = calcIsUpdatable( + sectionName, + priorityList, + details + ); + const canUpdate = updatableFields.length > 0; + setCanUpdateSubscriptionParams(canUpdate); + setSubscriptionUpdatableFields(updatableFields); }; vimOS.ehr.resourceUpdater.subscribe("encounter", onUpdate); @@ -63,7 +64,7 @@ export const useUpdateEncounterSubscription = < return useMemo( () => ({ canUpdateSubscriptionParams, - subscriptionUpdatableField, + subscriptionUpdatableFields, updateSubscriptionField: (content: string) => { if (!sectionName || !canUpdateSubscriptionParams) { return; @@ -86,7 +87,7 @@ export const useUpdateEncounterSubscription = < variant: "destructive", title: "Uh oh! Something went wrong.", sectionName, - subscriptionUpdatableField, + subscriptionUpdatableFields, description: error ? JSON.stringify(error) : "An error occurred.", }); }); @@ -95,7 +96,7 @@ export const useUpdateEncounterSubscription = < [ canUpdateSubscriptionParams, sectionName, - subscriptionUpdatableField, + subscriptionUpdatableFields, vimOS.ehr.resourceUpdater, ] ); From 2f5f5173b19eda3a3091205c24848d03a8523905 Mon Sep 17 00:00:00 2001 From: asherc Date: Mon, 19 May 2025 10:12:39 +0300 Subject: [PATCH 2/4] Disable push all when some are disabled --- .../organisms/notes-tab/NotesSections.tsx | 137 ++---------------- .../organisms/notes-tab/NotesTab.tsx | 33 ++++- .../notes-tab/useSectionWriteAvailability.ts | 85 +++++++++++ .../src/vimOs/useUpdateEncounter.ts | 49 ++++--- 4 files changed, 160 insertions(+), 144 deletions(-) create mode 100644 vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx index b7f7790..6152649 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx @@ -1,141 +1,36 @@ -import { useUpdateEncounterSubscription } from "@/vimOs/useUpdateEncounter"; import { SoapSection } from "../../molecules/SoapSection"; import type { SectionTypes, TranscriptionSegment, } from "../ai-scribe-demo/transcription.mock"; -import { useNoteFormContext } from "@/providers/NoteFormContext"; interface NotePanelProps { hoveredSegment: number | null; transcriptionSegments: TranscriptionSegment[]; renderHighlightedText: (text: string) => JSX.Element; + canUpdateSubjectiveNote: boolean; + canUpdateObjectiveNote: boolean; + canUpdateAssessmentNote: boolean; + canUpdatePlanNote: boolean; + updateSubjectiveNote: () => void; + updateObjectiveNote: () => void; + updateAssessmentNote: () => void; + updatePlanNote: () => void; } -const useUpdateSubjective = () => { - const encounterUpdates = useUpdateEncounterSubscription( - "subjective", - { - generalNotes: true, - chiefComplaintNotes: true, - historyOfPresentIllnessNotes: true, - reviewOfSystemsNotes: true, - }, - ["chiefComplaintNotes", "reviewOfSystemsNotes"] - ); - - const { updateSubscriptionField, canUpdateSubscriptionParams } = - encounterUpdates; - const { watch } = useNoteFormContext(); - - const updateSubjectiveNote = () => { - if (canUpdateSubscriptionParams) { - const formValues = watch(); - - updateSubscriptionField(formValues.subjective); - } - }; - - return { - canUpdateSubjectiveNote: canUpdateSubscriptionParams, - updateSubjectiveNote, - }; -}; - -const useUpdateObjective = () => { - const encounterUpdates = useUpdateEncounterSubscription( - "objective", - { - generalNotes: true, - physicalExamNotes: true, - }, - ["generalNotes", "physicalExamNotes"] - ); - - const { updateSubscriptionField, canUpdateSubscriptionParams } = - encounterUpdates; - const { watch } = useNoteFormContext(); - - const updateObjectiveNote = () => { - if (canUpdateSubscriptionParams) { - const formValues = watch(); - - updateSubscriptionField(formValues.objective); - } - }; - - return { - canUpdateObjectiveNote: canUpdateSubscriptionParams, - updateObjectiveNote, - }; -}; - -const useUpdateAssessment = () => { - const encounterUpdates = useUpdateEncounterSubscription( - "assessment", - { - generalNotes: true, - }, - ["generalNotes"] - ); - - const { updateSubscriptionField, canUpdateSubscriptionParams } = - encounterUpdates; - const { watch } = useNoteFormContext(); - - const updateAssessmentNote = () => { - if (canUpdateSubscriptionParams) { - const formValues = watch(); - - updateSubscriptionField(formValues.assessment); - } - }; - - return { - canUpdateAssessmentNote: canUpdateSubscriptionParams, - updateAssessmentNote, - }; -}; - -const useUpdatePlan = () => { - const encounterUpdates = useUpdateEncounterSubscription( - "plan", - { - generalNotes: true, - }, - ["generalNotes"] - ); - - const { updateSubscriptionField, canUpdateSubscriptionParams } = - encounterUpdates; - const { watch } = useNoteFormContext(); - - const updatePlanNote = () => { - if (canUpdateSubscriptionParams) { - const formValues = watch(); - - updateSubscriptionField(formValues.plan); - } - }; - - return { - canUpdatePlanNote: canUpdateSubscriptionParams, - updatePlanNote, - }; -}; - export const NotesSections = ({ hoveredSegment, transcriptionSegments, renderHighlightedText, + canUpdateSubjectiveNote, + canUpdateObjectiveNote, + canUpdateAssessmentNote, + canUpdatePlanNote, + updateSubjectiveNote, + updateObjectiveNote, + updateAssessmentNote, + updatePlanNote, }: NotePanelProps) => { - const { updateSubjectiveNote, canUpdateSubjectiveNote } = - useUpdateSubjective(); - const { updateObjectiveNote, canUpdateObjectiveNote } = useUpdateObjective(); - const { updateAssessmentNote, canUpdateAssessmentNote } = - useUpdateAssessment(); - const { updatePlanNote, canUpdatePlanNote } = useUpdatePlan(); - const isHighlighted = (section: SectionTypes) => { if (hoveredSegment === null) return false; return transcriptionSegments[hoveredSegment].affectedSections.includes( diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx index 32379c5..2832582 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx @@ -5,6 +5,12 @@ import { Button } from "../../atoms/Button"; import { DebugView } from "../../templates/DebugView"; import { MOCK_TRANSCRIPTION } from "../ai-scribe-demo/transcription.mock"; import { NotesSections } from "./NotesSections"; +import { + useUpdateSubjective, + useUpdateObjective, + useUpdateAssessment, + useUpdatePlan, +} from "./useSectionWriteAvailability"; export const NotesTab = ({ patientName, @@ -21,6 +27,21 @@ export const NotesTab = ({ const { watch } = useNoteFormContext(); const currentNote = watch(); + // Use the hooks to get write availability and update functions + const { canUpdateSubjectiveNote, updateSubjectiveNote } = + useUpdateSubjective(); + const { canUpdateObjectiveNote, updateObjectiveNote } = useUpdateObjective(); + const { canUpdateAssessmentNote, updateAssessmentNote } = + useUpdateAssessment(); + const { canUpdatePlanNote, updatePlanNote } = useUpdatePlan(); + + // Only enable the button if all are true + const canPushAll = + canUpdateSubjectiveNote && + canUpdateObjectiveNote && + canUpdateAssessmentNote && + canUpdatePlanNote; + const toggleDebugMode = () => { setIsDebugMode(!isDebugMode); vimOS.hub.setDynamicAppSize(isDebugMode ? "CLASSIC" : "LARGE"); @@ -41,7 +62,9 @@ export const NotesTab = ({ > Transcription - +
Note saved automatically
@@ -59,6 +82,14 @@ export const NotesTab = ({ hoveredSegment={hoveredSegment} transcriptionSegments={MOCK_TRANSCRIPTION} renderHighlightedText={renderHighlightedText} + canUpdateSubjectiveNote={canUpdateSubjectiveNote} + canUpdateObjectiveNote={canUpdateObjectiveNote} + canUpdateAssessmentNote={canUpdateAssessmentNote} + canUpdatePlanNote={canUpdatePlanNote} + updateSubjectiveNote={updateSubjectiveNote} + updateObjectiveNote={updateObjectiveNote} + updateAssessmentNote={updateAssessmentNote} + updatePlanNote={updatePlanNote} /> )} diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts b/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts new file mode 100644 index 0000000..5f95303 --- /dev/null +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts @@ -0,0 +1,85 @@ +import { useUpdateEncounterSubscription } from "@/vimOs/useUpdateEncounter"; +import { useNoteFormContext } from "@/providers/NoteFormContext"; + +export const useUpdateSubjective = () => { + const { updateSubscriptionField, canUpdateSubscriptionParams } = + useUpdateEncounterSubscription("subjective", [ + "chiefComplaintNotes", + "reviewOfSystemsNotes", + ]); + + const { watch } = useNoteFormContext(); + + const updateSubjectiveNote = () => { + if (canUpdateSubscriptionParams) { + const formValues = watch(); + updateSubscriptionField(formValues.subjective); + } + }; + + return { + canUpdateSubjectiveNote: canUpdateSubscriptionParams, + updateSubjectiveNote, + }; +}; + +export const useUpdateObjective = () => { + const encounterUpdates = useUpdateEncounterSubscription("objective", [ + "generalNotes", + "physicalExamNotes", + ]); + + const { updateSubscriptionField, canUpdateSubscriptionParams } = + encounterUpdates; + const { watch } = useNoteFormContext(); + + const updateObjectiveNote = () => { + if (canUpdateSubscriptionParams) { + const formValues = watch(); + updateSubscriptionField(formValues.objective); + } + }; + + return { + canUpdateObjectiveNote: canUpdateSubscriptionParams, + updateObjectiveNote, + }; +}; + +export const useUpdateAssessment = () => { + const { updateSubscriptionField, canUpdateSubscriptionParams } = + useUpdateEncounterSubscription("assessment", ["generalNotes"]); + + const { watch } = useNoteFormContext(); + + const updateAssessmentNote = () => { + if (canUpdateSubscriptionParams) { + const formValues = watch(); + updateSubscriptionField(formValues.assessment); + } + }; + + return { + canUpdateAssessmentNote: canUpdateSubscriptionParams, + updateAssessmentNote, + }; +}; + +export const useUpdatePlan = () => { + const { updateSubscriptionField, canUpdateSubscriptionParams } = + useUpdateEncounterSubscription("plan", ["generalNotes"]); + + const { watch } = useNoteFormContext(); + + const updatePlanNote = () => { + if (canUpdateSubscriptionParams) { + const formValues = watch(); + updateSubscriptionField(formValues.plan); + } + }; + + return { + canUpdatePlanNote: canUpdateSubscriptionParams, + updatePlanNote, + }; +}; diff --git a/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts b/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts index 8ef2a0a..ffba750 100644 --- a/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts +++ b/vim--ai-scribe--react/src/vimOs/useUpdateEncounter.ts @@ -13,58 +13,63 @@ const calcIsUpdatable = ( sectionName: T, priorityList: SectionFields, details: EHR.CanUpdateEncounterParams -): SectionFields => { - const section = details[sectionName] || {}; - const updatableFields = priorityList.filter( - (fieldName) => section[fieldName as keyof typeof section] === true - ); +): SectionField | undefined => { + if (sectionName && priorityList) { + const section = details[sectionName]; + if (!section) { + return undefined; + } + const updatableField = priorityList.find( + (fieldName) => section[fieldName] === true + ); - return updatableFields; + return updatableField; + } }; export const useUpdateEncounterSubscription = < T extends keyof EHR.UpdateEncounterParams >( sectionName: T, - subscriptionParams: EHR.CanUpdateEncounterParams[T], priorityList: SectionFields ) => { const vimOS = useVimOsContext(); const [canUpdateSubscriptionParams, setCanUpdateSubscriptionParams] = useState(false); - const [subscriptionUpdatableFields, setSubscriptionUpdatableFields] = - useState>(); + const [subscriptionUpdatableField, setSubscriptionUpdatableField] = + useState>(); useEffect(() => { const onUpdate = () => { const { details } = vimOS.ehr.resourceUpdater.canUpdateEncounter({ - [sectionName]: subscriptionParams, + [sectionName]: priorityList.reduce( + (acc, field) => ({ + ...acc, + [field]: true, + }), + {} + ), }); - const updatableFields = calcIsUpdatable( + const updatableField = calcIsUpdatable( sectionName, priorityList, details ); - const canUpdate = updatableFields.length > 0; + const canUpdate = updatableField !== undefined; setCanUpdateSubscriptionParams(canUpdate); - setSubscriptionUpdatableFields(updatableFields); + setSubscriptionUpdatableField(updatableField); }; vimOS.ehr.resourceUpdater.subscribe("encounter", onUpdate); return () => vimOS.ehr.resourceUpdater.unsubscribe("encounter", onUpdate); - }, [ - priorityList, - sectionName, - subscriptionParams, - vimOS.ehr.resourceUpdater, - ]); + }, [priorityList, sectionName, vimOS.ehr.resourceUpdater]); // Expose flag, field to update & update function return useMemo( () => ({ canUpdateSubscriptionParams, - subscriptionUpdatableFields, + subscriptionUpdatableField, updateSubscriptionField: (content: string) => { if (!sectionName || !canUpdateSubscriptionParams) { return; @@ -87,7 +92,7 @@ export const useUpdateEncounterSubscription = < variant: "destructive", title: "Uh oh! Something went wrong.", sectionName, - subscriptionUpdatableFields, + subscriptionUpdatableField, description: error ? JSON.stringify(error) : "An error occurred.", }); }); @@ -96,7 +101,7 @@ export const useUpdateEncounterSubscription = < [ canUpdateSubscriptionParams, sectionName, - subscriptionUpdatableFields, + subscriptionUpdatableField, vimOS.ehr.resourceUpdater, ] ); From 16c46f32666611c969783a4afcf63627b505a6c2 Mon Sep 17 00:00:00 2001 From: asherc Date: Tue, 20 May 2025 08:20:14 +0300 Subject: [PATCH 3/4] Add missing props --- .../notes-tab}/DebugView.tsx | 10 ++++-- .../organisms/notes-tab/NotesTab.tsx | 36 +++++-------------- .../notes-tab/useSectionWriteAvailability.ts | 19 ++++++++++ 3 files changed, 35 insertions(+), 30 deletions(-) rename vim--ai-scribe--react/src/components/{templates => organisms/notes-tab}/DebugView.tsx (70%) diff --git a/vim--ai-scribe--react/src/components/templates/DebugView.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx similarity index 70% rename from vim--ai-scribe--react/src/components/templates/DebugView.tsx rename to vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx index f77a7e1..4fe61dd 100644 --- a/vim--ai-scribe--react/src/components/templates/DebugView.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx @@ -1,6 +1,7 @@ -import { TranscriptionPanel } from "../organisms/transcription-panel/TranscriptionPanel"; -import { NotesSections } from "../organisms/notes-tab/NotesSections"; -import type { TranscriptionSegment } from "../organisms/ai-scribe-demo/transcription.mock"; +import { TranscriptionPanel } from "../transcription-panel/TranscriptionPanel"; +import { NotesSections } from "./NotesSections"; +import type { TranscriptionSegment } from "../ai-scribe-demo/transcription.mock"; +import { useUpdateEncounter } from "./useSectionWriteAvailability"; interface DebugViewProps { transcriptionSegments: TranscriptionSegment[]; @@ -21,6 +22,8 @@ export const DebugView = ({ onHoverSegment, renderHighlightedText, }: DebugViewProps) => { + const updateEncounterState = useUpdateEncounter(); + return (
); diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx index 2832582..9bb5e9f 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx @@ -1,16 +1,11 @@ -import { useState } from "react"; import { useNoteFormContext } from "@/providers/NoteFormContext"; import { useVimOsContext } from "@/providers/VimOSContext"; +import { useState } from "react"; import { Button } from "../../atoms/Button"; -import { DebugView } from "../../templates/DebugView"; +import { DebugView } from "./DebugView"; import { MOCK_TRANSCRIPTION } from "../ai-scribe-demo/transcription.mock"; import { NotesSections } from "./NotesSections"; -import { - useUpdateSubjective, - useUpdateObjective, - useUpdateAssessment, - useUpdatePlan, -} from "./useSectionWriteAvailability"; +import { useUpdateEncounter } from "./useSectionWriteAvailability"; export const NotesTab = ({ patientName, @@ -27,20 +22,14 @@ export const NotesTab = ({ const { watch } = useNoteFormContext(); const currentNote = watch(); - // Use the hooks to get write availability and update functions - const { canUpdateSubjectiveNote, updateSubjectiveNote } = - useUpdateSubjective(); - const { canUpdateObjectiveNote, updateObjectiveNote } = useUpdateObjective(); - const { canUpdateAssessmentNote, updateAssessmentNote } = - useUpdateAssessment(); - const { canUpdatePlanNote, updatePlanNote } = useUpdatePlan(); + const updateEncounterState = useUpdateEncounter(); // Only enable the button if all are true const canPushAll = - canUpdateSubjectiveNote && - canUpdateObjectiveNote && - canUpdateAssessmentNote && - canUpdatePlanNote; + updateEncounterState.canUpdateSubjectiveNote && + updateEncounterState.canUpdateObjectiveNote && + updateEncounterState.canUpdateAssessmentNote && + updateEncounterState.canUpdatePlanNote; const toggleDebugMode = () => { setIsDebugMode(!isDebugMode); @@ -82,14 +71,7 @@ export const NotesTab = ({ hoveredSegment={hoveredSegment} transcriptionSegments={MOCK_TRANSCRIPTION} renderHighlightedText={renderHighlightedText} - canUpdateSubjectiveNote={canUpdateSubjectiveNote} - canUpdateObjectiveNote={canUpdateObjectiveNote} - canUpdateAssessmentNote={canUpdateAssessmentNote} - canUpdatePlanNote={canUpdatePlanNote} - updateSubjectiveNote={updateSubjectiveNote} - updateObjectiveNote={updateObjectiveNote} - updateAssessmentNote={updateAssessmentNote} - updatePlanNote={updatePlanNote} + {...updateEncounterState} /> )} diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts b/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts index 5f95303..87d5c05 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/useSectionWriteAvailability.ts @@ -83,3 +83,22 @@ export const useUpdatePlan = () => { updatePlanNote, }; }; + +export const useUpdateEncounter = () => { + const { canUpdateSubjectiveNote, updateSubjectiveNote } = + useUpdateSubjective(); + const { canUpdateObjectiveNote, updateObjectiveNote } = useUpdateObjective(); + const { canUpdateAssessmentNote, updateAssessmentNote } = + useUpdateAssessment(); + const { canUpdatePlanNote, updatePlanNote } = useUpdatePlan(); + return { + canUpdateSubjectiveNote, + updateSubjectiveNote, + canUpdateObjectiveNote, + updateObjectiveNote, + canUpdateAssessmentNote, + updateAssessmentNote, + canUpdatePlanNote, + updatePlanNote, + }; +}; From e021bdf12a5264a417336050ec5bcb765c26b909 Mon Sep 17 00:00:00 2001 From: asherc Date: Tue, 20 May 2025 12:00:14 +0300 Subject: [PATCH 4/4] remove prop drilling --- vim--ai-scribe--react/.gitignore | 3 +- .../organisms/notes-tab/NotesSections.tsx | 27 ++++++--------- .../organisms/notes-tab/NotesTab.tsx | 3 +- .../notes-tab => templates}/DebugView.tsx | 10 ++---- .../tsconfig.app.tsbuildinfo | 34 ------------------- .../tsconfig.node.tsbuildinfo | 6 ---- 6 files changed, 17 insertions(+), 66 deletions(-) rename vim--ai-scribe--react/src/components/{organisms/notes-tab => templates}/DebugView.tsx (70%) delete mode 100644 vim--ai-scribe--react/tsconfig.app.tsbuildinfo delete mode 100644 vim--ai-scribe--react/tsconfig.node.tsbuildinfo diff --git a/vim--ai-scribe--react/.gitignore b/vim--ai-scribe--react/.gitignore index eec62cf..bfb2014 100644 --- a/vim--ai-scribe--react/.gitignore +++ b/vim--ai-scribe--react/.gitignore @@ -25,4 +25,5 @@ functions/**/*.js *.ntvs* *.njsproj *.sln -*.sw? \ No newline at end of file +*.sw? +*.tsbuildinfo \ No newline at end of file diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx index 6152649..d25b0fd 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesSections.tsx @@ -3,34 +3,29 @@ import type { SectionTypes, TranscriptionSegment, } from "../ai-scribe-demo/transcription.mock"; +import { useUpdateEncounter } from "./useSectionWriteAvailability"; interface NotePanelProps { hoveredSegment: number | null; transcriptionSegments: TranscriptionSegment[]; renderHighlightedText: (text: string) => JSX.Element; - canUpdateSubjectiveNote: boolean; - canUpdateObjectiveNote: boolean; - canUpdateAssessmentNote: boolean; - canUpdatePlanNote: boolean; - updateSubjectiveNote: () => void; - updateObjectiveNote: () => void; - updateAssessmentNote: () => void; - updatePlanNote: () => void; } export const NotesSections = ({ hoveredSegment, transcriptionSegments, renderHighlightedText, - canUpdateSubjectiveNote, - canUpdateObjectiveNote, - canUpdateAssessmentNote, - canUpdatePlanNote, - updateSubjectiveNote, - updateObjectiveNote, - updateAssessmentNote, - updatePlanNote, }: NotePanelProps) => { + const { + canUpdateSubjectiveNote, + canUpdateObjectiveNote, + canUpdateAssessmentNote, + canUpdatePlanNote, + updateSubjectiveNote, + updateObjectiveNote, + updateAssessmentNote, + updatePlanNote, + } = useUpdateEncounter(); const isHighlighted = (section: SectionTypes) => { if (hoveredSegment === null) return false; return transcriptionSegments[hoveredSegment].affectedSections.includes( diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx index 9bb5e9f..dacef61 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx +++ b/vim--ai-scribe--react/src/components/organisms/notes-tab/NotesTab.tsx @@ -2,7 +2,7 @@ import { useNoteFormContext } from "@/providers/NoteFormContext"; import { useVimOsContext } from "@/providers/VimOSContext"; import { useState } from "react"; import { Button } from "../../atoms/Button"; -import { DebugView } from "./DebugView"; +import { DebugView } from "../../templates/DebugView"; import { MOCK_TRANSCRIPTION } from "../ai-scribe-demo/transcription.mock"; import { NotesSections } from "./NotesSections"; import { useUpdateEncounter } from "./useSectionWriteAvailability"; @@ -71,7 +71,6 @@ export const NotesTab = ({ hoveredSegment={hoveredSegment} transcriptionSegments={MOCK_TRANSCRIPTION} renderHighlightedText={renderHighlightedText} - {...updateEncounterState} /> )} diff --git a/vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx b/vim--ai-scribe--react/src/components/templates/DebugView.tsx similarity index 70% rename from vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx rename to vim--ai-scribe--react/src/components/templates/DebugView.tsx index 4fe61dd..32d5309 100644 --- a/vim--ai-scribe--react/src/components/organisms/notes-tab/DebugView.tsx +++ b/vim--ai-scribe--react/src/components/templates/DebugView.tsx @@ -1,7 +1,6 @@ -import { TranscriptionPanel } from "../transcription-panel/TranscriptionPanel"; -import { NotesSections } from "./NotesSections"; -import type { TranscriptionSegment } from "../ai-scribe-demo/transcription.mock"; -import { useUpdateEncounter } from "./useSectionWriteAvailability"; +import type { TranscriptionSegment } from "../organisms/ai-scribe-demo/transcription.mock"; +import { TranscriptionPanel } from "../organisms/transcription-panel/TranscriptionPanel"; +import { NotesSections } from "../organisms/notes-tab/NotesSections"; interface DebugViewProps { transcriptionSegments: TranscriptionSegment[]; @@ -22,8 +21,6 @@ export const DebugView = ({ onHoverSegment, renderHighlightedText, }: DebugViewProps) => { - const updateEncounterState = useUpdateEncounter(); - return (
); diff --git a/vim--ai-scribe--react/tsconfig.app.tsbuildinfo b/vim--ai-scribe--react/tsconfig.app.tsbuildinfo deleted file mode 100644 index a56b4a3..0000000 --- a/vim--ai-scribe--react/tsconfig.app.tsbuildinfo +++ /dev/null @@ -1,34 +0,0 @@ -{ - "root": [ - "./src/app.tsx", - "./src/appsettings.tsx", - "./src/main.tsx", - "./src/vite-env.d.ts", - "./src/components/ai-scribe/aiscribe.tsx", - "./src/components/ai-scribe/icdcodes.mock.ts", - "./src/components/ai-scribe/keywords.mock.tsx", - "./src/components/ai-scribe/transcription.mock.ts", - "./src/components/atoms/button.stories.tsx", - "./src/components/atoms/button.tsx", - "./src/components/atoms/iconbutton.stories.tsx", - "./src/components/atoms/iconbutton.tsx", - "./src/components/atoms/input.stories.tsx", - "./src/components/atoms/input.tsx", - "./src/components/molecules/navigationbar.stories.tsx", - "./src/components/molecules/navigationbar.tsx", - "./src/components/molecules/searchbar.stories.tsx", - "./src/components/molecules/searchbar.tsx", - "./src/components/molecules/soapsection.stories.tsx", - "./src/components/molecules/soapsection.tsx", - "./src/components/organisms/notepanel.tsx", - "./src/components/organisms/recordingpanel.tsx", - "./src/components/organisms/transcriptionpanel.tsx", - "./src/components/templates/debugview.tsx", - "./src/components/templates/mainlayout.tsx", - "./src/providers/appcontextproviders.tsx", - "./src/providers/appsettingscontextproviders.tsx", - "./src/providers/vimoscontext.tsx", - "./src/providers/vimsettingssdkcontext.tsx" - ], - "version": "5.7.3" -} diff --git a/vim--ai-scribe--react/tsconfig.node.tsbuildinfo b/vim--ai-scribe--react/tsconfig.node.tsbuildinfo deleted file mode 100644 index 39d124f..0000000 --- a/vim--ai-scribe--react/tsconfig.node.tsbuildinfo +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": [ - "./vite.config.ts" - ], - "version": "5.7.3" -}