Add sorting to Web Testing UI

This commit is contained in:
James Agnew 2015-03-11 11:15:51 -04:00
parent 1a4a23bdc5
commit b4911788a3
4 changed files with 144 additions and 101 deletions

View File

@ -327,7 +327,7 @@ public class Controller {
IResource conformance = addCommonParams(theServletRequest, theRequest, theModel);
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(null, getContext(theRequest), myConfig, interceptor);
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
String resourceName = theRequest.getResource();
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
@ -370,80 +370,6 @@ public class Controller {
return "resource";
}
private boolean extractSearchParamsDstu1(IResource theConformance, String resourceName, TreeSet<String> includes, TreeSet<String> sortParams, List<RestQuery> queries, boolean haveSearchParams,
List<List<String>> queryIncludes) {
Conformance conformance = (Conformance) theConformance;
for (Rest nextRest : conformance.getRest()) {
for (RestResource nextRes : nextRest.getResource()) {
if (nextRes.getType().getValue().equals(resourceName)) {
for (StringDt next : nextRes.getSearchInclude()) {
if (next.isEmpty() == false) {
includes.add(next.getValue());
}
}
for (RestResourceSearchParam next : nextRes.getSearchParam()) {
if (next.getType().getValueAsEnum() != SearchParamTypeEnum.COMPOSITE) {
sortParams.add(next.getName().getValue());
}
}
if (nextRes.getSearchParam().size() > 0) {
haveSearchParams = true;
}
}
}
for (RestQuery nextQuery : nextRest.getQuery()) {
boolean queryMatchesResource = false;
List<ExtensionDt> returnTypeExt = nextQuery.getUndeclaredExtensionsByUrl(ExtensionConstants.QUERY_RETURN_TYPE);
if (returnTypeExt != null) {
for (ExtensionDt nextExt : returnTypeExt) {
if (resourceName.equals(nextExt.getValueAsPrimitive().getValueAsString())) {
queries.add(nextQuery);
queryMatchesResource = true;
break;
}
}
}
if (queryMatchesResource) {
ArrayList<String> nextQueryIncludes = new ArrayList<String>();
queryIncludes.add(nextQueryIncludes);
List<ExtensionDt> includesExt = nextQuery.getUndeclaredExtensionsByUrl(ExtensionConstants.QUERY_ALLOWED_INCLUDE);
if (includesExt != null) {
for (ExtensionDt nextExt : includesExt) {
nextQueryIncludes.add(nextExt.getValueAsPrimitive().getValueAsString());
}
}
}
}
}
return haveSearchParams;
}
private boolean extractSearchParamsDev(IResource theConformance, String resourceName, TreeSet<String> includes, TreeSet<String> sortParams, List<RestQuery> queries, boolean haveSearchParams,
List<List<String>> queryIncludes) {
ca.uhn.fhir.model.dstu2.resource.Conformance conformance = (ca.uhn.fhir.model.dstu2.resource.Conformance) theConformance;
for (ca.uhn.fhir.model.dstu2.resource.Conformance.Rest nextRest : conformance.getRest()) {
for (ca.uhn.fhir.model.dstu2.resource.Conformance.RestResource nextRes : nextRest.getResource()) {
if (nextRes.getTypeElement().getValue().equals(resourceName)) {
for (StringDt next : nextRes.getSearchInclude()) {
if (next.isEmpty() == false) {
includes.add(next.getValue());
}
}
for (ca.uhn.fhir.model.dstu2.resource.Conformance.RestResourceSearchParam next : nextRes.getSearchParam()) {
if (next.getTypeElement().getValueAsEnum() != ca.uhn.fhir.model.dstu2.valueset.SearchParamTypeEnum.COMPOSITE) {
sortParams.add(next.getNameElement().getValue());
}
}
if (nextRes.getSearchParam().size() > 0) {
haveSearchParams = true;
}
}
}
}
return haveSearchParams;
}
@SuppressWarnings("unchecked")
@RequestMapping(value = { "/search" })
public String actionSearch(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
@ -525,6 +451,20 @@ public class Controller {
clientCodeJsonWriter.writeNull("limit");
}
String[] sort = theReq.getParameterValues("sort_by");
if (sort != null) {
for (String next : sort) {
String direction = theReq.getParameter("sort_direction");
if ("asc".equals(direction)) {
query.sort().ascending(new StringClientParam(next));
} else if ("desc".equals(direction)) {
query.sort().descending(new StringClientParam(next));
} else {
query.sort().defaultOrder(new StringClientParam(next));
}
}
}
long start = System.currentTimeMillis();
ResultType returnsResource;
try {
@ -756,6 +696,80 @@ public class Controller {
}
private boolean extractSearchParamsDev(IResource theConformance, String resourceName, TreeSet<String> includes, TreeSet<String> sortParams, List<RestQuery> queries, boolean haveSearchParams,
List<List<String>> queryIncludes) {
ca.uhn.fhir.model.dstu2.resource.Conformance conformance = (ca.uhn.fhir.model.dstu2.resource.Conformance) theConformance;
for (ca.uhn.fhir.model.dstu2.resource.Conformance.Rest nextRest : conformance.getRest()) {
for (ca.uhn.fhir.model.dstu2.resource.Conformance.RestResource nextRes : nextRest.getResource()) {
if (nextRes.getTypeElement().getValue().equals(resourceName)) {
for (StringDt next : nextRes.getSearchInclude()) {
if (next.isEmpty() == false) {
includes.add(next.getValue());
}
}
for (ca.uhn.fhir.model.dstu2.resource.Conformance.RestResourceSearchParam next : nextRes.getSearchParam()) {
if (next.getTypeElement().getValueAsEnum() != ca.uhn.fhir.model.dstu2.valueset.SearchParamTypeEnum.COMPOSITE) {
sortParams.add(next.getNameElement().getValue());
}
}
if (nextRes.getSearchParam().size() > 0) {
haveSearchParams = true;
}
}
}
}
return haveSearchParams;
}
private boolean extractSearchParamsDstu1(IResource theConformance, String resourceName, TreeSet<String> includes, TreeSet<String> sortParams, List<RestQuery> queries, boolean haveSearchParams,
List<List<String>> queryIncludes) {
Conformance conformance = (Conformance) theConformance;
for (Rest nextRest : conformance.getRest()) {
for (RestResource nextRes : nextRest.getResource()) {
if (nextRes.getType().getValue().equals(resourceName)) {
for (StringDt next : nextRes.getSearchInclude()) {
if (next.isEmpty() == false) {
includes.add(next.getValue());
}
}
for (RestResourceSearchParam next : nextRes.getSearchParam()) {
if (next.getType().getValueAsEnum() != SearchParamTypeEnum.COMPOSITE) {
sortParams.add(next.getName().getValue());
}
}
if (nextRes.getSearchParam().size() > 0) {
haveSearchParams = true;
}
}
}
for (RestQuery nextQuery : nextRest.getQuery()) {
boolean queryMatchesResource = false;
List<ExtensionDt> returnTypeExt = nextQuery.getUndeclaredExtensionsByUrl(ExtensionConstants.QUERY_RETURN_TYPE);
if (returnTypeExt != null) {
for (ExtensionDt nextExt : returnTypeExt) {
if (resourceName.equals(nextExt.getValueAsPrimitive().getValueAsString())) {
queries.add(nextQuery);
queryMatchesResource = true;
break;
}
}
}
if (queryMatchesResource) {
ArrayList<String> nextQueryIncludes = new ArrayList<String>();
queryIncludes.add(nextQueryIncludes);
List<ExtensionDt> includesExt = nextQuery.getUndeclaredExtensionsByUrl(ExtensionConstants.QUERY_ALLOWED_INCLUDE);
if (includesExt != null) {
for (ExtensionDt nextExt : includesExt) {
nextQueryIncludes.add(nextExt.getValueAsPrimitive().getValueAsString());
}
}
}
}
}
return haveSearchParams;
}
private String format(String theResultBody, EncodingEnum theEncodingEnum) {
String str = StringEscapeUtils.escapeHtml4(theResultBody);
if (str == null || theEncodingEnum == null) {
@ -1008,7 +1022,7 @@ public class Controller {
throw new Error("Unknown qualifier: " + parts.get(0));
}
IAndUnits number = matcher.number(parts.get(1));
if (isBlank(parts.get(3))) {
theQuery.where(number.andNoUnits());
} else if (isBlank(parts.get(2))) {
@ -1016,9 +1030,9 @@ public class Controller {
} else {
theQuery.where(number.andUnits(parts.get(2), parts.get(3)));
}
values.add(parts.get(0) + parts.get(1) + "|" + parts.get(2) + "|" + parts.get(3));
if (values.isEmpty()) {
return true;
}
@ -1276,8 +1290,7 @@ public class Controller {
}
/*
* DSTU2 no longer has a title in the bundle format, but it's still
* useful here..
* DSTU2 no longer has a title in the bundle format, but it's still useful here..
*/
if (bundle != null) {
INarrativeGenerator gen = getContext(theRequest).getNarrativeGenerator();

View File

@ -131,36 +131,54 @@
<h4>Includes <small>Also load and include referenced resources in results</small></h4>
</div>
<!-- Includes -->
<div class="row-fluid">
<span th:each="include : ${includes}" class="includeCheckContainer">
<span class="includeCheckCheck">
<input type="checkbox" th:value="${include}" th:id="'inc_' + ${include}" />
</span>
<input type="checkbox" th:value="${include}" th:id="'inc_' + ${include}" />
</span>
<span class="includeCheckName" th:text="${include}"/>
</span>
</span>
</div>
<!-- Results Sorting -->
<div class="row-fluid">
<h4>Sort Results</h4>
</div>
<div class="row-fluid">
<div class='col-sm-3'>
<div class="btn-group">
<input type="hidden" id="search_sort" />
<button type="button" class="btn btn-info" id="search_sort_button">Default Sort</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Default Sort</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="javascript:updateSort('');">Default Sort</a></li>
<li class="divider"></li>
<li th:each="param : ${sortParams}"><a th:href="'javascript:updateSort(\'' + ${param} + '\');'" th:text="${param}"></a></li>
</ul>
</div>
</div>
<!-- Sort By... -->
<div class='col-sm-6'>
<label>Sort By</label>
<div class="btn-group">
<input type="hidden" id="sort_by" />
<button type="button" class="btn btn-info" id="search_sort_button">Default</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Default Sort</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="javascript:updateSort('');">Default Sort</a></li>
<li class="divider"></li>
<li th:each="param : ${sortParams}"><a th:href="'javascript:updateSort(\'' + ${param} + '\');'" th:text="${param}"></a></li>
</ul>
</div>
&nbsp;&nbsp;&nbsp;
<label>Direction</label>
<div class="btn-group">
<input type="hidden" id="sort_direction" />
<button type="button" class="btn btn-info" id="search_sort_direction_button">Default</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Default Sort</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="javascript:updateSortDirection('');">Default</a></li>
<li class="divider"></li>
<li><a href="javascript:updateSortDirection('asc');">Ascending</a></li>
<li><a href="javascript:updateSortDirection('desc');">Descending</a></li>
</ul>
</div>
</div>
</div>
<br clear="all"/>

View File

@ -446,7 +446,7 @@ function setResource(target, resourceName) {
}
function updateSort(value) {
$('#search_sort').val(value);
$('#sort_by').val(value);
if (value == '') {
$('#search_sort_button').text('Default Sort');
} else {
@ -454,6 +454,15 @@ function updateSort(value) {
}
}
function updateSortDirection(value) {
$('#sort_direction').val(value);
if (value == '') {
$('#search_sort_direction_button').text('Default');
} else {
$('#search_sort_direction_button').text(value);
}
}
$( document ).ready(function() {
addSearchParamRow();
});

View File

@ -153,6 +153,9 @@
(e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks
to baopingle for reporting and providing a test case!
</action>
<action type="add">
Sorting is now supported in the Web Testing UI (previously a button existed for sorting, but it didn't do anything)
</action>
</release>
<release version="0.8" date="2014-Dec-17">
<action type="add">