Skip to content

Commit

Permalink
Advanced json UI (#46)
Browse files Browse the repository at this point in the history
* UI fixes for advanced feature switch and footer version string

* Update quick sample button style

* Add UI for viewing resource JSON in advanced mode

* Responsive fixes
  • Loading branch information
daniellrgn authored Oct 23, 2024
1 parent 6223663 commit cd68022
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/lib/FetchSoF.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
<Col xs="auto">
<Button
color="secondary"
outline
style="width:fit-content"
disabled={processing || loadingSample}
type="button"
Expand Down
110 changes: 99 additions & 11 deletions src/lib/ResourceSelector.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
<script lang='ts'>
import { uploadResources } from './resourceUploader.js';
import { createEventDispatcher } from 'svelte';
import { derived, get, type Writable } from 'svelte/store';
import { download } from './util.js';
import { createEventDispatcher, getContext } from 'svelte';
import { get, type Writable } from 'svelte/store';
import {
Accordion,
AccordionItem,
Badge,
Button,
ButtonGroup,
Card,
CardBody,
CardHeader,
Col,
FormGroup,
Icon,
Input,
Offcanvas,
Label,
Row } from 'sveltestrap';
import { ResourceHelper } from './ResourceHelper.js';
Expand Down Expand Up @@ -64,6 +69,8 @@
const statusDispatch = createEventDispatcher<{ 'status-update': string }>();
const errorDispatch = createEventDispatcher<{ 'error': string }>();
let mode: Writable<string> = getContext('mode');
let reference: string;
let selectedPatient: string = get(resourceCollection.selectedPatient);
$: if (selectedPatient) {
Expand Down Expand Up @@ -163,7 +170,57 @@
patientBadgeColor = badgeColor ?? patientBadgeColor;
}
}
let json = "";
let resourceType = "";
let isOpen = false;
function setJson(rh: ResourceHelper) {
json = JSON.stringify(rh.resource, null, 2);
resourceType = rh.resource.resourceType;
isOpen = true;
}
function toggle() {
isOpen = !isOpen;
}
</script>

<Offcanvas
{isOpen}
{toggle}
scroll={false}
header={resourceType + " JSON"}
placement="end"
title={resourceType + " JSON"}
style="display: flex; overflow-y:hidden; height: 100dvh;"
>
<Row class="d-flex" style="height: 100%">
<Row class="d-flex pe-0" style="height:calc(100% - 50px)">
<Col class="d-flex pe-0" style="height:100%">
<div class="d-flex pe-0 pb-0 code-container">
<pre class="code"><code>{json}</code></pre>
</div>
</Col>
</Row>
<Row class="d-flex pe-0" style="height:50px">
<Col class="d-flex justify-content-start align-items-end" style="padding-top: 1rem">
<ButtonGroup>
<Button
size="sm"
color="primary"
on:click={() => navigator.clipboard.writeText(json)}
><Icon name="clipboard" /> Copy</Button>
<Button
size="sm"
outline
color="secondary"
on:click={() => download(resourceType + ".json", json)}
><Icon name="download" /> Download</Button>
</ButtonGroup>
</Col>
</Row>
</Row>
</Offcanvas>

<AccordionItem active class="edit-data">
<h5 slot="header" class="my-2">4. Directly edit your health summary content</h5>
<Label>Select which resources to include in your customized IPS</Label>
Expand Down Expand Up @@ -212,14 +269,29 @@
</span>
<FormGroup>
{#each Object.keys($resourcesByTypeStore[resourceType]) as key}
<Label style="width: 100%">
<Card style="width: 100%; max-width: 100%">
<CardHeader>
<span style="font-size:small">{resourceType}</span>
</CardHeader>
<Card style="width: 100%; max-width: 100%" class="mb-2">
<CardHeader>
<Row>
<Col class="d-flex justify-content-start align-items-center">
<span style="font-size:small">{resourceType}</span>
</Col>
{#if $mode === "advanced"}
<Col class="d-flex justify-content-end align-items-center">
<Button
size="sm"
color="secondary"
on:click={() => setJson($resourcesByTypeStore[resourceType][key])}
>
JSON
</Button>
</Col>
{/if}
</Row>
</CardHeader>
<Label style="width: 100%">
<CardBody>
<Row>
<Col xs=auto style="vertical-align:baseline">
<Row style="overflow:hidden">
<Col xs=auto class="d-flex align-items-center pe-0">
{#if resourceType === "Patient"}
<Input id={key} type="radio" bind:group={selectedPatient} value={key} />
{:else}
Expand All @@ -239,8 +311,8 @@
</Col>
</Row>
</CardBody>
</Card>
</Label>
</Label>
</Card>
{/each}
</FormGroup>
</AccordionItem>
Expand All @@ -250,3 +322,19 @@
{/if}
</AccordionItem>

<style>
.code {
overflow:auto;
margin: 0;
padding: 10px;
}
.code-container {
background-color: #f5f5f5;
border-radius: 10px;
border: 1px solid rgb(200, 200, 200);
overflow: hidden;
}
:global(div.offcanvas-body) {
overflow-y: hidden !important;
}
</style>
13 changes: 13 additions & 0 deletions src/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ export async function base64toBlob(base64:string, type="application/octet-stream
return window.URL.createObjectURL(await result.blob());
}

export function download(filename:string, text:string) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);

element.style.display = 'none';
document.body.appendChild(element);

element.click();

document.body.removeChild(element);
}

export function getResourcesFromIPS(ips: Bundle) {
let entries = ips.entry;
let resources = [] as Resource[];
Expand Down
23 changes: 14 additions & 9 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
</NavItem>
<Dropdown nav inNavbar size="sm" direction="down">
<DropdownToggle color="primary" nav caret>Actions</DropdownToggle>
<DropdownMenu end style="max-height: 500px; overflow:scroll">
<DropdownMenu end style="max-height: 500px; overflow:auto">
<DropdownItem
on:click={() => {
closeNav();
Expand All @@ -122,9 +122,11 @@
on:click={() => {
$mode = ($mode === 'advanced' ? 'normal' : 'advanced');
}}>
<Row>
<Col>{$mode === "advanced" ? "Hide" : "Show"} Advanced Features</Col>
<Col class="d-flex justify-content-end">
<Row class="mr-0" style="min-width:240px">
<Col class="d-flex justify-content-start align-items-center pe-0">
{$mode === "advanced" ? "Hide" : "Show"} Advanced Features
</Col>
<Col class="d-flex justify-content-end ps-0">
{#if $mode == 'advanced'}
<Icon class="text-primary" name="toggle-on"></Icon>
{:else}
Expand All @@ -151,7 +153,7 @@
<Icon name="globe2"></Icon>
{locale}
</DropdownToggle>
<DropdownMenu end style="height: 500px; overflow:scroll">
<DropdownMenu end style="height: 500px; overflow:auto">
{#each Object.entries(locales) as [en, loc]}
<DropdownItem
style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;"
Expand Down Expand Up @@ -190,10 +192,13 @@
<a href="https://build.fhir.org/ig/HL7/fhir-ips/" target="_blank" rel="noreferrer"
>International Patient Summary</a
>
document. SHLinks can be shared by copy/paste, or by presenting a QR code. Source code and license at
<a href="https://github.com/uwcirg/shl-ips" target="_blank" rel="noreferrer"
>https://github.com/uwcirg/shl-ips</a
>. Site version: {VERSION_STRING}
document. SHLinks can be shared by copy/paste, or by presenting a QR code.
{#if $mode === "advanced"}
For more information, view the source code and license at
<a href="https://github.com/uwcirg/shl-ips" target="_blank" rel="noreferrer"
>https://github.com/uwcirg/shl-ips</a
>. {VERSION_STRING ? "Site version: " + VERSION_STRING : ""}
{/if}
</footer>
</Col>
</Row>
Expand Down

0 comments on commit cd68022

Please sign in to comment.