Skip to content

Commit

Permalink
Merge pull request #803 from aehrc/issue/692
Browse files Browse the repository at this point in the history
Issue/692
  • Loading branch information
fongsean authored May 21, 2024
2 parents 59ce39c + 64d1477 commit 37f2a5c
Show file tree
Hide file tree
Showing 36 changed files with 601 additions and 220 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ const rendererPropsReducer = (state: RendererPropsState, action: RendererPropsAc
questionnaire: action.payload.questionnaire,
response: action.payload.response,
additionalVars: action.payload.additionalVars,
terminologyServerUrl: action.payload.terminologyServerUrl
terminologyServerUrl: action.payload.terminologyServerUrl,
readOnly: action.payload.readOnly
};
case 'SET_RESPONSE':
return { ...state, response: action.payload };
case 'SET_ADDITIONAL_VARS':
return { ...state, additionalVars: action.payload };
case 'SET_TERMINOLOGY_SERVER':
return { ...state, terminologyServerUrl: action.payload };
case 'SET_READ_ONLY':
return { ...state, readOnly: action.payload };
default:
return state;
}
Expand All @@ -55,7 +58,8 @@ function Standalone() {
questionnaire: rendererPropsList[0].questionnaire,
response: rendererPropsList[0].response,
additionalVars: rendererPropsList[0].additionalVars,
terminologyServerUrl: rendererPropsList[0].terminologyServerUrl
terminologyServerUrl: rendererPropsList[0].terminologyServerUrl,
readOnly: rendererPropsList[0].readOnly
});
const [resourcesShown, setResourcesShown] = useState(false);

Expand Down Expand Up @@ -87,6 +91,7 @@ function Standalone() {
questionnaireResponse={state.response ?? undefined}
additionalVariables={state.additionalVars ?? undefined}
terminologyServerUrl={state.terminologyServerUrl ?? undefined}
readOnly={state.readOnly}
/>
</Stack>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ function StandalonePropsPicker(props: StandalonePropsPickerProps) {
label="Terminology server url"
/>
) : null}

{rendererPropsSingle.readOnly !== null ? (
<FormControlLabel
control={
<Checkbox
checked={state.readOnly}
onChange={() => {
dispatch({
type: 'SET_READ_ONLY',
payload: !state.readOnly
});
}}
/>
}
label="Read only"
/>
) : null}
</FormGroup>
</FormControl>
<Box display="flex" alignItems="center" columnGap={1}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface RendererPropsState {
response: QuestionnaireResponse | null;
additionalVars: Record<string, object> | null;
terminologyServerUrl: string | null;
readOnly: boolean;
}

export type RendererPropsActions =
Expand All @@ -34,8 +35,10 @@ export type RendererPropsActions =
response: QuestionnaireResponse | null;
additionalVars: Record<string, object> | null;
terminologyServerUrl: string | null;
readOnly: boolean;
};
}
| { type: 'SET_RESPONSE'; payload: QuestionnaireResponse | null }
| { type: 'SET_ADDITIONAL_VARS'; payload: Record<string, object> | null }
| { type: 'SET_TERMINOLOGY_SERVER'; payload: string | null };
| { type: 'SET_TERMINOLOGY_SERVER'; payload: string | null }
| { type: 'SET_READ_ONLY'; payload: boolean };
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,31 @@ export const rendererPropsList: RendererPropsState[] = [
questionnaire: Q715Json as Questionnaire,
response: R715Json as QuestionnaireResponse,
additionalVars: null,
terminologyServerUrl: null
terminologyServerUrl: null,
readOnly: false
},
{
id: 'TestGrid',
questionnaire: QTestGridJson as Questionnaire,
response: RTestGridJson as QuestionnaireResponse,
additionalVars: AddVarsTestGridJson,
terminologyServerUrl: null
terminologyServerUrl: null,
readOnly: false
},
{
id: 'CVDRiskCalculator',
questionnaire: QCVDRiskJson as Questionnaire,
response: RCVDRiskJson as QuestionnaireResponse,
additionalVars: null,
terminologyServerUrl: null
terminologyServerUrl: null,
readOnly: false
},
{
id: 'DemoAnswerExpression',
questionnaire: QDemoAnsExp as Questionnaire,
response: RDemoAnsExp as QuestionnaireResponse,
additionalVars: null,
terminologyServerUrl: 'http://hapi.fhir.org/baseR4'
terminologyServerUrl: 'http://hapi.fhir.org/baseR4',
readOnly: false
}
];
4 changes: 2 additions & 2 deletions documentation/docs/sdc/population.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ In the below x-fhir-query variable, `{{%patient.id}}` is a reference to the laun
}
```

For usages, refer to [initial](/smart-forms/docs/sdc/population#initial), [initialExpression](/smart-forms/docs/sdc/population#initialExpression), and [calculatedExpression](<(/smart-forms/docs/sdc/population#calculatedExpression)>) sections on this page.
For usages, refer to [initial](/smart-forms/docs/sdc/population#initial), [initialExpression](/smart-forms/docs/sdc/population#initialExpression), and [calculatedExpression](/smart-forms/docs/sdc/population#calculatedexpression) sections on this page.

### X-FHIR-Query Variable

Expand Down Expand Up @@ -103,7 +103,7 @@ After the query is executed, the expression can be consumed by initialExpression
}
```

For usages, refer to [initial](/smart-forms/docs/sdc/population#initial), [initialExpression](/smart-forms/docs/sdc/population#initialExpression), and [calculatedExpression](<(/smart-forms/docs/sdc/population#calculatedExpression)>) sections on this page.
For usages, refer to [initial](/smart-forms/docs/sdc/population#initial), [initialExpression](/smart-forms/docs/sdc/population#initialExpression), and [calculatedExpression](/smart-forms/docs/sdc/population#calculatedexpression) sections on this page.

### SourceQueries

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,17 @@ const BooleanField = memo(function BooleanField(props: BooleanFieldProps) {
<FadingCheckIcon fadeIn={calcExpUpdated} disabled={readOnly} />
<Fade in={valueBoolean !== undefined} timeout={100}>
<Tooltip title="Set question as unanswered">
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
<span>
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
</span>
</Tooltip>
</Fade>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,17 @@ function ChoiceRadioAnswerOptionFields(props: ChoiceRadioAnswerOptionFieldsProps
<FadingCheckIcon fadeIn={calcExpUpdated} disabled={readOnly} />
<Fade in={!!valueRadio} timeout={100}>
<Tooltip title="Set question as unanswered">
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
<span>
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
</span>
</Tooltip>
</Fade>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,17 @@ function ChoiceRadioAnswerValueSetFields(props: ChoiceRadioAnswerValueSetFieldsP
<FadingCheckIcon fadeIn={calcExpUpdated} disabled={readOnly} />
<Fade in={!!valueRadio} timeout={100}>
<Tooltip title="Set question as unanswered">
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
<span>
<Button
sx={{
color: grey['500'],
'&:hover': { backgroundColor: grey['200'] }
}}
disabled={readOnly}
onClick={onClear}>
Clear
</Button>
</span>
</Tooltip>
</Fade>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
import React from 'react';
import RendererThemeProvider from '../../theme/Theme';
import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
import useInitialiseRenderer from '../../hooks/useInitialiseRenderer';
import useInitialiseForm from '../../hooks/useInitialiseForm';
import Box from '@mui/material/Box';
import CircularProgress from '@mui/material/CircularProgress';
import Typography from '@mui/material/Typography';

import { QueryClientProvider } from '@tanstack/react-query';
import useQueryClient from '../../hooks/useQueryClient';
import useRendererQueryClient from '../../hooks/useRendererQueryClient';
import BaseRenderer from './BaseRenderer';
import type Client from 'fhirclient/lib/Client';

Expand Down Expand Up @@ -53,7 +53,9 @@ export interface SmartFormsRendererProps {

/**
* A self-initialising wrapper around the BaseRenderer rendering engine.
* See SmartFormsRendererProps for props.
* // FIXME add github link
*
* @see {SmartFormsRendererProps} for props.
*
* @author Sean Fong
*/
Expand All @@ -67,15 +69,15 @@ function SmartFormsRenderer(props: SmartFormsRendererProps) {
readOnly
} = props;

const isLoading = useInitialiseRenderer(
const isLoading = useInitialiseForm(
questionnaire,
questionnaireResponse,
additionalVariables,
readOnly,
terminologyServerUrl,
fhirClient,
readOnly
additionalVariables,
fhirClient
);
const queryClient = useQueryClient();
const queryClient = useRendererQueryClient();

if (isLoading) {
return (
Expand Down
1 change: 1 addition & 0 deletions packages/smart-forms-renderer/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as useHidden } from './useHidden';
export { default as useBuildForm } from './useBuildForm';
export { default as useRendererQueryClient } from './useRendererQueryClient';
30 changes: 27 additions & 3 deletions packages/smart-forms-renderer/src/hooks/useBuildForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,38 @@ import { useLayoutEffect, useState } from 'react';
import { buildForm } from '../utils';
import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';

function useBuildForm(questionnaire: Questionnaire, questionnaireResponse?: QuestionnaireResponse) {
/**
* React hook wrapping around the buildForm() function to build a form from a questionnaire and an optional QuestionnaireResponse.
* @see {buildForm} for more information.
*
* @param questionnaire - Questionnaire to be rendered
* @param questionnaireResponse - Pre-populated/draft/loaded QuestionnaireResponse to be rendered (optional)
* @param readOnly - Applies read-only mode to all items in the form view
* @param terminologyServerUrl - Terminology server url to fetch terminology. If not provided, the default terminology server will be used. (optional)
* @param additionalVariables - Additional key-value pair of SDC variables <name, variable extension> for testing (optional)
*
* @author Sean Fong
*/
function useBuildForm(
questionnaire: Questionnaire,
questionnaireResponse?: QuestionnaireResponse,
readOnly?: boolean,
terminologyServerUrl?: string,
additionalVariables?: Record<string, object>
) {
const [isBuilding, setIsBuilding] = useState(true);

useLayoutEffect(() => {
buildForm(questionnaire, questionnaireResponse).then(() => {
buildForm(
questionnaire,
questionnaireResponse,
readOnly,
terminologyServerUrl,
additionalVariables
).then(() => {
setIsBuilding(false);
});
}, [questionnaire, questionnaireResponse]);
}, [additionalVariables, questionnaire, questionnaireResponse, readOnly, terminologyServerUrl]);

return isBuilding;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/smart-forms-renderer/src/hooks/useHidden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ import { useQuestionnaireStore } from '../stores';
import { isHiddenByEnableWhen } from '../utils/qItem';
import { structuredDataCapture } from 'fhir-sdc-helpers';

/**
* React hook to determine if a QuestionnaireItem is hidden via item.hidden, enableWhens, enableWhenExpressions.
* When checking for repeating group enableWhen items, the parentRepeatGroupIndex should be provided.
*
* @author Sean Fong
*/
function useHidden(qItem: QuestionnaireItem, parentRepeatGroupIndex?: number): boolean {
const enableWhenIsActivated = useQuestionnaireStore.use.enableWhenIsActivated();
const enableWhenItems = useQuestionnaireStore.use.enableWhenItems();
Expand Down
Loading

0 comments on commit 37f2a5c

Please sign in to comment.