Skip to content

Commit 19e51fa

Browse files
committed
Update custom renderers
1 parent f5d4352 commit 19e51fa

35 files changed

Lines changed: 18433 additions & 28837 deletions

.github/workflows/gh-pages.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ jobs:
1919
with:
2020
node-version: '18'
2121

22+
- name: Setup pnpm
23+
uses: pnpm/action-setup@v2
24+
with:
25+
version: '9'
26+
2227
- name: Create redirect page for fhirpath-editor
2328
run: |
2429
mkdir -p fhirpath-editor
@@ -80,6 +85,16 @@ jobs:
8085
</html>
8186
EOF
8287
88+
- name: Build Aidbox Forms renderers
89+
run: |
90+
pnpm install --frozen-lockfile --dir aidbox-forms/aidbox-forms-builder-custom-renderer/csiro-renderer
91+
pnpm install --frozen-lockfile --dir aidbox-forms/aidbox-forms-builder-custom-renderer/smart-forms-renderer
92+
pnpm --dir aidbox-forms/aidbox-forms-builder-custom-renderer/csiro-renderer build
93+
pnpm --dir aidbox-forms/aidbox-forms-builder-custom-renderer/smart-forms-renderer build
94+
mkdir -p examples/renderers/csiro examples/renderers/smart-forms
95+
cp -R aidbox-forms/aidbox-forms-builder-custom-renderer/csiro-renderer/dist/* examples/renderers/csiro/
96+
cp -R aidbox-forms/aidbox-forms-builder-custom-renderer/smart-forms-renderer/dist/* examples/renderers/smart-forms/
97+
8398
- name: Publish
8499
uses: JamesIves/github-pages-deploy-action@v4
85100
with:

aidbox-forms/aidbox-forms-builder-custom-renderer/Caddyfile

Lines changed: 0 additions & 15 deletions
This file was deleted.

aidbox-forms/aidbox-forms-builder-custom-renderer/Dockerfile

Lines changed: 0 additions & 15 deletions
This file was deleted.

aidbox-forms/aidbox-forms-builder-custom-renderer/README.md

Lines changed: 42 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@ This tutorial demonstrates how to connect a custom renderer to the Aidbox Forms
1010

1111
The Aidbox Forms Builder allows you to use custom renderers to display questionnaires with your own UI components. This example shows how to:
1212

13-
1. Wrap your renderer as a web component
14-
2. Host and configure it with Aidbox
15-
3. Use it in the Forms Builder preview
13+
1. Host a renderer page that speaks [SDC SMART Web Messaging](https://github.com/brianpos/sdc-smart-web-messaging)
14+
2. Register renderer URLs in Aidbox
15+
3. Use them in the Forms Builder preview
1616

1717
## Prerequisites
1818

19-
- Docker and Docker Compose
20-
- Aidbox license (get one from [Aidbox Console](https://aidbox.io))
19+
- Running Aidbox
2120

2221
## Tutorial
2322

@@ -30,145 +29,54 @@ cp .env.example .env
3029
# Add your AIDBOX_LICENSE to .env
3130
```
3231

33-
### Step 2: Build the Smartforms Component
32+
### Step 2: Pick a Renderer and Build It (Vite)
3433

35-
This example includes a CSIRO Smartforms renderer wrapped as a web component. Build it first:
34+
This repo includes two renderer pages: `csiro-renderer` and `smart-forms-renderer`. Pick the renderer you want and build it.
3635

3736
```bash
38-
cd smartforms-component
39-
npm install
40-
npm run build
41-
cd ..
37+
cd csiro-renderer
38+
pnpm install
39+
pnpm build
4240
```
4341

44-
### Step 3: Wrap Your Renderer for Forms Builder Compatibility
45-
46-
The Forms Builder expects a specific web component structure. Use the provided template `custom-renderer.template.js`:
47-
48-
```javascript
49-
// simple-questionnaire-renderer.js
50-
if(!customElements.get("simple-questionnaire-renderer")) {
51-
52-
class SimpleQuestionnaireRenderer extends HTMLElement {
53-
constructor() {
54-
super();
55-
this.attachShadow({ mode: 'open' });
56-
this._questionnaire = null;
57-
this._questionnaireResponse = null;
58-
this._onQuestionnaireResponseChange = null;
59-
}
60-
61-
static get observedAttributes() {
62-
return ['questionnaire', 'questionnaire-response'];
63-
}
64-
65-
// Handle attribute updates from Forms Builder
66-
attributeChangedCallback(name, oldValue, newValue) {
67-
if (!this.shadowRoot || oldValue === newValue) return;
68-
69-
try {
70-
const parsed = newValue ? JSON.parse(newValue) : null;
71-
if (name === 'questionnaire') this._questionnaire = parsed;
72-
if (name === 'questionnaire-response') this._questionnaireResponse = parsed;
73-
this.render();
74-
} catch (e) {
75-
console.error(`Invalid JSON for ${name}:`, e);
76-
}
77-
}
78-
79-
// Property accessors
80-
get questionnaire() { return this._questionnaire; }
81-
set questionnaire(value) { this._questionnaire = value; this.render(); }
82-
83-
get questionnaireResponse() { return this._questionnaireResponse; }
84-
set questionnaireResponse(value) { this._questionnaireResponse = value; this.render(); }
85-
86-
set onQuestionnaireResponseChange(callback) {
87-
this._onQuestionnaireResponseChange = callback;
88-
}
89-
90-
render() {
91-
if (!this.shadowRoot) return;
92-
// Implement your questionnaire rendering here
93-
}
94-
}
95-
96-
customElements.define('simple-questionnaire-renderer', SimpleQuestionnaireRenderer);
97-
}
98-
```
42+
If you want the other renderer later, repeat the same steps in `smart-forms-renderer`.
43+
44+
### Step 3: Use Renderer Pages (SDC SWM)
9945

100-
The only required attribute is `questionnaire`.
101-
Support `questionnaire-response` to receive populated QuestionnaireResponse.
102-
Support `onQuestionnaireResponseChange` if you want to send QuestionnaireResponse back to the builder.
46+
The Forms Builder loads a renderer by URL. The renderer page must implement [SDC SMART Web Messaging](https://github.com/brianpos/sdc-smart-web-messaging) and respond to `postMessage` requests from the host.
10347

104-
This tutorial includes `simple-questionnaire-renderer.js`, a reference implementation that renders FHIR Questionnaires using native HTML inputs.
48+
Each renderer page in this repo is a Vite app (`index.html` + `src/index.js`) that builds to a static `dist/` folder, mounts the SmartForms renderer, and bridges messages to the host.
10549

10650
### Step 4: Host Your Renderer
10751

108-
The web component must be accessible via URL. This tutorial uses Caddy to serve the renderer files:
109-
110-
```dockerfile
111-
# Dockerfile
112-
FROM caddy:alpine
113-
COPY Caddyfile /etc/caddy/Caddyfile
114-
WORKDIR /srv
115-
COPY ./smartforms-component/dist/aidbox-forms-renderer-csiro-webcomponent.js /srv/
116-
COPY ./simple-questionnaire-renderer.js /srv/
117-
EXPOSE 80
118-
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
119-
```
52+
The renderer page must be accessible via URL. You can use either:
12053

121-
### Step 5: Configure Aidbox
122-
123-
To register custom renderers with Aidbox Forms, update the `SDCConfig` resource.
124-
125-
Each renderer in the `custom-renderers` array requires:
126-
- **`name`** - The HTML tag name of your web component (e.g., `simple-questionnaire-renderer`)
127-
- **`source`** - URL where the renderer JavaScript file is hosted
128-
- **`title`** - Display name shown in the Forms Builder renderer dropdown
129-
130-
Create an initialization bundle (`init-bundle.json`) to configure the custom renderers:
131-
132-
```json
133-
{
134-
"resourceType" : "Bundle",
135-
"type" : "transaction",
136-
"entry" : [ {
137-
"resource" : {
138-
"resourceType" : "SDCConfig",
139-
"name": "custom-renderers-config",
140-
"default": true,
141-
"id" : "custom-renderer-config",
142-
"builder": {
143-
"custom-renderers": [
144-
{
145-
"name" : "aidbox-form-csiro-renderer",
146-
"source" : "http://localhost:8081/aidbox-forms-renderer-csiro-webcomponent.js",
147-
"title" : "CSIRO"
148-
},
149-
{
150-
"name" : "simple-questionnaire-renderer",
151-
"source" : "http://localhost:8081/simple-questionnaire-renderer.js",
152-
"title" : "Simple Questionnaire Renderer"
153-
}
154-
]
155-
}
156-
},
157-
"request" : {
158-
"method" : "PUT",
159-
"url" : "SDCConfig/custom-renderer-config"
160-
}
161-
}]
162-
}
54+
1) Vite dev server (local testing):
55+
56+
```bash
57+
cd csiro-renderer
58+
pnpm dev
16359
```
16460

165-
### Step 6: Start Services
61+
If you chose `smart-forms-renderer`, run the same command from that folder instead.
62+
63+
2) Built files hosted anywhere (for preview):
16664

16765
```bash
168-
docker-compose up -d --pull always --build
66+
pnpm build
16967
```
17068

171-
### Step 7: Use in Forms Builder
69+
Then host the resulting `dist/` folder with any static hosting.
70+
71+
### Step 5: Add the Renderer in Forms Builder
72+
73+
Open Forms Builder and use the renderer switcher (eye icon near the theme selector).
74+
75+
1) Click **Add custom renderer**
76+
2) Enter a name and the renderer URL (for example `http://localhost:5173`)
77+
3) Save
78+
79+
### Step 6: Use in Forms Builder
17280

17381
1. **Access Forms Builder:** Go to http://localhost:8080 and navigate to Forms Builder
17482
2. **Create/Edit Questionnaire:** Use the visual editor to build your form
@@ -177,31 +85,28 @@ docker-compose up -d --pull always --build
17785

17886
**Service URLs:**
17987
- Aidbox: http://localhost:8080
180-
- Custom renderer demo: http://localhost:8081
88+
- Renderer dev server: http://localhost:5173 (default Vite port)
18189

18290
## Troubleshooting
18391

18492
### Common Issues
18593

18694
1. **Renderer not appearing in Forms Builder:**
187-
- Check SDCConfig is properly loaded
188-
- Verify renderer URL is accessible
95+
- Verify the renderer URL is reachable
18996
- Check browser console for loading errors
19097

19198
2. **Response not updating:**
192-
- Ensure `onQuestionnaireResponseChange` callback is called
193-
- Check QuestionnaireResponse structure matches FHIR spec
194-
- Verify event listeners are attached to form inputs
99+
- Check browser console for postMessage errors
100+
- Confirm renderer page receives `sdc.displayQuestionnaire`
101+
- Verify the renderer sends `sdc.ui.changedQuestionnaireResponse`
195102

196103
3. **CORS issues:**
197104
- Ensure renderer URL is accessible from Forms Builder domain
198105
- Check network tab for failed requests
199106

200107
### Debug Steps
201108

202-
1. Check Aidbox logs: `docker-compose logs aidbox`
203-
2. Verify SDCConfig: `GET http://localhost:8080/SDCConfig/custom-renderer-config`
204-
3. Test renderer directly: http://localhost:8081/simple-questionnaire-renderer.js
109+
1. Test renderer directly: http://localhost:5173
205110
4. Check browser console in Forms Builder for errors
206111

207-
This example provides a complete foundation for integrating custom renderers that work seamlessly with the Aidbox Forms Builder.
112+
This example provides a complete foundation for integrating custom renderers that work seamlessly with the Aidbox Forms Builder.

aidbox-forms/aidbox-forms-builder-custom-renderer/smartforms-component/.gitignore renamed to aidbox-forms/aidbox-forms-builder-custom-renderer/csiro-renderer/.gitignore

File renamed without changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
features: [Custom renderer, Forms builder, Questionnaire, CSIRO, SMART Web Messaging]
3+
languages: [TypeScript]
4+
---
5+
# csiro-renderer
6+
7+
This package builds a static renderer page (`index.html` + `src/index.js`) that mounts the CSIRO SmartForms renderer and speaks [SDC SMART Web Messaging](https://github.com/brianpos/sdc-smart-web-messaging).
8+
9+
Renderer source: https://github.com/aehrc/smart-forms
10+
11+
To install dependencies:
12+
13+
```bash
14+
pnpm install
15+
```
16+
17+
To run a dev server:
18+
19+
```bash
20+
pnpm dev
21+
```
22+
23+
To build static assets:
24+
25+
```bash
26+
pnpm build
27+
```
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>CSIRO Renderer (SDC SWM)</title>
7+
<style>
8+
html, body {
9+
margin: 0;
10+
padding: 0;
11+
height: 100%;
12+
width: 100%;
13+
font-family: system-ui, -apple-system, sans-serif;
14+
background: #f8fafc;
15+
}
16+
17+
#status {
18+
position: fixed;
19+
top: 12px;
20+
left: 12px;
21+
right: 12px;
22+
padding: 10px 12px;
23+
background: #0f172a;
24+
color: #e2e8f0;
25+
border-radius: 8px;
26+
font-size: 12px;
27+
line-height: 1.4;
28+
z-index: 10;
29+
opacity: 0.92;
30+
}
31+
32+
#status.error {
33+
background: #7f1d1d;
34+
color: #fee2e2;
35+
}
36+
37+
#root {
38+
position: absolute;
39+
top: 56px;
40+
left: 0;
41+
right: 0;
42+
bottom: 0;
43+
width: 100%;
44+
height: calc(100% - 56px);
45+
overflow: auto;
46+
background: #fff;
47+
}
48+
49+
#portal {
50+
position: relative;
51+
z-index: 20;
52+
}
53+
</style>
54+
</head>
55+
<body>
56+
<div id="status">Initializing…</div>
57+
<div id="root"></div>
58+
<div id="portal"></div>
59+
<script type="module" src="/src/index.js"></script>
60+
</body>
61+
</html>

0 commit comments

Comments
 (0)