diff --git a/patientsearch/src/js/components/Header.js b/patientsearch/src/js/components/Header.js index ec13e2f3..5dca80b2 100644 --- a/patientsearch/src/js/components/Header.js +++ b/patientsearch/src/js/components/Header.js @@ -1,5 +1,5 @@ import React from "react"; -import makeStyles from '@mui/styles/makeStyles'; +import makeStyles from "@mui/styles/makeStyles"; import ClickAwayListener from "@mui/material/ClickAwayListener"; import ExitToAppIcon from "@mui/icons-material/ExitToApp"; import HowToRegIcon from "@mui/icons-material/HowToReg"; @@ -15,7 +15,14 @@ import Paper from "@mui/material/Paper"; import Toolbar from "@mui/material/Toolbar"; import Typography from "@mui/material/Typography"; import SiteLogo from "./SiteLogo"; -import { imageOK, setDocumentTitle, setFavicon } from "../helpers/utility"; +import { + getAppLaunchURL, + getClientsByRequiredRoles, + imageOK, + isEmptyArray, + setDocumentTitle, + setFavicon, +} from "../helpers/utility"; import { useSettingContext } from "../context/SettingContextProvider"; import { useUserContext } from "../context/UserContextProvider"; @@ -30,7 +37,7 @@ const useStyles = makeStyles((theme) => ({ flexDirection: "row", justifyContent: "space-between", flexWrap: "wrap", - gap: theme.spacing(1) + gap: theme.spacing(1), }, toolbarIcon: { display: "flex", @@ -49,18 +56,23 @@ const useStyles = makeStyles((theme) => ({ //logo styling logo: { width: "180px", - // marginLeft: theme.spacing(3), + // marginLeft: theme.spacing(3), }, title: { width: "100%", }, + desktopOnly: { + [theme.breakpoints.down("md")]: { + display: "none", + }, + }, welcomeContainer: { display: "flex", flexDirection: "column", alignItems: "center", marginRight: theme.spacing(4), marginLeft: theme.spacing(4), - [theme.breakpoints.down('md')]: { + [theme.breakpoints.down("md")]: { display: "none", }, }, @@ -122,6 +134,9 @@ export default function Header() { const classes = useStyles(); const appSettings = useSettingContext().appSettings; const { user: userInfo, error: userError } = useUserContext(); + const appClients = appSettings + ? getClientsByRequiredRoles(appSettings["SOF_CLIENTS"], userInfo?.roles) + : null; const [appTitle, setAppTitle] = React.useState(""); const [projectName, setProjectName] = React.useState(""); const [anchorEl, setAnchorEl] = React.useState(null); @@ -208,6 +223,32 @@ export default function Header() { ); + const renderClientButtons = (isMobile) => { + if (isEmptyArray(appClients)) return null; + if (!hasUserInfo()) return null; + const standaloneClients = appClients.filter(c => String(c.standalone).toLowerCase() === "true"); + if (!standaloneClients.length) return null; + return ( +
+ {standaloneClients.map((client, index) => { + const onClickEvent = () => (window.location = getAppLaunchURL("", {...appSettings, launch_url: client?.launch_url})); + return ( + + ); + })} +
+ ); + }; + React.useLayoutEffect(() => { if (appSettings) { if (appSettings["APPLICATION_TITLE"]) @@ -215,7 +256,7 @@ export default function Header() { if (appSettings["PROJECT_NAME"]) { setProjectName(appSettings["PROJECT_NAME"]); setDocumentTitle( - `${appSettings["PROJECT_NAME"]} ${appSettings["SEARCH_TITLE_TEXT"]}` + `${appSettings["PROJECT_NAME"]} ${appSettings["SEARCH_TITLE_TEXT"]}`, ); setFavicon(`/static/${appSettings["PROJECT_NAME"]}_favicon.ico`); } @@ -237,6 +278,7 @@ export default function Header() { onError={handleImageLoadError} /> + {!userError && renderClientButtons()} {!userError && ( {renderUserInfoComponent()} @@ -264,6 +306,7 @@ export default function Header() { square={true} > {renderUserInfoComponent()} + {renderClientButtons(true)} {hasUserInfo() && renderLogoutComponent()} diff --git a/patientsearch/src/js/context/PatientListContextProvider.js b/patientsearch/src/js/context/PatientListContextProvider.js index d0aeadc4..6bf99250 100644 --- a/patientsearch/src/js/context/PatientListContextProvider.js +++ b/patientsearch/src/js/context/PatientListContextProvider.js @@ -316,13 +316,21 @@ export default function PatientListContextProvider({ children }) { return getAppSettingByKey("EXTERNAL_FHIR_API"); }, [getAppSettingByKey]); - const hasSoFClients = useCallback(() => { - return !isEmptyArray(appClients); + const getLaunchableSofClients = useCallback(() => { + if (isEmptyArray(appClients)) return null; + return appClients.filter((c) => String(c.standalone).toLowerCase() !== "true"); }, [appClients]); - const hasMultipleSoFClients = useCallback(() => { - return hasSoFClients() && appClients.length > 1; - }, [hasSoFClients, appClients]); + const hasSoFClients = useCallback(() => { + const apps = getLaunchableSofClients(); + if (isEmptyArray(apps)) return false; + return apps.length > 0; + }, [getLaunchableSofClients]); + + const hasMultipleLaunchableSoFClients = useCallback(() => { + if (!hasSoFClients()) return false; + return getLaunchableSofClients()?.length > 1; + }, [hasSoFClients, getLaunchableSofClients]); const _getLaunchURL = useCallback( (patientId, launchParams) => { @@ -341,9 +349,9 @@ export default function PatientListContextProvider({ children }) { const canLaunchApp = useCallback( () => hasSoFClients() && - (appClients.length === 1 || + (getLaunchableSofClients()?.length === 1 || getAppSettingByKey("LAUNCH_AFTER_PATIENT_CREATION")), - [hasSoFClients, appClients, getAppSettingByKey], + [hasSoFClients, getLaunchableSofClients, getAppSettingByKey], ); const handleLaunchError = useCallback( @@ -361,9 +369,9 @@ export default function PatientListContextProvider({ children }) { const handleLaunchApp = useCallback( (rowData, launchParams) => { if (!launchParams) { - launchParams = canLaunchApp() ? appClients[0] : null; + launchParams = canLaunchApp() ? getLaunchableSofClients()[0] : null; } - if (!launchParams && hasMultipleSoFClients()) { + if (!launchParams && hasMultipleLaunchableSoFClients()) { dispatch({ type: ACTIONS.OPEN_LAUNCH_INFO_MODAL, payload: { currentRow: rowData }, @@ -385,8 +393,8 @@ export default function PatientListContextProvider({ children }) { }, [ canLaunchApp, - appClients, - hasMultipleSoFClients, + getLaunchableSofClients, + hasMultipleLaunchableSoFClients, handleLaunchError, _getLaunchURL, ], @@ -945,38 +953,40 @@ export default function PatientListContextProvider({ children }) { : []; if (isEmptyArray(appClients)) return actions; return [ - ...appClients.map((c) => ({ - icon: () => ( - - {c.label} - - ), - onClick: (event, rowData) => { - event.stopPropagation(); - const hasLastAccessedField = - columns.filter( - (column) => - String(column.field).toLowerCase() === "last_accessed", - ).length > 0; - if (hasLastAccessedField) { - putPatientData( - rowData.id, - rowData.resource, - (e) => { - handleErrorCallback(e); - handleLaunchApp(rowData, c); - }, - () => handleLaunchApp(rowData, c), - ); - return; - } - handleLaunchApp(rowData, c); - }, - tooltip: `Launch ${c.id}`, - })), + ...appClients + .filter((c) => !c.standalone) + .map((c) => ({ + icon: () => ( + + {c.label} + + ), + onClick: (event, rowData) => { + event.stopPropagation(); + const hasLastAccessedField = + columns.filter( + (column) => + String(column.field).toLowerCase() === "last_accessed", + ).length > 0; + if (hasLastAccessedField) { + putPatientData( + rowData.id, + rowData.resource, + (e) => { + handleErrorCallback(e); + handleLaunchApp(rowData, c); + }, + () => handleLaunchApp(rowData, c), + ); + return; + } + handleLaunchApp(rowData, c); + }, + tooltip: `Launch ${c.id}`, + })), ...actions, ]; }, [ diff --git a/patientsearch/src/js/helpers/utility.js b/patientsearch/src/js/helpers/utility.js index 1197acb3..0d6ddd24 100644 --- a/patientsearch/src/js/helpers/utility.js +++ b/patientsearch/src/js/helpers/utility.js @@ -542,10 +542,6 @@ export function getTimeAgoDisplay(objDate) { * @return {string} url for launching the client app */ export const getAppLaunchURL = (patientId, params) => { - if (!patientId) { - console.log("Missing information: patient Id"); - return ""; - } const launchParams = params ? params : {}; const iss = launchParams["SOF_HOST_FHIR_URL"]; const needPatientBanner = launchParams["NEED_PATIENT_BANNER"]; @@ -555,7 +551,7 @@ export const getAppLaunchURL = (patientId, params) => { return ""; } const arrParams = [ - `patient=${patientId}`, + patientId ? `patient=${patientId}`: "", `need_patient_banner=${needPatientBanner}`, `launch=${btoa(JSON.stringify({ a: 1, b: patientId }))}`, `iss=${encodeURIComponent(iss)}`,