diff --git a/apps/smart-forms-app/.env.production b/apps/smart-forms-app/.env.production
index fbdf8011f..a58e3ecc7 100644
--- a/apps/smart-forms-app/.env.production
+++ b/apps/smart-forms-app/.env.production
@@ -2,7 +2,7 @@ VITE_ONTOSERVER_URL=https://r4.ontoserver.csiro.au/fhir
VITE_FORMS_SERVER_URL=https://smartforms.csiro.au/api/fhir
VITE_LAUNCH_SCOPE=fhirUser online_access openid profile patient/Condition.rs patient/Observation.rs launch patient/Encounter.rs patient/QuestionnaireResponse.cruds patient/Patient.rs
-VITE_LAUNCH_CLIENT_ID=csiro-smart-forms
+VITE_LAUNCH_CLIENT_ID=9cbba311-bf9b-4200-8dd3-8459046fc522
VITE_IN_APP_POPULATE=true
diff --git a/apps/smart-forms-app/src/api/saveQr.ts b/apps/smart-forms-app/src/api/saveQr.ts
index a8e19c9d7..4900ac20c 100644
--- a/apps/smart-forms-app/src/api/saveQr.ts
+++ b/apps/smart-forms-app/src/api/saveQr.ts
@@ -137,17 +137,15 @@ function addQuestionnaireReference(
questionnaireResponseToSave: QuestionnaireResponse,
endpointUrl: string
): QuestionnaireResponse {
- let questionnaireReference: string;
if (endpointUrl.includes('https://launch.smarthealthit.org/v/r4/fhir')) {
- // Plugging questionnaire.id in because SMART Health IT has these weird requirements for canonicals
- questionnaireReference = questionnaire.id ? `Questionnaire/${questionnaire.id}` : '';
- } else {
- questionnaireReference = questionnaire.url ?? '';
+ // Plugging questionnaire.id in because SMART Health IT requires QRs to have Questionnaire/{id} as reference
+ questionnaireResponseToSave.questionnaire = questionnaire.id
+ ? `Questionnaire/${questionnaire.id}`
+ : '';
}
// Add questionnaire reference if it is not an empty string
- if (questionnaireReference) {
- questionnaireResponseToSave.questionnaire = questionnaireReference;
+ if (questionnaireResponseToSave.questionnaire) {
questionnaireResponseToSave._questionnaire = {
extension: [
{
diff --git a/apps/smart-forms-app/src/features/prepopulate/hooks/usePopulate.tsx b/apps/smart-forms-app/src/features/prepopulate/hooks/usePopulate.tsx
index c5c66306d..7b08eeb04 100644
--- a/apps/smart-forms-app/src/features/prepopulate/hooks/usePopulate.tsx
+++ b/apps/smart-forms-app/src/features/prepopulate/hooks/usePopulate.tsx
@@ -90,8 +90,8 @@ function usePopulate(spinner: RendererSpinner, onStopSpinner: () => void): void
onStopSpinner();
if (hasWarnings) {
enqueueSnackbar(
- 'Form partially populated, there might be issues while populating the form. View console for details.',
- { action: , variant: 'warning' }
+ 'Form partially populated, there might be pre-population issues. View console for details.',
+ { action: }
);
return;
}
diff --git a/apps/smart-forms-app/src/features/renderer/components/RendererActions/RepopulateAction.tsx b/apps/smart-forms-app/src/features/renderer/components/RendererActions/RepopulateAction.tsx
index effffe261..69ad9f140 100644
--- a/apps/smart-forms-app/src/features/renderer/components/RendererActions/RepopulateAction.tsx
+++ b/apps/smart-forms-app/src/features/renderer/components/RendererActions/RepopulateAction.tsx
@@ -99,7 +99,7 @@ function RepopulateAction(props: RepopulateActionProps) {
if (hasWarnings) {
enqueueSnackbar(
'There might be issues while retrieving the latest information, data is partially retrieved. View console for details.',
- { action: , variant: 'warning' }
+ { action: }
);
return;
}
diff --git a/packages/smart-forms-renderer/README.md b/packages/smart-forms-renderer/README.md
index 959054ed1..373553fe9 100644
--- a/packages/smart-forms-renderer/README.md
+++ b/packages/smart-forms-renderer/README.md
@@ -28,7 +28,7 @@ export default function App () {
)
}
```
-Note: The SmartFormsRenderer component is extremely basic and experimental, do not use it in production!
+Note: The SmartFormsRenderer component trades customisability for simplicity. If you need more control over the rendering engine, refer to the Advanced Usage section.
### SmartFormsRenderer Props
diff --git a/packages/smart-forms-renderer/package.json b/packages/smart-forms-renderer/package.json
index 5346c6d06..0f489e36d 100644
--- a/packages/smart-forms-renderer/package.json
+++ b/packages/smart-forms-renderer/package.json
@@ -1,6 +1,6 @@
{
"name": "@aehrc/smart-forms-renderer",
- "version": "0.10.2",
+ "version": "0.10.3",
"description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
"main": "lib/index.js",
"scripts": {
diff --git a/packages/smart-forms-renderer/src/components/Tabs/FormBodyTabListWrapper.tsx b/packages/smart-forms-renderer/src/components/Tabs/FormBodyTabListWrapper.tsx
index c053a4373..1f12da0f5 100644
--- a/packages/smart-forms-renderer/src/components/Tabs/FormBodyTabListWrapper.tsx
+++ b/packages/smart-forms-renderer/src/components/Tabs/FormBodyTabListWrapper.tsx
@@ -45,14 +45,20 @@ const FormBodyTabListWrapper = memo(function FormBodyTabListWrapper(
return (
-
+
{completedDisplayItemExists ? (
-
+ <>
+
+
+ >
) : null}
-
{
- buildSourceResponse(createEmptyQuestionnaireResponse(questionnaire));
+ buildSourceResponse(initialiseQuestionnaireResponse(questionnaire));
if (questionnaireResponse) {
const updatedResponse = updatePopulatedProperties(questionnaireResponse);
diff --git a/packages/smart-forms-renderer/src/index.ts b/packages/smart-forms-renderer/src/index.ts
index 11e1c3cc0..42e3aeea6 100644
--- a/packages/smart-forms-renderer/src/index.ts
+++ b/packages/smart-forms-renderer/src/index.ts
@@ -1,6 +1,6 @@
import { questionnaireResponseStore, questionnaireStore } from './stores';
import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
-import { createEmptyQuestionnaireResponse } from './utils/qrItem';
+import { initialiseQuestionnaireResponse } from './utils/qrItem';
import { removeHiddenAnswers } from './utils/removeHidden';
import type { ItemToRepopulate } from './utils/repopulateItems';
import { getItemsToRepopulate } from './utils/repopulateItems';
@@ -25,13 +25,16 @@ export async function buildForm(
await questionnaireStore.getState().buildSourceQuestionnaire(questionnaire);
if (!questionnaireResponse) {
- questionnaireResponseStore
- .getState()
- .buildSourceResponse(createEmptyQuestionnaireResponse(questionnaire));
+ const initialisedQuestionnaireResponse = initialiseQuestionnaireResponse(questionnaire);
+ questionnaireResponseStore.getState().buildSourceResponse(initialisedQuestionnaireResponse);
return;
}
- questionnaireResponseStore.getState().buildSourceResponse(questionnaireResponse);
+ const initialisedQuestionnaireResponse = initialiseQuestionnaireResponse(
+ questionnaire,
+ questionnaireResponse
+ );
+ questionnaireResponseStore.getState().buildSourceResponse(initialisedQuestionnaireResponse);
questionnaireStore.getState().updatePopulatedProperties(questionnaireResponse);
}
diff --git a/packages/smart-forms-renderer/src/utils/qrItem.ts b/packages/smart-forms-renderer/src/utils/qrItem.ts
index 0958b2d25..ada7ddc4e 100644
--- a/packages/smart-forms-renderer/src/utils/qrItem.ts
+++ b/packages/smart-forms-renderer/src/utils/qrItem.ts
@@ -25,20 +25,28 @@ import type {
import type { QrRepeatGroup } from '../interfaces/repeatGroup.interface';
/**
- * Create an empty questionnaireResponse from a given questionnaire
+ * Initialise a conformant questionnaireResponse from a given questionnaire
+ * optionally takes in an existing questionnaireResponse to be initialised
*
* @author Sean Fong
*/
-export function createEmptyQuestionnaireResponse(
- questionnaire: Questionnaire
-): QuestionnaireResponse {
- const questionnaireResponse: QuestionnaireResponse = {
- resourceType: 'QuestionnaireResponse',
- status: 'in-progress'
- };
- const firstTopLevelItem = questionnaire?.item?.[0];
+export function initialiseQuestionnaireResponse(
+ questionnaire: Questionnaire,
+ questionnaireResponse?: QuestionnaireResponse
+) {
+ if (!questionnaireResponse) {
+ questionnaireResponse = {
+ resourceType: 'QuestionnaireResponse',
+ status: 'in-progress'
+ };
+ }
+
+ if (!questionnaireResponse.status) {
+ questionnaireResponse.status = 'in-progress';
+ }
- if (firstTopLevelItem) {
+ const firstTopLevelItem = questionnaire?.item?.[0];
+ if (firstTopLevelItem && !questionnaireResponse.item) {
questionnaireResponse.item = [
{
linkId: firstTopLevelItem.linkId,
@@ -48,13 +56,31 @@ export function createEmptyQuestionnaireResponse(
];
}
- if (questionnaire.id) {
- questionnaireResponse.questionnaire = `Questionnaire/${questionnaire.id}`;
+ if (!questionnaireResponse.questionnaire) {
+ questionnaireResponse.questionnaire = setQuestionnaireReference(questionnaire);
}
return questionnaireResponse;
}
+export function setQuestionnaireReference(questionnaire: Questionnaire) {
+ // Use {url}|{version} - the ideal way
+ if (questionnaire.url) {
+ let questionnaireReference = questionnaire.url;
+ if (questionnaire.version) {
+ questionnaireReference += '|' + questionnaire.version;
+ }
+ return questionnaireReference;
+ }
+
+ // If no url exists, use Questionnaire/{id}
+ if (questionnaire.id) {
+ return `Questionnaire/${questionnaire.id}`;
+ }
+
+ return '';
+}
+
/**
* Remove items with no answers from a given questionnaireResponse
* Also remove any starting or trailing whitespace from valueStrings