Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LUI-197 UI for saving concept reference ranges #196

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
97bd354
Initial commit
dicksonmulli Aug 27, 2024
45c5846
Concept references header on the UI
dicksonmulli Aug 28, 2024
8004fd8
Showing reference range title and table headers
dicksonmulli Aug 28, 2024
c6ee428
Concept reference form - restructured
dicksonmulli Aug 29, 2024
0b72cf4
Showing saved data
dicksonmulli Aug 29, 2024
3d6c088
Updating concept page with reference ranges
dicksonmulli Aug 30, 2024
1af1c3d
Successfully saving new data
dicksonmulli Sep 1, 2024
9bcb15c
Hiding reference ranges when concept type is not numeric
dicksonmulli Sep 2, 2024
24963af
Updating version for testing purposes
dicksonmulli Sep 2, 2024
c888df0
Removing an existing row on the UI
dicksonmulli Sep 4, 2024
2695383
Adding tests
dicksonmulli Sep 5, 2024
71860fd
Hiding and showing referenceRange row on conceptForm
dicksonmulli Sep 5, 2024
5fee0d8
Creating a reflection object of reference range
dicksonmulli Sep 8, 2024
cd19cda
Using reflection to map reference ranges
dicksonmulli Sep 10, 2024
46e9cdf
Updating reflection in tests
dicksonmulli Sep 11, 2024
a43a391
Code refactor
dicksonmulli Sep 11, 2024
a1c1f4d
Update reference ranges
dicksonmulli Sep 14, 2024
04dfa3f
Reverting the core version
dicksonmulli Sep 14, 2024
270311a
Sorting reference ranges
dicksonmulli Sep 17, 2024
d3dd833
Fixing null pointer
dicksonmulli Sep 17, 2024
6cd4978
Code refactor
dicksonmulli Sep 18, 2024
36634bb
Ability to edit concept reference ranges
dicksonmulli Sep 22, 2024
2194cfb
Updating reference range validations
dicksonmulli Sep 22, 2024
71fea3e
Reconciliation of admin and dictionary views
dicksonmulli Sep 22, 2024
29ffdac
Fixing an error when 2 rows are added and the first one removed befor…
dicksonmulli Sep 27, 2024
a66e598
Conditional display of concept reference ranges based on openMRS-core…
dicksonmulli Oct 8, 2024
dd54bf1
Refactoring
dicksonmulli Oct 11, 2024
988d917
code refactor
dicksonmulli Oct 17, 2024
a98b735
code refactor
dicksonmulli Oct 17, 2024
2be1fed
removed unnecessary method
dicksonmulli Oct 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.openmrs.ConceptMapType;
import org.openmrs.ConceptName;
import org.openmrs.ConceptNumeric;
import org.openmrs.ConceptReferenceRange;
import org.openmrs.ConceptReferenceTerm;
import org.openmrs.ConceptSet;
import org.openmrs.Drug;
Expand Down Expand Up @@ -459,6 +460,8 @@ public class ConceptFormBackingObject {

public Collection<ConceptAttribute> activeAttributes;

public List<ConceptReferenceRange> referenceRanges;

/**
* Default constructor must take in a Concept object to create itself
*
Expand Down Expand Up @@ -517,6 +520,9 @@ public ConceptFormBackingObject(Concept concept) {
this.allowDecimal = cn.getAllowDecimal();
this.displayPrecision = cn.getDisplayPrecision();
this.units = cn.getUnits();

this.referenceRanges = ListUtils.lazyList(new ArrayList<>(cn.getReferenceRanges()),
FactoryUtils.instantiateFactory(ConceptReferenceRange.class));
} else if (concept instanceof ConceptComplex) {
ConceptComplex complex = (ConceptComplex) concept;
this.handlerKey = complex.getHandler();
Expand Down Expand Up @@ -662,6 +668,11 @@ public Concept getConceptFromFormData() {
cn.setDisplayPrecision(displayPrecision);
cn.setUnits(units);

for (ConceptReferenceRange referenceRange : this.referenceRanges) {
referenceRange.setConceptNumeric(cn);
dicksonmulli marked this conversation as resolved.
Show resolved Hide resolved
cn.addReferenceRange(referenceRange);
}

concept = cn;

} else if (concept.getDatatype().getName().equals("Complex")) {
Expand Down Expand Up @@ -938,6 +949,36 @@ public List<Form> getFormsInUse() {
return Context.getFormService().getFormsContainingConcept(concept);
}

/**
* Get reference ranges
*
* @return the referenceRanges
* @since 1.17.0
*/
public List<ConceptReferenceRange> getReferenceRanges() {
return referenceRanges;
}

/**
* Sets reference ranges
*
* @param referenceRanges the referenceRanges to set
* @since 1.17.0
*/
public void setReferenceRanges(List<ConceptReferenceRange> referenceRanges) {
this.referenceRanges = referenceRanges;
}

/**
* Adds a new reference range to the list of reference ranges
*
* @param referenceRange the referenceRange to add
* @since 1.17.0
*/
public void addReferenceRange(ConceptReferenceRange referenceRange) {
getReferenceRanges().add(referenceRange);
}

/**
* Get the list of extensions/metadata and the specific instances of them that use this
* concept.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,9 @@ protected int getTargetPage(HttpServletRequest request, Object command, Errors e
* @see #PARAM_TARGET
*/
protected int getTargetPage(HttpServletRequest request, int currentPage) {
return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage);
return 0;
// TODO REVERT THIS AFTER TESTING IS DONE
// return WebUtils.getTargetPage(request, PARAM_TARGET, currentPage);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions omod/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Concept.referenceRanges=Reference Ranges
Concept.referenceRanges.criteria=Criteria
Concept.referenceRanges.help=Defines reference ranges of this concept with a criteria
Concept.referenceRanges.add=Add a Reference Range
29 changes: 29 additions & 0 deletions omod/src/main/webapp/admin/dictionary/concept.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,35 @@
</table>
</td>
</tr>
<tr id="referenceRangeRow">
<th valign="top" style="padding-top: 8px" title="<openmrs:message code="Concept.referenceRanges.help"/>">
<openmrs:message code="Concept.referenceRanges"/>
</th>
<td>
<table cellpadding="5" cellspacing="3" align="left" class="lightBorderBox">
<tr id="ReferenceRangesHeadersRow" <c:if test="${fn:length(command.referenceRanges) == 0}">style="display:none"</c:if>>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalLow"/></th>
<th style="text-align: center"><openmrs:message code="Concept.referenceRanges.criteria"/></th>
</tr>
<c:forEach var="reference" items="${command.referenceRanges}" varStatus="mapStatus">
<tr <c:if test="${mapStatus.index % 2 == 0}">class='evenRow'</c:if>>
<td><c:out value="${reference.hiAbsolute}"/></td>
<td><c:out value="${reference.lowAbsolute}"/></td>
<td><c:out value="${reference.hiNormal}"/></td>
<td><c:out value="${reference.lowNormal}"/></td>
<td><c:out value="${reference.hiCritical}"/></td>
<td><c:out value="${reference.lowCritical}"/></td>
<td><c:out value="${reference.criteria}"/></td>
</tr>
</c:forEach>
</table>
</td>
</tr>

<c:if test="${command.concept.complex}">
<tr>
Expand Down
5 changes: 5 additions & 0 deletions omod/src/main/webapp/admin/dictionary/conceptForm.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
$j(".hideableEle").hide();
});

$j(document).ready(function(){
if(${fn:length(command.referenceRanges)} == 0)
$j(".referenceRangeHeader").hide();
});

</script>

<script src="<openmrs:contextPath/>/dwr/interface/DWRConceptService.js"></script>
Expand Down
29 changes: 29 additions & 0 deletions omod/src/main/webapp/dictionary/concept.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,35 @@
</table>
</td>
</tr>
<tr id="referenceRangeRow">
<th valign="top" style="padding-top: 8px" title="<openmrs:message code="Concept.referenceRanges.help"/>">
<openmrs:message code="Concept.referenceRanges"/>
</th>
<td>
<table cellpadding="5" cellspacing="3" align="left" class="lightBorderBox">
<tr id="ReferenceRangesHeadersRow" <c:if test="${fn:length(command.referenceRanges) == 0}">style="display:none"</c:if>>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalLow"/></th>
<th style="text-align: center"><openmrs:message code="Concept.referenceRanges.criteria"/></th>
</tr>
<c:forEach var="reference" items="${command.referenceRanges}" varStatus="mapStatus">
<tr <c:if test="${mapStatus.index % 2 == 0}">class='evenRow'</c:if>>
<td><c:out value="${reference.hiAbsolute}"/></td>
<td><c:out value="${reference.lowAbsolute}"/></td>
<td><c:out value="${reference.hiNormal}"/></td>
<td><c:out value="${reference.lowNormal}"/></td>
<td><c:out value="${reference.hiCritical}"/></td>
<td><c:out value="${reference.lowCritical}"/></td>
<td><c:out value="${reference.criteria}"/></td>
</tr>
</c:forEach>
</table>
</td>
</tr>

<c:forEach var="attribute" items="${command.concept.activeAttributes}">
<tr id="conceptAttributeRow">
Expand Down
69 changes: 67 additions & 2 deletions omod/src/main/webapp/dictionary/conceptForm.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,15 @@
}

$j(document).ready(function(){
if(${fn:length(command.conceptMappings)} == 0)
if(${fn:length(command.referenceRanges)} == 0)
$j(".hideableEle").hide();
});

$j(document).ready(function(){
if(${fn:length(command.referenceRanges)} == 0)
$j(".referenceRangeHeader").hide();
});

</script>

<script src="<openmrs:contextPath/>/dwr/interface/DWRConceptService.js"></script>
Expand Down Expand Up @@ -153,6 +158,7 @@
#addAnswerError{ margin-bottom: 0.5em; border: 1px dashed black; background: #FAA; line-height: 2em; text-align: center; display: none; }
#headerRow th { text-align: center; }
#footer { clear:both; }
#newReferenceRange { display: none; }
</style>

<c:choose>
Expand Down Expand Up @@ -789,7 +795,7 @@
<td colspan="3" valign="top" align="left">
<c:choose>
<c:when test="${sourceID != null}">
<input id="addMapButton" type="button" value='<openmrs:message code="Concept.mapping.add"/>' class="smallButton"
<input id="addMapButton" type="button" value='<openmrs:message code="Concept.mapping.add"/>' class="smallButton"
onClick="addConceptMapping(${fn:length(command.conceptMappings)})" />
</c:when>
<c:otherwise>
Expand All @@ -815,6 +821,65 @@
</table>
</td>
</tr>
<c:if test="${command.concept.datatype.name == 'Numeric'}">
<tr id="referenceRangeRow">
<th valign="top" style="padding-top: 8px">
<openmrs:message code="Concept.referenceRanges"/> <img class="help_icon" src="${pageContext.request.contextPath}/images/help.gif" border="0" title="<openmrs:message code="Concept.referenceRanges.help"/>"/>
</th>
<td>
<table id="referenceTable" cellpadding="3" cellspacing="1">
<tr id="headerRow" class="headerRow referenceRangeHeader">
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.absoluteLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.criticalLow"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalHigh"/></th>
<th style="text-align: center"><openmrs:message code="ConceptNumeric.normalLow"/></th>
<th style="text-align: center"><openmrs:message code="Concept.referenceRanges.criteria"/></th>
<th class="removeButtonCol">&nbsp;</th>
</tr>
<c:forEach var="reference" items="${command.referenceRanges}" varStatus="status">
<spring:nestedPath path="command.referenceRanges[${status.index}]">
<tr>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].hiAbsolute" value="${reference.hiAbsolute}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].lowAbsolute" value="${reference.lowAbsolute}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].hiNormal" value="${reference.hiNormal}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].lowNormal" value="${reference.lowNormal}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].hiCritical" value="${reference.hiCritical}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].lowCritical" value="${reference.lowCritical}" readonly="readonly" /></td>
<td><input type="text" size="25" name="command.referenceRanges[${status.index}].criteria" value="${reference.criteria}" readonly="readonly" /></td>
<td>
<input type="button" value='<openmrs:message code="general.remove"/>' class="smallButton" onClick="removeParentElement(this.parentNode)" />
<spring:bind path="command.referenceRanges[${status.index}]" ignoreNestedPath="true">
<c:if test="${status.errorMessage != ''}"><span class="error">${status.errorMessage}</span></c:if>
</spring:bind>
</td>
</tr>
</spring:nestedPath>
</c:forEach>
<tr id="newReferenceRange" style="display: none" varStatus="status">
<td><input type="text" name="[x].hiAbsolute" size="20" /></td>
<td><input type="text" name="[x].lowAbsolute" size="20" /></td>
<td><input type="text" name="[x].hiCritical" size="20" /></td>
<td><input type="text" name="[x].lowCritical" size="20" /></td>
<td><input type="text" name="[x].hiNormal" size="20" /></td>
<td><input type="text" name="[x].lowNormal" size="20" /></td>
<td><input type="text" name="[x].criteria" size="20" /></td>
<td>
<input type="button" value='<openmrs:message code="general.remove"/>' class="smallButton" onClick="removeReferenceRangeElement(this, 'newReferenceRange')" />
</td>
<td><input type="hidden" id="referenceRangesSize" name="refId" /></td>
</tr>
<tr id="addButton">
<td colspan="3" valign="top" align="left">
<input type="button" value='<openmrs:message code="Concept.referenceRanges.add"/>' class="smallButton"
onClick="addReferenceRanges(${fn:length(command.referenceRanges)})" />
</td>
</tr>
</table>
</td>
</tr>
</c:if>

<spring:bind path="command.activeAttributes">
<c:if test="${status.error}">
Expand Down
43 changes: 42 additions & 1 deletion omod/src/main/webapp/resources/scripts/dictionary/conceptForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ function addConceptMapping(initialSizeOfClonedSiblings){
input.id = 'term[' + index + '].name';
}
}

//find the select element and set the name attribute for the conceptSource and map type
for (var i in selects) {
var select = selects[i];
Expand All @@ -453,6 +453,47 @@ function addConceptMapping(initialSizeOfClonedSiblings){
}
}

/**
* Method is invoked to add a new reference range
* @param initialSizeOfReferenceRanges the number of mappings on page load
*/
function addReferenceRanges(initialSizeOfReferenceRanges) {
var inputNamePrefix = 'referenceRanges';
var newRow = cloneElement('newReferenceRange', initialSizeOfReferenceRanges, inputNamePrefix);

if(newRow){
newRow.id = "";
var index = numberOfClonedElements['newReferenceRange'];
var inputs = newRow.getElementsByTagName("input");

for (var x = 0; x < inputs.length; x++) {
var input = inputs[x];

if (input && input.type == 'text') {
input.id = inputNamePrefix + '[' + index + '].' + input.name.split('.')[1]
input.name = inputNamePrefix + '[' + index + '].' + input.name.split('.')[1]
}
}


if(!$j("#headerRow").is(":visible"))
$j(".referenceRangeHeader").show();
}
}

/**
* Handles deleting and update visibility of reference range fields
*
* @param btn
* the source object of event
* @param key
* the key object for receiving the save key
*/
function removeReferenceRangeElement(btn, key) {
removeParentElement(btn.parentNode);
numberOfClonedElements[key]--;
}

function addAutoComplete(displayInputId, sourceSelectElementId, hiddenElementId, nameInputId){
var selectOption = document.getElementById(sourceSelectElementId);
// set up the autocomplete on the conceptReferenceTerm input box for the new mapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.mockito.Mockito;
import org.openmrs.ConceptMap;
import org.openmrs.ConceptNumeric;
import org.openmrs.ConceptReferenceRange;
import org.openmrs.web.controller.ConceptFormController;
import org.openmrs.web.test.BaseModuleWebContextSensitiveTest;

Expand Down Expand Up @@ -56,4 +57,37 @@ public void ConceptFormBackingObject_shouldCopyNumericAttributes() {

org.junit.Assert.assertEquals("ml", conceptFormBackingObject.getUnits());
}

@Test
public void testConceptFormBackingObject_shouldSetReferenceRangeAttributes() {
ConceptReferenceRange referenceRange = Mockito.mock(ConceptReferenceRange.class);
ConceptNumeric conceptNumeric = Mockito.mock(ConceptNumeric.class);

Mockito.when(referenceRange.getHiAbsolute()).thenReturn(5.2);
Mockito.when(referenceRange.getLowAbsolute()).thenReturn(1.0);

Mockito.when(referenceRange.getHiCritical()).thenReturn(4.1);
Mockito.when(referenceRange.getLowCritical()).thenReturn(2.1);

Mockito.when(referenceRange.getLowNormal()).thenReturn(3.1);
Mockito.when(referenceRange.getHiNormal()).thenReturn(3.9);

Mockito.when(referenceRange.getCriteria()).thenReturn("");

ConceptFormController controller = new ConceptFormController();
ConceptReferenceRange conceptReferenceRange = controller.new ConceptFormBackingObject(
conceptNumeric).referenceRanges
.iterator().next();

org.junit.Assert.assertEquals(Double.valueOf(5.2), conceptReferenceRange.getHiAbsolute());
org.junit.Assert.assertEquals(Double.valueOf(1.0), conceptReferenceRange.getLowAbsolute());

org.junit.Assert.assertEquals(Double.valueOf(4.1), conceptReferenceRange.getHiCritical());
org.junit.Assert.assertEquals(Double.valueOf(2.1), conceptReferenceRange.getLowCritical());

org.junit.Assert.assertEquals(Double.valueOf(3.1), conceptReferenceRange.getLowNormal());
org.junit.Assert.assertEquals(Double.valueOf(3.9), conceptReferenceRange.getHiNormal());

org.junit.Assert.assertEquals("", conceptReferenceRange.getCriteria());
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</modules>

<properties>
<openmrsPlatformVersion>2.0.0</openmrsPlatformVersion>
<openmrsPlatformVersion>2.7.0-SNAPSHOT</openmrsPlatformVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<javaCompilerVersion>1.8</javaCompilerVersion>
</properties>
Expand Down
Loading