Changeset 13
- Timestamp:
- Feb 10, 2011, 5:03:02 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/conf/Config.groovy
r3 r13 41 41 // Otherwise, it should be given as an absolute path (e.g. '/home/user/sequences') 42 42 // The directory should be writable by the webserver user 43 metagenomics.fileUploadDir = "fil uploads/temp"43 metagenomics.fileUploadDir = "fileuploads/temp" 44 44 45 45 // Maximum age that uploaded files should be kept on the server before deleting them. When a user uploads a file, -
trunk/grails-app/controllers/nl/tno/metagenomics/AssayController.groovy
r12 r13 11 11 def excelService 12 12 def sampleExcelService 13 def fastaService 13 14 14 15 def index = { … … 326 327 } 327 328 328 329 /** 330 * Exports data about one or more assays in fasta format 331 */ 332 def exportAsFasta = { 333 def tokens = params.list( 'tokens' ); 334 def ids = params.list( 'ids' ); 335 def name; 336 337 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 338 339 if( !tokens && !ids ) { 340 def message = "No assay tokens or ids given" 341 response.setStatus( 400, message) 342 render message; 343 return; 344 } 345 346 def assaySamples = []; 347 348 // Determine which assaySamples to export 349 def assay; 350 tokens.each { token -> 351 assay = Assay.findByAssayToken( token ); 352 if( assay ) 353 assaySamples += assay.assaySamples 354 } 355 ids.each { id -> 356 assay = Assay.get( id ); 357 if( assay ) 358 assaySamples += assay.assaySamples 359 } 360 361 if( ( ids.size() + tokens.size() ) == 1 && assay ) 362 name = "Assay_" + assay?.name?.replace( ' ', '_' ); 363 else 364 name = "assays"; 365 366 // Export the sequences and quality scores 367 response.setHeader "Content-disposition", "attachment; filename=" + name.trim() + ".zip" 368 try { 369 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 370 response.outputStream.flush(); 371 } catch( Exception e ) { 372 log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." ); 373 } 374 } 329 375 } -
trunk/grails-app/controllers/nl/tno/metagenomics/RunController.groovy
r12 r13 9 9 def synchronizationService 10 10 def sampleExcelService 11 def fastaService 11 12 12 13 def index = { … … 25 26 // Make sure the newest data is available 26 27 synchronizationService.sessionToken = session.sessionToken 27 synchronizationService.synchronizeStudies(); 28 synchronizationService.user = session.user 29 try { 30 synchronizationService.synchronizeStudies(); 31 } catch( Exception e ) { 32 log.error "Exception occurred during synchronization in " + params.controller + ": " + e.getMessage() 33 redirect( url: synchronizationService.gscfService.urlAuthRemote(params, session.sessionToken) ) 34 } 28 35 29 36 // Determine runs not used in this assay … … 445 452 } 446 453 454 /** 455 * Exports data about one or more runs in fasta format 456 */ 457 def exportAsFasta = { 458 def ids = params.list( 'ids' ); 459 460 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 461 462 if( !ids ) { 463 def message = "No run ids given" 464 response.setStatus( 400, message) 465 render message; 466 return; 467 } 468 469 def assaySamples = []; 470 def name 471 472 if( ids.size() == 1 ) 473 name = "Run_" + Run.get( ids[ 0 ] )?.name?.replace( ' ', '_' ); 474 else 475 name = "runs"; 476 477 // Determine which assaySamples to export 478 ids.each { id -> 479 def run = Run.get( id ); 480 if( run ) 481 assaySamples += run.assaySamples 482 } 483 484 // Export the sequences and quality scores 485 response.setHeader "Content-disposition", "attachment; filename=${name}.zip" 486 try { 487 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 488 response.outputStream.flush(); 489 } catch( Exception e ) { 490 log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." ); 491 } 492 } 493 447 494 448 495 /** -
trunk/grails-app/controllers/nl/tno/metagenomics/StudyController.groovy
r12 r13 20 20 lastSynchronized: synchronizationService.lastFullSynchronization ] 21 21 } 22 23 def exportAsExcel = { 24 render "To be implemented" 25 } 22 26 23 27 } -
trunk/grails-app/controllers/nl/tno/metagenomics/integration/ActionController.groovy
r12 r13 3 3 4 4 class ActionController { 5 def fastaService 6 7 /** 8 * Exports data in fasta format 9 */ 10 def fasta = { 11 def entity = params.entity; 12 def tokens = params.tokens; 13 14 if( !tokens ) { 15 def message = "No entity tokens given" 16 response.setStatus( 400, message) 17 render message; 18 return; 19 } 20 21 if( tokens instanceof String ) 22 tokens = [tokens] 23 24 def assaySamples = []; 25 def name = "testfile"; 26 27 switch( params.entity ) { 28 case "Study": 29 // Determine which assaySamples to export 30 tokens.each { token -> 31 def study = Study.findByStudyToken( token ); 32 if( study ) 33 assaySamples += study.assay*.assaySamples.flatten() 34 } 35 break; 36 case "Assay": 37 // Determine which assaySamples to export 38 tokens.each { token -> 39 def assay = Assay.findByAssayToken( token ); 40 if( assay ) 41 assaySamples += assay.assaySamples 42 } 43 break; 44 case "Sample": 45 // Determine which assaySamples to export 46 tokens.each { token -> 47 def sample = Sample.findBySampleToken( token ); 48 if( sample ) 49 assaySamples += sample.assaySamples 50 } 51 break; 52 default: 53 def message = "Specified entity can't be handled by this module." 54 response.setStatus( 400, message) 55 render message; 56 return; 57 } 58 59 // Export the sequences and quality scores 60 response.setHeader "Content-disposition", "attachment; filename=${name}.zip" 61 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 62 response.outputStream.flush(); 63 } 5 64 6 } -
trunk/grails-app/controllers/nl/tno/metagenomics/integration/RestController.groovy
r12 r13 373 373 switch( entity ) { 374 374 case "Study": 375 actions[ entity ] = [ [ name: "excel", description: "Export as excel" ] ]375 actions[ entity ] = [ [ name: "excel", description: "Export as excel", url: createLink( controller: "study", action: "exportAsExcel", absolute: true ) ] ] 376 376 break; 377 377 case "Assay": 378 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta" ] ]378 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta", url: createLink( controller: "assay", action: "exportAsFasta", absolute: true ) ] ] 379 379 break; 380 380 case "Sample": 381 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta" ] ]381 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta", url: createLink( controller: "sample", action: "exportAsFasta", absolute: true ) ] ] 382 382 break; 383 383 default: -
trunk/grails-app/services/nl/tno/metagenomics/FastaService.groovy
r12 r13 3 3 import java.io.BufferedWriter; 4 4 import java.io.File; 5 import java.io.Writer; 5 6 import java.util.ArrayList; 6 7 import java.util.zip.ZipEntry … … 11 12 def fileService 12 13 def fuzzySearchService 14 def sampleExcelService 13 15 14 16 static transactional = true … … 428 430 429 431 // Save the tag for exporting 430 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, tag: tag]432 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: tag] 431 433 } 432 434 } … … 481 483 } 482 484 485 // Export a tab delimited file with tags 486 zipFile.putNextEntry( new ZipEntry( name + "_sample-tag.tab" ) ); 487 exportSampleTagFile( tags, zipWriter ); 488 zipWriter.flush(); 489 zipFile.closeEntry(); 490 491 // Export an excel file with information about the samples 492 zipFile.putNextEntry( new ZipEntry( name + ".xls" ) ); 493 sampleExcelService.exportExcelSampleData( assaySamples, tags, zipFile ); 494 zipFile.closeEntry(); 495 483 496 zipFile.close(); 484 485 // Export a tab delimited file with tags 486 //exportSampleTagFile( tags ); 497 } 498 499 /** 500 * Creates a tab delimited file with two columns and column headers "Sequence" and "Samplename" 501 * @param tags Map with newly created tags 502 * @param zipWriter Writer to write the data to 503 */ 504 protected void exportSampleTagFile( List tags, Writer zipWriter ) { 505 zipWriter.write( "Sequence" + "\t" + "Samplename" + "\n" ); 506 507 // Check whether the sample names are unique. If they aren't, the assay and study names 508 // are appended to the sample name 509 def sampleNames = tags*.sampleNames; 510 if( sampleNames.unique().size() < sampleNames.size() ) { 511 tags.each { 512 it.uniqueName = it.sampleName + " (" + it.assayName + " / " + it.studyName + ")"; 513 } 514 } else { 515 tags.each { 516 it.uniqueName = it.sampleName; 517 } 518 } 519 520 tags.each { 521 zipWriter.write( it.tag + "\t" + it.uniqueName + "\n" ); 522 } 487 523 } 488 524 -
trunk/grails-app/services/nl/tno/metagenomics/SampleExcelService.groovy
r9 r13 1 1 package nl.tno.metagenomics 2 3 import org.springframework.web.context.request.RequestContextHolder; 2 4 3 5 class SampleExcelService { 4 6 def excelService 5 7 def fuzzySearchService 8 def gscfService 6 9 7 10 static transactional = true … … 15 18 def possibleFields = [sampleNameName, runName, tagNameName, tagSequenceName, oligoNumberName] 16 19 17 def downloadSampleExcel( def assaySamples, boolean includeRun = true ) { 20 /** 21 * Download a sample excel file with information about the metagenomics data of the assaySamples (i.e. all assaySample properties) 22 * @param assaySamples AssaySamples for which the information should be exported 23 * @param includeRun Whether to include a column with run name or not 24 * @return 25 */ 26 def downloadSampleExcel( def assaySamples, boolean includeRun = true ) { 18 27 def sheetIndex = 0; 19 28 … … 50 59 excelService.autoSizeColumns( wb, sheetIndex, 0..2) 51 60 52 return wb; 61 return wb; 53 62 } 54 63 64 /** 65 * Parses a given excel file and tries to match the column names with assaySample properties 66 * @param file 67 * @return 68 */ 55 69 def parseTagsExcel( File file, boolean includeRun = true ) { 56 70 def sheetIndex = 0 … … 81 95 } 82 96 97 /** 98 * Updates given assay samples with data from the excel file 99 * @param matchColumns Indicated which columns from the excel file should go into which field of the assaySample 100 * @param possibleFields List with possible fields to enter 101 * @param file Excel file with the data 102 * @param assaySamples Assay Samples to be updated 103 * @return 104 */ 83 105 def updateTagsByExcel( def matchColumns, def possibleFields, File file, def assaySamples ) { 84 106 def sheetIndex = 0 … … 187 209 } 188 210 } 211 212 /** 213 * Exports all known data about the samples to an excel file 214 * @param assaySamples Assaysamples to export information about 215 * @param tags Tags associated with the assay samples 216 * @param stream Outputstream to write the data to 217 * @return 218 */ 219 def exportExcelSampleData( List<AssaySample> assaySamples, def tags, OutputStream stream ) { 220 if( assaySamples == null ) 221 assaySamples = [] 222 223 // Gather data from GSCF. 224 def sampleTokens = assaySamples*.sample.unique()*.sampleToken; 225 def sessionToken = RequestContextHolder.currentRequestAttributes().getSession().sessionToken 226 def gscfData 227 try { 228 gscfData = gscfService.getSamples( sessionToken, sampleTokens ); 229 } catch( Exception e ) { 230 log.error "Exception occurred while fetching sample data from gscf: " + e.getMessage(); 231 return; 232 } 233 234 // Determine which fields to show from the GSCF data 235 def gscfFields = [] 236 def subjectFields = [] 237 def eventFields = [] 238 def moduleFields = [ "Sample name", "Assay name", "Study name", "Run name", "# sequences", "Artificial tag sequence", "Original tag sequence", "Tag name", "Oligo number" ] 239 gscfData.each { sample -> 240 sample.each { key, value -> 241 if( key == "subjectObject" ) { 242 value.each { subjectKey, subjectValue -> 243 if( subjectValue && !value.isNull( subjectKey ) && !subjectFields.contains( subjectKey ) ) 244 subjectFields << subjectKey 245 } 246 } else if( key == "eventObject" ) { 247 value.each { eventKey, eventValue -> 248 if( eventValue && !value.isNull( eventKey ) && !eventFields.contains( eventKey ) ) 249 eventFields << eventKey 250 } 251 } else if( value && !sample.isNull( key ) && !gscfFields.contains( key ) ) { 252 gscfFields << key 253 } 254 } 255 } 256 257 // Handle specific fields and names in GSCF 258 def fields = handleSpecificFields( [ "module": moduleFields, "gscf": gscfFields, "subject": subjectFields, "event": eventFields ] ); 259 260 // Put the module data in the right format (and sorting the samples by name) 261 def data = [] 262 assaySamples.toList().sort { it.sample.name }.each { assaySample -> 263 // Lookup the tag for this assaySample 264 def currentTag = tags.find { it.assaySampleId == assaySample.id }; 265 266 // First add the module data 267 def row = [ 268 assaySample.sample.name, 269 assaySample.assay.name, 270 assaySample.assay.study.name, 271 assaySample.run?.name, 272 assaySample.numSequences(), 273 currentTag?.tag, 274 assaySample.tagName, 275 assaySample.tagSequence, 276 assaySample.oligoNumber 277 ] 278 279 // Afterwards add the gscfData including subject and event data 280 def gscfRow = gscfData.find { it.sampleToken == assaySample.sample.sampleToken }; 281 if( gscfRow ) { 282 fields[ "names" ][ "gscf" ].each { field -> 283 row << prepare( gscfRow, field ); 284 } 285 fields[ "names" ][ "subject" ].each { field -> 286 row << prepare( gscfRow.optJSONObject( "subjectObject" ), field ); 287 } 288 fields[ "names" ][ "event" ].each { field -> 289 row << prepare( gscfRow.optJSONObject( "eventObject" ), field ); 290 } 291 } 292 293 data << row; 294 295 } 296 297 // Create excel file 298 def sheetIndex = 0; 299 300 // Create an excel sheet 301 def wb = excelService.create(); 302 303 // Put the headers on the first row 304 excelService.writeHeader( wb, fields[ "descriptions" ][ "all" ], sheetIndex ); 305 excelService.writeData( wb, data, sheetIndex, 1 ); 306 307 // Auto resize columns 308 excelService.autoSizeColumns( wb, sheetIndex, 0..fields[ "names" ][ "all" ].size()-1) 309 310 // Write the data to the output stream 311 wb.write( stream ); 312 } 313 314 protected String prepare( def object, def fieldName ) { 315 if( object.isNull( fieldName ) ) 316 return ""; 317 318 // If the field is a object, return the 'name' property 319 def obj = object.optJSONObject( fieldName ) 320 if( obj ) 321 return obj.optString( "name" ) 322 else 323 return object.optString( fieldName ); 324 } 325 326 protected handleSpecificFields( def inputFields ) { 327 def fields = [ 328 "names": [ 329 "all": [] 330 ], 331 "descriptions": [ 332 "all": [] 333 ] 334 ] 335 336 inputFields.each { key, value -> 337 def names = []; 338 def descriptions = [] 339 switch( key ) { 340 case "gscf": 341 value.each { 342 if( it != "sampleToken" && it != "name" ) { 343 names << it; 344 if( it == "startTime" ) 345 descriptions << "Event start time"; 346 else 347 descriptions << it 348 } 349 } 350 break; 351 case "subject": 352 value.each { 353 if( it != "name" ) { 354 names << it; 355 descriptions << it 356 } 357 } 358 break; 359 case "event": 360 value.each { 361 if( it != "startTime" ) { 362 names << it; 363 descriptions << it 364 } 365 } 366 break; 367 default: 368 names = value; descriptions = value; 369 break; 370 } 371 372 fields[ "names" ][ key ] = names; 373 fields[ "names" ][ "all" ] += names; 374 fields[ "descriptions" ][ key ] = descriptions; 375 fields[ "descriptions" ][ "all" ] += descriptions; 376 } 377 378 return fields; 379 380 } 381 189 382 } -
trunk/grails-app/services/nl/tno/metagenomics/files/FileService.groovy
r12 r13 100 100 101 101 if( !uploadDir ) 102 uploadDir = "fileuploads"102 uploadDir = "fileuploads" 103 103 104 104 return absolutePath( uploadDir ); -
trunk/grails-app/services/nl/tno/metagenomics/integration/GscfService.groovy
r9 r13 12 12 */ 13 13 class GscfService { 14 15 14 def config = ConfigurationHolder.config 16 15 17 16 static transactional = true 18 19 20 17 21 18 /** … … 51 48 return "${config.gscf.baseURL}/study/showByToken/" + studyToken 52 49 } 53 54 /** 55 * Returns the url to add a new study in GSCF56 *57 * @return URL to redirect the user to58 */59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 50 51 /** 52 * Returns the url to add a new study in GSCF 53 * 54 * @return URL to redirect the user to 55 */ 56 public String urlAddStudy( String studyToken ) { 57 return config.gscf.baseURL + config.gscf.addStudyPath 58 } 59 60 /** 61 * Retrieves the currently logged in user from GSCF 62 * 63 * @param sessionToken String 64 * 65 * @return Map 66 */ 67 public Map getUser(String sessionToken) { 68 def user = [:] 69 this.callGSCF(sessionToken, "getUser").each { 70 user[ it.key ] = it.value; 71 } 72 return user 73 } 74 78 75 /** 79 76 * Retrieve a list of Studies from the GSCF … … 87 84 } 88 85 89 86 90 87 /** 91 88 * Retrieve a list of Studies from the GSCF … … 116 113 } catch( ResourceNotFoundException e ) { 117 114 throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF" ) 118 throw e // Other exceptions are thrown as they appear 119 } 115 } // Other exceptions are thrown as they appear 120 116 121 117 // Return only the first element of the list, since we are only interested in one study 122 if( list.size() == 0 ) { 118 if( list?.size() ) { 119 return list[0]; 120 } else { 123 121 return [] 124 } else {125 return list[0];126 122 } 127 123 } … … 172 168 } 173 169 174 /** 175 * Retrieve a list of Samples from the GSCF 176 * 177 * @param sessionToken String 178 * @param assay Assay (parameter assay is optional, only used when you want to limit the list of samples of an Assay within a Study) 179 * 180 * @return ArrayList 181 */ 182 public ArrayList getSamples(String sessionToken, String assayToken) throws NotAuthorizedException, ResourceNotFoundException { 183 // Samples of a Study limited to a single Assay 184 try { 185 return this.callGSCF(sessionToken, "getSamples", ["assayToken":assayToken]) 186 } catch( NotAuthorizedException e ) { 187 throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken ) 188 } catch( ResourceNotFoundException e ) {1 189 throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" ) 190 } // Other exceptions are thrown as they appear 191 192 } 193 170 194 171 /** 195 172 * Retrieve a single Sample from the GSCF 196 * 173 * 197 174 * @param sessionToken String 198 175 * @param assay Assay 199 * @param sample Sample 200 * 201 * @return ArrayList 176 * @param sample Sample 177 * 178 * @return ArrayList 202 179 */ 203 180 public def getSample(String sessionToken, String assayToken, String sampleToken) throws NotAuthorizedException, ResourceNotFoundException { … … 219 196 220 197 } 198 199 /** 200 * Retrieve a list of Samples from the GSCF 201 * 202 * @param sessionToken String 203 * @param assay Assay (parameter assay is optional, only used when you want to limit the list of samples of an Assay within a Study) 204 * 205 * @return ArrayList 206 */ 207 public ArrayList getSamples(String sessionToken, String assayToken) throws NotAuthorizedException, ResourceNotFoundException { 208 // Samples of a Study limited to a single Assay 209 try { 210 return this.callGSCF(sessionToken, "getSamples", ["assayToken":assayToken]) 211 } catch( NotAuthorizedException e ) { 212 throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken ) 213 } catch( ResourceNotFoundException e ) {1 214 throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" ) 215 } // Other exceptions are thrown as they appear 216 217 } 218 219 /** 220 * Retrieve a list of samples from the GSCF 221 * 222 * @param sessionToken String 223 * @param sampleTokens List of sampleTokens 224 * 225 * @return ArrayList 226 */ 227 public def getSamples(String sessionToken, List sampleTokens) throws NotAuthorizedException, ResourceNotFoundException { 228 def list 229 230 try { 231 list = this.callGSCF(sessionToken, "getSamples", ["sampleToken": sampleTokens]) 232 } catch( NotAuthorizedException e ) { 233 throw new NotAuthorizedException( "User is not authorized to access samples" ) 234 } catch( ResourceNotFoundException e ) { 235 throw new ResourceNotFoundException( "Samples with token " + sampleTokens + " not found in GSCF" ) 236 } // Other exceptions are thrown as they appear 237 238 // Return only the first element of the list, since we are only interested in one sample 239 return list 240 } 241 221 242 222 243 /** … … 273 294 274 295 // concat all Rest Call specific arguments behind addr 275 restParams.each {parameter -> 296 restParams.each {parameter -> 276 297 // If a list is given as value, the parameter should show up multiple times 277 298 if( parameter.value instanceof Collection ) { … … 281 302 } else { 282 303 addr += "&${parameter.key}=" + parameter.value.toString().encodeAsURL() 283 } 304 } 284 305 } 285 306 -
trunk/grails-app/services/nl/tno/metagenomics/integration/SynchronizationService.groovy
r12 r13 261 261 // Can't retrieve data. Maybe sessionToken has expired or invalid. Anyway, stop 262 262 // synchronizing and return null 263 e.printStackTrace() 263 264 log.error( "Exception occurred when fetching study " + study.studyToken + ": " + e.getMessage() ) 264 265 throw new Exception( "Error while fetching study " + study.studyToken, e) -
trunk/grails-app/views/assay/index.gsp
r12 r13 12 12 </g:if> 13 13 <g:else> 14 <table class="paginate"> 14 <form id="assayForm"> 15 </form> 16 <table id="assays" class="paginate"> 15 17 <thead> 16 18 <tr> 19 <th class="nonsortable"></th> 17 20 <th>Assay</th> 18 21 <th>Study</th> … … 26 29 <g:each in="${study.assays}" var="assay"> 27 30 <tr> 31 <td><g:checkBox name="ids" value="${assay.id}" checked="${false}" /></td> 32 28 33 <td><g:link controller="assay" action="show" id="${assay.id}">${assay.name}</g:link></td> 29 34 <td><a href="${study.viewUrl()}">${study.name}</a></td> … … 43 48 </tbody> 44 49 </table> 50 <p class="options"> 51 <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#assayForm' ), '<g:createLink action="exportAsFasta" />', '#assays', 'Please select an assay to export' ); return false;">Export as fasta</a> 52 </p> 53 45 54 </g:else> 46 55 </body> -
trunk/grails-app/views/assay/show.gsp
r12 r13 100 100 </tbody> 101 101 </table> 102 <p class="options"> 103 <g:if test="${editable}"> 104 <a class="editAssociation" onClick="showEnterTagsDialog();" href="#">Edit sample data</a> 105 </g:if> 106 <g:else> 107 <a class="editAssociation disabled" onClick="return false;" href="#">Edit sample data</a> 108 </g:else> 109 <g:if test="${!editable || assay.runs == null || assay.runs.size() == 0}"> 110 <a class="addSequences disabled" onClick="return false;" href="#">Add sequence files</a> 111 </g:if> 112 <g:else> 113 <a class="addSequences" onClick="showAddFilesDialog();" href="#">Add sequence files</a> 114 </g:else> 115 </p> 116 102 117 <g:if test="${editable}"> 103 <input type="button" value="Edit sample data" onClick="showEnterTagsDialog();">104 <input type="button" value="Add sequence files" onClick="showAddFilesDialog();" <g:if test="${assay.runs == null || assay.runs.size() == 0}">disabled="disabled"</g:if>>105 118 <g:render template="enterTagsDialog" model="[assay: assay, sortedAssaySamples: assaySamples]" /> 106 119 <g:render template="addFilesDialog" model="[assay: assay]" /> … … 162 175 </table> 163 176 </g:else> 177 <p class="options"> 178 <g:if test="${editable}"> 179 <a class="addAssociation" onClick="showAddRunDialog();" href="#">Add run</a> 180 </g:if> 181 <g:else> 182 <a class="addAssociation disabled" onClick="return false;" href="#">Add run</a> 183 </g:else> 184 </p> 185 164 186 <g:if test="${editable}"> 165 <input type="button" value="Add run" onClick="showAddRunDialog();">166 187 <g:render template="addRunDialog" model="[assay: assay]" /> 167 188 <div id="editRunDialog" class="dialog"></div> -
trunk/grails-app/views/layouts/main.gsp
r7 r13 8 8 <link rel="stylesheet" href="${resource(dir: 'css', file: session.style + '.css')}"/> 9 9 <link rel="stylesheet" href="${resource(dir: 'css', file: 'login_panel.css')}"/> 10 <link rel="stylesheet" href="${resource(dir: 'css', file: 'buttons.css')}"/> 10 11 <link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon"/> 11 12 … … 21 22 </script> 22 23 <script type="text/javascript" src="${resource(dir: 'js', file: 'paginate.js')}"></script> 24 <script type="text/javascript" src="${resource(dir: 'js', file: 'forms.js')}"></script> 23 25 24 26 <g:layoutHead/> -
trunk/grails-app/views/run/index.gsp
r7 r13 25 25 </g:if> 26 26 <g:else> 27 <table class="paginate"> 27 <form id="runForm"> 28 </form> 29 <table id="runs" class="paginate"> 28 30 <thead> 29 31 <tr> 32 <th class="nonsortable"></th> 30 33 <th>Run</th> 31 34 <th># samples</th> … … 36 39 <g:each in="${runs}" var="run"> 37 40 <tr> 41 <td><g:checkBox name="ids" value="${run.id}" checked="${false}" /></td> 38 42 <td><g:link controller="run" action="show" id="${run.id}">${run.name}</g:link></td> 39 43 <td>${run.assaySamples?.size()}</td> … … 43 47 </tbody> 44 48 </table> 49 <p class="options"> 50 <a class="add" href="#" onClick="showAddRunDialog(); return false;">Add run</a> 51 <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#runForm' ), '<g:createLink action="exportAsFasta" />', '#runs', 'Please select a run to export' ); return false;">Export as fasta</a> 52 </p> 45 53 </g:else> 46 54 <g:render template="addRunDialog" /> -
trunk/grails-app/views/run/show.gsp
r12 r13 56 56 <label>Machine</label>: ${run.machine}<br /> 57 57 <label>Parameters</label>: <g:uploadedFile value="${run.parameterFile}" /><br /> 58 <a href="#" onClick="showEditRunDialog( ${run.id} ); return false;">Edit run</a>59 58 </div> 60 59 <div class="blok_data"> … … 79 78 <label># files</label>: ${run.numFiles()}<br /> 80 79 </div> 80 <p class="options"> 81 <a class="edit" href="#" onClick="showEditRunDialog( ${run.id} ); return false;">Edit run</a> 82 </p> 81 83 82 84 <!-- Samples --> … … 137 139 </table> 138 140 <g:if test="${editable}"> 139 <% def writableAssaySamples = assaySamples.findAll { it.assay.study.canWrite( session.user ) } %> 141 <p class="options"> 142 <% def writableAssaySamples = assaySamples.findAll { it.assay.study.canWrite( session.user ) } %> 143 <a class="addAssociation" onClick="showAddSamplesDialog();" href="#">Add samples</a> 144 145 <g:if test="${writableAssaySamples.size() > 0}"> 146 <a class="editAssociation" onClick="showEnterTagsDialog();" href="#">Edit sample data</a> 147 </g:if> 148 <g:else> 149 <a class="editAssociation disabled" onClick="return false;" href="#">Edit sample data</a> 150 </g:else> 151 152 <g:if test="${writableAssaySamples.size() == 0 || !run.assays?.size()}"> 153 <a class="addSequences disabled" onClick="return false;" href="#">Add sequence files</a> 154 </g:if> 155 <g:else> 156 <a class="addSequences" onClick="showAddFilesDialog();" href="#">Add sequence files</a> 157 </g:else> 158 159 </p> 140 160 <g:if test="${writableAssaySamples.size() > 0}"> 141 <input type="button" value="Edit sample data" onClick="showEnterTagsDialog();">142 <input type="button" value="Add sequence files" onClick="showAddFilesDialog();" <g:if test="${run.assays == null || run.assays.size() == 0}">disabled="disabled"</g:if>>143 161 <g:render template="enterTagsDialog" model="[run: run, writableAssaySamples: writableAssaySamples]" /> 144 162 <g:render template="addFilesDialog" model="[run: run]" /> 145 163 </g:if> 146 <g:else> 147 <input type="button" value="Edit sample data" disabled="disabled"> 148 <input type="button" value="Add sequence files" disabled="disabled"> 149 </g:else> 150 <input type="button" value="Add sample" onClick="showAddSamplesDialog();"> 164 151 165 <g:render template="addSamplesDialog" model="[run: run]" /> 166 152 167 </g:if> 153 168 <div id="showSampleDialog" class="dialog"></div> … … 208 223 <% def writableAssays = otherAssays.findAll { it.study.canWrite( session.user ) } %> 209 224 <g:if test="${editable}"> 225 <p class="options"> 226 <g:if test="${writableAssays.size() > 0}"> 227 <a class="addAssociation" href="#" onClick="showAddAssayDialog();">Add assay</a> 228 </g:if> 229 <g:else> 230 <a class="addAssociation disabled" href="#" onClick="return false;">Add assay</a> 231 </g:else> 232 </p> 210 233 <g:if test="${writableAssays.size() > 0}"> 211 <input type="button" value="Add assay" onClick="showAddAssayDialog();" />212 234 <g:render template="addAssayDialog" model="[run: run, writableAssays: writableAssays]" /> 213 235 </g:if> 214 <g:else>215 <input type="button" value="Add assay" disabled="disabled" />216 </g:else>217 236 </g:if> 218 237 <div id="showRunDialog" class="dialog"></div>
Note: See TracChangeset
for help on using the changeset viewer.