Skip to content

Commit

Permalink
Merge pull request #127 from thehyve/trait_v2
Browse files Browse the repository at this point in the history
Merge The Hyve trait_v2 into master
  • Loading branch information
ferryjagers committed Jul 28, 2015
2 parents 3d7c485 + c73b80e commit 08aabaf
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 37 deletions.
2 changes: 1 addition & 1 deletion application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
#Sat Jan 05 12:13:45 CET 2013
app.grails.version=2.4.5
app.name=gscf
app.version=0.9.5.4
app.version=0.9.5.5
30 changes: 30 additions & 0 deletions grails-app/controllers/dbnp/studycapturing/StudyController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,36 @@ class StudyController {
render datatableData as JSON
}


/**
* Returns data for a templated datatable with samples.
*
* Due to the formatting of the data, this is a separate method
* @return
*/
def dataTableSamples() {
// As we add columns to the table, we should shift the sort column
def sortColumn = params.int( "iSortCol_0" )

if( sortColumn > 3 )
params.iSortCol_0 = sortColumn - 3

def datatableData = getTemplatedDatatablesData({ sample ->
def defaultData = datatablesService.defaultEntityFormatter(sample)

// Remove the IDs, as they are irrelevant for now
defaultData = defaultData.tail()

// Add additional columns
defaultData.add(1, sample.parentSubject?.name )
defaultData.add(2, sample.parentEvent?.event?.name )
defaultData.add(3, sample.parentEvent?.eventGroup?.name )

defaultData
})
render datatableData as JSON
}

/**
* Returns data for a templated datatable. The type of entities is based on the template given.
* @return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,23 @@ class StudyEditController {
*/
def deleteAssays() {
if( !request.post ) {
response.status = 400
render "Bad Request"
return
response.status = 400
render "Bad Request"
return
}

def numIds = params.list( 'ids' )?.size()
def numDeleted = deleteEntities( Assay )

if( numDeleted )
flash.message = "" + numDeleted + " assay(s) were deleted"
else
flash.error= "No assays were selected"

if( numIds ) {
if( numDeleted == numIds )
flash.message = "All " + numDeleted + " selected assay(s) were deleted"
else
flash.error = "" + numDeleted + " of the " + numIds + " selected assay(s) were deleted. Most probably the other assays contain measurements in one of the modules and cannot be deleted."
} else {
flash.error= "No assays were selected"
}

redirect action: "assays", id: params.id
}

Expand Down Expand Up @@ -481,13 +486,17 @@ class StudyEditController {
def entity = entityType.get( id.toLong() )

switch( entityType ) {
case Subject:
case Subject:
study.deleteSubject( entity )
break
case Sample:
case Sample:
study.deleteSample( entity )
break
case Assay:
case Assay:
// Can't delete assays with measurements
if( entity.hasMeasurements() ) {
return
}
study.deleteAssay( entity )
break
}
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/home/index.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
<li><a target="_blank" href="${resource(dir:'downloads', file: 'license_terms.pdf')}" title="">License Terms</a></li>
</ul>
</div>
<p class="note">If you encounter a problem or have a suggestion for improvement feel free to submit an issue <a href="#" title="">here</a></p>
<p class="note">If you encounter a problem or have a suggestion for improvement feel free to submit an issue <a href="${issueUrl}" title="">here</a></p>
</div>
</div>
<h1>Usage Statistics</h1>
Expand Down
10 changes: 8 additions & 2 deletions grails-app/views/study/samples.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@

<g:each in="${templates}" var="template">
<h3>Template: ${template.name}</h3>
<table id="samplesTable_${template.id}" data-templateId="${template.id}" data-fieldPrefix="sample" data-formId="sampleForm" class="samplesTable" rel="${g.createLink(action:"dataTableEntities", id: study.id, params: [template: template.id])}">
<table id="samplesTable_${template.id}" data-templateId="${template.id}" data-fieldPrefix="sample" data-formId="sampleForm" class="samplesTable" rel="${g.createLink(action:"dataTableSamples", id: study.id, params: [template: template.id])}">
<thead>
<tr>
<th data-fieldname="name">Name</th>
<th data-fieldname="subject" class="nonsortable">Subject</th>
<th data-fieldname="event" class="nonsortable">Event</th>
<th data-fieldname="group" class="nonsortable">Group</th>
<g:each in="${domainFields + template.getFields()}" var="field">
<th data-fieldname="${field.escapedName()}">${field.name}</th>
<g:unless test="${field.name == 'name'}">
<th data-fieldname="${field.escapedName()}">${field.name}</th>
</g:unless>
</g:each>
</tr>
</thead>
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/studyEdit/assaysamples.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</g:each>
<th>Sample</th>
<th>Subject</th>
<th>Eventgroup</th>
<th>Group</th>
<th>Sampling event</th>
<th>Sample template</th>
<th>Starttime (combined)</th>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.dbnp.gdt

import grails.converters.*
import grails.util.Holders

class TemplateEditorController {
def entityName
Expand Down Expand Up @@ -167,7 +168,7 @@ class TemplateEditorController {
// set content type
response.setContentType("text/html; charset=UTF-8")

render('view': 'error');
render('view': 'error', model: [ issueUrl: Holders.config.gscf.issueURL ] );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<p>
You tried to access the template editor in an invalid way. If you feel you get this message
in error, please file a bugreport <a href="https://trac.nbic.nl/gscf/newticket?summary=templateEditor%20invalid%20request&version=${meta(name: 'app.version')}" target="_new">here</a> with as many details as possible.
in error, please file a bugreport <a href="${issueUrl}" target="_new">here</a> with as many details as possible.
</p>

<g:if test="${layout == 'main'}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,16 @@ abstract class TemplateEntity extends Identity {
* Retrieve a the value of a single field for a set of entities
*/
public getColumnForEntities( def entities, TemplateField field ) {
if( !entities )
return []

def fieldType = field.type
String store = "template${fieldType.casedName}Fields"

def columnData = this.class.executeQuery( "SELECT e.id, store FROM " + this.class.simpleName + " e INNER JOIN e." + store + " store WHERE e in (:entities) AND index(store) = :fieldName", [entities: entities, fieldName: field.name ] )
def columnMap = columnData.collectEntries { [ (it[0]): it[1] ] }

entities.collect { columnMap[ it.id ] }
entities.collect { it ? columnMap[ it.id ] : null }
}

/**
Expand Down
3 changes: 2 additions & 1 deletion local-plugins/SAM/grails-app/conf/SamResources.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ modules = {
sam2 {
dependsOn 'jquery'
dependsOn 'datatables' // from dbxpModuleBase

dependsOn 'infoboxes'

resource url: [dir: 'js', file: 'selectAddMore.js', plugin: 'dbxp-sam']
resource url: [dir: 'js', file: 'removeWebFlowExecutionKey.js', plugin: 'dbxp-sam']
resource url: [dir: 'css', file: 'sam.css', plugin: 'dbxp-sam']
Expand Down
39 changes: 28 additions & 11 deletions local-plugins/SAM/grails-app/views/SAMAssay/show.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
</content>
<h1>${module} ${assayInstance.name} / ${assayInstance.parent.title}</h1>

<span class="message info">
<span class="title">List of measurements</span>
You can select measurements by clicking on them. Comments to the measurements are denoted with an icon.
</span>

<g:if test="${measurements.size() > 0}">
<ul class="data_nav buttons ontop">
<li><g:link class="delete" controller="measurement" action="deleteByAssay" id="${assayInstance.id}" params="${[module: module]}" onClick="return confirm('Are you sure?');">Delete all measurements</g:link></li>
Expand All @@ -26,7 +31,7 @@
<form id="deleteform" action="<g:createLink controller="measurement" action="delete" />" method="post">
<input type="hidden" name="assayId" value="${assayInstance.id}" />
<input type="hidden" name="module" value="${module}" />
<table>
<table class="measurements">
<thead>
<tr>
<th></th>
Expand All @@ -39,7 +44,7 @@
<g:set var="measurementIndex" value="${0}" />
<g:each var="sample" in="${samples}">
<tr>
<td>${sample.name}</td>
<th>${sample.name}</th>

<g:each var="feature" in="${features}">
<%--
Expand Down Expand Up @@ -96,7 +101,10 @@
<g:if test="${isNumeric}">
<g:if test="${comments}">
<%-- numeric value and comments --%>
<span class="tooltip"> ${cellMeasurements[0].value}<span>${comments}</span></span>
<div class="tooltip">
${cellMeasurements[0].value}
<span>${comments}</span>
</div>
</g:if>
<g:else>
<g:if test="${cellMeasurements[0].value==cellMeasurements[0].value.round(3)}">
Expand All @@ -111,16 +119,12 @@
</g:if>
<g:else>
<%-- measurement is not numeric, so use text value from comments --%>
<span>${comments}</span>
<div class="tooltip">
${comments}
<span>${comments}</span>
</div>
</g:else>
</td>
<script>
$('#td${cellMeasurements[0].id}').on('click', function() {
var checkbox = $('#check${cellMeasurements[0].id}');
checkbox.prop('checked', !checkbox.prop('checked'));
$(this).toggleClass('selected', checkbox.prop('checked'));
});
</script>
</g:if>
<g:else>
<td></td>
Expand Down Expand Up @@ -159,5 +163,18 @@
to import your data or add your measurements <g:link controller="measurement" action="create" params="${[module: module]}">manually</g:link>.
</p>
</g:else>

<r:script>
$('.measurements td').on('click', function() {
// Update checkbox on click
var checkbox = $(this).find( "input[type=checkbox]" );
checkbox.prop('checked', !checkbox.prop('checked'));
$(this).toggleClass('selected', checkbox.prop('checked'));
}).each(function(idx,el) {
// Initialize styling based on checkboxes
var checkbox = $(this).find( "input[type=checkbox]" );
$(this).toggleClass('selected', checkbox.prop('checked'));
});;
</r:script>
</body>
</html>
17 changes: 14 additions & 3 deletions local-plugins/SAM/web-app/css/sam.css
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ td {
text-overflow: clip;
}

/* Comments field in the assay overview */
td.comments { background-color: pink; }

/* Selected cells */
td.selected { background-color: #CCFFCC; }

Expand Down Expand Up @@ -212,3 +209,17 @@ td.styleFeatureGroup {
text-decoration: underline;
}

table.measurements td {
vertical-align: middle;
white-space: nowrap;
max-width: 60px;
overflow: hidden;
text-overflow: ellipsis;
}

table.measurements td.comments {
background-size: 12px 12px;
background-image: url(../../famfamfam-1.0.1/images/icons/page_edit.png);
background-position: center right;
background-repeat: no-repeat;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dbnp.studycapturing

import org.dbnp.gdt.*
import dbnp.authentication.*
import org.dbxp.sam.Measurement

/**
* This class describes an Assay, which describes the application of a certain (omics) measurement to multiple samples.
Expand Down Expand Up @@ -124,4 +125,13 @@ class Assay extends TemplateEntity {
return 0
}
}

/**
* Checks whether the SAM module has measurements associated with this assay
*/
public boolean hasMeasurements() {
def num = Measurement.executeQuery( "SELECT COUNT(*) FROM Measurement m WHERE m.sample.parentAssay = :assay", [ "assay": this ] )

return num[0] > 0
}
}
5 changes: 3 additions & 2 deletions web-app/js/studyEdit/studyEdit.design.eventGroupDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ StudyEdit.design.eventGroups = {

edit: function( id, dataUrl ) {
var dialog = StudyEdit.design.eventGroups.dialog.get();
dialog.dialog( "option", "title", "Edit treatment & sample group" );
dialog.dialog( "option", "title", "Edit sample & treatment group" );
dialog.data( "eventgroup-id", id );

StudyEdit.design.eventGroups.dialog.open()
Expand Down Expand Up @@ -278,7 +278,8 @@ StudyEdit.design.eventGroups = {

if( confirm( "Deleting this treatment&sample group will also delete all samples that originated from it, and remove all instances of this group. Are you sure you want to delete the treatment&sample group?" ) ) {
$.post( url, data, function() {
console.log( "Eventgroup deleted" );
if( console && console.log )
console.log( "Eventgroup deleted" );
});

// Also delete the eventgroup from the timeline with subjectEventgroups
Expand Down
3 changes: 2 additions & 1 deletion web-app/js/studyEdit/studyEdit.design.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ StudyEdit.design.subjectEventGroups = {

if( !hasSamples || confirm( "Deleting this treatment&sample group will also delete all samples that originated from it. Are you sure you want to delete the group?" ) ) {
$.post( url, data, function() {
console.log( "SubjectEventgroup deleted" );
if( console && console.log )
console.log( "SubjectEventgroup deleted" );
});

return true;
Expand Down

0 comments on commit 08aabaf

Please sign in to comment.