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

Last change on this file since 453 was 453, checked in by roberth, 13 years ago

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

  • Property svn:keywords set to Date Author Rev
File size: 20.3 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="${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            %>
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                  <th></th>
147                  <g:each in="${new dbnp.studycapturing.Subject().giveDomainFields()}" var="field">
148                    <th>${field}</th>
149                  </g:each>
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">
193                    <th>${field}</th>
194                  </g:each>
195
196                </tr>
197              </thead>
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}" />
232                </g:each>
233              </g:each>
234            </table>
235          </g:else>
236        </div>
237
238        <div id="events">
239          <g:if test="${studyList*.events.flatten().size()==0 && studyInstance*.samplingEvents.flatten().size()==0 }">
240            No events in these studies
241          </g:if>
242          <g:else>
243
244              <table>
245                <thead>
246                  <tr>
247                    <th></th>
248                    <th>Start time</th>
249                    <th>Duration</th>
250                    <th>Type</th>
251                    <th>Sampling event</th>
252                    <th>Parameters</th>
253                  </tr>
254                </thead>
255
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>
275                      </g:if>
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}"/>
282                        </g:if>
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>
301                </g:each>
302              </table>
303
304          </g:else>
305        </div>
306
307        <div id="event-group">
308          <g:if test="${studyList*.eventGroups.flatten().size()==0}">
309            No event groups in this study
310          </g:if>
311          <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            %>
320            <table>
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}" />
375                </g:each>
376
377              </g:each>
378
379            </table>
380          </g:else>
381        </div>
382
383        <div id="assays">
384          <g:if test="${studyList*.assays.flatten().size()==0}">
385            No assays in these studies
386          </g:if>
387          <g:else>
388            <table>
389              <thead>
390                <tr>
391                  <th></th>
392                  <th width="100">Assay Name</th>
393                  <th width="100">Module</th>
394                  <th>Type</th>
395                  <th width="150">Platform</th>
396                  <th>Url</th>
397                  <th>Samples</th>
398                </tr>
399              </thead>
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>
424            </table>
425          </g:else>
426        </div>
427
428        <div id="persons">
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
435          </g:if>
436          <g:else>
437            <table>
438              <tr>
439                <thead>
440                  <th>Name</th>
441                  <th>Affiliations</th>
442                  <th>Phone</th>
443                  <th>Email</th>
444                  <g:each in="${studyList}" var="studyInstance">
445                    <th>${studyInstance.title}</th>
446                  </g:each>
447                </thead>
448              </tr>
449              <g:each in="${allPersons}" var="person" status="i">
450                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
451                  <td>${person.firstName} ${person.prefix} ${person.lastName}</td>
452                  <td>
453                    ${person.affiliations.join(', ')}
454                  </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
468                </tr>
469              </g:each>
470            </table>
471          </g:else>
472        </div>
473
474        <div id="publications">
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
481          </g:if>
482          <g:else>
483            <table>
484              <tr>
485                <thead>
486                  <th>Title</th>
487                  <th>Authors</th>
488                  <th>Comments</th>
489                  <g:each in="${studyList}" var="studyInstance">
490                    <th>${studyInstance.title}</th>
491                  </g:each>
492                </thead>
493              </tr>
494              <g:each in="${allPublications}" var="publication" status="i">
495                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
496                  <td>${publication.title}</td>
497                  <td>
498                    ${publication.authorsList}
499                  </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>
508                </tr>
509              </g:each>
510            </table>
511          </g:else>
512        </div>
513
514      </div>
515    </div>
516    <br>
517    <div class="buttons">
518      <g:form>
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>
525        <span class="button"><g:link class="backToList" action="list">Back to list</g:link></span>
526      </g:form>
527    </div>
528
529  </div>
530</body>
531</html>
Note: See TracBrowser for help on using the repository browser.