Skip to content
2 changes: 1 addition & 1 deletion apps/smart-forms-app/public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"defaultClientId": "a57d90e3-5f69-4b92-aa2e-2992180863c1",
"launchScopes": "launch openid fhirUser online_access patient/AllergyIntolerance.cus patient/Condition.cus patient/Encounter.r patient/Immunization.cs patient/Medication.r patient/MedicationStatement.cus patient/Observation.cs patient/Patient.r patient/QuestionnaireResponse.crus user/Practitioner.r launch/questionnaire?role=http://ns.electronichealth.net.au/smart/role/new",
"registeredClientIdsUrl": "https://smartforms.csiro.au/smart-config/config.json",
"showDeveloperMessages": true
"showDeveloperMessages": false
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { populateQuestionnaire } from '@aehrc/sdc-populate';
import { fetchResourceCallback } from './PrePopCallbackForPlayground.tsx';
import { useQuestionnaireStore } from '@aehrc/smart-forms-renderer';
import {
questionnaireStore,
rendererConfigStore,
useQuestionnaireStore
} from '@aehrc/smart-forms-renderer';
import type { Encounter, Patient, Practitioner, PractitionerRole } from 'fhir/r4';
import { ListItemIcon, ListItemText } from '@mui/material';
import MenuItem from '@mui/material/MenuItem';
import CloudDownloadIcon from '@mui/icons-material/CloudDownload';
import type { RendererSpinner } from '../../renderer/types/rendererSpinner.ts';
import { resetAndBuildForm } from '../../../utils/manageForm.ts';
import { useSnackbar } from 'notistack';
import CloseSnackbar from '../../../components/Snackbar/CloseSnackbar.tsx';
import {
extractWarningMessages,
formatPopulateIssuesForUser,
getWarningFieldNames
} from '../../prepopulate/utils/prepopulateIssues.ts';

interface PrePopulateMenuItemProps {
sourceFhirServerUrl: string | null;
Expand All @@ -32,6 +43,7 @@ function PrePopulateMenuItem(props: PrePopulateMenuItemProps) {
} = props;

const sourceQuestionnaire = useQuestionnaireStore.use.sourceQuestionnaire();
const { enqueueSnackbar } = useSnackbar();

const populateEnabled = sourceFhirServerUrl !== null && patient !== null;

Expand Down Expand Up @@ -62,33 +74,57 @@ function PrePopulateMenuItem(props: PrePopulateMenuItemProps) {
fhirContext: practitionerRole
? [{ reference: `PractitionerRole/${practitionerRole.id}` }]
: undefined
}).then(async ({ populateSuccess, populateResult }) => {
if (!populateSuccess || !populateResult) {
onSpinnerChange({
isSpinning: false,
status: null,
message: ''
});
return;
}
})
.then(async ({ populateSuccess, populateResult }) => {
if (!populateSuccess || !populateResult) {
onSpinnerChange({ isSpinning: false, status: null, message: '' });
enqueueSnackbar('Form could not be pre-populated.', {
variant: 'warning',
action: <CloseSnackbar variant="warning" />
});
return;
}

const { populatedResponse, populatedContext } = populateResult;
const { populatedResponse, issues, populatedContext } = populateResult;

// Call to buildForm to pre-populate the QR which repaints the entire BaseRenderer view
// Also passes the populatedContext to the FhirPathContext
await resetAndBuildForm({
questionnaire: sourceQuestionnaire,
questionnaireResponse: populatedResponse,
terminologyServerUrl,
additionalContext: populatedContext
});
// Call to buildForm to pre-populate the QR which repaints the entire BaseRenderer view
// Also passes the populatedContext to the FhirPathContext
await resetAndBuildForm({
questionnaire: sourceQuestionnaire,
questionnaireResponse: populatedResponse,
terminologyServerUrl,
additionalContext: populatedContext
});

onSpinnerChange({
isSpinning: false,
status: null,
message: ''
onSpinnerChange({ isSpinning: false, status: null, message: '' });

if (issues) {
const warningMessages = extractWarningMessages(issues);
rendererConfigStore
.getState()
.setRendererConfig({ prepopulationWarningMessages: warningMessages });
const questionnaire = questionnaireStore.getState().sourceQuestionnaire;
const fieldNames = getWarningFieldNames(questionnaire, new Set(warningMessages.keys()));
enqueueSnackbar(formatPopulateIssuesForUser(issues, warningMessages.size, fieldNames), {
variant: 'warning',
persist: true,
action: <CloseSnackbar variant="warning" />
});
console.warn('Pre-population issues:', issues);
} else {
rendererConfigStore
.getState()
.setRendererConfig({ prepopulationWarningMessages: new Map() });
enqueueSnackbar('Form pre-populated.', { action: <CloseSnackbar /> });
}
})
.catch(() => {
onSpinnerChange({ isSpinning: false, status: null, message: '' });
enqueueSnackbar('Form could not be pre-populated.', {
variant: 'warning',
action: <CloseSnackbar variant="warning" />
});
});
});
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@
* limitations under the License.
*/

import { useState, useContext } from 'react';
import { useContext, useState } from 'react';
import CloseSnackbar from '../../../components/Snackbar/CloseSnackbar.tsx';
import { useSnackbar } from 'notistack';
import { ConfigContext } from '../../configChecker/contexts/ConfigContext.tsx';
import {
extractWarningMessages,
formatPopulateIssuesForUser,
getWarningFieldNames
} from '../utils/prepopulateIssues.ts';
import {
buildForm,
questionnaireStore,
rendererConfigStore,
useQuestionnaireResponseStore,
useQuestionnaireStore,
useTerminologyServerStore
Expand All @@ -29,6 +35,7 @@ import useSmartClient from '../../../hooks/useSmartClient.ts';
import type { RendererSpinner } from '../../renderer/types/rendererSpinner.ts';
import { populateQuestionnaire } from '@aehrc/sdc-populate';
import { fetchResourceCallback, fetchTerminologyCallback } from '../utils/callback.ts';
import { ConfigContext } from '../../configChecker/contexts/ConfigContext.tsx';

function usePopulate(spinner: RendererSpinner, onStopSpinner: () => void): void {
const { isSpinning, status } = spinner;
Expand All @@ -45,7 +52,9 @@ function usePopulate(spinner: RendererSpinner, onStopSpinner: () => void): void
const [isPopulated, setIsPopulated] = useState(false);

const { enqueueSnackbar } = useSnackbar();

const { config } = useContext(ConfigContext);
const { showDeveloperMessages } = config;

// Do not run population if spinner purpose is "repopulate"
if (status !== 'prepopulate') {
Expand Down Expand Up @@ -129,18 +138,33 @@ function usePopulate(spinner: RendererSpinner, onStopSpinner: () => void): void

onStopSpinner();
if (issues) {
// Only show the snackbar message if developer messages are enabled
if (config.showDeveloperMessages ?? true) {
const warningMessages = extractWarningMessages(issues);
rendererConfigStore
?.getState()
.setRendererConfig({ prepopulationWarningMessages: warningMessages });
if (showDeveloperMessages) {
enqueueSnackbar(
'Form partially populated, there might be pre-population issues. View console for details.',
{ action: <CloseSnackbar /> }
);
} else {
const questionnaire = questionnaireStore?.getState().sourceQuestionnaire;
const fieldNames = questionnaire
? getWarningFieldNames(questionnaire, new Set(warningMessages.keys()))
: [];
enqueueSnackbar(formatPopulateIssuesForUser(issues, warningMessages.size, fieldNames), {
variant: 'warning',
persist: true,
action: <CloseSnackbar variant="warning" />
});
}
// Always log to console - clinicians won't see this, but developers need it
console.warn(issues);
return;
}

rendererConfigStore
?.getState()
.setRendererConfig({ prepopulationWarningMessages: new Map() });
enqueueSnackbar('Form populated', {
preventDuplicate: true,
action: <CloseSnackbar />
Expand Down
Loading
Loading