EHRbase入門4 - Medblock-ui

# はじめに

今回は以前に準備したTemplateをもとに[Medblocks UI]()で爆速Web開発をしていきます。

Medblocks UIはopenEHRのテンプレートをベースに[Svelte](https://svelte.jp/)をフレームワークとして[TypeScript](https://www.typescriptlang.org/)でWeb UIを作成します。EHRbaseのフロントエンドを効率よく開発できることで注目されています。




# 準備

EHRbaseのセットアップは以前に書いた[記事](https://qiita.com/skoba/items/9ff2946bc719858781f6)を参考にしてください。REST APIでtemplateを登録するのも[過去記事](https://qiita.com/skoba/items/98b4f993ae3e54480f53)を参考にしてください。

以下の3つが必要な準備事項です。

* openEHR Template
* Medblocs-uiのインストール
* [Visual Studio code(VS code)](https://code.visualstudio.com/)の設定


## openEHR template

今回の題材として「[Archetype Designer](https://tools.openehr.org/designer/)で体温のモニタリングするテンプレート」を作成します。

Archetype Designerで作ったファイルは以下においております。このファイルをArchetype Designerに取り込んでもらえればテンプレート開発環境が再現できます。

https://github.com/skoba/openehr-lesson-archetypes-jp/tree/main/local

Export済のWeb template，OPTを下記においておきます。

* Web template(JSON)


https://github.com/skoba/all-forms/blob/master/templates/body_temperature_check.v0.json

* Operational Template (OPT, XML形式)

https://github.com/skoba/all-forms/blob/master/public/opts/body_temperature_check.v0.opt


ダウンロードしたOPTファイルは[この記事](https://qiita.com/skoba/items/98b4f993ae3e54480f53)を参考にEHRbaseに登録しておいてください。

## Medblocks UIの設定

まず，npmを使ってMedblocks UIのパッケージをインストールします。npmはNode.js関連のパッケージ管理ツールです。

```shell
npm install medblocks-ui
```

Medblocks UIの[ドキュメント: Building CLinical Apps with openEHR](https://docs.medblocks.org/guides/building-clinical-apps-with-openehr)通りに進めても簡単ですが，一部のディレクトリ設定などが省略されています。手っ取り早く始めるには下記のリポジトリを clone して始めるのが便利です。

```shell
git clone https://github.com/medblocks/all-forms
```

cloneしたディレクトリからMedblocks-UIを起動します。

```shell
cd all-forms
npm run dev
```

http://localhost:3000/ にアクセスして動作を確認しましょう。

![Medblocks Forms - Example Forms using Medblocks UI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/a83e823e-fe67-386b-0654-5d15af34bf67.png)

EHRbaseが[以前の記事](https://qiita.com/skoba/items/9ff2946bc719858781f6)と同様にlocalhostにセットアップされていれば，下記のように入力して環境設定を行います。アドレスが違う場合にはそれを指定してください。


openEHR REST API: http://localhost:8080/ehrbase/rest/openehr/v1/
EHRScape API: http://localhost:8080/ehrbase/rest/ecis/v1/
EHR ID: [この記事](https://qiita.com/skoba/items/98b4f993ae3e54480f53)をもとにPOST EHRでEHRを作成してresponse headerからIDを取得してください。

Dockerから立ち上げていれば，以下のようにusername,passwordを設定します。
Username: ehrbase-user
Password: SuperSecretPassword

Saveボタンを押して保存します。


上のOPTファイルを下記ディレクトリにコピーします。

```
public/opts/
```


Web template file(JSON)は下記のディレクトリにコピーします。

```
templates/
```
## VS codeのセットアップ

Medblocks UIではVS codeのプラグインを使ってUIをTemplateから生成します。

VS codeを開いて，Shift + Ctrl + xをおして，medblocksを検索して medblocks uiのプラグインをインストールします。

```
https://marketplace.visualstudio.com/items?itemName=tornadoalert.medblocks-ui
```

インストールが成功すると左のツールバーにMedblocks UIというボタンができています。


![medblocks_button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/72470cd8-473d-f519-86bd-50be7145dcec.png)



# UIの生成

VS codeで左のMedblocks UIボタンを押すとWebテンプレートの一覧が出てきます。

body_temperature_check.v0 の横にあるコピーボタンを押すとクリップボードにhtml形式に変換されたデータがコピーされます。

左側の一番上のボタンを押して，ファイルメニューに切り替え，src/lib/formsを右クリックして新しいファイル(body_temperature_check.svelte)を作成して，内容をペーストします。

```html
    <mb-quantity default="Cel" path="body_temperature_check.v0/body_temperature/any_event:0/temperature" label="Temperature">
        <mb-unit unit="Cel" label="Cel" min="0" max="100"></mb-unit>
        <mb-unit unit="[degF]" label="[degF]" min="30" max="200"></mb-unit>
    </mb-quantity>
    <mb-context path="body_temperature_check.v0/body_temperature/any_event:0/time"></mb-context>
    <mb-select path="body_temperature_check.v0/body_temperature/location_of_measurement" label="Location of measurement" terminology="local">
    <mb-option value="at0061" label="Forehead"></mb-option>
    </mb-select>
    <mb-context path="body_temperature_check.v0/body_temperature/language"></mb-context>
    <mb-context path="body_temperature_check.v0/body_temperature/encoding"></mb-context>
    <mb-context path="body_temperature_check.v0/body_temperature/subject"></mb-context>
    <mb-context path="body_temperature_check.v0/category"></mb-context>
    <mb-context path="body_temperature_check.v0/language"></mb-context>
    <mb-context path="body_temperature_check.v0/territory"></mb-context>
    <mb-context path="body_temperature_check.v0/composer"></mb-context>
```


保存すると下記のURLでアクセスできるようになります。

```url
http://localhost:3000/body_temperature_check
```

これだけだとまだフォームが見えてこないかもしれません。


## FormListへの登録

 src/libにあるFormList.svelteをVS codeで開いて，body_temperature_checkを登録します。ここでは単にHTMLのリンクとして記載するのではなく、OPTやWeb templateも同時に登録します。変更した後セーブすると、動的にForm Listが書き換わり、Body Temperature checkというメニューが出てきます。

```html
<script lang="ts" context="module">
    import { Link } from "svelte-routing";
    import Allergy from "./forms/Allergy.svelte";
    import BloodPressure from "./forms/BloodPressure.svelte";
    import CovidForm from "./forms/CovidForm.svelte";
    import Opd from "./forms/Opd.svelte";
    import BodyTemperatureCheck from "./forms/body_temperature_check.svelte";

    export const forms: {
        name: string;
        id: string;
        component: any;
        opt: string;
    }[] = [
        {
            name: "Allergy",
            id: "pdjallergy.vo",
            component: Allergy,
            opt: "pdjallergy.vo.opt",
        },
        {
            name: "OPD",
            id: "opdvisitpdj.v0",
            component: Opd,
            opt: "opdvisitpdj.v0.opt",
        },
        {
            name: 'Blood Pressure',
            id: 'petetest',
            component: BloodPressure,
            opt: "petetest.opt"
        },
        {
            name: 'Covid Form',
            id: 'covid.form.v1',
            component: CovidForm,
            opt: "covid.form.v1.opt"
        },
        {
            name: 'Body Temperature check',
            id: 'body_temperature_check.v0',
            component: BodyTemperatureCheck,
            opt: "body_temperature_check.v0.opt"
        }
    ];
</script>

<div>
    
    {#each forms as form}
        <div class="bg-gray-100 flex p-3 m-3 border justify-between rounded-md">
            <Link class="font-medium" to={form.name.replaceAll(' ', '_')}>{form.name}</Link>
            <sl-tooltip content="Download Template">
                <sl-icon-button
                    download
                    href={`opts/${form.opt}`}
                    name="download"
                    label="Download"
                />
            </sl-tooltip>
        </div>
    {/each}
</div>
```

下記のようにBody Temperature CheckがForm listに掲載されるようになったら、Body Temperature Checkをおしてください。

![Screenshot 2022-04-23 at 12-57-56 Medblocks Forms - Example Forms using Medblocks UI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/fb912759-29b0-90d9-3bdb-a423b941bf29.png)


下記のような画面が出てくれば成功です。

![Medblocks Forms - Example Forms using Medblocks UI (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/4adffa50-ae53-9d18-22f8-9bb0896200a7.png)

送信ボタンがありませんので、追加します。

## 送信ボタンをつける

もう一度、VS codeでsrc/lib/forms/body_temperature_check.svelteを開いて以下のようにformに関連するタグを挿入します。

```html
<mb-form class="flex flex-col gap-3 p-5 shadow-lg rounded-lg border">
    <mb-quantity default="Cel" path="body_temperature_check.v0/body_temperature/any_event:0/temperature" label="Temperature">
        <mb-unit unit="Cel" label="Cel" min="0" max="100"></mb-unit>
        <mb-unit unit="[degF]" label="[degF]" min="30" max="200"></mb-unit>
    </mb-quantity>
    <mb-context path="body_temperature_check.v0/body_temperature/any_event:0/time"></mb-context>
    <mb-select path="body_temperature_check.v0/body_temperature/location_of_measurement" label="Location of measurement" terminology="local">
    <mb-option value="at0061" label="Forehead"></mb-option>
    </mb-select>
    <mb-context path="body_temperature_check.v0/body_temperature/language"></mb-context>
    <mb-context path="body_temperature_check.v0/body_temperature/encoding"></mb-context>
    <mb-context path="body_temperature_check.v0/body_temperature/subject"></mb-context>
    <mb-context path="body_temperature_check.v0/category"></mb-context>
    <mb-context path="body_temperature_check.v0/language"></mb-context>
    <mb-context path="body_temperature_check.v0/territory"></mb-context>
    <mb-context path="body_temperature_check.v0/composer"></mb-context>

    
    <mb-submit>
        <sl-button type="neutral">Submit</sl-button>
    </mb-submit>
</mb-form>

```

これをセーブすると下記のように表示されるはずです。

![Screenshot 2022-04-23 at 17-54-54 Medblocks Forms - Example Forms using Medblocks UI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/b90c26de-a353-39ec-004c-b7b8f1d76022.png)

体温を記入して登録すると右上に登録が成功したというメッセージが出てきます。

![screenshot_success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18960/af17d674-91fa-41c1-0209-fc2dcad938c2.png)

失敗する場合は下記をチェックしてみてください。

* OPTをEHRbaseに登録しているか。
* FormList.svelteにOPTやWeb templateを間違いなく登録できているか。

他のフォームなどを参考にしながら、チェックを進めてください。

登録した体温は直接Webには反映されませんが、EHRbaseには登録されていますので、AQLなどを使ってデータを見てください。

上記のデータをすべて反映させたものを以下で公開しております。

https://github.com/skoba/all-forms