Skip to content

Commit

Permalink
Merge pull request #834 from aehrc/issue/833
Browse files Browse the repository at this point in the history
Issue/833
  • Loading branch information
fongsean authored Jun 3, 2024
2 parents 76d2f30 + dd4dc4b commit b2e19ea
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 16 deletions.
4 changes: 2 additions & 2 deletions apps/smart-forms-app/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ Cypress.Commands.add('waitForPopulation', () => {
});

Cypress.Commands.add('launchFromEHRProxy', () => {
const launchUrl = `${appUrl}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjUxNzMvIiwiMWZmN2JkYzItMzZiMi00MzAzLThjMDUtYzU3MzQyYzViMDQzIiwiIiwiIiwiIiwiIiwwLDEsIiIsZmFsc2Vd`;
const launchUrl = `${appUrl}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjQxNzMvIiwiYTU3ZDkwZTMtNWY2OS00YjkyLWFhMmUtMjk5MjE4MDg2M2MxIiwiIiwiIiwiIiwiIiwwLDEsIiIsZmFsc2Vd`;
cy.visit(launchUrl);
});

Cypress.Commands.add('launchFromEHRProxyQuesContext', () => {
const launchUrl = `${appUrl}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjUxNzMvIiwiMWZmN2JkYzItMzZiMi00MzAzLThjMDUtYzU3MzQyYzViMDQzIiwiIiwiIiwiIiwiIiwwLDEsIntcInJvbGVcIjpcInF1ZXN0aW9ubmFpcmUtcmVuZGVyLW9uLWxhdW5jaFwiLFwiY2Fub25pY2FsXCI6XCJodHRwOi8vd3d3LmhlYWx0aC5nb3YuYXUvYXNzZXNzbWVudHMvbWJzLzcxNXwwLjEuMC1hc3NlbWJsZWRcIixcInR5cGVcIjpcIlF1ZXN0aW9ubmFpcmVcIn0iLGZhbHNlXQ`;
const launchUrl = `${appUrl}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjQxNzMvIiwiYTU3ZDkwZTMtNWY2OS00YjkyLWFhMmUtMjk5MjE4MDg2M2MxIiwiIiwiIiwiIiwiIiwwLDEsIntcInJvbGVcIjpcInF1ZXN0aW9ubmFpcmUtcmVuZGVyLW9uLWxhdW5jaFwiLFwiY2Fub25pY2FsXCI6XCJodHRwOi8vd3d3LmhlYWx0aC5nb3YuYXUvYXNzZXNzbWVudHMvbWJzLzcxNXwwLjEuMC1hc3NlbWJsZWRcIixcInR5cGVcIjpcIlF1ZXN0aW9ubmFpcmVcIn0iLGZhbHNlXQ`;
cy.visit(launchUrl);
});

Expand Down
6 changes: 4 additions & 2 deletions documentation/docs/api/sdc-populate/functions/populate.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Function: populate()

> **populate**(`parameters`, `fetchResourceCallback`, `requestConfig`): `Promise` \<[`OutputParameters`](../interfaces/OutputParameters.md) \| `OperationOutcome`\>
> **populate**(`parameters`, `fetchResourceCallback`, `fetchResourceRequestConfig`, `terminologyCallback`?, `terminologyRequestConfig`?): `Promise` \<[`OutputParameters`](../interfaces/OutputParameters.md) \| `OperationOutcome`\>
Executes the SDC Populate Questionnaire operation - $populate.
Input and output specific parameters conformant to the SDC populate specification. Can be deployed as a $populate microservice.
Expand All @@ -13,7 +13,9 @@ This function expects a nice set of populate input parameters to go. If you do y
| :------ | :------ |
| `parameters` | [`InputParameters`](../interfaces/InputParameters.md) |
| `fetchResourceCallback` | [`FetchResourceCallback`](../interfaces/FetchResourceCallback.md) |
| `requestConfig` | `any` |
| `fetchResourceRequestConfig` | `any` |
| `terminologyCallback`? | [`FetchResourceCallback`](../interfaces/FetchResourceCallback.md) |
| `terminologyRequestConfig`? | `any` |

## Returns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ Any request configuration to be passed to the fetchResourceCallback i.e. headers

***

### terminologyCallback?

> `optional` **terminologyCallback**: [`FetchResourceCallback`](FetchResourceCallback.md)
A callback function to fetch terminology resources, optional

***

### terminologyRequestConfig?

> `optional` **terminologyRequestConfig**: `any`
Any request configuration to be passed to the terminologyCallback i.e. headers, auth etc., optional

***

### user?

> `optional` **user**: `Practitioner`
Expand Down
10 changes: 10 additions & 0 deletions documentation/docs/components/display.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ import IframeContainer from '../../src/react/IframeContainer';
/>
</IframeContainer>

#### Calculations with [cqf-expression](/docs/sdc/calculations#cqf-expression) styled with [rendering-style](/docs/sdc/advanced/display#rendering-style)

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-itemtype-display--display-calculation-styled">
<iframe
src="http://smartforms.csiro.au/storybook/iframe.html?args=&id=component-itemtype-display--display-calculation-styled"
width="100%"
height="240"
/>
</IframeContainer>

There are SDC advanced form rendering usages in the SDC [Display/Text Rendering](/docs/sdc/advanced/display) section.

If there are any advanced usage scenarios you'd like to see, feel free to [let us know](https://github.com/aehrc/smart-forms/issues/new).
Expand Down
26 changes: 26 additions & 0 deletions documentation/docs/sdc/advanced/display.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,32 @@ This mechanic doesn't interact with the "Previous/Next Tab" buttons. You can sti

:::

### Rendering Style

Allows styling of the item's label using CSS styles. This is useful when the item's label needs to be styled differently from the rest of the form to draw attention to it.

For more information, refer to http://hl7.org/fhir/uv/sdc/rendering.html#rendering-style.

#### Basic Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-8-1-1-advanced-text-appearance--rendering-style-boolean-checkbox">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-8-1-1-advanced-text-appearance--rendering-style-boolean-checkbox"
width="100%"
height="100"
/>
</IframeContainer>

#### Calculations Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-itemtype-display--display-calculation-styled">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-itemtype-display--display-calculation-styled"
width="100%"
height="240"
/>
</IframeContainer>

### Rendering XHTML

Provides an alternate representation of the item's label as a XHTML string. Allows for the rendering of styled text and base64-encoded images.
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/smart-forms-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-markdown": "^8.0.7",
"style-to-object": "^1.0.6",
"zustand": "^4.5.2"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import React, { memo } from 'react';
import type { QuestionnaireItem } from 'fhir/r4';
import { getMarkdownString, getXHtmlString } from '../../../utils/itemControl';
import parse from 'html-react-parser';
import { default as htmlParse } from 'html-react-parser';
import Box from '@mui/material/Box';
import ReactMarkdown from 'react-markdown';
import Typography from '@mui/material/Typography';
import useDisplayCqfAndCalculatedExpression from '../../../hooks/useDisplayCqfAndCalculatedExpression';
import { structuredDataCapture } from 'fhir-sdc-helpers';
import { default as styleParse } from 'style-to-js';

interface ItemLabelTextProps {
qItem: QuestionnaireItem;
Expand All @@ -32,21 +34,18 @@ interface ItemLabelTextProps {
const ItemLabelText = memo(function ItemLabelText(props: ItemLabelTextProps) {
const { qItem, readOnly } = props;

let labelText = qItem.text ?? '';

// Use calculatedExpressionString if available
const calculatedExpressionString = useDisplayCqfAndCalculatedExpression(qItem);
const calculatedExpressionString = useDisplayCqfAndCalculatedExpression(qItem) ?? '';
if (calculatedExpressionString) {
return (
<Typography color={readOnly ? 'text.disabled' : 'text.primary'} sx={{ mt: 0.25 }}>
{calculatedExpressionString}
</Typography>
);
labelText = calculatedExpressionString;
}

// parse xHTML if found
const xHtmlString = getXHtmlString(qItem);

if (xHtmlString) {
return <Box>{parse(xHtmlString)}</Box>;
return <Box>{htmlParse(xHtmlString)}</Box>;
}

// parse markdown if found
Expand All @@ -59,14 +58,26 @@ const ItemLabelText = memo(function ItemLabelText(props: ItemLabelTextProps) {
);
}

// labelText is empty, return null
if (!labelText) {
return null;
}

// parse styles if found
const stylesString = structuredDataCapture.getStyle(qItem._text);
if (stylesString) {
const styles = styleParse(stylesString);
return <div style={styles}>{labelText}</div>;
}

if (qItem.type === 'group') {
return <>{qItem.text}</>;
return <>{labelText}</>;
}

// parse regular text
return (
<Typography color={readOnly ? 'text.disabled' : 'text.primary'} sx={{ mt: 0.25 }}>
{qItem.text}
{labelText}
</Typography>
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
import type { Questionnaire } from 'fhir/r4';

export const qRenderingStyleBooleanCheckboxItem: Questionnaire = {
resourceType: 'Questionnaire',
id: 'RenderingStyle-1',
name: 'RenderingStyle-1',
title: 'Rendering Style 1',
version: '0.1.0',
status: 'draft',
publisher: 'AEHRC CSIRO',
date: '2024-05-01',
url: 'https://smartforms.csiro.au/docs/advanced/text/rendering-style-1',
item: [
{
linkId: 'mark-complete',
text: 'Mark section as complete',
_text: {
extension: [
{
url: 'http://hl7.org/fhir/StructureDefinition/rendering-style',
valueString:
'padding: 0.75rem; margin-bottom: 1rem; font-size: 0.875rem; color: #2E7D32; border-radius: 0.5rem; background-color: #d5e5d6; font-weight: 700;'
}
]
},
type: 'boolean',
repeats: false
}
]
};

export const qRenderingXhtmlBooleanCheckboxItem: Questionnaire = {
resourceType: 'Questionnaire',
id: 'RenderingXhtml-1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,85 @@ export const qDisplayCalculation: Questionnaire = {
}
]
};

export const qDisplayCalculationStyled: Questionnaire = {
resourceType: 'Questionnaire',
id: 'DisplayCalculationStyled',
name: 'DisplayCalculationStyled',
title: 'Display Calculation Styled',
version: '0.1.0',
status: 'draft',
publisher: 'AEHRC CSIRO',
date: '2024-05-01',
url: 'https://smartforms.csiro.au/docs/components/display/calculation-styled',
extension: [
{
url: 'http://hl7.org/fhir/StructureDefinition/variable',
valueExpression: {
name: 'gender',
language: 'text/fhirpath',
expression: "item.where(linkId = 'gender-controller').answer.valueCoding.code"
}
}
],
item: [
{
linkId: 'gender-controller',
text: 'Gender',
type: 'choice',
repeats: false,
answerOption: [
{
valueCoding: {
system: 'http://hl7.org/fhir/administrative-gender',
code: 'female',
display: 'Female'
}
},
{
valueCoding: {
system: 'http://hl7.org/fhir/administrative-gender',
code: 'male',
display: 'Male'
}
},
{
valueCoding: {
system: 'http://hl7.org/fhir/administrative-gender',
code: 'other',
display: 'Other'
}
},
{
valueCoding: {
system: 'http://hl7.org/fhir/administrative-gender',
code: 'unknown',
display: 'Unknown'
}
}
]
},
{
linkId: 'gender-display',
type: 'display',
repeats: false,
_text: {
extension: [
{
url: 'http://hl7.org/fhir/StructureDefinition/cqf-expression',
valueExpression: {
language: 'text/fhirpath',
expression: "'Gender: '+ %gender"
}
},
{
url: 'http://hl7.org/fhir/StructureDefinition/rendering-style',
valueString:
'padding: 0.75rem; margin-bottom: 1rem; font-size: 0.875rem; color: #2E7D32; border-radius: 0.5rem; background-color: #d5e5d6; font-weight: 700;'
}
]
},
text: ''
}
]
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

import type { Meta, StoryObj } from '@storybook/react';
import BuildFormWrapperForStorybook from '../storybookWrappers/BuildFormWrapperForStorybook';
import { qDisplayBasic, qDisplayCalculation } from '../assets/questionnaires/QDisplay';
import {
qDisplayBasic,
qDisplayCalculation,
qDisplayCalculationStyled
} from '../assets/questionnaires/QDisplay';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
Expand All @@ -43,3 +47,9 @@ export const DisplayCalculation: Story = {
questionnaire: qDisplayCalculation
}
};

export const DisplayCalculationStyled: Story = {
args: {
questionnaire: qDisplayCalculationStyled
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
qDisplayCategoryInstructions,
qHidden,
qOpenLabel,
qRenderingStyleBooleanCheckboxItem,
qRenderingXhtmlBooleanCheckboxItem,
qRenderingXhtmlDisplayBase64ImageItem,
qRenderingXhtmlDisplayListItem
Expand All @@ -39,6 +40,12 @@ type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args

export const RenderingStyleBooleanCheckbox: Story = {
args: {
questionnaire: qRenderingStyleBooleanCheckboxItem
}
};

export const RenderingXHTMLBooleanCheckbox: Story = {
args: {
questionnaire: qRenderingXhtmlBooleanCheckboxItem
Expand Down

0 comments on commit b2e19ea

Please sign in to comment.