diff --git a/containers/tefca-viewer/package.json b/containers/tefca-viewer/package.json index c073a64a6c..6b27a54e95 100644 --- a/containers/tefca-viewer/package.json +++ b/containers/tefca-viewer/package.json @@ -4,7 +4,7 @@ "version": "1.0.1", "private": true, "scripts": { - "dev": "docker-compose -f docker-compose-dev.yaml up && next dev", + "dev": "docker-compose -f docker-compose-dev.yaml up -d && next dev", "dev-win": "start docker-compose -f docker-compose-dev.yaml up && next dev", "dev:db": "docker-compose -f docker-compose-dev.yaml up", "dev:next": "dotenv -e ./tefca.env.local -e ./tefca.env -- next dev", diff --git a/containers/tefca-viewer/src/app/constants.ts b/containers/tefca-viewer/src/app/constants.ts index bf7ee3be5d..77d104e87d 100644 --- a/containers/tefca-viewer/src/app/constants.ts +++ b/containers/tefca-viewer/src/app/constants.ts @@ -300,8 +300,9 @@ export const stateOptions = [ export type Mode = | "search" | "results" - | "patient-results" - | "customize-queries"; + | "customize-queries" + | "select-query" + | "patient-results"; /*Type to specify the expected components for each item in a value set that will be displayed in the CustomizeQuery component*/ diff --git a/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.module.css b/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.module.css new file mode 100644 index 0000000000..3cb2e2e448 --- /dev/null +++ b/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.module.css @@ -0,0 +1,37 @@ +.searchCallToActionButton { + height: 2.5rem; +} + +.selectQueryHeaderText { + line-height: 2.0625rem; + word-wrap: break-word; + font-size: 2.5rem; +} + +.selectQueryExplanationText { + padding-top: 0.75rem; + padding-bottom: 1.5rem; + line-height: 2.0625rem; + word-wrap: break-word; + font-size: 1.375rem; + width: 50.6875rem; +} + +.queryRow { + display: flex; + align-items: center; + padding-bottom: 1.5rem; +} + +.customizeButton { + margin-left: 1.25rem; + margin-top: 0.5rem; +} + +.queryDropDown { + display: flex; + width: 20rem; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; +} diff --git a/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.tsx b/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.tsx new file mode 100644 index 0000000000..7bcaa1e3cb --- /dev/null +++ b/containers/tefca-viewer/src/app/query/components/selectQuery/selectQuery.tsx @@ -0,0 +1,167 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { Button, Select } from "@trussworks/react-uswds"; +import { demoQueryOptions, FHIR_SERVERS, Mode } from "../../../constants"; +import Backlink from "../backLink/Backlink"; +import { fhirServers } from "../../../fhir-servers"; +import styles from "./selectQuery.module.css"; + +interface SelectQueryProps { + setQueryType: (queryType: string) => void; + setHCO: (hco: string) => void; + setMode: (mode: Mode) => void; + onSubmit: () => void; // Callback when the user submits the query + goBack: () => void; +} + +/** + * + * @param root0 - SelectQueryProps + * @param root0.setQueryType - Callback to update the query type + * @param root0.setHCO - Callback to update selected Health Care Organization (HCO) + * @param root0.setMode - Callback to switch mode + * @param root0.onSubmit - Callback for submit action + * @param root0.goBack - back button + * @returns - The selectQuery component. + */ +const SelectQuery: React.FC = ({ + setQueryType, + setHCO, + setMode, + onSubmit, + goBack, +}) => { + const [selectedQuery, setSelectedQuery] = useState(""); + const [selectedHCO, setSelectedHCO] = useState(""); // Keep this as string for HCO selection + const [showAdvanced, setShowAdvanced] = useState(false); + + // When query changes, update the parent component state + useEffect(() => { + setQueryType(selectedQuery); + }, [selectedQuery, setQueryType]); + + const handleQueryChange = (event: React.ChangeEvent) => { + setSelectedQuery(event.target.value); + }; + + const handleHCOChange = (event: React.ChangeEvent) => { + setSelectedHCO(event.target.value); + setHCO(event.target.value as FHIR_SERVERS); // Update parent component state + }; + + // Link to go to customize-queries page + const handleClick = () => { + setMode("customize-queries"); + }; + + // Submit and go to results; if no custom query selected, add alert + const handleSubmit = () => { + if (selectedQuery) { + onSubmit(); + } else { + alert("Please select a query."); + } + }; + + return ( +
+ {/* Back button */} +
+ +
+

+ Step 3: Select a query +

+
+ We will request all data related to your selected patient and query. By + only showing relevant data for your query, we decrease the burden on our + systems and protect patient privacy. If you would like to customize the + query response, click on the "customize query" button. +
+

Query

+
+ {/* Select a query drop down */} + + {/* Customize query button */} + +
+ + {/* Show Advanced options only when `showAdvanced` is true */} + {showAdvanced && ( +
+

Health Care Organization (HCO)

+ +
+ )} + + {/* Only show the "Advanced" button if `showAdvanced` is false */} + {!showAdvanced && ( +
+ +
+ )} + + {/* Submit Button */} +
+ +
+
+ ); +}; + +export default SelectQuery; +export const RETURN_TO_STEP_ONE_LABEL = "Return to Select patient"; diff --git a/containers/tefca-viewer/src/app/query/page.tsx b/containers/tefca-viewer/src/app/query/page.tsx index c7d38fcebd..662248650c 100644 --- a/containers/tefca-viewer/src/app/query/page.tsx +++ b/containers/tefca-viewer/src/app/query/page.tsx @@ -4,6 +4,7 @@ import { UseCaseQueryResponse, UseCaseQueryRequest } from "../query-service"; import ResultsView from "./components/ResultsView"; import PatientSearchResults from "./components/PatientSearchResults"; import SearchForm from "./components/searchForm/SearchForm"; +import SelectQuery from "./components/selectQuery/selectQuery"; import { Mode, QueryTypeToQueryName, @@ -67,18 +68,31 @@ const Query: React.FC = () => {
{mode === "search" && ( - - - + <> + + + + + )} + + {/* Render SelectQuery component when the mode is "select-query" */} + {mode === "select-query" && ( + {}} + setMode={setMode} + goBack={() => setMode("patient-results")} + onSubmit={() => setMode("results")} + /> )} {/* Switch the mode to view to show the results of the query */} diff --git a/package-lock.json b/package-lock.json index 0f71cd4068..1d4e679a10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -906,7 +906,8 @@ "react": "^18", "react-dom": "^18", "react-toastify": "^10.0.5", - "sharp": "^0.33.5" + "sharp": "^0.33.5", + "uswds": "^2.14.0" }, "devDependencies": { "@next/eslint-plugin-next": "^14.0.4", @@ -8362,6 +8363,11 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/domready": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", + "integrity": "sha512-uIzsOJUNk+AdGE9a6VDeessoMCzF8RrZvJCX/W8QtyfgdR6Uofn/MvRonih3OtCO79b2VDzDOymuiABrQ4z3XA==" + }, "node_modules/domutils": { "version": "3.1.0", "license": "BSD-2-Clause", @@ -16033,6 +16039,22 @@ "requires-port": "^1.0.0" } }, + "node_modules/uswds": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/uswds/-/uswds-2.14.0.tgz", + "integrity": "sha512-r5ebL3av9jOPcbXTxKnGiT5k5NVIAWmtYcO8LeJkA5Svh2qc90YRhzCUWbz9TbGdXJriMCPb7whiULPDxmRhxg==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "classlist-polyfill": "1.2.0", + "domready": "1.0.8", + "object-assign": "4.1.1", + "receptor": "1.0.0", + "resolve-id-refs": "0.1.0" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT"