source: trunk/grails-app/views/study/show.gsp @ 454

Last change on this file since 454 was 454, checked in by roberth, 9 years ago

Improved study list to be able to handle one or more studies. Also improved performance issues with Subject and Sample classes. I have set the domainFields property to a static property, filled it in the class description and attached an ontology to it in the bootstrap (because it can't be done in the class description). It might not be the prettiest solution, it does improve the performance of the study detail page and study comparison with 90%.

  • Property svn:keywords set to Date Author Rev
File size: 21.1 KB
Line 
1
2<%@ page import="dbnp.studycapturing.Study" %>
3<html>
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <meta name="layout" content="main" />
7  <g:set var="entityName" value="${message(code: 'study.label', default: 'Study')}" />
8  <title><g:message code="default.show.label" args="[entityName]" /></title>
9  <script type="text/javascript">
10    $(function() {
11            $("#tabs").tabs();
12    });
13  </script>
14  <link rel="stylesheet" href="${resource(dir: 'css', file: 'studies.css')}"/>
15
16</head>
17<body>
18
19  <div class="body" id="studies">
20    <h1><g:message code="default.show.label" args="[entityName]" /></h1>
21    <g:if test="${flash.message}">
22      <div class="message">${flash.message}</div>
23    </g:if>
24    <div class="dialog">
25
26      <div id="tabs">
27        <ul>
28          <li><a href="#study">Study Information</a></li>
29          <li><a href="#subjects">Subjects</a></li>
30          <li><a href="#events">Events</a></li>
31          <li><a href="#event-group">Event Groups</a></li>
32          <li><a href="#assays">Assays</a></li>
33          <li><a href="#persons">Persons</a></li>
34          <li><a href="#publications">Publications</a></li>
35        </ul>
36
37        <div id="study">
38
39          <table>
40            <!-- only show the head section if there are multiple studies -->
41            <g:if test="${multipleStudies}">
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            %>
57            <!-- Show all template and domain fields, if filled -->
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}">
65                <tr>
66                  <td>${field}</td>
67                  <g:each in="${studyList}" var="studyInstance">
68                    <td>${studyInstance.getFieldValue(field.name)}</td>
69                  </g:each>
70                </tr>
71              </g:if>
72            </g:each>
73
74            <!-- Add some extra fields -->
75            <tr>
76              <td>Events</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>
87            </tr>
88            <tr>
89              <td>Sampling events</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>
100            </tr>
101            <tr>
102              <td>Readers</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>
116            </tr>
117            <tr>
118              <td>Editors</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>
132            </tr>
133
134          </table>
135        </div>
136
137        <div id="subjects">
138
139          <g:if test="${studyList*.subjects.flatten().size()==0}">
140            No subjects in the selected studies
141          </g:if>
142          <g:else>
143            <table>
144              <thead>
145                <tr>
146                  <g:if test="${multipleStudies}">
147                    <th></th>
148                  </g:if>
149                  <g:each in="${new dbnp.studycapturing.Subject().giveDomainFields()}" var="field">
150                    <th>${field}</th>
151                  </g:each>
152
153                  <%
154                    // Determine a union of the fields for all different
155                    // subjects in all studies. In order to show a proper list.
156                    // We want every field to appear just once,
157                    // so the list is filtered for unique values
158                    subjectTemplates = studyList*.giveSubjectTemplates().flatten().unique()
159                    subjectFields = subjectTemplates*.fields.flatten().unique()
160
161                    showSubjectFields = subjectFields
162
163                    /*
164                     * These lines are rewritten because
165                     * performance sucked
166                     *
167                     *   // These took about 9 seconds (for 31 subjects and
168                     *   allSubjects = studyList*.subjects.flatten()
169                     *
170                     *   subjectFields = subjectFields.findAll { subjectField ->
171                     *     ( true in allSubjects.collect { subject -> subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) != null }.flatten() )
172                     *   }
173                     */
174
175                    // Filter out all fields that are left blank for all subjects
176                    allSubjects = studyList*.subjects.flatten()
177
178                    showSubjectFields = []
179                    subjectFields.each { subjectField ->
180                      for( subject in allSubjects )
181                      {
182                        // If the field is filled for this subject, we have to
183                        // show the field and should not check any other
184                        // subjects (hence the break)
185                        if( subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) ) {
186                          showSubjectFields << subjectField;
187                          break;
188                        }
189                      }
190                    }
191                  %>
192
193                  <g:each in="${showSubjectFields}" var="field">
194                    <th>${field}</th>
195                  </g:each>
196
197                </tr>
198              </thead>
199
200              <g:set var="i" value="${1}" />
201
202              <g:each in="${studyList}" var="studyInstance">
203                <%
204                  // Sort subjects by name
205                  subjects = studyInstance.subjects;
206                  sortedSubjects = subjects.sort( { a, b -> a.name <=> b.name } as Comparator )
207                %>
208
209                <g:each in="${sortedSubjects}" var="subject" status="j">
210                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
211                    <g:if test="${multipleStudies && j==0}">
212                      <td class="studytitle" rowspan="${sortedSubjects.size()}">
213                        ${studyInstance.title}
214                      </td>
215                    </g:if>
216                    <g:each in="${subject.giveDomainFields()}" var="field">
217                      <td>${subject.getFieldValue(field.name)}</td>
218                    </g:each>
219                 
220                    <g:each in="${showSubjectFields}" var="field">
221                      <td>
222                        <g:if test="${subject.fieldExists(field.name)}">
223                          ${subject.getFieldValue(field.name)}
224                        </g:if>
225                        <g:else>
226                          N/A
227                        </g:else>
228                      </td>
229                    </g:each>
230
231                  </tr>
232                  <g:set var="i" value="${i + 1}" />
233                </g:each>
234              </g:each>
235            </table>
236          </g:else>
237        </div>
238
239        <div id="events">
240          <g:if test="${studyList*.events.flatten().size()==0 && studyInstance*.samplingEvents.flatten().size()==0 }">
241            No events in these studies
242          </g:if>
243          <g:else>
244
245              <table>
246                <thead>
247                  <tr>
248                    <g:if test="${multipleStudies}">
249                      <th></th>
250                    </g:if>
251                    <th>Start time</th>
252                    <th>Duration</th>
253                    <th>Type</th>
254                    <th>Sampling event</th>
255                    <th>Parameters</th>
256                  </tr>
257                </thead>
258
259                <g:set var="i" value="${1}" />
260
261                <g:each in="${studyList}" var="studyInstance">
262                  <%
263                    // Sort events by starttime and duration
264                    events = studyInstance.events + studyInstance.samplingEvents;
265                    sortedEvents = events.sort( { a, b ->
266                          a.startTime == b.startTime ?
267                            a.getDuration().toMilliseconds() <=> b.getDuration().toMilliseconds() :
268                            a.startTime <=> b.startTime
269                      } as Comparator )
270                  %>
271
272                  <g:each in="${sortedEvents}" var="event" status="j">
273                    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
274                      <g:if test="${multipleStudies && j==0}">
275                        <td class="studytitle" rowspan="${sortedEvents.size()}">
276                          ${studyInstance.title}
277                        </td>
278                      </g:if>
279                      <td>${event.getPrettyDuration(studyInstance.startDate,event.startTime)}</td>
280                      <td>${event.getPrettyDuration()}</td>
281                      <td>${event.template.name}</td>
282                      <td>
283                        <g:if test="${event instanceof dbnp.studycapturing.SamplingEvent}">
284                          <g:checkBox name="samplingEvent" disabled="${true}" value="${true}"/>
285                        </g:if>
286                        <g:else>
287                          <g:checkBox name="event" disabled="${true}" value="${false}" />
288                        </g:else>
289                      </td>
290                      <td>
291                        <g:set var="fieldCounter" value="${1}" />
292                        <g:each in="${event.giveTemplateFields()}" var="field">
293                          <g:if test="${event.getFieldValue(field.name)}">
294                            <g:if test="${fieldCounter > 1}">, </g:if>
295                              ${field.name} = ${event.getFieldValue( field.name )}
296                            <g:set var="fieldCounter" value="${fieldCounter + 1}" />
297                          </g:if>
298                        </g:each>
299                      </td>
300                    </tr>
301
302                    <g:set var="i" value="${i + 1}" />
303                  </g:each>
304                </g:each>
305              </table>
306
307          </g:else>
308        </div>
309
310        <div id="event-group">
311          <g:if test="${studyList*.eventGroups.flatten().size()==0}">
312            No event groups in this study
313          </g:if>
314          <g:else>
315            <%
316              // Determine a union of the event templates for all different
317              // eventgroups in all studies, in order to show a proper list.
318              // We want every field to appear just once,
319              // so the list is filtered for unique values
320              groupTemplates = studyList*.giveAllEventTemplates().flatten().unique()
321              subjectFields = subjectTemplates*.fields.flatten().unique()
322            %>
323            <table>
324              <thead>
325                <tr>
326                  <g:if test="${multipleStudies}">
327                    <th></th>
328                  </g:if>
329                  <th>Name</th>
330                  <th colspan="${groupTemplates.size()}">Events</th>
331                  <th>Subjects</th>
332                </tr>
333                <tr>
334                  <g:if test="${multipleStudies}">
335                    <th></th>
336                  </g:if>
337                  <th></th>
338                  <g:each in="${groupTemplates}" var="eventTemplate">
339                    <th>${eventTemplate.name}</th>
340                  </g:each>
341                  <th></th>
342                </tr>
343              </thead>
344
345              <g:set var="i" value="${1}" />
346
347              <g:each in="${studyList}" var="studyInstance">
348
349                <g:each in="${studyInstance.eventGroups}" var="eventGroup" status="j">
350                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
351                    <g:if test="${multipleStudies && j==0}">
352                      <td class="studytitle" rowspan="${studyInstance.eventGroups.size()}">
353                        ${studyInstance.title}
354                      </td>
355                    </g:if>
356                    <td>${eventGroup.name}</td>
357
358                    <g:each in="${groupTemplates}" var="currentEventTemplate">
359                      <td>
360                        <g:each in="${eventGroup.events}" var="event">
361                          <g:if test="${event.template.name==currentEventTemplate.name}">
362
363                            <g:set var="fieldCounter" value="${1}" />
364                            <g:each in="${event.giveTemplateFields()}" var="field">
365                              <g:if test="${event.getFieldValue(field.name)}">
366                                <g:if test="${fieldCounter > 1}">, </g:if>
367                                  ${field.name} = ${event.getFieldValue( field.name )}
368                                <g:set var="fieldCounter" value="${fieldCounter + 1}" />
369                              </g:if>
370                            </g:each>
371                          </g:if>
372                        </g:each>
373                      </td>
374                    </g:each>
375                    <td>
376                      <% sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
377                      ${sortedGroupSubjects.name.join( ', ' )}
378                    </td>
379                  </tr>
380
381                  <g:set var="i" value="${i + 1}" />
382                </g:each>
383
384              </g:each>
385
386            </table>
387          </g:else>
388        </div>
389
390        <div id="assays">
391          <g:if test="${studyList*.assays.flatten().size()==0}">
392            No assays in these studies
393          </g:if>
394          <g:else>
395            <table>
396              <thead>
397                <tr>
398                  <g:if test="${multipleStudies}">
399                    <th></th>
400                  </g:if>
401                  <th width="100">Assay Name</th>
402                  <th width="100">Module</th>
403                  <th>Type</th>
404                  <th width="150">Platform</th>
405                  <th>Url</th>
406                  <th>Samples</th>
407                </tr>
408              </thead>
409              <g:set var="i" value="${1}" />
410
411              <g:each in="${studyList}" var="studyInstance">
412                <g:each in="${studyInstance.assays}" var="assay" status="j">
413                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
414                    <g:if test="${multipleStudies && j==0}">
415                      <td class="studytitle" rowspan="${studyInstance.assays.size()}">
416                        ${studyInstance.title}
417                      </td>
418                    </g:if>
419                    <td>${assay.name}</td>
420                    <td>${assay.module.name}</td>
421                    <td>${assay.module.type}</td>
422                    <td>${assay.module.platform}</td>
423                    <td>${assay.module.url}</td>
424                    <td>
425                      <% sortedAssaySamples = assay.samples.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
426                      ${sortedAssaySamples.name.join( ', ' )}
427                    </td>
428                  </tr>
429                  <g:set var="i" value="${i + 1}" />
430
431                </g:each>
432              </g:each>
433            </table>
434          </g:else>
435        </div>
436
437        <div id="persons">
438          <%
439            // Determine a list of all persons
440            allPersons = studyList*.persons*.person.flatten().unique()
441          %>
442          <g:if test="${allPersons.size()==0}">
443            No persons involved in these studies
444          </g:if>
445          <g:else>
446            <table>
447              <tr>
448                <thead>
449                  <th>Name</th>
450                  <th>Affiliations</th>
451                  <th>Phone</th>
452                  <th>Email</th>
453                  <g:if test="${multipleStudies}">
454                    <g:each in="${studyList}" var="studyInstance">
455                      <th>${studyInstance.title}</th>
456                    </g:each>
457                  </g:if>
458                  <g:else>
459                    <th>Role</th>
460                  </g:else>
461                </thead>
462              </tr>
463              <g:each in="${allPersons}" var="person" status="i">
464                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
465                  <td>${person.firstName} ${person.prefix} ${person.lastName}</td>
466                  <td>
467                    ${person.affiliations.join(', ')}
468                  </td>
469                  <td>${person.phone}</td>
470                  <td>${person.email}</td>
471                  <g:each in="${studyList}" var="studyInstance">
472                    <%
473                      studyperson = studyInstance.persons.find { it.person == person }
474                    %>
475                    <td>
476                      <g:if test="${studyperson}">
477                        ${studyperson.role.name}
478                      </g:if>
479                     </td>
480                  </g:each>
481
482                </tr>
483              </g:each>
484            </table>
485          </g:else>
486        </div>
487
488        <div id="publications">
489          <%
490            // Determine a list of all persons
491            allPublications = studyList*.publications.flatten().unique()
492          %>
493          <g:if test="${allPublications.size()==0}">
494            No publications attached to these studies
495          </g:if>
496          <g:else>
497            <table>
498              <tr>
499                <thead>
500                  <th>Title</th>
501                  <th>Authors</th>
502                  <th>Comments</th>
503
504                  <g:if test="${multipleStudies}">
505                    <g:each in="${studyList}" var="studyInstance">
506                      <th>${studyInstance.title}</th>
507                    </g:each>
508                  </g:if>
509                </thead>
510              </tr>
511              <g:each in="${allPublications}" var="publication" status="i">
512                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
513                  <td>${publication.title}</td>
514                  <td>
515                    ${publication.authorsList}
516                  </td>
517                  <td>${publication.comments}</td>
518                  <g:if test="${multipleStudies}">
519                    <g:each in="${studyList}" var="studyInstance">
520                      <td>
521                        <g:if test="${publication in studyInstance.publications}">
522                          x
523                        </g:if>
524                      </td>
525                    </g:each>
526                  </g:if>
527                </tr>
528              </g:each>
529            </table>
530          </g:else>
531        </div>
532
533      </div>
534    </div>
535    <br>
536    <div class="buttons">
537      <g:form>
538        <g:if test="${studyList.size() == 1}">
539          <g:set var="studyInstance" value="${studyList[0]}" />
540          <g:hiddenField name="id" value="${studyInstance?.id}" />
541          <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
542          <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>
543        </g:if>
544        <span class="button"><g:link class="backToList" action="list">Back to list</g:link></span>
545      </g:form>
546    </div>
547
548  </div>
549</body>
550</html>
Note: See TracBrowser for help on using the repository browser.