Skip to content

Commit

Permalink
Update ad demo for National POLST demonstration (#52)
Browse files Browse the repository at this point in the history
* For advance directive query, use first returned patient instead of last

* Add treatment type to comfort treatment POLST note

* Update POLST formatting and add treatment type to comfort treatment lines

* Update default demo server AD patient to Maria SEATTLE Gravitate

* Only display resource types in selector that have at least one resource

* Fix Advance Directive loops to handle async control for SDC and PDF retrieval

* Fix navbar closing on some unwanted scroll and click eventswq
  • Loading branch information
daniellrgn authored Dec 19, 2024
1 parent e822f30 commit a3d0fc6
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 110 deletions.
32 changes: 19 additions & 13 deletions src/lib/components/app/FetchAD.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@
gender = "Female";
dob = "1950-11-15";
} else if (selectedSource === 'WA Verify+ Demo Server') {
last = "deBronkartTest";
first = "DaveTest";
gender = "Male";
dob = "1951-01-20";
last = "Gravitate";
first = "Maria SEATTLE";
gender = "Female";
dob = "1946-05-05";
}
}
}
Expand Down Expand Up @@ -155,7 +155,7 @@
}
function buildPatientSearchQuery() {
let query = "?";
let query = "?_count=1&";
if (selectedSource === 'AD Vault') {
query += 'active=true&';
}
Expand Down Expand Up @@ -206,7 +206,7 @@
if (body.resourceType == 'Bundle' && (body.total == 0 || body.entry.length === 0)) {
throw new Error('Unable to find patient');
}
let patient_response = body.entry[body.entry.length - 1].resource;
let patient_response = body.entry[0].resource;
return patient_response;
}
Expand Down Expand Up @@ -284,12 +284,13 @@
const contentResponse = await fetchAdvanceDirective(patient.id);
content = await contentResponse.json();
hostname = sources[selectedSource].url;
processing = false;
let resources: Array<DocumentReferencePOLST> = content.entry ? content.entry.map((e: BundleEntry) => {
return e.resource;
}) : [];
if (resources.length === 0) {
console.warn("No advance directives found for patient "+patient.id);
processing = false;
return;
}
// Filter out DR's with 'status' == 'superseded'. In May '24 we included these,
Expand Down Expand Up @@ -335,7 +336,7 @@
// if one of the DR's
const isPolst = (dr: DocumentReferencePOLST) => dr.type && dr.type.coding && dr.type.coding.some(coding => coding.system === 'http://loinc.org' && coding.code === '100821-8');
resources.forEach(async (dr: DocumentReferencePOLST) => {
for (let dr of resources) {
// If this DR is a POLST, add the following chain of queries:
if (isPolst(dr)){
dr.isPolst = true;
Expand Down Expand Up @@ -369,6 +370,7 @@
{
exists: dr.isComfortTreatments,
doNotPerform: dr.doNotPerformComfortTreatments,
type: dr.typeComfortTreatments,
detail: dr.detailComfortTreatments
} = digestServiceRequestByCode(serviceRequests, '100823-4')
);
Expand All @@ -394,16 +396,18 @@
);
}
}
});
resources.forEach(async (dr: DocumentReferencePOLST) => {
}
for (let dr of resources) {
if (hasPdfContent(dr)) {
const pdfContent = dr.content.find(content => content.attachment && content.attachment.contentType === 'application/pdf');
if (pdfContent && pdfContent.attachment && pdfContent.attachment.url) {
await injectPdfIntoDocRef (pdfContent.attachment.url, pdfContent.attachment);
}
}
});
}
processing = false;
let result:ResourceRetrieveEvent = {
resources: resources,
sectionKey: sectionKey,
Expand All @@ -422,6 +426,7 @@
interface ServiceRequestProperties {
exists: boolean;
doNotPerform?: boolean;
type?: string;
detail?: string;
}
Expand All @@ -432,7 +437,8 @@
return {
exists: serviceRequest !== undefined,
doNotPerform: serviceRequest?.doNotPerform === true,
detail: serviceRequest?.note?.[0].text
type: serviceRequest?.orderDetail?.[0].text ?? serviceRequest?.code?.coding?.[0].display,
detail: serviceRequest?.note?.[0].text ?? serviceRequest?.orderDetail?.[0].text
};
}
</script>
Expand Down
162 changes: 82 additions & 80 deletions src/lib/components/app/ResourceSelector.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -228,94 +228,96 @@
<Accordion>
{#if Object.keys($resourcesByTypeStore).length > 0}
{#each Object.keys($resourcesByTypeStore) as resourceType}
<AccordionItem on:toggle={() => updateBadge(resourceType)}>
<span slot="header">
{#if resourceType === "Patient"}
Patients
<Badge
positioned
class="mx-1"
color={patientBadgeColor}
>
{patientCount}
</Badge>
{:else}
{#if resourceType in $extensionSectionStore}
{resourceType}
{#if Object.keys($resourcesByTypeStore[resourceType]).length > 0}
<AccordionItem on:toggle={() => updateBadge(resourceType)}>
<span slot="header">
{#if resourceType === "Patient"}
Patients
<Badge
positioned
class="mx-1"
color={patientBadgeColor}
>
{patientCount}
</Badge>
{:else}
{`${resourceType}s`}
{/if}
<Badge
positioned
class="mx-1"
color={
Object.values($resourcesByTypeStore[resourceType])
.filter(resource => resource.include).length
== Object.keys($resourcesByTypeStore[resourceType]).length
? "primary"
: Object.values($resourcesByTypeStore[resourceType])
{#if resourceType in $extensionSectionStore}
{resourceType}
{:else}
{`${resourceType}s`}
{/if}
<Badge
positioned
class="mx-1"
color={
Object.values($resourcesByTypeStore[resourceType])
.filter(resource => resource.include).length
== Object.keys($resourcesByTypeStore[resourceType]).length
? "primary"
: Object.values($resourcesByTypeStore[resourceType])
.filter(resource => resource.include).length
> 0
? "info"
: "secondary"
}>
{Object.values($resourcesByTypeStore[resourceType]).filter(resource => resource.include).length}
</Badge>
{/if}
</span>
<FormGroup>
{#each Object.keys($resourcesByTypeStore[resourceType]) as key}
<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 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}
<Input id={key} type="checkbox" bind:checked={$resourcesByTypeStore[resourceType][key].include} value={key} />
{/if}
</Col>
<Col>
{#if resourceType in components}
<svelte:component this={components[resourceType]} resource={$resourcesByTypeStore[resourceType][key].resource} />
<!-- ResourceType: {resourceType}
Resource: {JSON.stringify($resourcesByTypeStore[resourceType][key].resource)} -->
{:else if $resourcesByTypeStore[resourceType][key].resource.text?.div}
{@html $resourcesByTypeStore[resourceType][key].resource.text?.div}
{:else}
{$resourcesByTypeStore[resourceType][key].tempId}
{/if}
== Object.keys($resourcesByTypeStore[resourceType]).length
? "primary"
: Object.values($resourcesByTypeStore[resourceType])
.filter(resource => resource.include).length
> 0
? "info"
: "secondary"
}>
{Object.values($resourcesByTypeStore[resourceType]).filter(resource => resource.include).length}
</Badge>
{/if}
</span>
<FormGroup>
{#each Object.keys($resourcesByTypeStore[resourceType]) as key}
<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>
</CardBody>
</Label>
</Card>
{/each}
</FormGroup>
</AccordionItem>
</CardHeader>
<Label style="width: 100%">
<CardBody>
<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}
<Input id={key} type="checkbox" bind:checked={$resourcesByTypeStore[resourceType][key].include} value={key} />
{/if}
</Col>
<Col>
{#if resourceType in components}
<svelte:component this={components[resourceType]} resource={$resourcesByTypeStore[resourceType][key].resource} />
<!-- ResourceType: {resourceType}
Resource: {JSON.stringify($resourcesByTypeStore[resourceType][key].resource)} -->
{:else if $resourcesByTypeStore[resourceType][key].resource.text?.div}
{@html $resourcesByTypeStore[resourceType][key].resource.text?.div}
{:else}
{$resourcesByTypeStore[resourceType][key].tempId}
{/if}
</Col>
</Row>
</CardBody>
</Label>
</Card>
{/each}
</FormGroup>
</AccordionItem>
{/if}
{/each}
{/if}
</Accordion>
Expand Down
36 changes: 19 additions & 17 deletions src/lib/components/resource-templates/AdvanceDirective.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -109,50 +109,50 @@ Text:

{#if resource.isPolst && (resource.isCpr || resource.isComfortTreatments || resource.isAdditionalTx || resource.isMedicallyAssisted)}
<br/>
<b>
POLST Details:
<b>POLST Details:</b>
<ul>
{#if resource.isCpr}
<ol>
{#if resource.doNotPerformCpr}
This includes an order to NOT perform CPR.
{:else}
This includes an order to perform CPR.
{/if}
<b>
{#if resource.doNotPerformCpr}
This includes an order to NOT perform CPR.
{:else}
This includes an order to perform CPR.
{/if}
</b>
</ol>
{/if}

{#if resource.isComfortTreatments}
<ol>
{#if resource.doNotPerformComfortTreatments}
This includes an order to NOT perform comfort-focused treatments: {@html resource.detailComfortTreatments}
<b>This includes an order to NOT perform treatments:</b> {@html resource.detailComfortTreatments}
{:else}
This includes an order to perform comfort-focused treatments: {@html resource.detailComfortTreatments}
<b>This includes an order to perform {resource.typeComfortTreatments ? `${resource.typeComfortTreatments.toLowerCase()}` : 'treatments'}:</b> {@html resource.detailComfortTreatments}
{/if}
</ol>
{/if}

{#if resource.isAdditionalTx}
<ol>
{#if resource.doNotPerformAdditionalTx}
This includes an order to NOT perform additional treatments: {@html resource.detailAdditionalTx}
<b>This includes an order to NOT perform additional treatments:</b> {@html resource.detailAdditionalTx}
{:else}
This includes an order to perform additional treatments: {@html resource.detailAdditionalTx}
<b>This includes an order to perform additional treatments:</b> {@html resource.detailAdditionalTx}
{/if}
</ol>
{/if}

{#if resource.isMedicallyAssisted}
<ol>
{#if resource.doNotPerformMedicallyAssisted}
This includes an order to NOT perform medically assisted nutrition: {@html resource.detailMedicallyAssisted}
<b>This includes an order to NOT perform medically assisted nutrition:</b> {@html resource.detailMedicallyAssisted}
{:else}
This includes an order to perform medically assisted nutrition: {@html resource.detailMedicallyAssisted}
<b>This includes an order to perform medically assisted nutrition:</b> {@html resource.detailMedicallyAssisted}
{/if}
</ol>
{/if}
</ul>
</b>
{/if}

{#if resource.content}
Expand All @@ -168,9 +168,11 @@ Text:
{/if}
{#each resource.content as content}
{#if content.attachment.contentType === "application/pdf" && content.attachment.data}
{#await base64toBlob(content.attachment.data, content.attachment.contentType) then url}
<b>PDF present:</b>
<a href={url} target="_blank" rel="noopener noreferrer">View</a>
<b>PDF present:</b>
{#await base64toBlob(content.attachment.data, content.attachment.contentType)}
Loading PDF...
{:then url}
<a href={url} target="_blank" rel="noopener noreferrer">View</a>
{/await}
{/if}
{/each}
Expand Down
1 change: 1 addition & 0 deletions src/lib/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface DocumentReferencePOLST extends DocumentReference {

isComfortTreatments?: boolean;
doNotPerformComfortTreatments?: boolean;
typeComfortTreatments?: string;
detailComfortTreatments?: string;

isAdditionalTx?: boolean;
Expand Down
14 changes: 14 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,27 @@
$isOpen = false;
}
let navOpening = false;
document.addEventListener('click', (event) => {
// Ignore clicks on the navbar toggler
if (event.target?.className?.includes('navbar-toggler')) return;
// Ignore clicks on the dropdown toggle menu items
if (event.target?.className?.includes('nav-link') && event.target?.className?.includes('dropdown-toggle')) {
navOpening = true;
setTimeout(() => {
navOpening = false;
}, 100);
return;
}
closeNav();
});
document.addEventListener('keydown', (event) => {
closeNav();
});
window.addEventListener('scroll', (event) => {
if (document.getElementsByClassName('navbar-collapse collapsing').length > 0) return;
if (navOpening) return;
closeNav();
});
Expand Down

0 comments on commit a3d0fc6

Please sign in to comment.