Changeset 453


Ignore:
Timestamp:
May 20, 2010, 5:02:22 PM (7 years ago)
Author:
roberth
Message:

Improved study list, study detail view and study comparison. Also improved performance issues

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/conf/BootStrap.groovy

    r442 r453  
    104104                        ).save();
    105105
    106                         // Create 30 roles to test pagination
    107                         def roleCounter = 1;
    108                         30.times { new PersonRole( name: "Rol #${roleCounter++}" ).save() }
    109 
    110106                        // Create persons
    111107                        def person1 = new Person(
     
    138134                        30.times { new Person( firstName: "Person #${personCounter}", lastName: "Testperson", email: "email${personCounter++}@testdomain.com" ).save() }
    139135
    140                         // Create templates
     136                        // Create a few publications
     137                        println ".adding publications"
     138                        def publication1 = new Publication(
     139                            title: "Postnatal development of hypothalamic leptin receptors",
     140                            authorsList: "Cottrell EC, Mercer JG, Ozanne SE.",
     141                            pubMedID: "20472140",
     142                            comments: "Not published yet",
     143                            DOI: "unknown"
     144                        )
     145                        .save();
     146
     147                        def publication2 = new Publication(
     148                            title: "Induction of regulatory T cells decreases adipose inflammation and alleviates insulin resistance in ob/ob mice",
     149                            authorsList: "Ilan Y, Maron R, Tukpah AM, Maioli TU, Murugaiyan G, Yang K, Wu HY, Weiner HL.",
     150                            pubMedID: "20445103",
     151                            comments: "",
     152                            DOI: ""
     153                        )
     154                        .save();
     155
     156            // Create templates
    141157
    142158                        def genderField = new TemplateField(
     
    554570                                .addToEventGroups(HFBL4)
    555571
    556                                 // Add persons to study
     572                                // Add persons and publications to study
    557573                                def studyperson1 = new StudyPerson( person: person1, role: role1 ).save();
    558574                                def studyperson2 = new StudyPerson( person: person2, role: role2 ).save();
     
    561577                                .addToPersons( studyperson1 )
    562578                                .addToPersons( studyperson2 )
     579                                .addToPublications( publication1 )
     580                                .addToPublications( publication2 )
    563581                                .save()
    564582
     
    624642                                humanStudy.addToSamplingEvents(bloodSamplingEvent)
    625643                                humanStudy.addToEventGroups rootGroup
    626                                 humanStudy.save()
     644
     645
     646                                // Add persons to study
     647                                def studyperson3 = new StudyPerson( person: person1, role: role2 ).save();
     648
     649                                humanStudy
     650                                .addToPersons( studyperson3 )
     651                                .addToPublications( publication2 )
     652                                .save()
    627653
    628654                                /*
     
    697723                                humanStudy.addToAssays(lipidAssayRef);
    698724                                humanStudy.save()
    699                                
     725
     726                                mouseStudy.addToAssays(lipidAssayRef);
     727                                mouseStudy.save()
     728
    700729                        }
    701730                }
  • trunk/grails-app/controllers/dbnp/studycapturing/StudyController.groovy

    r397 r453  
    5757    }
    5858
     59    /**
     60     * Shows a comparison of multiple studies using the show view
     61     *
     62     *
     63     */
    5964    def list_extended = {
     65       
    6066        params.max = Math.min(params.max ? params.int('max') : 10, 100)
    61         [studyList: Study.list(params), studyInstanceTotal: Study.count()]
     67       
     68        render(view:'show',model:[studyList: Study.list(params), studyInstanceTotal: Study.count() ] )
    6269    }
    6370
     
    8087
    8188    def show = {
     89
    8290        def studyInstance = Study.get(params.id)
    8391        if (!studyInstance) {
     
    8694        }
    8795        else {
    88             [studyInstance: studyInstance]
     96            // The study instance is packed into an array, to be able to
     97            // use the same view for showing the study and comparing multiple
     98            // studies
     99            [studyList: [ studyInstance ] ]
    89100        }
    90101    }
  • trunk/grails-app/domain/dbnp/studycapturing/Event.groovy

    r416 r453  
    4343         * @return List
    4444         */
    45         List<TemplateField> giveDomainFields() {
     45        List<TemplateField> giveDomainFields() { return Event.domainFields }
     46        static final List<TemplateField> domainFields =
    4647                [
    4748                        new TemplateField(
     
    5253                                type: TemplateFieldType.DATE)
    5354                ]
    54         }
    5555
    5656        /**
  • trunk/grails-app/domain/dbnp/studycapturing/Study.groovy

    r421 r453  
    2121         * @return List
    2222         */
    23         List<TemplateField> giveDomainFields() {
     23        List<TemplateField> giveDomainFields() { return Study.domainFields }
     24
     25        static final List<TemplateField> domainFields =
    2426                [
    2527                        new TemplateField(
     
    3032                                type: TemplateFieldType.DATE)
    3133                ]
    32         }
    3334
    3435        static hasMany = [
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r435 r453  
    282282         */
    283283        def getFieldValue(String fieldName) {
    284                 TemplateField field = getField(this.giveFields(),fieldName)
    285                 if (isDomainField(field)) {
    286                         return this[field.name]
     284
     285                if (isDomainField(fieldName)) {
     286                    return this[fieldName]
    287287                }
    288288                else {
    289                         return getStore(field.type)[fieldName]
    290                 }
     289                    TemplateField field = getField(this.giveTemplateFields(),fieldName)
     290                    return getStore(field.type)[fieldName]
     291                }
     292
    291293        }
    292294
     
    404406         */
    405407        boolean isDomainField(TemplateField field) {
    406                 return this.giveDomainFields()*.name.contains(field.name)
     408            return isDomainField( field.name )
    407409        }
    408410
     
    411413         * @param String        field name
    412414         * @return boolean
    413          */     boolean isDomainField(String fieldName) {
    414                 return this.giveDomainFields()*.name.contains(fieldName)
    415         }
    416 
     415         */
     416        boolean isDomainField(String fieldName) {
     417            return this.giveDomainFields()*.name.contains(fieldName)
     418        }
     419       
    417420        /**
    418421         * Return all fields defined in the underlying template and the built-in
  • trunk/grails-app/views/study/show.gsp

    r442 r453  
    1212    });
    1313  </script>
     14  <link rel="stylesheet" href="${resource(dir: 'css', file: 'studies.css')}"/>
    1415
    1516</head>
    1617<body>
    1718
    18   <div class="body">
     19  <div class="body" id="studies">
    1920    <h1><g:message code="default.show.label" args="[entityName]" /></h1>
    2021    <g:if test="${flash.message}">
     
    3738
    3839          <table>
     40            <!-- only show the head section if there are multiple studies -->
     41            <g:if test="${studyList.size()>1}">
     42              <thead>
     43                <tr>
     44                  <th></th>
     45                  <g:each in="${studyList}" var="studyInstance">
     46                    <th>${studyInstance.title}</th>
     47                  </g:each>
     48                </tr>
     49              </thead>
     50            </g:if>
     51            <%
     52              // Determine a union of the fields from all studies, in order
     53              // to show a proper list. We want every field to appear just once,
     54              // so the list is filtered for unique values
     55              studyFields = studyList[0].giveDomainFields() + studyList*.giveTemplateFields().flatten().unique()
     56            %>
    3957            <!-- Show all template and domain fields, if filled -->
    40             <g:each in="${studyInstance.giveFields()}" var="field">
    41               <g:if test="${studyInstance.getFieldValue(field.name)}">
     58            <g:each in="${studyFields}" var="field">
     59              <%
     60                // If a value is not set for any of the selected studies, the
     61                // field should not appear in the list
     62                showField = true in studyList.collect { it.fieldExists( field.name ) && it.getFieldValue( field.name ) != null }.flatten()
     63              %>
     64              <g:if test="${showField}">
    4265                <tr>
    4366                  <td>${field}</td>
    44                   <td>${studyInstance.getFieldValue(field.name)}</td>
     67                  <g:each in="${studyList}" var="studyInstance">
     68                    <td>${studyInstance.getFieldValue(field.name)}</td>
     69                  </g:each>
    4570                </tr>
    4671              </g:if>
     
    5075            <tr>
    5176              <td>Events</td>
    52               <td>
    53                 <g:if test="${studyInstance.giveEventTemplates().size()==0}">
    54                   -
    55                 </g:if>
    56                 <g:else>
    57                  ${studyInstance.giveEventTemplates().name.join(", ")}
    58                 </g:else>
    59               </td>
     77              <g:each in="${studyList}" var="studyInstance">
     78                <td>
     79                  <g:if test="${studyInstance.giveEventTemplates().size()==0}">
     80                    -
     81                  </g:if>
     82                  <g:else>
     83                   ${studyInstance.giveEventTemplates().name.join(", ")}
     84                  </g:else>
     85                </td>
     86              </g:each>
    6087            </tr>
    6188            <tr>
    6289              <td>Sampling events</td>
    63               <td>
    64                 <g:if test="${studyInstance.giveSamplingEventTemplates().size()==0}">
    65                   -
    66                 </g:if>
    67                 <g:else>
    68                  ${studyInstance.giveSamplingEventTemplates().name.join(", ")}
    69                 </g:else>
    70               </td>
     90              <g:each in="${studyList}" var="studyInstance">
     91                <td>
     92                  <g:if test="${studyInstance.giveSamplingEventTemplates().size()==0}">
     93                    -
     94                  </g:if>
     95                  <g:else>
     96                   ${studyInstance.giveSamplingEventTemplates().name.join(", ")}
     97                  </g:else>
     98                </td>
     99              </g:each>
    71100            </tr>
    72101            <tr>
    73102              <td>Readers</td>
    74               <td>
    75                 <g:if test="${studyInstance.readers.size()==0}">
    76                   -
    77                 </g:if>
    78                 <g:else>
    79                   <g:each in="${studyInstance.readers}" var="r" status="i">
    80                     <g:if test="${i > 0}">, </g:if>
    81                     <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
    82                   </g:each>
    83                 </g:else>
    84               </td>
     103              <g:each in="${studyList}" var="studyInstance">
     104                <td>
     105                  <g:if test="${studyInstance.readers.size()==0}">
     106                    -
     107                  </g:if>
     108                  <g:else>
     109                    <g:each in="${studyInstance.readers}" var="r" status="i">
     110                      <g:if test="${i > 0}">, </g:if>
     111                      <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
     112                    </g:each>
     113                  </g:else>
     114                </td>
     115              </g:each>
    85116            </tr>
    86117            <tr>
    87118              <td>Editors</td>
    88               <td>
    89                 <g:if test="${studyInstance.editors.size()==0}">
    90                   -
    91                 </g:if>
    92                 <g:else>
    93                   <g:each in="${studyInstance.editors}" var="r" status="i">
    94                     <g:if test="${i > 0}">, </g:if>
    95                     <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
    96                   </g:each>
    97                 </g:else>
    98               </td>
     119              <g:each in="${studyList}" var="studyInstance">
     120                <td>
     121                  <g:if test="${studyInstance.editors.size()==0}">
     122                    -
     123                  </g:if>
     124                  <g:else>
     125                    <g:each in="${studyInstance.editors}" var="r" status="i">
     126                      <g:if test="${i > 0}">, </g:if>
     127                      <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
     128                    </g:each>
     129                  </g:else>
     130                </td>
     131              </g:each>
    99132            </tr>
    100133
     
    103136
    104137        <div id="subjects">
    105           <g:each in="${studyInstance.giveSubjectTemplates()}" var="template">
     138
     139          <g:if test="${studyList*.subjects.flatten().size()==0}">
     140            No subjects in the selected studies
     141          </g:if>
     142          <g:else>
    106143            <table>
    107144              <thead>
    108145                <tr>
     146                  <th></th>
    109147                  <g:each in="${new dbnp.studycapturing.Subject().giveDomainFields()}" var="field">
    110148                    <th>${field}</th>
    111149                  </g:each>
    112                   <g:each in="${template.fields}" var="field">
     150
     151                  <%
     152                    // Determine a union of the fields for all different
     153                    // subjects in all studies. In order to show a proper list.
     154                    // We want every field to appear just once,
     155                    // so the list is filtered for unique values
     156                    subjectTemplates = studyList*.giveSubjectTemplates().flatten().unique()
     157                    subjectFields = subjectTemplates*.fields.flatten().unique()
     158
     159                    showSubjectFields = subjectFields
     160
     161                    /*
     162                     * These lines are rewritten because
     163                     * performance sucked
     164                     *
     165                     *   // These took about 9 seconds (for 31 subjects and
     166                     *   allSubjects = studyList*.subjects.flatten()
     167                     *
     168                     *   subjectFields = subjectFields.findAll { subjectField ->
     169                     *     ( true in allSubjects.collect { subject -> subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) != null }.flatten() )
     170                     *   }
     171                     */
     172
     173                    // Filter out all fields that are left blank for all subjects
     174                    allSubjects = studyList*.subjects.flatten()
     175
     176                    showSubjectFields = []
     177                    subjectFields.each { subjectField ->
     178                      for( subject in allSubjects )
     179                      {
     180                        // If the field is filled for this subject, we have to
     181                        // show the field and should not check any other
     182                        // subjects (hence the break)
     183                        if( subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) ) {
     184                          showSubjectFields << subjectField;
     185                          break;
     186                        }
     187                      }
     188                    }
     189                     
     190                  %>
     191
     192                  <g:each in="${showSubjectFields}" var="field">
    113193                    <th>${field}</th>
    114194                  </g:each>
     195
    115196                </tr>
    116197              </thead>
    117              
    118               <%
    119                 subjects = studyInstance.subjects.findAll {it.template == template};
    120                 sortedSubjects = subjects.sort( { a, b -> a.name <=> b.name } as Comparator )
    121               %>
    122               <g:each in="${sortedSubjects}" var="s" status="i">
    123                 <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    124                   <g:each in="${s.giveDomainFields()}" var="field">
    125                     <td>${s.getFieldValue(field.name)}</td>
    126                   </g:each>
    127                   <g:each in="${template.fields}" var="field">
    128                     <td>
    129                       ${s.getFieldValue(field.name)}
    130                     </td>
     198
     199              <g:set var="i" value="${1}" />
     200
     201              <g:each in="${studyList}" var="studyInstance">
     202                <%
     203                  // Sort subjects by name
     204                  subjects = studyInstance.subjects;
     205                  sortedSubjects = subjects.sort( { a, b -> a.name <=> b.name } as Comparator )
     206                %>
     207
     208                <g:each in="${sortedSubjects}" var="subject" status="j">
     209                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
     210                    <g:if test="${j==0}">
     211                      <td class="studytitle" rowspan="${sortedSubjects.size()}">
     212                        ${studyInstance.title}
     213                      </td>
     214                    </g:if>
     215                    <g:each in="${subject.giveDomainFields()}" var="field">
     216                      <td>${subject.getFieldValue(field.name)}</td>
     217                    </g:each>
     218                 
     219                    <g:each in="${showSubjectFields}" var="field">
     220                      <td>
     221                        <g:if test="${subject.fieldExists(field.name)}">
     222                          ${subject.getFieldValue(field.name)}
     223                        </g:if>
     224                        <g:else>
     225                          N/A
     226                        </g:else>
     227                      </td>
     228                    </g:each>
     229
     230                  </tr>
     231                  <g:set var="i" value="${i + 1}" />
    131232                </g:each>
    132                 </tr>
    133               </g:each>
    134 
     233              </g:each>
    135234            </table>
    136 
    137           </g:each>
     235          </g:else>
    138236        </div>
    139237
    140238        <div id="events">
    141           <g:if test="${studyInstance.events.size()==0}">
    142             No events in this study
     239          <g:if test="${studyList*.events.flatten().size()==0 && studyInstance*.samplingEvents.flatten().size()==0 }">
     240            No events in these studies
    143241          </g:if>
    144242          <g:else>
     
    147245                <thead>
    148246                  <tr>
     247                    <th></th>
    149248                    <th>Start time</th>
    150249                    <th>Duration</th>
     
    155254                </thead>
    156255
    157               <%
    158                 // Sort events by starttime and duration
    159                 events = studyInstance.events + studyInstance.samplingEvents;
    160                 sortedEvents = events.sort( { a, b ->
    161                       a.startTime == b.startTime ?
    162                         a.getDuration().toMilliseconds() <=> b.getDuration().toMilliseconds() :
    163                         a.startTime <=> b.startTime
    164                   } as Comparator )
    165               %>
    166 
    167                 <g:each in="${sortedEvents}" var="event" status="i">
    168                   <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    169                     <td>${event.getPrettyDuration(studyInstance.startDate,event.startTime)}</td>
    170                     <td>${event.getPrettyDuration()}</td>
    171                     <td>${event.template.name}</td>
    172                     <td>
    173                       <g:if test="${event instanceof dbnp.studycapturing.SamplingEvent}">
    174                         <g:checkBox name="samplingEvent" disabled="${true}" value="${true}"/>
     256                <g:set var="i" value="${1}" />
     257
     258                <g:each in="${studyList}" var="studyInstance">
     259                  <%
     260                    // Sort events by starttime and duration
     261                    events = studyInstance.events + studyInstance.samplingEvents;
     262                    sortedEvents = events.sort( { a, b ->
     263                          a.startTime == b.startTime ?
     264                            a.getDuration().toMilliseconds() <=> b.getDuration().toMilliseconds() :
     265                            a.startTime <=> b.startTime
     266                      } as Comparator )
     267                  %>
     268
     269                  <g:each in="${sortedEvents}" var="event" status="j">
     270                    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
     271                      <g:if test="${j==0}">
     272                        <td class="studytitle" rowspan="${sortedEvents.size()}">
     273                          ${studyInstance.title}
     274                        </td>
    175275                      </g:if>
    176                       <g:else>
    177                         <g:checkBox name="event" disabled="${true}" value="${false}" />
    178                       </g:else>
    179                     </td>
    180                     <td>
    181                       <g:set var="fieldCounter" value="${1}" />
    182                       <g:each in="${event.giveTemplateFields()}" var="field">
    183                         <g:if test="${event.getFieldValue(field.name)}">
    184                           <g:if test="${fieldCounter > 1}">, </g:if>
    185                             ${field.name} = ${event.getFieldValue( field.name )}
    186                           <g:set var="fieldCounter" value="${fieldCounter + 1}" />
     276                      <td>${event.getPrettyDuration(studyInstance.startDate,event.startTime)}</td>
     277                      <td>${event.getPrettyDuration()}</td>
     278                      <td>${event.template.name}</td>
     279                      <td>
     280                        <g:if test="${event instanceof dbnp.studycapturing.SamplingEvent}">
     281                          <g:checkBox name="samplingEvent" disabled="${true}" value="${true}"/>
    187282                        </g:if>
    188                       </g:each>
    189                     </td>
    190                   </tr>
     283                        <g:else>
     284                          <g:checkBox name="event" disabled="${true}" value="${false}" />
     285                        </g:else>
     286                      </td>
     287                      <td>
     288                        <g:set var="fieldCounter" value="${1}" />
     289                        <g:each in="${event.giveTemplateFields()}" var="field">
     290                          <g:if test="${event.getFieldValue(field.name)}">
     291                            <g:if test="${fieldCounter > 1}">, </g:if>
     292                              ${field.name} = ${event.getFieldValue( field.name )}
     293                            <g:set var="fieldCounter" value="${fieldCounter + 1}" />
     294                          </g:if>
     295                        </g:each>
     296                      </td>
     297                    </tr>
     298
     299                    <g:set var="i" value="${i + 1}" />
     300                  </g:each>
    191301                </g:each>
    192 
    193302              </table>
    194303
     
    197306
    198307        <div id="event-group">
    199           <g:if test="${studyInstance.eventGroups.size()==0}">
     308          <g:if test="${studyList*.eventGroups.flatten().size()==0}">
    200309            No event groups in this study
    201310          </g:if>
    202311          <g:else>
     312            <%
     313              // Determine a union of the event templates for all different
     314              // eventgroups in all studies, in order to show a proper list.
     315              // We want every field to appear just once,
     316              // so the list is filtered for unique values
     317              groupTemplates = studyList*.giveAllEventTemplates().flatten().unique()
     318              subjectFields = subjectTemplates*.fields.flatten().unique()
     319            %>
    203320            <table>
    204               <tr>
    205                 <td><b>Name</b></td>
    206                 <td colspan="${studyInstance.giveAllEventTemplates().size()}"><b>Events</b></td>
    207                 <td><b>Subjects</b></td>
    208               </tr>
    209               <tr>
    210                 <td></td>
    211                 <g:each in="${studyInstance.giveAllEventTemplates()}" var="eventTemplate">
    212                   <td><b>${eventTemplate.name}</b></td>
     321              <thead>
     322                <tr>
     323                  <th></th>
     324                  <th>Name</th>
     325                  <th colspan="${groupTemplates.size()}">Events</th>
     326                  <th>Subjects</th>
     327                </tr>
     328                <tr>
     329                  <th></th>
     330                  <th></th>
     331                  <g:each in="${groupTemplates}" var="eventTemplate">
     332                    <th>${eventTemplate.name}</th>
     333                  </g:each>
     334                  <th></th>
     335                </tr>
     336              </thead>
     337
     338              <g:set var="i" value="${1}" />
     339
     340              <g:each in="${studyList}" var="studyInstance">
     341
     342                <g:each in="${studyInstance.eventGroups}" var="eventGroup" status="j">
     343                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
     344                    <g:if test="${j==0}">
     345                      <td class="studytitle" rowspan="${studyInstance.eventGroups.size()}">
     346                        ${studyInstance.title}
     347                      </td>
     348                    </g:if>
     349                    <td>${eventGroup.name}</td>
     350
     351                    <g:each in="${groupTemplates}" var="currentEventTemplate">
     352                      <td>
     353                        <g:each in="${eventGroup.events}" var="event">
     354                          <g:if test="${event.template.name==currentEventTemplate.name}">
     355
     356                            <g:set var="fieldCounter" value="${1}" />
     357                            <g:each in="${event.giveTemplateFields()}" var="field">
     358                              <g:if test="${event.getFieldValue(field.name)}">
     359                                <g:if test="${fieldCounter > 1}">, </g:if>
     360                                  ${field.name} = ${event.getFieldValue( field.name )}
     361                                <g:set var="fieldCounter" value="${fieldCounter + 1}" />
     362                              </g:if>
     363                            </g:each>
     364                          </g:if>
     365                        </g:each>
     366                      </td>
     367                    </g:each>
     368                    <td>
     369                      <% sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
     370                      ${sortedGroupSubjects.name.join( ', ' )}
     371                    </td>
     372                  </tr>
     373
     374                  <g:set var="i" value="${i + 1}" />
    213375                </g:each>
    214                 <td></td>
    215               </tr>
    216               <g:each in="${studyInstance.eventGroups}" var="eventGroup">
    217                 <tr>
    218                   <td>${eventGroup.name}</td>
    219 
    220                   <g:each in="${studyInstance.giveAllEventTemplates()}" var="currentEventTemplate">
    221                     <td>
    222                       <g:each in="${eventGroup.events}" var="event">
    223                         <g:if test="${event.template.name==currentEventTemplate.name}">
    224 
    225                           <g:set var="fieldCounter" value="${1}" />
    226                           <g:each in="${event.giveTemplateFields()}" var="field">
    227                             <g:if test="${event.getFieldValue(field.name)}">
    228                               <g:if test="${fieldCounter > 1}">, </g:if>
    229                                 ${field.name} = ${event.getFieldValue( field.name )}
    230                               <g:set var="fieldCounter" value="${fieldCounter + 1}" />
    231                             </g:if>
    232                           </g:each>
    233                         </g:if>
    234                       </g:each>
    235                      </td>
    236                   </g:each>
    237                   <td>
    238                     <% sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
    239                     ${sortedGroupSubjects.name.join( ', ' )}
    240                   </td>
    241                 </tr>
    242               </g:each>
     376
     377              </g:each>
     378
    243379            </table>
    244380          </g:else>
     
    246382
    247383        <div id="assays">
    248           <g:if test="${studyInstance.assays.size()==0}">
    249             No assays in this study
     384          <g:if test="${studyList*.assays.flatten().size()==0}">
     385            No assays in these studies
    250386          </g:if>
    251387          <g:else>
     
    253389              <thead>
    254390                <tr>
     391                  <th></th>
    255392                  <th width="100">Assay Name</th>
    256393                  <th width="100">Module</th>
     
    261398                </tr>
    262399              </thead>
    263               <g:each in="${studyInstance.assays}" var="assay" status="i">
    264                 <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    265                   <td>${assay.name}</td>
    266                   <td>${assay.module.name}</td>
    267                   <td>${assay.module.type}</td>
    268                   <td>${assay.module.platform}</td>
    269                   <td>${assay.module.url}</td>
    270                   <td>
    271                     <% sortedAssaySamples = assay.samples.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
    272                     ${sortedAssaySamples.name.join( ', ' )}
    273                   </td>
    274                 </tr>
    275               </g:each>
    276 
     400              <g:set var="i" value="${1}" />
     401
     402              <g:each in="${studyList}" var="studyInstance">
     403                <g:each in="${studyInstance.assays}" var="assay" status="j">
     404                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
     405                    <g:if test="${j==0}">
     406                      <td class="studytitle" rowspan="${studyInstance.assays.size()}">
     407                        ${studyInstance.title}
     408                      </td>
     409                    </g:if>
     410                    <td>${assay.name}</td>
     411                    <td>${assay.module.name}</td>
     412                    <td>${assay.module.type}</td>
     413                    <td>${assay.module.platform}</td>
     414                    <td>${assay.module.url}</td>
     415                    <td>
     416                      <% sortedAssaySamples = assay.samples.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
     417                      ${sortedAssaySamples.name.join( ', ' )}
     418                    </td>
     419                  </tr>
     420                  <g:set var="i" value="${i + 1}" />
     421
     422                </g:each>
     423              </g:each>
    277424            </table>
    278425          </g:else>
     
    280427
    281428        <div id="persons">
    282           <g:if test="${studyInstance.persons.size()==0}">
    283             No persons involved in this study
     429          <%
     430            // Determine a list of all persons
     431            allPersons = studyList*.persons*.person.flatten().unique()
     432          %>
     433          <g:if test="${allPersons.size()==0}">
     434            No persons involved in these studies
    284435          </g:if>
    285436          <g:else>
     
    289440                  <th>Name</th>
    290441                  <th>Affiliations</th>
    291                   <th>Role</th>
    292442                  <th>Phone</th>
    293443                  <th>Email</th>
     444                  <g:each in="${studyList}" var="studyInstance">
     445                    <th>${studyInstance.title}</th>
     446                  </g:each>
    294447                </thead>
    295448              </tr>
    296               <g:each in="${studyInstance.persons}" var="studyperson" status="i">
     449              <g:each in="${allPersons}" var="person" status="i">
    297450                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    298                   <td>${studyperson.person.firstName} ${studyperson.person.prefix} ${studyperson.person.lastName}</td>
     451                  <td>${person.firstName} ${person.prefix} ${person.lastName}</td>
    299452                  <td>
    300                     ${studyperson.person.affiliations.join(', ')}
     453                    ${person.affiliations.join(', ')}
    301454                  </td>
    302                   <td>${studyperson.role.name}</td>
    303                   <td>${studyperson.person.phone}</td>
    304                   <td>${studyperson.person.email}</td>
     455                  <td>${person.phone}</td>
     456                  <td>${person.email}</td>
     457                  <g:each in="${studyList}" var="studyInstance">
     458                    <%
     459                      studyperson = studyInstance.persons.find { it.person == person }
     460                    %>
     461                    <td>
     462                      <g:if test="${studyperson}">
     463                        ${studyperson.role.name}
     464                      </g:if>
     465                     </td>
     466                  </g:each>
     467
    305468                </tr>
    306469              </g:each>
     
    310473
    311474        <div id="publications">
    312           <g:if test="${studyInstance.publications.size()==0}">
    313             No publications attached to this study
     475          <%
     476            // Determine a list of all persons
     477            allPublications = studyList*.publications.flatten().unique()
     478          %>
     479          <g:if test="${allPublications.size()==0}">
     480            No publications attached to these studies
    314481          </g:if>
    315482          <g:else>
     
    320487                  <th>Authors</th>
    321488                  <th>Comments</th>
     489                  <g:each in="${studyList}" var="studyInstance">
     490                    <th>${studyInstance.title}</th>
     491                  </g:each>
    322492                </thead>
    323493              </tr>
    324               <g:each in="${studyInstance.publications}" var="publication" status="i">
     494              <g:each in="${allPublications}" var="publication" status="i">
    325495                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    326496                  <td>${publication.title}</td>
    327497                  <td>
    328                     ${publication.authorlist}
     498                    ${publication.authorsList}
    329499                  </td>
    330                   <td>${publication.comment}</td>
     500                  <td>${publication.comments}</td>
     501                  <g:each in="${studyList}" var="studyInstance">
     502                    <td>
     503                      <g:if test="${publication in studyInstance.publications}">
     504                        x
     505                      </g:if>
     506                    </td>
     507                  </g:each>
    331508                </tr>
    332509              </g:each>
     
    340517    <div class="buttons">
    341518      <g:form>
    342         <g:hiddenField name="id" value="${studyInstance?.id}" />
    343         <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
    344         <span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
     519        <g:if test="${studyList.size() == 1}">
     520          <g:set var="studyInstance" value="${studyList[0]}" />
     521          <g:hiddenField name="id" value="${studyInstance?.id}" />
     522          <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
     523          <span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
     524        </g:if>
    345525        <span class="button"><g:link class="backToList" action="list">Back to list</g:link></span>
    346526      </g:form>
    347527    </div>
     528
    348529  </div>
    349530</body>
Note: See TracChangeset for help on using the changeset viewer.