Skip to content

Commit ce2c8a4

Browse files
committed
Merge remote-tracking branch
'origin/issue/325_documentreference-html-view' into develop_2
2 parents 21ff2ad + cabac8f commit ce2c8a4

File tree

10 files changed

+242
-1
lines changed

10 files changed

+242
-1
lines changed

dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractSearchSet.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.URI;
44
import java.net.URISyntaxException;
55
import java.util.List;
6+
import java.util.Objects;
67
import java.util.function.BiConsumer;
78
import java.util.function.Function;
89
import java.util.function.Predicate;
@@ -18,6 +19,7 @@
1819
import org.hl7.fhir.r4.model.Identifier;
1920
import org.hl7.fhir.r4.model.OperationOutcome;
2021
import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent;
22+
import org.hl7.fhir.r4.model.Reference;
2123
import org.hl7.fhir.r4.model.Resource;
2224
import org.hl7.fhir.r4.model.StringType;
2325
import org.hl7.fhir.r4.model.Task.ParameterComponent;
@@ -168,6 +170,19 @@ private int getCount(MultivaluedMap<String, String> params, int defaultPageCount
168170
return defaultPageCount;
169171
}
170172

173+
protected final <D extends DomainResource> String getIdentifierValue(D resource, Function<D, Boolean> hasIdentifier,
174+
Function<D, Identifier> getIdentifier)
175+
{
176+
Objects.requireNonNull(hasIdentifier, "hasIdentifier");
177+
Objects.requireNonNull(getIdentifier, "getIdentifier");
178+
179+
if (!hasIdentifier.apply(resource))
180+
return "";
181+
182+
Identifier identifier = getIdentifier.apply(resource);
183+
return (identifier != null && identifier.hasValue()) ? identifier.getValue() : "";
184+
}
185+
171186
protected final <D extends DomainResource> String getIdentifierValues(D resource,
172187
Function<D, Boolean> hasIdentifier, Function<D, List<Identifier>> getIdentifier, String identifierSystem)
173188
{
@@ -184,6 +199,24 @@ protected final <D extends DomainResource> String getIdentifierValues(D resource
184199
return filteredIdentifiers.get(0) + (filteredIdentifiers.size() > 1 ? ", ..." : "");
185200
}
186201

202+
protected final <D extends DomainResource> String getReferenceIdentifierValues(D resource,
203+
Function<D, Boolean> hasReference, Function<D, List<Reference>> getReference)
204+
{
205+
Objects.requireNonNull(hasReference, "hasReference");
206+
Objects.requireNonNull(getReference, "getReference");
207+
208+
if (!hasReference.apply(resource))
209+
return "";
210+
211+
List<String> identifiers = getReference.apply(resource).stream().filter(Reference::hasIdentifier)
212+
.map(Reference::getIdentifier).filter(Identifier::hasValue).map(Identifier::getValue).toList();
213+
214+
if (identifiers.isEmpty())
215+
return "";
216+
217+
return identifiers.get(0) + (identifiers.size() > 1 ? ", ..." : "");
218+
}
219+
187220
protected final String getResourceType(IIdType id)
188221
{
189222
return id != null ? id.getResourceType() : "";

dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractThymeleafContext.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import org.hl7.fhir.r4.model.DecimalType;
1919
import org.hl7.fhir.r4.model.Enumeration;
2020
import org.hl7.fhir.r4.model.Identifier;
21+
import org.hl7.fhir.r4.model.InstantType;
2122
import org.hl7.fhir.r4.model.IntegerType;
2223
import org.hl7.fhir.r4.model.PrimitiveType;
24+
import org.hl7.fhir.r4.model.Reference;
2325
import org.hl7.fhir.r4.model.Resource;
2426
import org.hl7.fhir.r4.model.StringType;
2527
import org.hl7.fhir.r4.model.UriType;
@@ -134,6 +136,12 @@ protected final <E extends Base> String getDateTime(E resource, Predicate<E> has
134136
return formatDateTime(getValue(resource, hasDateTime, getDateTime));
135137
}
136138

139+
protected final <E extends Base> String getInstant(E resource, Predicate<E> hasInstant,
140+
Function<E, InstantType> getInstant)
141+
{
142+
return formatDateTime(getValue(resource, hasInstant, getInstant));
143+
}
144+
137145
protected final <E extends Base> Boolean getBoolean(E resource, Predicate<E> hasBoolean,
138146
Function<E, BooleanType> getBoolean)
139147
{
@@ -175,6 +183,19 @@ protected final <E extends Base> String getEnumeration(E resource, Predicate<E>
175183
return e != null && e.hasCode() ? e.getCode() : null;
176184
}
177185

186+
protected final <E extends Base> ElementSystemValue getIdentifier(E resource, Predicate<E> hasIdentifier,
187+
Function<E, Identifier> getIdentifier)
188+
{
189+
Objects.requireNonNull(hasIdentifier, "hasIdentifier");
190+
Objects.requireNonNull(getIdentifier, "getIdentifier");
191+
192+
if (resource == null || !hasIdentifier.test(resource))
193+
return null;
194+
195+
Identifier identifier = getIdentifier.apply(resource);
196+
return identifier != null ? ElementSystemValue.from(identifier) : null;
197+
}
198+
178199
protected final <E extends Base> List<ElementSystemValue> getIdentifiers(E resource, Predicate<E> hasIdentifier,
179200
Function<E, List<Identifier>> getIdentifier)
180201
{
@@ -187,4 +208,20 @@ protected final <E extends Base> List<ElementSystemValue> getIdentifiers(E resou
187208
List<Identifier> identifier = getIdentifier.apply(resource);
188209
return identifier != null ? identifier.stream().map(ElementSystemValue::from).toList() : null;
189210
}
211+
212+
protected final <E extends Base> List<ElementSystemValue> getReferenceIdentifiers(E resource,
213+
Predicate<E> hasReference, Function<E, List<Reference>> getReference)
214+
{
215+
Objects.requireNonNull(hasReference, "hasReference");
216+
Objects.requireNonNull(getReference, "getReference");
217+
218+
if (resource == null || !hasReference.test(resource))
219+
return null;
220+
221+
List<Reference> references = getReference.apply(resource);
222+
return references != null
223+
? references.stream().filter(Reference::hasIdentifier).map(Reference::getIdentifier)
224+
.map(ElementSystemValue::from).toList()
225+
: null;
226+
}
190227
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dev.dsf.fhir.adapter;
2+
3+
import java.util.List;
4+
5+
import org.hl7.fhir.r4.model.Attachment;
6+
import org.hl7.fhir.r4.model.DocumentReference;
7+
8+
public class ResourceDocumentReference extends AbstractResource<DocumentReference>
9+
{
10+
private record AttachmentElement(String url, String contentType)
11+
{
12+
static AttachmentElement from(Attachment attachment)
13+
{
14+
return new AttachmentElement(attachment.getUrl(), attachment.getContentType());
15+
}
16+
}
17+
18+
private record Element(ElementSystemValue masterIdentifier, List<ElementSystemValue> identifier,
19+
List<ElementSystemValue> author, String docStatus, String date, List<AttachmentElement> attachment)
20+
{
21+
}
22+
23+
public ResourceDocumentReference()
24+
{
25+
super(DocumentReference.class, AbstractResource.ActiveOrStatus.status(DocumentReference::hasStatusElement,
26+
DocumentReference::getStatusElement));
27+
}
28+
29+
@Override
30+
protected Element toElement(DocumentReference resource)
31+
{
32+
ElementSystemValue masterIdentifier = getIdentifier(resource, DocumentReference::hasMasterIdentifier,
33+
DocumentReference::getMasterIdentifier);
34+
List<ElementSystemValue> identifier = getIdentifiers(resource, DocumentReference::hasIdentifier,
35+
DocumentReference::getIdentifier);
36+
37+
List<ElementSystemValue> author = getReferenceIdentifiers(resource, DocumentReference::hasAuthor,
38+
DocumentReference::getAuthor);
39+
String docStatus = resource.hasDocStatus() ? resource.getDocStatus().toCode() : null;
40+
41+
String date = getInstant(resource, DocumentReference::hasDate, DocumentReference::getDateElement);
42+
43+
List<AttachmentElement> attachment = resource.getContent().stream()
44+
.filter(DocumentReference.DocumentReferenceContentComponent::hasAttachment)
45+
.map(DocumentReference.DocumentReferenceContentComponent::getAttachment).map(AttachmentElement::from)
46+
.toList();
47+
48+
return new Element(masterIdentifier, nullIfEmpty(identifier), nullIfEmpty(author), docStatus, date, attachment);
49+
}
50+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package dev.dsf.fhir.adapter;
2+
3+
import org.hl7.fhir.r4.model.DocumentReference;
4+
5+
public class SearchSetDocumentReference extends AbstractSearchSet<DocumentReference>
6+
{
7+
private record Row(ElementId id, String masterIdentifier, String author, String status, String docStatus,
8+
String lastUpdated)
9+
{
10+
}
11+
12+
public SearchSetDocumentReference(int defaultPageCount)
13+
{
14+
super(defaultPageCount, DocumentReference.class);
15+
}
16+
17+
@Override
18+
protected Row toRow(ElementId id, DocumentReference resource)
19+
{
20+
String masterIdentifier = getIdentifierValue(resource, DocumentReference::hasMasterIdentifier,
21+
DocumentReference::getMasterIdentifier);
22+
String author = getReferenceIdentifierValues(resource, DocumentReference::hasAuthor,
23+
DocumentReference::getAuthor);
24+
String status = resource.hasStatus() ? resource.getStatus().toCode() : "";
25+
String docStatus = resource.hasDocStatus() ? resource.getDocStatus().toCode() : "";
26+
String lastUpdated = formatLastUpdated(resource);
27+
28+
return new Row(id, masterIdentifier, author, status, docStatus, lastUpdated);
29+
}
30+
}

dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/AdapterConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import dev.dsf.fhir.adapter.ResourceActivityDefinition;
1919
import dev.dsf.fhir.adapter.ResourceBinary;
2020
import dev.dsf.fhir.adapter.ResourceCodeSystem;
21+
import dev.dsf.fhir.adapter.ResourceDocumentReference;
2122
import dev.dsf.fhir.adapter.ResourceEndpoint;
2223
import dev.dsf.fhir.adapter.ResourceLibrary;
2324
import dev.dsf.fhir.adapter.ResourceMeasure;
@@ -33,6 +34,7 @@
3334
import dev.dsf.fhir.adapter.ResourceValueSet;
3435
import dev.dsf.fhir.adapter.SearchSetActivityDefinition;
3536
import dev.dsf.fhir.adapter.SearchSetBinary;
37+
import dev.dsf.fhir.adapter.SearchSetDocumentReference;
3638
import dev.dsf.fhir.adapter.SearchSetEndpoint;
3739
import dev.dsf.fhir.adapter.SearchSetMeasureReport;
3840
import dev.dsf.fhir.adapter.SearchSetMetadataResource;
@@ -70,14 +72,15 @@ public ThymeleafTemplateService thymeleafTemplateService()
7072
{
7173
List<ThymeleafContext> thymeleafContexts = List.of(new ResourceActivityDefinition(),
7274
new ResourceBinary(propertiesConfig.getDsfServerBaseUrl()), new ResourceCodeSystem(),
73-
new ResourceEndpoint(), new ResourceLibrary(), new ResourceMeasure(),
75+
new ResourceDocumentReference(), new ResourceEndpoint(), new ResourceLibrary(), new ResourceMeasure(),
7476
new ResourceMeasureReport(propertiesConfig.getDsfServerBaseUrl()), new ResourceNamingSystem(),
7577
new ResourceOrganizationAffiliation(), new ResourceOrganization(), new ResourceQuestionnaire(),
7678
new ResourceQuestionnaireResponse(), new ResourceStructureDefinition(), new ResourceSubscription(),
7779
new ResourceTask(), new ResourceValueSet(),
7880
new SearchSetActivityDefinition(propertiesConfig.getDefaultPageCount()),
7981
new SearchSetBinary(propertiesConfig.getDefaultPageCount()),
8082
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), CodeSystem.class),
83+
new SearchSetDocumentReference(propertiesConfig.getDefaultPageCount()),
8184
new SearchSetEndpoint(propertiesConfig.getDefaultPageCount()),
8285
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), Library.class),
8386
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), Measure.class),

dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function getInitialBookmarks() {
129129
'$ActivityDefinition': ['ActivityDefinition', "ActivityDefinition?_sort=status,url,version"],
130130
'$Binary': ['Binary'],
131131
'$CodeSystem': ['CodeSystem'],
132+
'$DocumentReference': ['DocumentReference'],
132133
'$Endpoint': ['Endpoint'],
133134
'$NamingSystem': ['NamingSystem'],
134135
'$Library': ['Library'],

dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,18 @@ pre.lang-html {
452452
border-left-color: var(--color-row-border-grey);
453453
}
454454

455+
.bundle>#list>table tr[resource-type="DocumentReference"] td[status="current"] {
456+
border-left-color: var(--color-row-border-green);
457+
}
458+
459+
.bundle>#list>table tr[resource-type="DocumentReference"] td[status="superseded"] {
460+
border-left-color: var(--color-row-border-grey);
461+
}
462+
463+
.bundle>#list>table tr[resource-type="DocumentReference"] td[status="entered-in-error"] {
464+
border-left-color: var(--color-row-border-red);
465+
}
466+
455467
.bundle>#list>table tr[resource-type="Endpoint"] td[status="active"] {
456468
border-left-color: var(--color-row-border-green);
457469
}
@@ -639,6 +651,21 @@ pre.lang-html {
639651
color: var(--color-info-grey);
640652
}
641653

654+
#resource[resource-type="DocumentReference"][status="current"] #base-data {
655+
background-color: var(--color-info-background-green);
656+
color: var(--color-info-green);
657+
}
658+
659+
#resource[resource-type="DocumentReference"][status="superseded"] #base-data {
660+
background-color: var(--color-info-background-grey);
661+
color: var(--color-info-grey);
662+
}
663+
664+
#resource[resource-type="DocumentReference"][status="entered-in-error"] #base-data {
665+
background-color: var(--color-info-background-red);
666+
color: var(--color-info-red);
667+
}
668+
642669
#resource[resource-type="Endpoint"][status="active"] #base-data {
643670
background-color: var(--color-info-background-green);
644671
color: var(--color-info-green);
@@ -800,6 +827,18 @@ pre.lang-html {
800827
fill: var(--color-info-grey);
801828
}
802829

830+
#resource[resource-type="DocumentReference"][status="current"] #base-data path {
831+
fill: var(--color-info-green);
832+
}
833+
834+
#resource[resource-type="DocumentReference"][status="superseded"] #base-data path {
835+
fill: var(--color-info-grey);
836+
}
837+
838+
#resource[resource-type="DocumentReference"][status="entered-in-error"] #base-data path {
839+
fill: var(--color-info-red);
840+
}
841+
803842
#resource[resource-type="Endpoint"][status="active"] #base-data path {
804843
fill: var(--color-info-green);
805844
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html xmlns:th="http://www.thymeleaf.org">
3+
<body>
4+
<div id="resource">
5+
<div id="resource-data" th:fragment="resource-data">
6+
<th:block th:insert="~{resourceElements::systemAndValue}" th:with="label='Master Identifier',systemAndValue=${documentReference.masterIdentifier}" th:if="${documentReference.masterIdentifier}"></th:block>
7+
<th:block th:insert="~{resourceElements::identifier}" th:with="identifier=${documentReference.identifier}" th:if="${documentReference.identifier}"></th:block>
8+
<th:block th:insert="~{resourceElements::status}" th:if="${resource.status}"></th:block>
9+
<th:block th:insert="~{resourceElements::string}" th:with="label='Document Status',string=${documentReference.docStatus}" th:if="${documentReference.docStatus}"></th:block>
10+
<th:block th:insert="~{resourceElements::systemsAndValues}" th:with="label='Author',systemsAndValues=${documentReference.author}" th:if="${documentReference.author}"></th:block>
11+
<th:block th:insert="~{resourceElements::string}" th:with="label='Date',string=${documentReference.date}" th:if="${documentReference.date}"></th:block>
12+
<th:block th:insert="~{resourceElements::attachments}" th:with="attachments=${documentReference.attachment}" th:if="${documentReference.attachment}"></th:block>
13+
<th:block th:insert="~{resourceElements::additionalValuesComment}"></th:block>
14+
</div>
15+
</div>
16+
</body>
17+
</html>

dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@
7575
</li>
7676
</ul>
7777
</div>
78+
79+
<div th:class="${class} ? ${class} : 'element element-100'" th:fragment="attachments">
80+
<label>Attachments</label>
81+
<ul th:if="${attachments}" th:each="a : ${attachments}">
82+
<li class="attachments">
83+
<th:block th:if="${a.url != null and a.contentType != null}">
84+
<a href="#" title="Open" th:href="${a.url}" th:title="'Open ' + ${a.url}" th:text="${a.url} + ' (' + ${a.contentType} + ')'">url</a>
85+
</th:block>
86+
<th:block th:if="${a.url != null and a.contentType == null}">
87+
<a href="#" title="Open" th:href="${a.url}" th:title="'Open ' + ${a.url}" th:text="${a.url}">url</a>
88+
</th:block>
89+
</li>
90+
</ul>
91+
</div>
92+
7893
<i th:fragment="additionalValuesComment">See json or xml for additional values.</i>
7994
</div>
8095
</body>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html xmlns:th="http://www.thymeleaf.org">
3+
<body>
4+
<table>
5+
<tr th:fragment="header"><th>ID</th><th>Master Identifier</th><th>Author</th><th>Status</th><th>Document Status</th><th>Last Updated</th></tr>
6+
<tr th:fragment="row" title="Open" th:title="'Open ' + ${element.id.resourceType}" th:attr="resource-type=${element.id.resourceType}">
7+
<td class="id-value" status="current" th:attr="status=${element.status}"><a href="#" title="Open" th:href="${element.id.href}" th:title="'Open ' + ${element.id.resourceType}" th:text="${element.id.value}">id</a></td>
8+
<td th:text="${element.masterIdentifier}">identifier</td>
9+
<td th:text="${element.author}">name</td>
10+
<td th:text="${element.status}">status</td>
11+
<td th:text="${element.docStatus}">docStatus</td>
12+
<td th:text="${element.lastUpdated}">lastUpdated</td>
13+
</tr>
14+
</table>
15+
</body>
16+
</html>

0 commit comments

Comments
 (0)