source: extensions/net.sf.basedb.reggie/trunk/resources/index.jsp @ 2020

Last change on this file since 2020 was 2020, checked in by Nicklas Nordborg, 8 years ago

References #481: Register prepared flow cells

Preliminary wizards for flow cell creation and registration.

File size: 21.2 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.Application"
5  import="net.sf.basedb.core.User"
6  import="net.sf.basedb.core.Role"
7  import="net.sf.basedb.core.Group"
8  import="net.sf.basedb.core.DbControl"
9  import="net.sf.basedb.core.Item"
10  import="net.sf.basedb.core.Permission"
11  import="net.sf.basedb.core.SessionControl"
12  import="net.sf.basedb.core.SystemItems"
13  import="net.sf.basedb.core.ItemQuery"
14  import="net.sf.basedb.core.query.Expressions"
15  import="net.sf.basedb.core.query.Hql"
16  import="net.sf.basedb.core.query.Restrictions"
17  import="net.sf.basedb.clients.web.Base"
18  import="net.sf.basedb.clients.web.util.HTML"
19  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
20  import="net.sf.basedb.util.Values"
21  import="java.util.List"
22%>
23<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
24<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
25<%
26final SessionControl sc = Base.getExistingSessionControl(request, true);
27final String ID = sc.getId();
28final float scale = Base.getScale(sc);
29final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
30DbControl dc = null;
31try
32{
33  dc = sc.newDbControl();
34  final User user = User.getById(dc, sc.getLoggedInUserId());
35 
36  boolean isAdmin = user.getId() == SystemItems.getId(User.ROOT);
37  boolean isPatientCurator = false;
38  boolean hasCreateSamplePermission = sc.hasPermission(Permission.CREATE, Item.SAMPLE);
39  boolean hasCreateExtractPermission = sc.hasPermission(Permission.CREATE, Item.EXTRACT);
40  boolean hasCreateBioPlatePermission = sc.hasPermission(Permission.CREATE, Item.BIOPLATE);
41  if (!isAdmin)
42  {
43    try
44    {
45      Role admin = Role.getById(dc, SystemItems.getId(Role.ADMINISTRATOR));
46      isAdmin = sc.isMemberOf(admin);
47    }
48    catch (RuntimeException ex)
49    {}
50  }
51  try
52  {
53    ItemQuery<Group> query = Group.getQuery();
54    query.restrict(Restrictions.eq(Hql.property("name"), Expressions.string("PatientCurator")));
55    List<Group> result = query.list(dc);
56    if (result.size() == 1)
57    {
58      isPatientCurator = sc.isMemberOf(result.get(0));
59    }
60  }
61  catch (RuntimeException ex)
62  {}
63%>
64<base:page type="default" >
65<base:head styles="path.css" scripts="ajax.js">
66  <script language="JavaScript" src="reggie.js" type="text/javascript" charset="UTF-8"></script>
67  <link rel="stylesheet" type="text/css" href="css/reggie.css">
68  <script language="JavaScript">
69 
70  var debug = false;
71 
72  function caseSummary()
73  {
74    var frm = document.forms['reggie'];
75   
76    var caseName = frm.caseName.value;
77    if (!caseName)
78    {
79      alert('Please enter a 7-digit case id');
80      return;
81    }
82    location.href = 'reports/case_summary.jsp?ID=<%=ID%>&caseName='+encodeURIComponent(caseName);
83  }
84 
85  var currentCount;
86  function startCounting(what)
87  {
88    var url;
89    currentCount = what;
90    if (what == 'specimen')
91    {
92      url = 'PartitionRegistration.servlet?ID=<%=ID%>&cmd=CountSpecimenTubes';
93    }
94    else if (what == 'histology-lists')
95    {
96      url = 'Histology.servlet?ID=<%=ID%>&cmd=CountHistologyWorkLists';
97    }
98    else if (what == 'paraffin-blocks')
99    {
100      url = 'Histology.servlet?ID=<%=ID%>&cmd=CountParaffinBlocks';
101    }
102    else if (what == 'paraffin-blocks-without-heglass')
103    {
104      url = 'Histology.servlet?ID=<%=ID%>&cmd=CountParaffinBlocksWithoutHeGlass';
105    }
106    else if (what == 'lysate')
107    {
108      url = 'Extraction.servlet?ID=<%=ID%>&cmd=CountUnprocessedLysates';
109    }
110    else if (what == 'rnaqc')
111    {
112      url = 'RnaQc.servlet?ID=<%=ID%>&cmd=CountRnaExtractsWithoutQc';
113    }
114    else if (what == 'caliper-plates')
115    {
116      url = 'RnaQc.servlet?ID=<%=ID%>&cmd=CountActiveRnaQcBioPlates';
117    }
118    else if (what == 'rna-without-mrna')
119    {
120      url = 'MRna.servlet?ID=<%=ID%>&cmd=CountRnaWithoutMRna';
121    }
122    else if (what == 'mrna-plates')
123    {
124      url = 'MRna.servlet?ID=<%=ID%>&cmd=CountUnprocessedPlates&plateType=MRNA';
125    }
126    else if (what == 'cdna-plates')
127    {
128      url = 'MRna.servlet?ID=<%=ID%>&cmd=CountUnprocessedPlates&plateType=CDNA';
129    }
130    else if (what == 'cdna-plates-for-barcoding')
131    {
132      url = 'LibPrep.servlet?ID=<%=ID%>&cmd=CountCDNAPlatesForBarcoding';
133    }
134    else if (what == 'lib-plates')
135    {
136      url = 'LibPrep.servlet?ID=<%=ID%>&cmd=CountLibPlatesForLibPrep';
137    }
138    else if (what == 'lib-plates-for-pooling')
139    {
140      url = 'Pool.servlet?ID=<%=ID%>&cmd=CountLibraryPlatesForPooling';
141    }
142    else if (what == 'unregistered-pools')
143    {
144      url = 'Pool.servlet?ID=<%=ID%>&cmd=CountUnprocessedPools';
145    }
146    else if (what == 'unused-pools')
147    {
148      url = 'FlowCell.servlet?ID=<%=ID%>&cmd=CountUnusedPools';
149    }
150    else if (what == 'unregistered-flow-cells')
151    {
152      url = 'FlowCell.servlet?ID=<%=ID%>&cmd=CountUnprocessedFlowCells';
153    }
154   
155    if (url)
156    {
157      var request = Main.getAjaxRequest();
158      request.open("GET", url, false);
159      Ajax.setReadyStateHandler(request, onCounted, onCounted);
160      request.send(null);
161    }
162  }
163 
164  function onCounted(request)
165  {
166    if (debug) Main.debug(currentCount +': ' + Main.encodeTags(request.responseText));
167    var response;
168    var error = false;
169    try
170    {
171      response = JSON.parse(request.responseText);
172      if (response.status != 'ok')
173      {
174        error = response.message || response.stacktrace || 'Unexpected error';
175      }
176    }
177    catch (ex)
178    {
179      error = ex;
180    }
181   
182    if (currentCount == 'specimen')
183    {
184      var msg = error || 'Number of unpartitioned specimen';
185      var count = error ? -1 : response.count;
186      setCount('count.specimen', count, 'specimens', msg);
187      startCounting('histology-lists');
188    }
189    else if (currentCount == 'histology-lists')
190    {
191      var msg = error || 'Number of active histology work lists';
192      var count = error ? -1 : response.count;
193      setCount('count.histology-lists', count, 'work lists', msg);
194      startCounting('paraffin-blocks');
195    }
196    else if (currentCount == 'paraffin-blocks')
197    {
198      var msg = error || 'Number of paraffin blocks waiting for registration';
199      var count = error ? -1 : response.count;
200      setCount('count.paraffin-blocks', count, 'paraffin blocks', msg);
201      startCounting('paraffin-blocks-without-heglass');
202    }
203    else if (currentCount == 'paraffin-blocks-without-heglass')
204    {
205      var msg = error || 'Number of paraffin blocks without HE glass';
206      var count = error ? -1 : response.count;
207      setCount('count.paraffin-blocks-without-heglass', count, 'paraffin blocks', msg);
208      startCounting('lysate');
209    }
210    else if (currentCount == 'lysate')
211    {
212      var msg = error || 'Number of unprocessed lysates';
213      var count = error ? -1 : response.count;
214      setCount('count.lysate.1', count, 'lysates', msg);
215      setCount('count.lysate.2', count, 'lysates', msg);
216      startCounting('rnaqc');
217    }
218    else if (currentCount == 'rnaqc')
219    {
220      var msg = error || 'Number of RNA waiting for QC';
221      var count = error ? -1 : response.count;
222      setCount('count.rnaqc', count, 'RNA', msg);
223      startCounting('caliper-plates');
224    }
225    else if (currentCount == 'caliper-plates')
226    {
227      var msg = error || 'Number of active Caliper plates';
228      var count = error ? -1 : response.count;
229      setCount('count.caliper-plates.1', count, 'Caliper plates', msg);
230      setCount('count.caliper-plates.2', count, 'Caliper plates', msg);
231      startCounting('rna-without-mrna');
232    }
233    else if (currentCount == 'rna-without-mrna')
234    {
235      var msg = error || 'Number of RNA with no mRNA';
236      var count = error ? -1 : response.count;
237      setCount('count.rna-without-mrna', count, 'RNA', msg);
238      startCounting('mrna-plates');
239    }
240    else if (currentCount == 'mrna-plates')
241    {
242      var msg = error || 'Number of mRNA plates waiting for registration';
243      var count = error ? -1 : response.count;
244      setCount('count.mrna-plates.1', count, 'mRNA plates', msg);
245      setCount('count.mrna-plates.2', count, 'mRNA plates', msg);
246      startCounting('cdna-plates');
247    }
248    else if (currentCount == 'cdna-plates')
249    {
250      var msg = error || 'Number of cDNA plates waiting for registration';
251      var count = error ? -1 : response.count;
252      setCount('count.cdna-plates.1', count, 'cDNA plates', msg);
253      startCounting('cdna-plates-for-barcoding');
254    }
255    else if (currentCount == 'cdna-plates-for-barcoding')
256    {
257      var msg = error || 'Number of cDNA plates waiting for barcode layout';
258      var count = error ? -1 : response.count;
259      setCount('count.cdna-plates-for-barcoding', count, 'cDNA plates', msg);
260      startCounting('lib-plates')
261    }
262    else if (currentCount == 'lib-plates')
263    {
264      var msg = error || 'Number of Lib plates waiting for registration';
265      var count = error ? -1 : response.count;
266      setCount('count.lib-plates.1', count, 'Lib plates', msg);
267      setCount('count.lib-plates.2', count, 'Lib plates', msg);
268      setCount('count.lib-plates.3', count, 'Lib plates', msg);
269      startCounting('lib-plates-for-pooling');
270    }
271    else if (currentCount == 'lib-plates-for-pooling')
272    {
273      var msg = error || 'Number of Lib plates waiting for pooling';
274      var count = error ? -1 : response.count;
275      setCount('count.lib-plates-for-pooling', count, 'Lib plates', msg);
276      startCounting('unregistered-pools');
277    }
278    else if (currentCount == 'unregistered-pools')
279    {
280      var msg = error || 'Number of pools waiting for registration';
281      var count = error ? -1 : response.count;
282      setCount('count.pools.1', count, 'pools', msg);
283      setCount('count.pools.2', count, 'pools', msg);
284      startCounting('unused-pools');
285    }
286    else if (currentCount == 'unused-pools')
287    {
288      var msg = error || 'Number of pools waiting for sequencing';
289      var count = error ? -1 : response.count;
290      setCount('count.pools.3', count, 'pools', msg);
291      startCounting('unregistered-flow-cells');
292    }
293    else if (currentCount == 'unregistered-flow-cells')
294    {
295      var msg = error || 'Number of flow cells waiting for registration';
296      var count = error ? -1 : response.count;
297      setCount('count.flow-cells', count, 'flow cells', msg);
298    }
299   
300  }
301 
302  function setCount(id, count, unit, msg)
303  {
304    var div = document.getElementById(id);
305    div.title = msg;
306    if (count == -1)
307    {
308      div.innerHTML = '(-)';
309    }
310    else
311    {
312      div.innerHTML = '(' + count + ')';
313    }
314  }
315 
316  </script>
317<style>
318dl
319{
320  margin-top: 0px;
321  padding: 3px;
322}
323dt
324{
325  margin-top: 0.5em;
326  margin-left: 0.5em;
327}
328dd
329{
330  margin-left: 0.5em;
331  margin-bottom: 0.5em;
332  padding-left: 3em;
333}
334ul
335{
336  margin-top: 0px;
337  margin-bottom: 0px;
338  margin-left: 0em;
339  padding-left: 0em;
340}
341li
342{
343  margin-left: 0em;
344}
345img
346{
347  vertical-align: text-bottom;
348}
349h3
350{
351  color: #333377;
352  background: #E8E8E8;
353  font-weight: bold;
354  margin-bottom: 0em;
355  padding: 1px 4px 1px 4px;
356  border: 1px solid #A0A0A0;
357  font-size: 1em;
358}
359a.not-implemented
360{
361  filter: url(css/filters.svg#grayscale); /* Firfox, etc */
362  filter: gray; /* IE */
363  opacity: 0.75;
364  pointer-events: none;
365}
366
367a.not-implemented:after
368{
369  content: ' -- coming soon';
370}
371.counter
372{
373  color: #999999;
374  font-style: italic;
375}
376</style>
377</base:head>
378<base:body onload="startCounting('specimen')">
379
380  <p:path><p:pathelement title="Reggie" /></p:path>
381
382  <div class="content">
383    <form name="reggie" onsubmit="return false;">
384    <div class="absolutefull" style="width: 50%;">
385      <div class="absolutefull" style="left: 1em; right: 0.5em; ">
386     
387        <h3>Sample processing wizards</h3>
388        <dl class="leftborder rightborder bottomborder">
389        <%
390        if (hasCreateSamplePermission)
391        {
392          %>
393          <dt>
394            <base:icon image="<%=home+"/images/specimen.png" %>" />
395            <a href="sampleproc/specimentube.jsp?ID=<%=ID%>">Specimen tube registration</a>
396          </dt>
397          <dd>
398            <ul>
399            <li>Register new specimen tubes.
400            <li>Update existing specimen tubes.
401            </ul>
402          </dd>
403          <%
404        }
405        if (hasCreateSamplePermission && hasCreateExtractPermission)
406        {
407          %>
408          <dt>
409            <base:icon image="<%=home+"/images/partition.png" %>" />
410            <a href="sampleproc/partitionform.jsp?ID=<%=ID%>">Partition wizard</a>
411          </dt>
412          <dd>
413            <ul>
414            <li>Register new partitions of existing specimens <span class="counter" id="count.specimen" title="Counting..."><img src="images/loading-small.gif"></span>
415            </ul>
416          </dd>
417          <%
418        }
419        if (hasCreateSamplePermission && hasCreateBioPlatePermission)
420        {
421          %>
422          <dt>
423            <base:icon image="<%=home+"/images/microscope.png" %>" />
424            Histology wizards
425          </dt>
426          <dd>
427            <ul>
428            <li><a href="sampleproc/histology_protocol.jsp?ID=<%=ID%>">Lab tracking protocol for FFPE/HE</a> <span class="counter" id="count.histology-lists" title="Counting..."><img src="images/loading-small.gif"></span>
429            <li><a href="sampleproc/histology_block.jsp?ID=<%=ID%>">Register paraffin blocks</a> <span class="counter" id="count.paraffin-blocks" title="Counting..."><img src="images/loading-small.gif"></span>
430            <li><a href="sampleproc/histology_glass.jsp?ID=<%=ID%>">Register histology HE glass information</a> <span class="counter" id="count.paraffin-blocks-without-heglass" title="Counting..."><img src="images/loading-small.gif"></span>
431            </ul>
432          </dd>
433          <%
434        }
435        if (hasCreateExtractPermission)
436        {
437          %>
438          <dt>
439            <base:icon image="<%=home+"/images/extraction.png" %>" />
440            DNA/RNA extraction wizards
441          </dt>
442          <dd>
443            <ul>
444            <li><a href="sampleproc/allprep_protocol.jsp?ID=<%=ID%>">Lab tracking protocol for Allprep isolation</a> <span class="counter" id="count.lysate.1" title="Counting..."><img src="images/loading-small.gif"></span>
445            <li><a href="sampleproc/extraction_registration.jsp?ID=<%=ID%>">DNA/RNA/FlowThrough registration</a> <span class="counter" id="count.lysate.2" title="Counting..."><img src="images/loading-small.gif"></span>
446            </ul>
447          </dd>
448          <dt>
449            <base:icon image="<%=home+"/images/rnaqc.png" %>" />
450            RNA quality control wizards
451          </dt>
452          <dd>
453            <ul>
454            <li><a href="sampleproc/rnaqc_aliquot.jsp?ID=<%=ID%>">Create aliquots on Bioanalyzer/Caliper plates</a> <span class="counter" id="count.rnaqc" title="Counting..."><img src="images/loading-small.gif"></span>
455            <li><a href="sampleproc/rnaqc_plate_export.jsp?ID=<%=ID%>">Export Caliper sample names and run parameters</a> <span class="counter" id="count.caliper-plates.1" title="Counting..."><img src="images/loading-small.gif"></span>
456            <li><a href="sampleproc/rnaqc_plate_import.jsp?ID=<%=ID%>">Import RQS scores from Caliper well table file</a> <span class="counter" id="count.caliper-plates.2" title="Counting..."><img src="images/loading-small.gif"></span>
457            </ul>
458          </dd>
459          <%
460        }
461        %>       
462        </dl>
463     
464     
465        <h3>Library preparation wizards</h3>
466        <dl class="leftborder rightborder bottomborder">
467        <%
468        if (hasCreateExtractPermission && hasCreateBioPlatePermission)
469        {
470          %>
471          <dt>
472            <base:icon image="<%=home+"/images/pipette.png" %>" />
473            RNA to cDNA wizards
474          </dt>
475          <dd>
476            <ul>
477            <li><a href="libprep/select_rna.jsp?ID=<%=ID%>">Create new mRNA plate</a> <span class="counter" id="count.rna-without-mrna" title="Counting..."><img src="images/loading-small.gif"></span>
478            <li><a href="libprep/mrna_protocol.jsp?ID=<%=ID%>">Lab protocols for mRNA and cDNA preparation</a> <span class="counter" id="count.mrna-plates.1" title="Counting..."><img src="images/loading-small.gif"></span>
479            <li><a href="libprep/mrna_registration.jsp?ID=<%=ID%>">mRNA registration and quality control results</a> <span class="counter" id="count.mrna-plates.2" title="Counting..."><img src="images/loading-small.gif"></span>
480            <li><a href="libprep/cdna_registration.jsp?ID=<%=ID%>">cDNA registration</a> <span class="counter" id="count.cdna-plates.1" title="Counting..."><img src="images/loading-small.gif"></span>
481            </ul>
482          </dd>
483         
484          <dt>
485            <base:icon image="<%=home+"/images/libprep.png" %>" />
486            Library preparation wizards
487          </dt>
488          <dd>
489            <ul>
490            <li><a href="libprep/assign_barcode.jsp?ID=<%=ID%>">Assign barcodes to cDNA plate</a> <span class="counter" id="count.cdna-plates-for-barcoding" title="Counting..."><img src="images/loading-small.gif"></span>
491            <li><a href="libprep/libprep_protocol.jsp?ID=<%=ID%>">Lab protocols and files for library preparation</a> <span class="counter" id="count.lib-plates.1" title="Counting..."><img src="images/loading-small.gif"></span>
492            <li><a href="libprep/libqc_registration.jsp?ID=<%=ID%>">Register quality control results</a> <span class="counter" id="count.lib-plates.2" title="Counting..."><img src="images/loading-small.gif"></span>
493            <li><a href="libprep/lib_registration.jsp?ID=<%=ID%>">Library registration</a> <span class="counter" id="count.lib-plates.3" title="Counting..."><img src="images/loading-small.gif"></span>
494            </ul>
495          </dd>
496          <dt>
497            <base:icon image="<%=home+"/images/flowcell.png" %>" />
498            Pooling and clustering wizards
499          </dt>
500          <dd>
501            <ul>
502            <li><a href="libprep/create_pools.jsp?ID=<%=ID%>">Create pooled libraries</a> <span class="counter" id="count.lib-plates-for-pooling" title="Counting..."><img src="images/loading-small.gif"></span>
503            <li><a href="libprep/pool_protocol.jsp?ID=<%=ID%>">Lab protocols for pooling</a> <span class="counter" id="count.pools.1" title="Counting..."><img src="images/loading-small.gif"></span>
504            <li><a href="libprep/pool_registration.jsp?ID=<%=ID%>">Register pooled libraries</a> <span class="counter" id="count.pools.2" title="Counting..."><img src="images/loading-small.gif"></span>
505            <li><a href="libprep/create_flowcells.jsp?ID=<%=ID%>">Create flow cells</a> <span class="counter" id="count.pools.3" title="Counting..."><img src="images/loading-small.gif"></span>
506            <li><a href="libprep/flowcell_registration.jsp?ID=<%=ID%>">Register flow cells</a> <span class="counter" id="count.flow-cells" title="Counting..."><img src="images/loading-small.gif"></span>
507            </ul>
508          </dd>
509          <%
510        }
511        %>
512        </dl>
513      </div>
514    </div>
515   
516    <div class="absolutefull" style="width: 50%; left: auto;">
517      <div class="absolutefull" style="left: 0.5em; right: 1em;">
518        <%
519        if (isAdmin)
520        {
521          %>
522          <h3>Server administrator wizards</h3>
523          <dl class="leftborder rightborder bottomborder">
524          <dt>
525            <base:icon image="<%=home + "/images/install.png" %>" />
526            <a href="admin/install.jsp?ID=<%=ID%>">Installation wizard</a>
527          </dt>
528          <dd>
529            <ul>
530            <li>Check that annotation types and other items used by Reggie exists in BASE.
531            <li>Create missing items.
532            </ul>
533          </dd>
534          </dl>
535          <%
536        }
537        if (isPatientCurator || isAdmin)
538        {
539          %>
540          <h3>Personal information wizards</h3>
541          <dl class="leftborder rightborder bottomborder">
542          <dt>
543            <base:icon image="<%=home + "/images/personal.png" %>"/>
544            <a href="personal/persinfo.jsp?ID=<%=ID%>">Pathology referral form registration</a>
545          </dt>
546          <dd>
547            <ul>
548            <li>Register new cases and patients.
549            <li>Update existing cases and specimen tubes.
550            </ul>
551          </dd>
552         
553          <dt>
554            <base:icon image="<%=home + "/images/blood.png" %>"/>
555            <a href="personal/bloodform.jsp?ID=<%=ID%>">Blood referral form registration</a>
556          </dt>
557          <dd>
558            <ul>
559            <li>Register new blood referral forms and patients.
560            <li>Update information for existing blood referral forms.
561            </ul>
562          </dd>
563         
564          <dt>
565            <base:icon image="<%=home+"/images/consent.png" %>"/>
566            <a href="personal/consentform.jsp?ID=<%=ID%>">Consent form registration</a>
567          </dt>
568          <dd>
569            <ul>
570            <li>Register consent forms.
571            </ul>
572          </dd>
573         
574          <dt>
575            <base:icon image="<%=home+"/images/export_import.png" %>" />
576            Export/import information to/from external registers.
577          </dt>
578          <dd>
579            <ul>
580            <li><a href="personal/export_monthly_oplist.jsp?ID=<%=ID%>">Export monthly operation list</a>
581            <li><a href="personal/export_inca.jsp?ID=<%=ID%>">INCA export</a>
582            </ul>
583          </dd>
584          </dl>
585          <%
586        }
587        %>
588       
589        <h3>Statistics and reporting wizards</h3>
590        <dl class="leftborder rightborder bottomborder">
591          <dt>
592            <base:icon image="<%=home+"/images/case_summary.png" %>" />
593            Case summary
594          </dt>
595          <dd>
596            <table>
597            <tr>
598              <td><input type="text" class="text" 
599                name="caseName" title="Please enter a 7-digit case id" 
600                style="width: 25em;"
601                onkeypress="if (event.keyCode==13 && this.value) caseSummary()"></td>
602              <td><base:button title="Go" image="<%=home+"/images/gonext.png"%>" onclick="caseSummary()"/></td>
603            </tr>
604            </table>
605          </dd>
606       
607          <dt>
608            <base:icon image="<%=home+"/images/report.png" %>" />
609            <a href="reports/samplereportgenerator.jsp?ID=<%=ID%>">Sample source report</a>
610          </dt>       
611          <dd>       
612            <ul>
613            <li>Sample count report</li> 
614            <li>Consent count report</li> 
615            <li>Patient count report</li> 
616            <li>Overview report</li> 
617            <li>Missing sample data report</li> 
618            </ul>
619          </dd>
620          <dt>
621            <base:icon image="<%=home+"/images/chart_bar.png" %>" />
622            <a href="reports/scanbquartermonthreportgenerator.jsp?ID=<%=ID%>">Sample processing statistics</a>
623          </dt>       
624          <dd>       
625            <ul>
626            <li>SCAN-B quarter/month report</li> 
627            </ul>
628          </dd>
629        </dl>
630      </div>
631    </div>
632    </form>
633  </div>
634 
635</base:body>
636</base:page>
637<%
638}
639finally
640{
641  if (dc != null) dc.close();
642}
643%>
Note: See TracBrowser for help on using the repository browser.