From a3d0fc6098e9d511819f1bb48447f7f77e7f012a Mon Sep 17 00:00:00 2001 From: Daniel Lorigan Date: Thu, 19 Dec 2024 11:20:04 -0800 Subject: [PATCH] Update ad demo for National POLST demonstration (#52) * 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 --- src/lib/components/app/FetchAD.svelte | 32 ++-- .../components/app/ResourceSelector.svelte | 162 +++++++++--------- .../AdvanceDirective.svelte | 36 ++-- src/lib/utils/types.ts | 1 + src/routes/+layout.svelte | 14 ++ 5 files changed, 135 insertions(+), 110 deletions(-) diff --git a/src/lib/components/app/FetchAD.svelte b/src/lib/components/app/FetchAD.svelte index c23250bd..d1ab3d35 100644 --- a/src/lib/components/app/FetchAD.svelte +++ b/src/lib/components/app/FetchAD.svelte @@ -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"; } } } @@ -155,7 +155,7 @@ } function buildPatientSearchQuery() { - let query = "?"; + let query = "?_count=1&"; if (selectedSource === 'AD Vault') { query += 'active=true&'; } @@ -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; } @@ -284,12 +284,13 @@ const contentResponse = await fetchAdvanceDirective(patient.id); content = await contentResponse.json(); hostname = sources[selectedSource].url; - processing = false; let resources: Array = 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, @@ -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; @@ -369,6 +370,7 @@ { exists: dr.isComfortTreatments, doNotPerform: dr.doNotPerformComfortTreatments, + type: dr.typeComfortTreatments, detail: dr.detailComfortTreatments } = digestServiceRequestByCode(serviceRequests, '100823-4') ); @@ -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, @@ -422,6 +426,7 @@ interface ServiceRequestProperties { exists: boolean; doNotPerform?: boolean; + type?: string; detail?: string; } @@ -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 }; } diff --git a/src/lib/components/app/ResourceSelector.svelte b/src/lib/components/app/ResourceSelector.svelte index 047e8ebb..7148f95b 100644 --- a/src/lib/components/app/ResourceSelector.svelte +++ b/src/lib/components/app/ResourceSelector.svelte @@ -228,94 +228,96 @@ {#if Object.keys($resourcesByTypeStore).length > 0} {#each Object.keys($resourcesByTypeStore) as resourceType} - updateBadge(resourceType)}> - - {#if resourceType === "Patient"} - Patients - - {patientCount} - - {:else} - {#if resourceType in $extensionSectionStore} - {resourceType} + {#if Object.keys($resourcesByTypeStore[resourceType]).length > 0} + updateBadge(resourceType)}> + + {#if resourceType === "Patient"} + Patients + + {patientCount} + {:else} - {`${resourceType}s`} - {/if} - resource.include).length - == Object.keys($resourcesByTypeStore[resourceType]).length - ? "primary" - : Object.values($resourcesByTypeStore[resourceType]) + {#if resourceType in $extensionSectionStore} + {resourceType} + {:else} + {`${resourceType}s`} + {/if} + 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} - - {/if} - - - {#each Object.keys($resourcesByTypeStore[resourceType]) as key} - - - - - {resourceType} - - {#if $mode === "advanced"} - - - - {/if} - - - + + {#each Object.keys($resourcesByTypeStore[resourceType]) as key} + + + + + {resourceType} + {#if $mode === "advanced"} + + + + {/if} - - - - {/each} - - + + + + {/each} + + + {/if} {/each} {/if} diff --git a/src/lib/components/resource-templates/AdvanceDirective.svelte b/src/lib/components/resource-templates/AdvanceDirective.svelte index 034b765d..ee9854b3 100644 --- a/src/lib/components/resource-templates/AdvanceDirective.svelte +++ b/src/lib/components/resource-templates/AdvanceDirective.svelte @@ -109,25 +109,26 @@ Text: {#if resource.isPolst && (resource.isCpr || resource.isComfortTreatments || resource.isAdditionalTx || resource.isMedicallyAssisted)}
- - POLST Details: + POLST Details:
    {#if resource.isCpr}
      - {#if resource.doNotPerformCpr} - This includes an order to NOT perform CPR. - {:else} - This includes an order to perform CPR. - {/if} + + {#if resource.doNotPerformCpr} + This includes an order to NOT perform CPR. + {:else} + This includes an order to perform CPR. + {/if} +
    {/if} {#if resource.isComfortTreatments}
      {#if resource.doNotPerformComfortTreatments} - This includes an order to NOT perform comfort-focused treatments: {@html resource.detailComfortTreatments} + This includes an order to NOT perform treatments: {@html resource.detailComfortTreatments} {:else} - This includes an order to perform comfort-focused treatments: {@html resource.detailComfortTreatments} + This includes an order to perform {resource.typeComfortTreatments ? `${resource.typeComfortTreatments.toLowerCase()}` : 'treatments'}: {@html resource.detailComfortTreatments} {/if}
    {/if} @@ -135,9 +136,9 @@ Text: {#if resource.isAdditionalTx}
      {#if resource.doNotPerformAdditionalTx} - This includes an order to NOT perform additional treatments: {@html resource.detailAdditionalTx} + This includes an order to NOT perform additional treatments: {@html resource.detailAdditionalTx} {:else} - This includes an order to perform additional treatments: {@html resource.detailAdditionalTx} + This includes an order to perform additional treatments: {@html resource.detailAdditionalTx} {/if}
    {/if} @@ -145,14 +146,13 @@ Text: {#if resource.isMedicallyAssisted}
      {#if resource.doNotPerformMedicallyAssisted} - This includes an order to NOT perform medically assisted nutrition: {@html resource.detailMedicallyAssisted} + This includes an order to NOT perform medically assisted nutrition: {@html resource.detailMedicallyAssisted} {:else} - This includes an order to perform medically assisted nutrition: {@html resource.detailMedicallyAssisted} + This includes an order to perform medically assisted nutrition: {@html resource.detailMedicallyAssisted} {/if}
    {/if}
-
{/if} {#if resource.content} @@ -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} - PDF present: - View + PDF present: + {#await base64toBlob(content.attachment.data, content.attachment.contentType)} + Loading PDF... + {:then url} + View {/await} {/if} {/each} diff --git a/src/lib/utils/types.ts b/src/lib/utils/types.ts index f255c7af..c81a1357 100644 --- a/src/lib/utils/types.ts +++ b/src/lib/utils/types.ts @@ -48,6 +48,7 @@ export interface DocumentReferencePOLST extends DocumentReference { isComfortTreatments?: boolean; doNotPerformComfortTreatments?: boolean; + typeComfortTreatments?: string; detailComfortTreatments?: string; isAdditionalTx?: boolean; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 02537b65..5c98723c 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -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(); });