Changeset 1512

Show
Ignore:
Timestamp:
10-02-11 13:04:32 (3 years ago)
Author:
robert@…
Message:

Improved query views

Location:
trunk
Files:
12 modified

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/query/AdvancedQueryController.groovy

    r1501 r1512  
    44import org.dbnp.gdt.* 
    55 
    6 // TODO: Make use of the searchable-plugin possibilities instead of querying the database directly 
     6// TODO: Make use of the searchable-plugin or Lucene possibilities instead of querying the database directly 
    77 
    88/** 
     
    113113                        redirect( action: "index" ); 
    114114                        return; 
     115                } 
     116                 
     117                // Attach all objects to the current hibernate thread, because the 
     118                // object might be attached to an old thread, since the results are 
     119                // saved in session 
     120                s.getResults().each { 
     121                        it.attach(); 
    115122                } 
    116123 
     
    613620                                if( json[ s.entity ] ) { 
    614621                                        json[ s.entity ].each { action -> 
    615                                                 def url = module.url + "/action/" + action.name 
    616                                                 url += "?entity=" + s.entity 
     622                                                def url = action.url ?: module.url + "/action/" + action.name 
     623                                                 
     624                                                if( url.find( /\?/ ) ) 
     625                                                        url += "&" 
     626                                                else 
     627                                                        url += "?" 
     628                                                 
     629                                                url += "entity=" + s.entity 
    617630                                                url += "&" + s.filterResults(selectedIds).collect { "tokens=" + it.giveUUID() }.join( "&" ) 
    618631                                                actions << [ 
  • trunk/grails-app/controllers/RestController.groovy

    r1482 r1512  
    419419         * Example 3: two sampleTokens given. 
    420420         * Query:  
    421          * http://localhost:8080/gscf/rest/getSamples/query?assayToken=PPSH-Glu-A&sampleToken=5_A 
     421         * http://localhost:8080/gscf/rest/getSamples/query?assayToken=PPSH-Glu-A&sampleToken=5_A&sampleToken=6_A 
    422422         *  
    423423         * Result:  
    424424         * [{"sampleToken":"5_A","material":"blood plasma","subject":"5","event":"Blood extraction","startTime":"4 days, 6 hours"}, 
    425425         *  {"sampleToken":"6_A","material":"blood plasma","subject":"6","event":"Blood extraction","startTime":"4 days, 6 hours"}] 
     426         * 
     427         * 
     428         * Example 4: no assaytoken given 
     429         * Query:  
     430         * http://localhost:8080/gscf/rest/getSamples/query?sampleToken=5_A&sampleToken=6_A 
     431         *  
     432         * Result:  
     433         * [{"sampleToken":"5_A","material":"blood plasma","subject":"5","event":"Blood extraction","startTime":"4 days, 6 hours"}, 
     434         *  {"sampleToken":"6_A","material":"blood plasma","subject":"6","event":"Blood extraction","startTime":"4 days, 6 hours"}] 
     435         * 
    426436         */ 
    427437        def getSamples = { 
    428438                def items = [] 
     439                def samples 
    429440                if( params.assayToken ) { 
    430441                        def assay = Assay.findByAssayUUID( params.assayToken ); 
     
    437448                                } 
    438449                                 
    439                                 def samples = assay.getSamples() // on all samples 
    440  
    441                                 if( params.sampleToken ) {       // or on a subset of samples? 
    442                                         def sampleTokens = (params.sampleToken instanceof String) ?  
    443                                                 [params.sampleToken] : params.sampleToken 
    444                                         samples = [] 
    445                                         sampleTokens.each{ sampleToken -> 
    446                                                 samples.addAll(assay.getSamples().find{ sample -> sampleToken == sample.giveUUID() })  
    447                                         } 
    448                                 } 
    449  
    450                                 samples.each { sample -> 
    451  
    452                                         def item = [  
    453                                                 'sampleToken' : sample.giveUUID(), 
    454                                                 'material'        : sample.material?.name, 
    455                                                 'subject'         : sample.parentSubject?.name, 
    456                                                 'event'           : sample.parentEvent?.template?.name, 
    457                                                 'startTime'       : sample.parentEvent?.getStartTimeString() 
    458                                         ] 
    459  
    460                                         sample.giveFields().each { field -> 
    461                                                 def name = field.name 
    462                                                 def value = sample.getFieldValue( name ) 
    463                                                 if(name!='material') 
    464                                                 { 
    465                                                         item[name]=value 
    466                                                 } 
    467                                         } 
    468  
    469                                         if(sample.parentEvent) { 
    470                                                 def parentEvent = sample.parentEvent 
    471                                                 def eventHash = [:] 
    472                                                 parentEvent.giveFields().each { field -> 
    473                                                         def name = field.name 
    474                                                         if( name !='sampleTemplate' && name != 'fields') { 
    475                                                                 def value = parentEvent.getFieldValue( name ) 
    476                                                                 eventHash[name]=value 
    477                                                         } 
    478                                                 } 
    479                                                 item['eventObject'] = eventHash  
    480                                         } 
    481  
    482                                         if(sample.parentSubject) { 
    483                                                 def parentSubject = sample.parentSubject 
    484                                                 def subject = [:] 
    485                                                 parentSubject.giveFields().each { field -> 
    486                                                         def name = field.name 
    487                                                         if( name!='fields') { 
    488                                                                 def value = parentSubject.getFieldValue( name ) 
    489                                                                 subject[name]=value 
    490                                                         } 
    491                                                 } 
    492                                                 item['subjectObject'] = subject  
    493                                         } 
    494  
    495                                         items.push item  
    496                                 } 
     450                                samples = assay.getSamples() // on all samples 
    497451                        } else { 
    498452                                // Assay not found 
     
    500454                                return false 
    501455                        } 
    502                 } 
     456                } else { 
     457                        // Find all samples from studies the user can read 
     458                        def studies = Study.list().findAll { it.canRead( AuthenticationService.getRemotelyLoggedInUser( params.consumer, params.token ) ) }; 
     459                        samples = studies*.getSamples().flatten(); 
     460                } 
     461                 
     462                // Check whether only a subset of samples should be returned 
     463                if( params.sampleToken ) { 
     464                        def sampleTokens = params.list( "sampleToken" ); 
     465                        samples = samples.findAll { sampleTokens.contains( it.giveUUID() ) }  
     466                } 
     467 
     468                samples.each { sample -> 
     469 
     470                        def item = [  
     471                                'sampleToken' : sample.giveUUID(), 
     472                                'material'        : sample.material?.name, 
     473                                'subject'         : sample.parentSubject?.name, 
     474                                'event'           : sample.parentEvent?.template?.name, 
     475                                'startTime'       : sample.parentEvent?.getStartTimeString() 
     476                        ] 
     477 
     478                        sample.giveFields().each { field -> 
     479                                def name = field.name 
     480                                def value = sample.getFieldValue( name ) 
     481                                if(name!='material') 
     482                                { 
     483                                        item[name]=value 
     484                                } 
     485                        } 
     486 
     487                        if(sample.parentEvent) { 
     488                                def parentEvent = sample.parentEvent 
     489                                def eventHash = [:] 
     490                                parentEvent.giveFields().each { field -> 
     491                                        def name = field.name 
     492                                        if( name !='sampleTemplate' && name != 'fields') { 
     493                                                def value = parentEvent.getFieldValue( name ) 
     494                                                eventHash[name]=value 
     495                                        } 
     496                                } 
     497                                item['eventObject'] = eventHash  
     498                        } 
     499 
     500                        if(sample.parentSubject) { 
     501                                def parentSubject = sample.parentSubject 
     502                                def subject = [:] 
     503                                parentSubject.giveFields().each { field -> 
     504                                        def name = field.name 
     505                                        if( name!='fields') { 
     506                                                def value = parentSubject.getFieldValue( name ) 
     507                                                subject[name]=value 
     508                                        } 
     509                                } 
     510                                item['subjectObject'] = subject  
     511                        } 
     512 
     513                        items.push item  
     514                } 
     515 
    503516                render items as JSON 
    504517        } 
  • trunk/grails-app/views/advancedQuery/_criteria.gsp

    r1501 r1512  
    33        <g:each in="${criteria}" var="criterion" status="j"> 
    44                <li> 
    5                         <span class="entityfield">${criterion.entityField()}</span> 
     5                        <span class="entityfield">${criterion.entityField().toLowerCase()}</span> 
    66                        <span class="operator">${criterion.operator}</span> 
    77                        <span class="value"> 
  • trunk/grails-app/views/advancedQuery/index.gsp

    r1501 r1512  
    5050</g:if> 
    5151 
    52 <form id="input_criteria"> 
     52<div id="searchForm"> 
     53        <form id="input_criteria"> 
    5354        <h2>Add criterium</h2> 
    5455        <p class="explanation"> 
     
    7879                        <option value="&lt;">Lower than</option> 
    7980                        <option value="&lt;=">Lower than or equals</option> 
    80                 </select>  
    81  
     81                </select> 
     82         
    8283        <label for="value">Value</label> 
    8384                <input class='text' type="text" name="value" /> 
    8485         
    8586        <input class="button" type="button" onClick="addCriterium();" value="Add" /> 
    86 </form> 
    87  
    88 <div id="searchForm"> 
     87        </form> 
    8988        <g:form action="search" method="get"> 
    9089                <label for="entity">Search for</label><g:select from="${entitiesToSearchFor}" optionKey="key" optionValue="value" name="entity" /><br /> 
     
    9796                <input type="submit" value="Run query" class="submitcriteria" disabled="disabled" /> 
    9897        </g:form> 
     98         
     99        <br clear="all" /> 
    99100</div> 
    100101<p class="options"> 
  • trunk/grails-app/views/advancedQuery/list.gsp

    r1501 r1512  
    7272                                <td>${search.getNumResults()}</td> 
    7373                                <td><g:formatDate date="${search.executionDate}" format="HH:mm" /></td> 
    74                                 <td><g:link action="show" id="${search.id}">Show</g:link> 
    75                                 <td><g:link action="discard" id="${search.id}">Discard</g:link> 
     74                                <td><g:link action="show" id="${search.id}"><img border="0" src="${fam.icon(name: 'application_form_magnify')}" alt="Show" /></g:link> 
     75                                <td><g:link action="discard" id="${search.id}"><img border="0" src="${fam.icon(name: 'basket_remove')}" alt="Discard" /></g:link> 
    7676                        </tr> 
    7777                </g:each> 
     
    8181 
    8282<p class="options"> 
    83         <a href="#" class="combine" onClick="combineResults( $( '#searchform' ) ); return false;">Combine results</a><br /> 
    84         <a href="#" class="searchIn" onClick="searchWithinResults( $( '#searchform' ) ); return false;">Search within results</a><br /> 
    85         <g:link class="search" action="index">Search again</g:link><br /> 
    86         <a href="#" class="discard" onClick="discardResults( $( '#searchform' ) ); return false;">Discard results</a><br /> 
     83        <a href="#" class="combine" onClick="combineResults( $( '#searchform' ) ); return false;">Combine results</a> 
     84        <a href="#" class="searchIn" onClick="searchWithinResults( $( '#searchform' ) ); return false;">Search within results</a> 
     85        <g:link class="search" action="index">Search again</g:link> 
     86        <a href="#" class="discard" onClick="discardResults( $( '#searchform' ) ); return false;">Discard results</a> 
    8787</p> 
    88  
     88<br clear="all" /> 
    8989</body> 
    9090</html> 
  • trunk/grails-app/views/advancedQuery/_resultbuttons.gsp

    r1501 r1512  
    1 <p class="options"> 
    2         <g:link class="searchIn" action="searchIn" id="${queryId}">Search within results</g:link><br /> 
     1<p class="options multiple"> 
     2        <g:if test="${search.getNumResults() == 0}"> 
     3                <a href="#" onClick="return false;" class="searchIn disabled">Search within results</a> 
     4        </g:if> 
     5        <g:else> 
     6                <g:link class="searchIn" action="searchIn" id="${queryId}">Search within results</g:link> 
     7        </g:else> 
     8        <br /> 
     9         
    310        <g:link class="search" action="index">Search again</g:link><br /> 
    411        <g:link class="discard" action="discard" id="${queryId}">Discard results</g:link><br /> 
    512        <g:link class="listPrevious" action="list">Previous searches</g:link> 
    613</p> 
    7 <p class="options"> 
     14<p class="options multiple"> 
    815        <g:each in="${actions}" var="action"> 
    9                 <a class="performAction ${action.name}" href="${action.url}" onClick="performAction( $('form#results'), '${action.name}', '${action.module}' ); return false;">${action.description}</a><br /> 
     16                <g:if test="${search.getNumResults() == 0}"> 
     17                        <a href="#" onClick="return false;" class="performAction ${action.name} disabled">${action.description}</a> 
     18                </g:if> 
     19                <g:else> 
     20                        <a class="performAction ${action.name}" href="${action.url}" onClick="performAction( $('form#results'), '${action.name}', '${action.module}' ); return false;">${action.description}</a> 
     21                </g:else> 
     22                <br /> 
    1023        </g:each> 
    1124</p> 
  • trunk/grails-app/views/advancedQuery/results.gsp

    r1501 r1512  
    1111<h1>Query results</h1> 
    1212 
    13 <p> 
    14         Your search for: 
    15 </p> 
    16 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
    17 <p>  
    18         resulted in ${search.getNumResults()} results. 
    19 </p> 
    20  
     13<div class="searchoptions"> 
     14        ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">result</g:if><g:else>results</g:else> found with  
     15        <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
     16</div> 
    2117<g:if test="${search.getNumResults() > 0}"> 
    2218        <%  
  • trunk/grails-app/views/advancedQuery/sampleresults.gsp

    r1501 r1512  
    1111<h1>Query results</h1> 
    1212 
    13 <p> 
    14         Your search for samples with: 
    15 </p> 
    16 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
    17 <p>  
    18         resulted in ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">sample</g:if><g:else>samples</g:else>. 
    19 </p> 
    20  
     13<div class="searchoptions"> 
     14        ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">sample</g:if><g:else>samples</g:else> found with  
     15        <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
     16</div> 
    2117<g:if test="${search.getNumResults() > 0}"> 
    2218        <%  
  • trunk/grails-app/views/advancedQuery/studyresults.gsp

    r1501 r1512  
    1111<h1>Query results</h1> 
    1212 
    13 <p> 
    14         Your search for studies with: 
    15 </p> 
    16 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
    17 <p>  
    18         resulted in ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">study</g:if><g:else>studies</g:else>. 
    19 </p> 
     13<div class="searchoptions"> 
     14        ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">study</g:if><g:else>studies</g:else> found with  
     15        <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 
     16</div> 
    2017<g:if test="${search.getNumResults() > 0}"> 
    2118        <%  
  • trunk/grails-app/views/common/_topnav.gsp

    r1439 r1512  
    4848                </ul> 
    4949        </li> 
     50        <li><g:link controller="advancedQuery">Query</g:link></li> 
    5051        <sec:ifAllGranted roles="ROLE_ADMIN"> 
    5152                <li> 
  • trunk/web-app/css/advancedQuery.css

    r1501 r1512  
    11label { display: inline-block; zoom: 1; *display: inline; width: 110px; margin-top: 10px;  } 
     2 
     3#searchForm { position: relative; border: 1px solid #666666; padding: 5px 10px; margin: 10px 0; } 
    24 
    35#searchForm ul#criteria { margin-left: 110px; padding-left: 0px; margin-top: -19px; list-style-type: none;  } 
     
    57#searchForm ul#criteria li span,  
    68#searchForm ul#criteria li a { display: inline-block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 5px; } 
    7 #searchForm ul#criteria li .entityfield { width: 200px; } 
     9#searchForm ul#criteria li .entityfield { width: 180px; } 
    810#searchForm ul#criteria li .operator { width: 100px; } 
    911#searchForm ul#criteria li .value { width: 240px; } 
     
    1517#searchForm ul#criteria li:hover span { text-decoration: line-through; } 
    1618 
    17 #input_criteria { display: block; float: right; width: 260px; border: 1px solid #666; padding: 10px; } 
     19#input_criteria { display: block; float: right; width: 260px; border-left: 1px solid #666; padding: 10px; position: relative; height: 100%; } 
    1820#input_criteria h2 { margin-top: 2px; margin-bottom: 8px; font-weight: bold; } 
    1921#input_criteria label { width: 80px; margin-top: 8px; } 
     
    2426.ui-menu-item .entity { color: #666; font-style: italic; } 
    2527 
    26 .options { float: left; width: 300px; } 
     28.searchoptions { font-size: 10px; margin-bottom: 3px; } 
     29.searchoptions label { margin-top: 4px; } 
     30.searchoptions ul#criteria { list-style-type: none; margin-left: 0; padding-left: 0; display: inline; } 
     31.searchoptions ul#criteria li { margin-left: 0; padding-left: 0; display: inline; } 
     32 
     33/** Options buttons **/ 
     34.options { margin-top: 8px; } 
     35.options.multiple { float: left; width: 300px; } 
     36 
    2737.options a { 
    2838        font-size: 10px; 
    2939        font-weight: bold; 
    30         margin-left: 3px; 
    31         margin-right: 3px; 
     40        margin-right: 10px; 
    3241        padding-top: 2px; 
    3342        padding-bottom: 2px; 
     
    3544        padding-left: 28px;      
    3645} 
     46 
     47#content .options a.disabled { color: #aaa; cursor: default; } 
    3748 
    3849.options a.performAction { 
  • trunk/web-app/css/datatables/demo_table_jui.css

    r1507 r1512  
    7575} 
    7676 
     77.dataTables_wrapper { font-size: 10px; } 
    7778 
    7879/*