Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 49 additions & 6 deletions patientsearch/src/js/components/Header.js
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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";

Expand All @@ -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",
Expand All @@ -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",
},
},
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -208,14 +223,40 @@ export default function Header() {
</div>
);

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 (
<div
className={`${isMobile ? "flex-column" : "flex"}`}
style={{ justifyContent: "flex-end", flex: 1, gap: "8px" }}
>
{standaloneClients.map((client, index) => {
const onClickEvent = () => (window.location = getAppLaunchURL("", {...appSettings, launch_url: client?.launch_url}));
return (
<Button
variant="outlined"
onClick={onClickEvent}
key={`${client.id}_standalone_button_${index}`}
>
{client.label}
</Button>
);
})}
</div>
);
};

React.useLayoutEffect(() => {
if (appSettings) {
if (appSettings["APPLICATION_TITLE"])
setAppTitle(appSettings["APPLICATION_TITLE"]);
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`);
}
Expand All @@ -237,6 +278,7 @@ export default function Header() {
onError={handleImageLoadError}
/>
<SiteLogo />
{!userError && renderClientButtons()}
{!userError && (
<Box className={classes.welcomeContainer}>
{renderUserInfoComponent()}
Expand Down Expand Up @@ -264,6 +306,7 @@ export default function Header() {
square={true}
>
{renderUserInfoComponent()}
{renderClientButtons(true)}
{hasUserInfo() && renderLogoutComponent()}
</Paper>
</Fade>
Expand Down
96 changes: 53 additions & 43 deletions patientsearch/src/js/context/PatientListContextProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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(
Expand All @@ -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 },
Expand All @@ -385,8 +393,8 @@ export default function PatientListContextProvider({ children }) {
},
[
canLaunchApp,
appClients,
hasMultipleSoFClients,
getLaunchableSofClients,
hasMultipleLaunchableSoFClients,
handleLaunchError,
_getLaunchURL,
],
Expand Down Expand Up @@ -945,38 +953,40 @@ export default function PatientListContextProvider({ children }) {
: [];
if (isEmptyArray(appClients)) return actions;
return [
...appClients.map((c) => ({
icon: () => (
<span
className="action-button"
style={{ background: theme.palette.primary.main }}
>
{c.label}
</span>
),
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: () => (
<span
className="action-button"
style={{ background: theme.palette.primary.main }}
>
{c.label}
</span>
),
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,
];
}, [
Expand Down
6 changes: 1 addition & 5 deletions patientsearch/src/js/helpers/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
Expand All @@ -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)}`,
Expand Down