+ goBack()}
+ label={"Return to query selection"}
+ />
@@ -70,7 +79,9 @@ const ResultsView: React.FC = ({
Query:{" "}
- {queryName}
+
+ {demoQueryValToLabelMap[selectedQuery]}
+
diff --git a/query-connector/src/app/query/components/SelectQuery.tsx b/query-connector/src/app/query/components/SelectQuery.tsx
new file mode 100644
index 000000000..8617ef3e1
--- /dev/null
+++ b/query-connector/src/app/query/components/SelectQuery.tsx
@@ -0,0 +1,123 @@
+"use client";
+import React, { useEffect, useState } from "react";
+import { FHIR_SERVERS, USE_CASES, ValueSetItem } from "../../constants";
+import CustomizeQuery from "./CustomizeQuery";
+import SelectSavedQuery from "./selectQuery/SelectSavedQuery";
+
+import { QueryResponse } from "@/app/query-service";
+import { Patient } from "fhir/r4";
+import {
+ fetchQueryResponse,
+ fetchUseCaseValueSets,
+} from "./selectQuery/queryHooks";
+import LoadingView from "./LoadingView";
+
+interface SelectQueryProps {
+ goForward: () => void;
+ goBack: () => void;
+ selectedQuery: USE_CASES;
+ setSelectedQuery: React.Dispatch
>;
+ patientForQuery: Patient | undefined;
+ resultsQueryResponse: QueryResponse;
+ setResultsQueryResponse: React.Dispatch>;
+ fhirServer: FHIR_SERVERS;
+ setFhirServer: React.Dispatch>;
+ setLoading: (isLoading: boolean) => void;
+}
+
+/**
+ * @param root0 - SelectQueryProps
+ * @param root0.goBack - Callback to return to previous page
+ * @param root0.goForward - Callback to go to the next page
+ * @param root0.selectedQuery - query we chose for further customization
+ * @param root0.setSelectedQuery - callback function to update the selected query
+ * @param root0.patientForQuery - patient to apply a particular query for
+ * @param root0.resultsQueryResponse - Response of selected query
+ * @param root0.setResultsQueryResponse - Callback function to update selected
+ * query
+ * @param root0.fhirServer - the FHIR server that we're running the query against
+ * @param root0.setFhirServer - callback function to update the FHIR server
+ * @returns - The selectQuery component.
+ */
+const SelectQuery: React.FC = ({
+ selectedQuery,
+ patientForQuery,
+ resultsQueryResponse,
+ fhirServer,
+ goForward,
+ goBack,
+ setSelectedQuery,
+ setResultsQueryResponse,
+ setFhirServer,
+}) => {
+ const [showCustomizeQuery, setShowCustomizedQuery] = useState(false);
+ const [queryValueSets, setQueryValueSets] = useState(
+ [] as ValueSetItem[],
+ );
+ const [loadingQueryValueSets, setLoadingQueryValueSets] =
+ useState(false);
+
+ const [loadingResultResponse, setLoadingResultResponse] =
+ useState(false);
+
+ useEffect(() => {
+ // Gate whether we actually update state after fetching so we
+ // avoid name-change race conditions
+ let isSubscribed = true;
+
+ fetchUseCaseValueSets(
+ selectedQuery,
+ setQueryValueSets,
+ isSubscribed,
+ setLoadingQueryValueSets,
+ ).catch(console.error);
+
+ // Destructor hook to prevent future state updates
+ return () => {
+ isSubscribed = false;
+ };
+ }, [selectedQuery, setQueryValueSets]);
+
+ async function onSubmit() {
+ await fetchQueryResponse({
+ patientForQuery: patientForQuery,
+ selectedQuery: selectedQuery,
+ queryValueSets: queryValueSets,
+ fhirServer: fhirServer,
+ queryResponseStateCallback: setResultsQueryResponse,
+ setIsLoading: setLoadingResultResponse,
+ }).catch(console.error);
+ goForward();
+ }
+
+ const displayLoading = loadingResultResponse || loadingQueryValueSets;
+ return (
+ <>
+ {displayLoading && }
+
+ {showCustomizeQuery ? (
+ setShowCustomizedQuery(false)}
+ >
+ ) : (
+
+ )}
+ >
+ );
+};
+
+export default SelectQuery;
+export const RETURN_TO_STEP_ONE_LABEL = "Return to Select patient";
diff --git a/query-connector/src/app/query/components/header/header.tsx b/query-connector/src/app/query/components/header/header.tsx
index b36e3017e..5667dfab3 100644
--- a/query-connector/src/app/query/components/header/header.tsx
+++ b/query-connector/src/app/query/components/header/header.tsx
@@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from "react";
import { Modal, ModalButton } from "../../designSystem/Modal";
import { ModalRef } from "@trussworks/react-uswds";
import styles from "./header.module.css";
+import { metadata } from "@/app/constants";
/**
* Produces the header.
* @returns The HeaderComponent component.
@@ -33,9 +34,9 @@ export default function HeaderComponent() {
- TEFCA Viewer
+ {metadata.title}
diff --git a/query-connector/src/app/query/components/patientSearchResults/PatientSearchResultsTable.tsx b/query-connector/src/app/query/components/patientSearchResults/PatientSearchResultsTable.tsx
index 53fabf08b..59bdf38b7 100644
--- a/query-connector/src/app/query/components/patientSearchResults/PatientSearchResultsTable.tsx
+++ b/query-connector/src/app/query/components/patientSearchResults/PatientSearchResultsTable.tsx
@@ -9,7 +9,7 @@ import {
type PatientSeacrchResultsTableProps = {
patients: Patient[];
- setPatientForQueryResponse: (patient: Patient) => void;
+ handlePatientSelect: (patient: Patient) => void;
};
/**
@@ -17,18 +17,18 @@ type PatientSeacrchResultsTableProps = {
* include in their query
* @param param0 - props
* @param param0.patients - Patient[] from the FHIR spec to display as rows
- * @param param0.setPatientForQueryResponse - state setter function to redirect
+ * @param param0.handlePatientSelect - state setter function to redirect
* to the results view
* @returns The patient search results view
*/
const PatientSearchResultsTable: React.FC = ({
patients,
- setPatientForQueryResponse,
+ handlePatientSelect: setPatientForQueryResponse,
}) => {
return (
<>
- Select a patient
+ {STEP_TWO_PAGE_TITLE}
The following records match your search. Select a patient to continue.
@@ -74,3 +74,4 @@ const PatientSearchResultsTable: React.FC = ({
};
export default PatientSearchResultsTable;
+export const STEP_TWO_PAGE_TITLE = "Step 2: Select a patient";
diff --git a/query-connector/src/app/query/components/resultsView/ResultsViewTable.tsx b/query-connector/src/app/query/components/resultsView/ResultsViewTable.tsx
index 5481ba517..b828b46c3 100644
--- a/query-connector/src/app/query/components/resultsView/ResultsViewTable.tsx
+++ b/query-connector/src/app/query/components/resultsView/ResultsViewTable.tsx
@@ -57,5 +57,5 @@ export default ResultsViewTable;
* @returns - A hyphenated id that can be linked as an anchor tag
*/
export function formatIdForAnchorTag(title: string) {
- return title.toLocaleLowerCase().replace(" ", "-");
+ return title?.toLocaleLowerCase().replace(" ", "-");
}
diff --git a/query-connector/src/app/query/components/searchForm/SearchForm.tsx b/query-connector/src/app/query/components/searchForm/SearchForm.tsx
index aedac810e..cc12ab403 100644
--- a/query-connector/src/app/query/components/searchForm/SearchForm.tsx
+++ b/query-connector/src/app/query/components/searchForm/SearchForm.tsx
@@ -10,18 +10,10 @@ import {
USE_CASES,
FHIR_SERVERS,
demoData,
- PatientType,
- demoQueryOptions,
- patientOptions,
stateOptions,
Mode,
- ValueSetItem,
} from "../../../constants";
-import {
- UseCaseQueryResponse,
- UseCaseQuery,
- UseCaseQueryRequest,
-} from "../../../query-service";
+import { UseCaseQueryResponse, UseCaseQuery } from "../../../query-service";
import { fhirServers } from "../../../fhir-servers";
import styles from "./searchForm.module.css";
@@ -29,45 +21,41 @@ import { FormatPhoneAsDigits } from "@/app/format-service";
interface SearchFormProps {
useCase: USE_CASES;
- queryValueSets: ValueSetItem[];
setUseCase: (useCase: USE_CASES) => void;
- setOriginalRequest: (originalRequest: UseCaseQueryRequest) => void;
- setUseCaseQueryResponse: (UseCaseQueryResponse: UseCaseQueryResponse) => void;
+ setPatientDiscoveryQueryResponse: (
+ UseCaseQueryResponse: UseCaseQueryResponse,
+ ) => void;
setMode: (mode: Mode) => void;
setLoading: (loading: boolean) => void;
- setQueryType: (queryType: string) => void;
+ fhirServer: FHIR_SERVERS;
+ setFhirServer: React.Dispatch>;
}
/**
* @param root0 - SearchFormProps
* @param root0.useCase - The use case this query will cover.
- * @param root0.queryValueSets - Stateful collection of valuesets to use in the query.
* @param root0.setUseCase - Update stateful use case.
- * @param root0.setOriginalRequest - The function to set the original request.
- * @param root0.setUseCaseQueryResponse - The function to set the use case query response.
* @param root0.setMode - The function to set the mode.
* @param root0.setLoading - The function to set the loading state.
- * @param root0.setQueryType - The function to set the query type.
+ * @param root0.setPatientDiscoveryQueryResponse - callback function to set the
+ * patient for use in future steps
+ * @param root0.fhirServer - server to do the query against
+ * @param root0.setFhirServer - callback function to update specified query
* @returns - The SearchForm component.
*/
const SearchForm: React.FC = ({
useCase,
- queryValueSets,
setUseCase,
- setOriginalRequest,
- setUseCaseQueryResponse,
+ setPatientDiscoveryQueryResponse,
setMode,
setLoading,
- setQueryType,
+ fhirServer,
+ setFhirServer,
}) => {
//Set the patient options based on the demoOption
- const [patientOption, setPatientOption] = useState(
- patientOptions[useCase]?.[0]?.value || "",
- );
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
- const [fhirServer, setFhirServer] = useState();
- // "Public HAPI: Direct",
+
const [phone, setPhone] = useState("");
const [dob, setDOB] = useState("");
const [mrn, setMRN] = useState("");
@@ -75,10 +63,10 @@ const SearchForm: React.FC = ({
const [showAdvanced, setShowAdvanced] = useState(false);
const [autofilled, setAutofilled] = useState(false); // boolean indicating if the form was autofilled, changes color if true
- // Fills fields with sample data based on the selected patientOption
+ // Fills fields with sample data based on the selected
const fillFields = useCallback(
- (patientOption: PatientType, highlightAutofilled = true) => {
- const data = demoData[patientOption];
+ (highlightAutofilled = true) => {
+ const data = demoData["cancer"];
if (data) {
setFirstName(data.FirstName);
setLastName(data.LastName);
@@ -90,23 +78,9 @@ const SearchForm: React.FC = ({
setAutofilled(highlightAutofilled);
}
},
- [patientOption, setUseCase, setQueryType],
+ [setUseCase],
);
- // Change the selectedDemoOption in the dropdown and update the
- // query type (which governs the DB fetch) accordingly
- const handleDemoQueryChange = (selectedDemoOption: string) => {
- setPatientOption(patientOptions[selectedDemoOption][0].value);
- setQueryType(
- demoQueryOptions.find((dqo) => dqo.value == selectedDemoOption)?.label ||
- "",
- );
- };
-
- const handleClick = () => {
- setMode("customize-queries");
- };
-
async function HandleSubmit(event: React.FormEvent) {
event.preventDefault();
if (!useCase || !fhirServer) {
@@ -124,15 +98,10 @@ const SearchForm: React.FC = ({
use_case: useCase,
phone: FormatPhoneAsDigits(phone),
};
- setOriginalRequest(originalRequest);
- const queryResponse = await UseCaseQuery(originalRequest, queryValueSets);
- setUseCaseQueryResponse(queryResponse);
+ const queryResponse = await UseCaseQuery(originalRequest, []);
+ setPatientDiscoveryQueryResponse(queryResponse);
- if (queryResponse.Patient && queryResponse.Patient.length === 1) {
- setMode("results");
- } else {
- setMode("patient-results");
- }
+ setMode("patient-results");
setLoading(false);
}
useEffect(() => {
@@ -143,7 +112,7 @@ const SearchForm: React.FC = ({
<>