diff --git a/apps/ehr/src/constants/data-test-ids.ts b/apps/ehr/src/constants/data-test-ids.ts
index 8cd7842045..3a90c12ec5 100644
--- a/apps/ehr/src/constants/data-test-ids.ts
+++ b/apps/ehr/src/constants/data-test-ids.ts
@@ -468,6 +468,8 @@ export const dataTestIds = {
procedureType: 'procedure-type',
cptCodeInput: 'cpt-code-input',
cptCode: 'cpt-code',
+ recommendedCptCode: (code: string) => `recommended-cpt-code-${code}`,
+ cptCodeQuickAddButton: (code: string) => `cpt-code-quick-add-${code}`,
diagnosis: 'diagnosis',
diagnosisItem: 'diagnosis-item',
diagnosisDeleteButton: 'diagnosis-delete-button',
diff --git a/apps/ehr/src/features/visits/in-person/components/AiSuggestion.tsx b/apps/ehr/src/features/visits/in-person/components/AiSuggestion.tsx
index 8b3e1c674b..c5d5e9d825 100644
--- a/apps/ehr/src/features/visits/in-person/components/AiSuggestion.tsx
+++ b/apps/ehr/src/features/visits/in-person/components/AiSuggestion.tsx
@@ -1,4 +1,4 @@
-import { AddCircleOutline, CheckCircle, InfoOutlined } from '@mui/icons-material';
+import { AddCircleOutline, CheckCircle } from '@mui/icons-material';
import {
Box,
Checkbox,
@@ -32,7 +32,6 @@ import {
MedicalConditionDTO,
MedicationDTO,
ObservationTextFieldDTO,
- ProcedureSuggestion,
} from 'utils';
interface SearchResult {
@@ -290,7 +289,6 @@ export interface AiSuggestionProps {
title: string;
chartData?: GetChartDataResponse | undefined;
content?: ObservationTextFieldDTO[];
- procedureSuggestions?: ProcedureSuggestion[];
loading?: boolean;
hideHeader?: boolean;
onAppendToNote?: (text: string, resourceId?: string) => void;
@@ -301,7 +299,6 @@ export default function AiSuggestion({
title,
chartData,
content,
- procedureSuggestions,
loading,
hideHeader,
onAppendToNote,
@@ -505,24 +502,6 @@ export default function AiSuggestion({
}
function SuggestionsItem(): React.ReactElement {
- if (procedureSuggestions) {
- return (
- <>
- {procedureSuggestions.map((code) => (
- <>
-
- {code.code} – {code.description}
-
-
-
-
-
-
- >
- ))}
- >
- );
- }
return (
<>
{content
diff --git a/apps/ehr/src/features/visits/in-person/pages/ProceduresNew.tsx b/apps/ehr/src/features/visits/in-person/pages/ProceduresNew.tsx
index d89096c731..8875d2f0b4 100644
--- a/apps/ehr/src/features/visits/in-person/pages/ProceduresNew.tsx
+++ b/apps/ehr/src/features/visits/in-person/pages/ProceduresNew.tsx
@@ -1,3 +1,4 @@
+import { AddCircleOutline, CheckCircle, InfoOutlined } from '@mui/icons-material';
import {
Autocomplete,
Backdrop,
@@ -14,12 +15,14 @@ import {
FormControlLabel,
FormHelperText,
FormLabel,
+ IconButton,
InputLabel,
MenuItem,
Radio,
RadioGroup,
Select,
TextField,
+ Tooltip,
Typography,
} from '@mui/material';
import { Box, Stack, useTheme } from '@mui/system';
@@ -30,7 +33,7 @@ import { keepPreviousData, useQuery, useQueryClient, UseQueryResult } from '@tan
import { ValueSet } from 'fhir/r4b';
import { DateTime } from 'luxon';
import { enqueueSnackbar } from 'notistack';
-import { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { ReactElement, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { createProcedureQuickPick, getProcedureQuickPicks, updateProcedureQuickPick } from 'src/api/api';
@@ -70,6 +73,7 @@ import {
TECHNIQUES_VALUE_SET_URL,
TIME_SPENT_VALUE_SET_URL,
} from 'utils';
+import { AiSectionContainer } from '../../shared/components/AiSection';
import { DiagnosesField } from '../../shared/components/assessment-tab/DiagnosesField';
import { PageTitle } from '../../shared/components/PageTitle';
import { QuickPicksButton } from '../../shared/components/QuickPicksButton';
@@ -80,7 +84,6 @@ import {
useRecommendBillingCodes,
} from '../../shared/stores/appointment/appointment.queries';
import { useChartData, useDeleteChartData, useSaveChartData } from '../../shared/stores/appointment/appointment.store';
-import AiSuggestion from '../components/AiSuggestion';
import { InfoAlert } from '../components/InfoAlert';
import { ROUTER_PATH } from '../routing/routesInPerson';
import {
@@ -553,6 +556,74 @@ export default function ProceduresNew(): ReactElement {
});
};
+ const existingCptCodeSet = useMemo(() => new Set(state.cptCodes?.map((cptCode) => cptCode.code)), [state.cptCodes]);
+
+ const addRecommendedCptCode = (suggestion: ProcedureSuggestion): void =>
+ updateState((state) => {
+ if (!state.cptCodes?.some((cptCode) => cptCode.code === suggestion.code)) {
+ state.cptCodes = [...(state.cptCodes ?? []), { code: suggestion.code, display: suggestion.description }];
+ }
+ });
+
+ const renderRecommendedCptActions = (value: ProcedureSuggestion): ReactElement => (
+
+
+
+
+
+
+ {existingCptCodeSet.has(value.code) ? (
+
+
+
+ ) : (
+
+ addRecommendedCptCode(value)}
+ data-testid={dataTestIds.documentProcedurePage.cptCodeQuickAddButton(value.code)}
+ >
+
+
+
+ )}
+
+ );
+
+ const recommendedCptCodesContent = (): ReactNode => {
+ if (loadingSuggestions) {
+ return null;
+ }
+
+ if (!formValues.procedureType) {
+ return Select a procedure type to see recommended CPT codes;
+ }
+
+ // Suggestions not fetched yet.
+ if (!recommendedBillingCodes) {
+ return null;
+ }
+
+ if (recommendedBillingCodes.length === 0) {
+ return No suggestions;
+ }
+
+ return (
+ value.code}
+ renderItem={(value) => (
+
+ {value.code} – {value.description}
+
+ )}
+ renderActions={isReadOnly ? undefined : renderRecommendedCptActions}
+ divider
+ />
+ );
+ };
+
const cptWidget = (): ReactElement => {
return (
<>
@@ -1127,13 +1198,7 @@ export default function ProceduresNew(): ReactElement {
CPT Code
- {recommendedBillingCodes && (
-
- )}
+ {recommendedCptCodesContent()}
{suggestionNote && suggestionNote.suggestions?.[0] !== 'Procedure details are included' && (