source: trunk/www/biomaterials/events/list_events.jsp @ 6038

Last change on this file since 6038 was 6038, checked in by Nicklas Nordborg, 10 years ago

References #1674: Define extension points for adding columns to table listings

Implemented for all list pages in the Biomaterial LIMS menu.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 20.2 KB
Line 
1<%-- $Id: list_events.jsp 6038 2012-03-29 11:49:50Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson
4  Copyright (C) 2007 Johan Enell
5
6  This file is part of BASE - BioArray Software Environment.
7  Available at http://base.thep.lu.se/
8
9  BASE is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License
11  as published by the Free Software Foundation; either version 3
12  of the License, or (at your option) any later version.
13
14  BASE is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with BASE. If not, see <http://www.gnu.org/licenses/>.
21  ------------------------------------------------------------------
22
23  @author Nicklas
24  @version 2.0
25--%>
26<%@ page pageEncoding="UTF-8" session="false"
27  import="net.sf.basedb.core.SessionControl"
28  import="net.sf.basedb.core.DbControl"
29  import="net.sf.basedb.core.Item"
30  import="net.sf.basedb.core.ItemContext"
31  import="net.sf.basedb.core.BioMaterialEvent"
32  import="net.sf.basedb.core.BioPlateEvent"
33  import="net.sf.basedb.core.BioPlateEventParticipant"
34  import="net.sf.basedb.core.BioPlate"
35  import="net.sf.basedb.core.MeasuredBioMaterial"
36  import="net.sf.basedb.core.Quantity"
37  import="net.sf.basedb.core.Unit"
38  import="net.sf.basedb.core.ItemQuery"
39  import="net.sf.basedb.core.ItemResultIterator"
40  import="net.sf.basedb.core.Permission"
41  import="net.sf.basedb.core.PluginDefinition"
42  import="net.sf.basedb.core.PermissionDeniedException"
43  import="net.sf.basedb.core.query.Restrictions"
44  import="net.sf.basedb.core.query.Expressions"
45  import="net.sf.basedb.core.query.Orders"
46  import="net.sf.basedb.core.query.Hql"
47  import="net.sf.basedb.core.plugin.GuiContext"
48  import="net.sf.basedb.core.plugin.Plugin"
49  import="net.sf.basedb.util.Enumeration"
50  import="net.sf.basedb.util.units.UnitUtil"
51  import="net.sf.basedb.clients.web.Base"
52  import="net.sf.basedb.clients.web.ChangeHistoryUtil"
53  import="net.sf.basedb.clients.web.ModeInfo"
54  import="net.sf.basedb.clients.web.PermissionUtil"
55  import="net.sf.basedb.clients.web.util.HTML"
56  import="net.sf.basedb.util.Values"
57  import="net.sf.basedb.util.formatter.Formatter"
58  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
59  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
60  import="net.sf.basedb.clients.web.extensions.JspContext"
61  import="net.sf.basedb.clients.web.extensions.renderer.PrefixSuffixRenderer"
62  import="net.sf.basedb.clients.web.extensions.toolbar.ToolbarUtil"
63  import="net.sf.basedb.clients.web.extensions.list.ListColumnUtil"
64  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
65  import="java.util.List"
66  import="java.util.Map"
67  import="java.util.Date"
68%>
69<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
70<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
71<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
72<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
73<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
74<%!
75  private static final Item itemType = Item.BIOMATERIALEVENT;
76  private static final GuiContext guiContext = new GuiContext(itemType, GuiContext.Type.LIST);
77%>
78<%
79final Item bioMaterialType = Item.valueOf(request.getParameter("biomaterial_type"));
80final int bioMaterialId = Values.getInt(request.getParameter("biomaterial_id"));
81final SessionControl sc = Base.getExistingSessionControl(pageContext, Permission.DENIED, itemType);
82final String ID = sc.getId();
83final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
84
85final ModeInfo mode = ModeInfo.get(request.getParameter("mode"));
86final String callback = request.getParameter("callback");
87final String title = mode.generateTitle("event", "events");
88final DbControl dc = sc.newDbControl();
89ItemResultIterator<BioMaterialEvent> events = null;
90try
91{
92  final MeasuredBioMaterial bioMaterial = (MeasuredBioMaterial)bioMaterialType.getById(dc, bioMaterialId);
93  final BioMaterialEvent creationEvent = bioMaterial.getCreationEvent();
94  final boolean createPermission = bioMaterial.hasPermission(Permission.WRITE);
95  final boolean deletePermission = createPermission;
96
97  String viewPage = null;
98  String listName = null;
99  if (bioMaterialType == Item.SAMPLE)
100  {
101    listName = "Samples";
102    viewPage = "../samples/index.jsp";
103  }
104  else if (bioMaterialType == Item.EXTRACT)
105  {
106    listName = "Extracts";
107    viewPage = "../extracts/index.jsp";
108  }
109 
110  Unit microGram = UnitUtil.getUnit(dc, Quantity.MASS, "µg");
111  Map<Plugin.MainType, Integer> pluginCount = PluginDefinition.countPlugins(dc, guiContext);
112  try
113  {
114    final ItemQuery<BioMaterialEvent> query = Base.getConfiguredQuery(dc, cc, true, bioMaterial.getEvents(), mode);
115    events = query.iterate(dc);
116  }
117  catch (Throwable t)
118  {
119    cc.setMessage(t.getMessage());
120    t.printStackTrace();
121  }
122  int numListed = 0;
123  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
124  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, guiContext, bioMaterial);
125  ExtensionsInvoker invoker = ToolbarUtil.useExtensions(jspContext);
126  ExtensionsInvoker columnsInvoker = ListColumnUtil.useExtensions(jspContext);
127  %>
128  <base:page title="<%=title%>" type="<%=mode.getPageType()%>">
129  <base:head scripts="table.js,tabcontrol.js" styles="table.css,toolbar.css,headertabcontrol.css,path.css">
130    <ext:scripts context="<%=jspContext%>" />
131    <ext:stylesheets context="<%=jspContext%>" />
132    <script language="JavaScript">
133    var submitPage = 'index.jsp';
134    var formId = 'events';
135    function newItem()
136    {
137      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', 0, true, '&biomaterial_type=<%=bioMaterialType.name()%>&biomaterial_id=<%=bioMaterial.getId()%>');
138    }
139    function editItem(itemId)
140    {
141      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', itemId, true, '&biomaterial_type=<%=bioMaterialType.name()%>&biomaterial_id=<%=bioMaterial.getId()%>');
142    }
143    function viewItem(itemId)
144    {
145      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', itemId, false, '&biomaterial_type=<%=bioMaterialType.name()%>&biomaterial_id=<%=bioMaterial.getId()%>');
146    }
147    function itemOnClick(evt, itemId)
148    {
149      Table.itemOnClick(formId, evt, itemId, '<%=mode.getName()%>', viewItem, editItem, returnSelected);
150    }
151    function deleteItems()
152    {
153      var frm = document.forms[formId];
154      var numChecked = Forms.numChecked(frm);
155      if (numChecked == 0)
156      {
157        alert('Please select at least one item in the list');
158        return;
159      }
160      else
161      {
162        var rep = numChecked == 1 ? 'event' : 'events';
163        if (!confirm('You are about to delete '+numChecked+' '+rep+'. This can\'t be undone. Continue?'))
164        {
165          return;
166        }
167      }
168      frm.action = submitPage;
169      frm.cmd.value = 'DeleteItems';
170      frm.submit();
171    }
172    function configureColumns()
173    {
174      Table.configureColumns('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>');
175    }
176    function runPlugin(cmd)
177    {
178      Table.submitToPopup(formId, cmd, 750, 500);
179    }
180    function returnSelected()
181    {
182      Table.returnSelected(formId, <%=callback != null ? "window.opener."+callback : "null" %>);
183      window.close();
184    }
185    function presetOnChange()
186    {
187      Table.presetOnChange('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>');
188    }
189    function switchTab(tabControlId, tabId)
190    {
191      if (tabId == 'properties' || tabId == 'annotations' || tabId == 'overview' || tabId == 'history')
192      {
193        location.href = '<%=viewPage%>?ID=<%=ID%>&cmd=ViewItem&item_id=<%=bioMaterialId%>&tab='+tabId;
194      }
195      else
196      {
197        TabControl.setActiveTab(tabControlId, tabId);
198      }
199    }
200    </script>
201  </base:head>
202 
203  <base:body>
204    <p:path><p:pathelement 
205      title="<%=listName%>" href="<%=viewPage+"?ID="+ID%>" 
206      /><p:pathelement title="<%=HTML.encodeTags(bioMaterial.getName())%>"
207      /></p:path>
208
209    <t:tabcontrol 
210      id="main" 
211      subclass="mastertabcontrol content"
212      active="events" switch="switchTab">
213    <t:tab id="properties" title="Properties" />
214    <t:tab id="annotations" title="Annotations &amp; parameters"
215      tooltip="View annotation values and protocol parameters" />
216   
217    <t:tab id="events" title="Events">
218    <tbl:table 
219      id="events" 
220      columns="<%=cc.getSetting("columns")%>"
221      sortby="<%=cc.getSortProperty()%>" 
222      direction="<%=cc.getSortDirection()%>"
223      action="index.jsp"
224      sc="<%=sc%>"
225      item="<%=itemType%>"
226      subclass="fulltable"
227      >
228      <tbl:hidden 
229        name="mode" 
230        value="<%=mode.getName()%>" 
231      />
232      <tbl:hidden 
233        name="biomaterial_id"
234        value="<%=String.valueOf(bioMaterialId)%>" 
235      />
236      <tbl:hidden 
237        name="biomaterial_type" 
238        value="<%=bioMaterialType.name()%>" 
239      />
240      <tbl:hidden 
241        name="callback" 
242        value="<%=callback%>" 
243        skip="<%=callback == null%>" 
244      />
245      <%
246      Enumeration<String, String> eventTypes = new Enumeration<String, String>();
247      for (BioMaterialEvent.Type et : BioMaterialEvent.Type.values())
248      {
249        eventTypes.add(Integer.toString(et.getValue()), HTML.encodeTags(et.toString()));
250      }
251      %>
252      <tbl:columndef 
253        id="type"
254        property="eventType"
255        datatype="int"
256        title="Type"
257        enumeration="<%=eventTypes%>"
258        sortable="true" 
259        filterable="true"
260        exportable="true"
261        show="always" 
262      />
263      <tbl:columndef 
264        id="id"
265        clazz="uniquecol"
266        property="id"
267        datatype="int"
268        title="ID"
269        sortable="true"
270        filterable="true"
271        exportable="true"
272      />
273      <tbl:columndef 
274        id="entryDate"
275        property="entryDate"
276        datatype="date"
277        title="Entry date"
278        sortable="true" 
279        filterable="true"
280        exportable="true"
281        formatter="<%=dateFormatter%>"
282      />
283      <tbl:columndef 
284        id="eventDate"
285        property="eventDate"
286        datatype="date"
287        title="Event date"
288        sortable="true" 
289        filterable="true"
290        exportable="true"
291        formatter="<%=dateFormatter%>"
292      />
293      <tbl:columndef 
294        id="quantity"
295        datatype="float"
296        title="Used quantity (µg)"
297        sortable="false" 
298        filterable="false"
299        exportable="false"
300        unit="<%=microGram%>"
301      />
302      <tbl:columndef
303        id="bioPlateEvent"
304        property="bioPlateEventParticipant.event.name"
305        datatype="string"
306        title="Plate event"
307        sortable="true" 
308        filterable="true"
309        exportable="true"
310      />
311      <tbl:columndef 
312        id="protocol"
313        property="protocol.name"
314        datatype="string"
315        title="Protocol"
316        sortable="true" 
317        filterable="true"
318        exportable="true"
319      />
320      <tbl:columndef 
321        id="user"
322        property="user.name"
323        datatype="string"
324        title="User"
325        sortable="true" 
326        filterable="true"
327        exportable="true"
328      />
329      <tbl:columndef 
330        id="comment"
331        property="comment"
332        datatype="string"
333        title="Comment" 
334        sortable="true" 
335        filterable="true" 
336        exportable="true"
337      />
338      <tbl:columndef
339        id="permission"
340        title="Permission"
341      />
342      <tbl:columndef 
343        id="xt-columns" 
344        extensions="<%=columnsInvoker%>" 
345        jspcontext="<%=jspContext%>" 
346      />
347      <div class="panelgroup bottomborder">
348        <tbl:toolbar
349          visible="<%=mode.hasToolbar()%>"
350          subclass="bottomborder"
351          >
352          <tbl:button 
353            disabled="<%=!createPermission%>" 
354            image="new.png" 
355            onclick="newItem()" 
356            title="New&hellip;" 
357            tooltip="<%=createPermission ? "Create new event" : "You do not have permission to create events"%>" 
358          />
359          <tbl:button 
360            disabled="<%=!deletePermission%>" 
361            image="delete.png" 
362            title="Delete&hellip;"
363            onclick="deleteItems()" 
364            tooltip="<%=deletePermission ? "Delete the selected events" : "You do not have permission to delete events"%>" 
365          />
366          <tbl:button 
367            image="columns.png" 
368            onclick="configureColumns()" 
369            title="Columns&hellip;" 
370            tooltip="Show, hide and re-order columns" 
371          />
372          <tbl:button 
373            image="import.png" 
374            onclick="runPlugin('ImportItems')" 
375            title="Import&hellip;" 
376            tooltip="Import data" 
377            visible="<%=pluginCount.containsKey(Plugin.MainType.IMPORT)%>"
378          />
379          <tbl:button 
380            image="export.png" 
381            onclick="runPlugin('ExportItems')" 
382            title="Export&hellip;" 
383            tooltip="Export data" 
384            visible="<%=pluginCount.containsKey(Plugin.MainType.EXPORT)%>"
385          />
386          <tbl:button 
387            image="runplugin.png" 
388            onclick="runPlugin('RunListPlugin')" 
389            title="Run plugin&hellip;" 
390            tooltip="Run a plugin" 
391            visible="<%=pluginCount.containsKey(Plugin.MainType.OTHER)%>"
392          />
393          <ext:render extensions="<%=invoker%>" context="<%=jspContext%>" 
394            wrapper="<%=new PrefixSuffixRenderer(jspContext, "<td>", "</td>") %>"/>
395        </tbl:toolbar>
396        <tbl:panel>
397          <tbl:presetselector 
398            onchange="presetOnChange()"
399          />
400          <tbl:navigator
401            page="<%=cc.getPage()%>" 
402            rowsperpage="<%=cc.getRowsPerPage()%>" 
403            totalrows="<%=events == null ? 0 : events.getTotalCount()%>" 
404            visible="<%=mode.hasNavigator()%>"
405          />
406        </tbl:panel>
407      </div>
408      <tbl:data>
409        <tbl:headers>
410          <tbl:headerrow>
411            <tbl:header colspan="3" />
412            <tbl:columnheaders />
413          </tbl:headerrow>
414          <tbl:headerrow>
415            <tbl:header subclass="index" />
416            <tbl:header 
417              subclass="check" 
418              visible="<%=mode.hasCheck()%>"
419              ><base:icon 
420                image="check_uncheck.png" 
421                tooltip="Check/uncheck all" 
422                onclick="Forms.checkUncheck(document.forms[formId])" 
423              /></tbl:header>
424            <tbl:header 
425              subclass="check" 
426              visible="<%=mode.hasRadio()%>"
427              />
428            <tbl:header 
429              subclass="icons" 
430              visible="<%=mode.hasIcons()%>"
431              />
432            <tbl:propertyfilter />
433          </tbl:headerrow>
434        </tbl:headers>
435        <tbl:rows>
436          <%
437          if (cc.getMessage() != null)
438          {
439            %>
440            <tbl:panel clazz="messagepanel">
441              <div class="messagecontainer error"><%=cc.getMessage()%></div>
442            </tbl:panel>
443            <%
444            cc.setMessage(null);
445          }
446          int index = cc.getPage()*cc.getRowsPerPage();
447          int selectedItemId = cc.getId();
448          if (events != null)
449          {
450            while (events.hasNext())
451            {
452              BioMaterialEvent item = events.next();
453              BioMaterialEvent.Type eventType = item.getEventType();
454              int itemId = item.getId();
455              String name = "TODO";
456              index++;
457              numListed++;
458              %>
459              <tbl:row>
460                <tbl:header 
461                  clazz="index"
462                  ><%=index%></tbl:header>
463                <tbl:header 
464                  clazz="check" 
465                  visible="<%=mode.hasCheck()%>"
466                  ><input 
467                    type="checkbox" 
468                    name="<%=itemId%>" 
469                    value="<%=itemId%>" 
470                    title="TODO" 
471                    <%=cc.getSelected().contains(itemId) ? "checked" : ""%>
472                  ></tbl:header>
473                <tbl:header 
474                  clazz="check" 
475                  visible="<%=mode.hasRadio()%>"
476                  ><input 
477                      type="radio" 
478                      name="item_id" 
479                      value="<%=itemId%>" 
480                      title="<%=name%>" 
481                      <%=selectedItemId == itemId ? "checked" : ""%>
482                    ></tbl:header>
483                <tbl:header 
484                  clazz="icons" 
485                  visible="<%=mode.hasIcons()%>"
486                  >&nbsp;</tbl:header>
487                <tbl:cell column="type">
488                  <%
489                  if (eventType == BioMaterialEvent.Type.OTHER)
490                  {
491                    if (item.hasPermission(Permission.WRITE))
492                    {
493                      %>
494                      <div class="link" onclick="itemOnClick(event, <%=itemId%>)"><%=eventType%></div>
495                      <%
496                    }
497                    else
498                    {
499                      %>
500                      <div class="link" onclick="viewItem(<%=itemId%>)"><%=eventType%></div>
501                      <%
502                    }
503                  }
504                  else if (eventType == BioMaterialEvent.Type.CREATION)
505                  {
506                    if (item.equals(creationEvent))
507                    {
508                      %>
509                      <div class="link" onclick="viewItem(<%=itemId%>)">
510                      Created
511                      </div>
512                      <%
513                    }
514                    else
515                    {
516                      MeasuredBioMaterial child = null;
517                      try
518                      {
519                        child = item.getBioMaterial();
520                      }
521                      catch (PermissionDeniedException ex)
522                      {}
523                      %>
524                      <div class="link" onclick="viewItem(<%=itemId%>)">
525                      Created <%=child == null ? "child" : child.getType().toString().toLowerCase() %>: <base:propertyvalue 
526                            item="<%=item%>" 
527                            property="bioMaterial"
528                            enableEditLink="<%=false%>" 
529                            enablePropertyLink="<%=false%>"
530                          />
531                      </div>
532                      <%
533                    }
534                  }
535                  else if (eventType == BioMaterialEvent.Type.BIOASSAY)
536                  {
537                    %>
538                    <div class="link" onclick="viewItem(<%=itemId%>)">
539                    Bioassay: <base:propertyvalue 
540                              item="<%=item%>" 
541                              property="physicalBioAssay"
542                              enableEditLink="<%=false%>" 
543                              enablePropertyLink="<%=false%>"
544                            />
545                    </div>
546                    <%
547                  }
548                  %>
549                </tbl:cell>
550                <tbl:cell column="id"><%=item.getId()%></tbl:cell>
551                <tbl:cell column="eventDate" value="<%=item.getEventDate()%>" />
552                <tbl:cell column="entryDate" value="<%=item.getEntryDate()%>" />
553                <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(bioMaterial), 2)%></tbl:cell>
554                <tbl:cell column="bioPlateEvent">
555                  <%
556                  try
557                  {
558                    BioPlateEventParticipant participant = item.getBioPlateEventParticipant();
559                    if (participant != null)
560                    {
561                      BioPlateEvent event = participant.getEvent();
562                      String extraUrl = "";
563                      try
564                      {
565                        extraUrl = "&bioplate_id=" + participant.getBioPlate().getId();
566                      }
567                      catch (PermissionDeniedException ex)
568                      {}
569                      boolean editLink = event.hasPermission(Permission.WRITE);
570                      if (mode.hasPropertyLink())
571                      {
572                        %>
573                        <span class="link" 
574                          onclick="Main.itemOnClick(event, '<%=ID%>', 'BIOPLATEEVENT', <%=event.getId()%>, <%=editLink%>, '<%=extraUrl%>')"
575                          title="View this bioplate event <%=editLink? "(use CTRL, ALT or SHIFT to edit)" : ""%>"
576                        >
577                        <%=HTML.encodeTags(event.getName()) %>
578                        </span>
579                        <%
580                      }
581                      else
582                      {
583                        %>
584                        <%=HTML.encodeTags(event.getName()) %>
585                        <%
586                      }
587                    }
588                    else
589                    {
590                      %>
591                      <i>- none -</i>
592                      <%
593                    }
594                  }
595                  catch (PermissionDeniedException ex)
596                  {
597                    %>
598                    <i>- denied -</i>
599                    <%
600                  }
601                  %>
602                </tbl:cell>
603                <tbl:cell column="protocol"
604                  ><base:propertyvalue 
605                    item="<%=item%>" 
606                    property="protocol"
607                    enableEditLink="<%=mode.hasEditLink()%>" 
608                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
609                  /></tbl:cell>
610                <tbl:cell column="user"
611                  ><base:propertyvalue 
612                    item="<%=item%>" 
613                    property="user"
614                    enableEditLink="<%=mode.hasEditLink()%>" 
615                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
616                  /></tbl:cell>
617                <tbl:cell column="comment"><%=HTML.encodeTags(item.getComment())%></tbl:cell>
618                <tbl:cell column="permission"><%=PermissionUtil.getShortPermissions(item)%></tbl:cell>
619                <tbl:xt-cells dc="<%=dc%>" item="<%=item%>">
620                  <tbl:cell column="xt-columns" />
621                </tbl:xt-cells>
622              </tbl:row>
623              <%
624            }
625          }
626          if (numListed == 0)
627          {
628            %>
629            <tbl:panel clazz="messagepanel">
630              <div class="messagecontainer note">
631              <%=events == null || events.getTotalCount() == 0 ? "No events were found" : "No events on this page. Please select another page!" %>
632              </div>
633            </tbl:panel>
634            <%
635          }
636          %>
637          </tbl:rows>
638        </tbl:data>
639    </tbl:table>
640    <base:buttongroup subclass="dialogbuttons">
641      <base:button onclick="returnSelected();" title="Ok" visible="<%=mode.hasOkButton()%>" />
642      <base:button onclick="window.close();" title="Cancel" visible="<%=mode.hasCancelButton()%>" />
643      <base:button onclick="window.close();" title="Close" visible="<%=mode.hasCloseButton()%>" />
644    </base:buttongroup>
645    </t:tab>
646   
647    <t:tab id="overview" title="Overview" 
648      tooltip="Display a tree overview of related items" />
649    <t:tab id="history" title="Change history" 
650        tooltip="Displays a log of all modifications made to this item"
651        visible="<%=ChangeHistoryUtil.showChangeHistoryTab(sc)%>" />
652    </t:tabcontrol>
653
654  </base:body>
655  </base:page>
656  <%
657}
658finally
659{
660  if (events != null) events.close();
661  if (dc != null) dc.close();
662}
663%>
Note: See TracBrowser for help on using the repository browser.