source: branches/3.18-stable/www/admin/diskusage/list_users.jsp @ 7932

Last change on this file since 7932 was 7932, checked in by Nicklas Nordborg, 6 months ago

References #2246: Sticky table headers

Implemented for all item list pages and a few other places:

  • Extensions installation dialog
  • Administrate / Services list page
  • Batch inherit annotations
  • Manage list presets
  • List of changed item in view job dialog


File size: 20.0 KB
Line 
1<%-- $Id$
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Nicklas Nordborg
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.Application"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.User"
32  import="net.sf.basedb.core.Group"
33  import="net.sf.basedb.core.Role"
34  import="net.sf.basedb.core.Type"
35  import="net.sf.basedb.core.ItemQuery"
36  import="net.sf.basedb.core.Include"
37  import="net.sf.basedb.core.ItemResultIterator"
38  import="net.sf.basedb.core.ItemResultList"
39  import="net.sf.basedb.core.ItemContext"
40  import="net.sf.basedb.core.Permission"
41  import="net.sf.basedb.core.PluginDefinition"
42  import="net.sf.basedb.core.DiskUsage"
43  import="net.sf.basedb.core.DiskUsageStatistics"
44  import="net.sf.basedb.core.QuotaType"
45  import="net.sf.basedb.core.Location"
46  import="net.sf.basedb.core.query.Orders"
47  import="net.sf.basedb.core.query.Hql"
48  import="net.sf.basedb.core.query.Restrictions"
49  import="net.sf.basedb.core.query.Expressions"
50  import="net.sf.basedb.core.plugin.GuiContext"
51  import="net.sf.basedb.core.plugin.Plugin"
52  import="net.sf.basedb.util.Enumeration"
53  import="net.sf.basedb.clients.web.Base"
54  import="net.sf.basedb.clients.web.ModeInfo"
55  import="net.sf.basedb.clients.web.PermissionUtil"
56  import="net.sf.basedb.clients.web.util.HTML"
57  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
58  import="net.sf.basedb.util.Values"
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.ButtonAction" 
63  import="net.sf.basedb.clients.web.extensions.toolbar.ToolbarUtil"
64  import="net.sf.basedb.clients.web.extensions.list.ListColumnAction"
65  import="net.sf.basedb.clients.web.extensions.list.ListColumnUtil"
66  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
67  import="java.util.List"
68  import="java.util.Map"
69%>
70<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
71<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
72<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
73<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
74<%!
75  private static final Item itemType = Item.DISKUSAGE;
76  private static final String subContext = "perUser";
77  private static final GuiContext guiContext = new GuiContext(itemType, GuiContext.Type.LIST, subContext);
78%>
79<%
80final SessionControl sc = Base.getExistingSessionControl(pageContext, Permission.DENIED, itemType);
81final String ID = sc.getId();
82final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, subContext, null, null);
83final ModeInfo mode = ModeInfo.get(request.getParameter("mode"));
84final boolean impersonatePermission = sc.hasSystemPermission(Permission.ACT_AS_ANOTHER_USER);
85final boolean writePermission = sc.hasPermission(Permission.WRITE, Item.USER);
86final String showStatistics = Values.getString(cc.getSetting("showStatistics"), "full");
87
88final boolean hasLocation = "location".equals(showStatistics) || "full".equals(showStatistics);
89final boolean hasQuotaType = "quotaType".equals(showStatistics) || "full".equals(showStatistics);
90
91final DbControl dc = sc.newDbControl();
92ItemResultIterator<User> users = null;
93try
94{
95  DiskUsageStatistics du = sc.getSessionSetting("diskUsageStatistics");
96  if (du == null)
97  {
98    du = DiskUsage.getStatistics(dc);
99    sc.setSessionSetting("diskUsageStatistics", du);
100  }
101  du.setDbControl(dc);
102  List<QuotaType> quotaTypes = du.getQuotaTypes();
103 
104  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, guiContext, null);
105  try
106  {
107    final ItemQuery<User> query = Base.getConfiguredQuery(dc, cc, jspContext, true, User.getQuery(), mode);
108    query.include(Include.ALL);
109    users = query.iterate(dc);
110  }
111  catch (Throwable t)
112  {
113    cc.setMessage(t.getMessage());
114  }
115  int numListed = 0;
116  ExtensionsInvoker<ButtonAction> invoker = ToolbarUtil.useExtensions(jspContext);
117  ExtensionsInvoker<ListColumnAction<User,?>> columnsInvoker = ListColumnUtil.useExtensions(jspContext);
118  %>
119  <base:page title="Disk usage" id="list-users">
120  <base:head scripts="table.js,tabcontrol-2.js,~diskusage.js" styles="table.css,toolbar.css,headertabcontrol.css">
121    <ext:scripts context="<%=jspContext%>" />
122    <ext:stylesheets context="<%=jspContext%>" />
123    <style>
124    table.special
125    {
126      border-width: 1px;
127      margin: 2px;
128      border-collapse: collapse;
129      width: calc(100% - 6px);
130    }
131    table.special td, table.special th
132    {
133      text-align: right;
134      border-right-width: 1px;
135      border-right-style: dotted;
136      padding: 1px 2px 1px 2px;
137    }
138    </style>
139  </base:head>
140 
141  <base:body>
142    <h1>Disk usage</h1>
143    <t:tabcontrol 
144      id="main" 
145      subclass="mastertabcontrol content" 
146      active="users">
147    <t:tab id="overview" title="Overview" data-cmd="Overview"/>
148    <t:tab id="users" title="Per user" data-cmd="ListUsers">
149    <tbl:table 
150      id="users" 
151      columns="<%=cc.getSetting("columns")%>"
152      sortby="<%=cc.getSortProperty()%>" 
153      direction="<%=cc.getSortDirection()%>"
154      action="index.jsp"
155      sc="<%=sc%>"
156      item="<%=itemType%>"
157      subcontext="<%=subContext%>"
158      filterrows="<%=cc.getFilterRows()%>"
159      subclass="fulltable sticky-headers"
160      >
161      <tbl:hidden 
162        name="subcontext"
163        value="<%=subContext%>"
164      />
165      <tbl:columndef 
166        id="name"
167        property="name"
168        datatype="string"
169        title="Name"
170        sortable="true" 
171        filterable="true"
172        exportable="true"
173        show="always" 
174      />
175      <tbl:columndef 
176        id="id"
177        clazz="uniquecol"
178        property="id"
179        datatype="int"
180        title="ID"
181        sortable="true"
182        filterable="true"
183        exportable="true"
184      />
185      <tbl:columndef
186        id="diskUsage"
187        title="Disk usage summary"
188        show="always"
189      />
190      <tbl:columndef 
191        id="login"
192        clazz="uniquecol"
193        property="login"
194        datatype="string"
195        title="Login"
196        sortable="true" 
197        filterable="true"
198        exportable="true"
199      />
200      <tbl:columndef 
201        id="systemId"
202        clazz="uniquecol"
203        property="systemId"
204        datatype="string"
205        title="System ID"
206        sortable="true"
207        filterable="true"
208        exportable="true"
209      />
210      <tbl:columndef 
211        id="externalId"
212        clazz="uniquecol"
213        property="externalId"
214        datatype="string"
215        title="External ID"
216        sortable="true" 
217        filterable="true"
218        exportable="true"
219      />
220      <tbl:columndef 
221        id="expirationDate"
222        property="expirationDate"
223        datatype="date"
224        title="Expiration date"
225        sortable="true" 
226        filterable="true"
227        exportable="true"
228        formatter="<%=FormatterFactory.getDateFormatter(sc)%>"
229      />
230      <tbl:columndef 
231        id="disabled"
232        property="disabled"
233        datatype="boolean"
234        title="Disabled"
235        sortable="true" 
236        filterable="true"
237        exportable="true"
238      />
239      <tbl:columndef 
240        id="multiuserAccount"
241        property="multiuserAccount"
242        datatype="boolean"
243        title="Multi-user account"
244        sortable="true" 
245        filterable="true"
246        exportable="true"
247      />
248      <tbl:columndef 
249        id="organisation"
250        property="organisation"
251        datatype="string"
252        title="Organisation"
253        sortable="true" 
254        filterable="true"
255        exportable="true"
256      />
257      <tbl:columndef 
258        id="address"
259        property="address"
260        datatype="string"
261        title="Address"
262        sortable="true" 
263        filterable="true"
264        exportable="true"
265      />
266      <tbl:columndef 
267        id="email"
268        property="email"
269        datatype="string"
270        title="Email"
271        sortable="true" 
272        filterable="true"
273        exportable="true"
274      />
275      <tbl:columndef 
276        id="phone"
277        property="phone"
278        datatype="string"
279        title="Phone"
280        sortable="true" 
281        filterable="true"
282        exportable="true"
283      />
284      <tbl:columndef 
285        id="fax"
286        property="fax"
287        datatype="string"
288        title="Fax"
289        sortable="true" 
290        filterable="true"
291        exportable="true"
292      />
293      <tbl:columndef 
294        id="url"
295        property="url"
296        datatype="string"
297        title="Url"
298        sortable="true" 
299        filterable="true"
300        exportable="true"
301      />
302      <tbl:columndef 
303        id="quota"
304        property="quota.name"
305        datatype="string"
306        title="Quota"
307        sortable="true" 
308        filterable="true"
309        exportable="true"
310      />
311      <tbl:columndef 
312        id="quotagroup"
313        property="quotaGroup.name"
314        datatype="string"
315        title="Quota group"
316        sortable="true" 
317        filterable="true"
318        exportable="true"
319      />
320      <tbl:columndef 
321        id="description"
322        property="description"
323        datatype="string"
324        title="Description" 
325        sortable="true" 
326        filterable="true" 
327        exportable="true"
328      />
329      <tbl:columndef 
330        id="xt-columns" 
331        extensions="<%=columnsInvoker%>" 
332        jspcontext="<%=jspContext%>" 
333      />
334      <div class="panelgroup bg-filled-50 bottomborder">
335        <tbl:toolbar
336          visible="<%=mode.hasToolbar()%>"
337          subclass="bottomborder"
338          >
339          <tbl:button 
340            id="btnColumns"
341            image="columns.png"
342            title="Columns&hellip;" 
343            tooltip="Show, hide and re-order columns" 
344          />
345          <ext:render extensions="<%=invoker%>" context="<%=jspContext%>" 
346            wrapper="<%=new PrefixSuffixRenderer<ButtonAction>(jspContext, "<td>", "</td>") %>"/>
347        </tbl:toolbar>
348        <tbl:panel>
349          <tbl:presetselector />
350          <tbl:navigator
351            page="<%=cc.getPage()%>" 
352            rowsperpage="<%=cc.getRowsPerPage()%>" 
353            totalrows="<%=users == null ? 0 : users.getTotalCount()%>" 
354          />
355          <b>Show summary</b>
356          <span id="changeSummary">
357          <label><input type="radio" name="showStatistics" value="total"
358            <%="total".equals(showStatistics) ? "checked" : ""%>>Total only</label>
359          <label><input type="radio" name="showStatistics" value="location"
360            <%="location".equals(showStatistics) ? "checked" : ""%>>Per location</label>
361          <label><input type="radio" name="showStatistics" value="quotaType"
362            <%="quotaType".equals(showStatistics) ? "checked" : ""%>>Per quota type</label>
363          <label><input type="radio" name="showStatistics" value="full"
364            <%="full".equals(showStatistics) ? "checked" : ""%>>Full</label>
365          </span>
366        </tbl:panel>
367      </div>
368      <tbl:data>
369        <tbl:headers>
370          <tbl:headerrow>
371            <tbl:header colspan="3" />
372            <tbl:columnheaders />
373          </tbl:headerrow>
374          <%
375          int numFilters = cc.getNumPropertyFilters();
376          int numRows = cc.getFilterRows();
377          for (int filterNo = 0; filterNo < numRows; filterNo++)
378          {
379            boolean lastRow = filterNo == numRows-1;
380            %>
381            <tbl:headerrow>
382              <tbl:header subclass="index" />
383              <tbl:header 
384                subclass="check" 
385                visible="<%=mode.hasCheck()%>"
386                ><base:icon 
387                  subclass="link table-check"
388                  image="check_uncheck.png" 
389                  tooltip="Toggle all (use CTRL, ALT or SHIFT to check/uncheck)" 
390                  visible="<%=lastRow%>"
391                /></tbl:header>
392              <tbl:header 
393                subclass="check" 
394                visible="<%=mode.hasRadio()%>"
395                />
396              <tbl:header 
397                subclass="icons" 
398                visible="<%=mode.hasIcons()%>"
399                >
400                <base:icon
401                  subclass="link table-filter-row-action"
402                  image="add.png"
403                  tooltip="Add extra filter row"
404                  visible="<%=lastRow%>"
405                /><base:icon
406                  subclass="link table-filter-row-action"
407                  image="remove.png"
408                  tooltip="Remove this filter row"
409                  visible="<%=numRows > 1 || numFilters > 0 %>"
410                  data-remove-row="<%=filterNo%>"
411                />
412              </tbl:header>
413              <tbl:propertyfilter row="<%=filterNo%>" />
414            </tbl:headerrow>
415            <%
416          }
417          %>
418          <tbl:columnsubtitles />
419        </tbl:headers>
420        <tbl:rows>
421          <%
422          if (cc.getMessage() != null)
423          {
424            %>
425            <tbl:panel subclass="bg-filled-50">
426              <div class="messagecontainer error"><%=cc.getMessage()%></div>
427            </tbl:panel>
428            <%
429            cc.setMessage(null);
430          }
431          int index = cc.getPage()*cc.getRowsPerPage();
432          int selectedItemId = cc.getId();
433          if (users != null)
434          {           
435            while (users.hasNext())
436            {
437              User item = users.next();
438              int itemId = item.getId();
439              String name = HTML.encodeTags(item.getName());
440              String tooltip = mode.isSelectionMode() ? 
441                  "Select this item" : "View this item" + (writePermission ? " (use CTRL, ALT or SHIFT to edit)" : "");
442              index++;
443              numListed++;
444              %>
445              <tbl:row>
446                <tbl:header 
447                  clazz="index"
448                  ><%=index%></tbl:header>
449                <tbl:header 
450                  clazz="check" 
451                  visible="<%=mode.hasCheck()%>"
452                  ><input 
453                    type="checkbox" 
454                    name="<%=itemId%>" 
455                    value="<%=itemId%>" 
456                    title="<%=name%>" 
457                    <%=cc.getSelected().contains(itemId) ? "checked" : ""%> 
458                  ></tbl:header>
459                <tbl:header 
460                  clazz="check" 
461                  visible="<%=mode.hasRadio()%>"
462                  ><input 
463                    type="radio" 
464                    name="item_id" 
465                    value="<%=itemId%>" 
466                    title="<%=name%>" 
467                    <%=selectedItemId == itemId ? "checked" : ""%>
468                  ></tbl:header>
469                <tbl:header 
470                  clazz="icons" 
471                  visible="<%=mode.hasIcons()%>"
472                  ><base:icon 
473                    image="deleted.png" 
474                    tooltip="This item has been scheduled for deletion" 
475                    visible="<%=item.isRemoved()%>"
476                  /><base:icon
477                    subclass="link auto-init"
478                    data-auto-init="impersonate-user"
479                    data-user-id="<%=itemId%>"
480                    image="login.png"
481                    tooltip="Login as this user"
482                    visible="<%=impersonatePermission%>"
483                  /></tbl:header>
484                <tbl:cell column="name"><div 
485                  class="link auto-init"
486                  data-auto-init="item-link"
487                  data-item-type="USER"
488                  data-item-id="<%=itemId%>"
489                  data-no-edit="<%=writePermission ? 0 : 1 %>"
490                  title="<%=tooltip%>"><%=name%></div></tbl:cell>
491                <tbl:cell column="id"><%=item.getId()%></tbl:cell>
492                <tbl:cell column="diskUsage" style="padding: 0px;">
493                  <%
494                  DiskUsageStatistics.Summary summary = du.getSummary(item);
495                  long total = summary.getTotal();
496                  if (total > 0 && (hasLocation || hasQuotaType))
497                  {
498                    %>
499                    <table class="special bottomborder">
500                    <%
501                    if (hasLocation)
502                    {
503                      %>
504                      <tr class="bottomborder bg-filled-100">
505                        <%
506                        if (hasQuotaType)
507                        {
508                          %>
509                          <th>&nbsp;</th>
510                          <%
511                        }
512                        %>
513                        <th>Total</th>
514                        <td>Primary</td>
515                        <td>External</td>
516                        <td>Offline</td>
517                      </tr>
518                      <%
519                    }
520                    %> 
521                    <tr class="bottomborder <%=!hasLocation ? "bg-filled-100" : "" %>">
522                      <%
523                      if (hasQuotaType)
524                      {
525                        %>
526                        <th>Total</th>
527                        <%
528                      }
529                      %>
530                      <td><%=Values.formatBytes(total)%></td>
531                      <%
532                      if (hasLocation)
533                      {
534                        %>
535                        <td><%=Values.formatBytes(summary.getTotal(Location.PRIMARY))%></td>
536                        <td><%=Values.formatBytes(summary.getTotal(Location.EXTERNAL))%></td>
537                        <td><%=Values.formatBytes(summary.getTotal(Location.OFFLINE))%></td>
538                        <%
539                      }
540                      %>
541                    </tr>
542                    <%
543                    if (hasQuotaType && total > 0)
544                    {
545                      for (QuotaType qt : quotaTypes)
546                      {
547                        %>
548                        <tr>
549                          <td><%=HTML.encodeTags(qt.getName())%></td>
550                          <td><%=Values.formatBytes(summary.getTotal(qt))%></td>
551                          <%
552                          if (hasLocation)
553                          {
554                            %>
555                            <td><%=Values.formatBytes(summary.getTotal(qt, Location.PRIMARY))%></td>
556                            <td><%=qt.getSystemId().equals(QuotaType.FILE) ? Values.formatBytes(summary.getTotal(qt, Location.EXTERNAL)) : "n/a"%></td>
557                            <td><%=qt.getSystemId().equals(QuotaType.FILE) ? Values.formatBytes(summary.getTotal(qt, Location.OFFLINE)) : "n/a"%></td>
558                            <%
559                          }
560                          %>
561                        </tr>
562                        <%
563                      }
564                    }
565                    %>
566                    </table>
567                    <%
568                  }
569                  else
570                  {
571                    %>
572                    &nbsp;<%=Values.formatBytes(total)%>
573                    <%
574                  }
575                  if (total > 0)
576                  {
577                    %>
578                    <base:icon image="gonext.png" 
579                      subclass="link auto-init"
580                      data-auto-init="view-details"
581                      data-item-type="USER"
582                      data-item-id="<%=itemId %>">View details</base:icon>
583                    <%
584                  }
585                  %>
586                </tbl:cell>
587                <tbl:cell column="login"><%=HTML.encodeTags(item.getLogin())%></tbl:cell>
588                <tbl:cell column="systemId"><%=Values.getString(item.getSystemId())%></tbl:cell>
589                <tbl:cell column="externalId"><%=HTML.encodeTags(item.getExternalId())%></tbl:cell>
590                <tbl:cell column="expirationDate" value="<%=item.getExpirationDate()%>" />
591                <tbl:cell column="disabled"><%=item.isDisabled() ? "yes" : "no" %></tbl:cell>
592                <tbl:cell column="multiuserAccount"><%=item.isMultiuserAccount() ? "yes" : "no" %></tbl:cell>
593                <tbl:cell column="organisation"><%=HTML.encodeTags(item.getOrganisation())%></tbl:cell>
594                <tbl:cell column="address"><%=HTML.encodeTags(item.getAddress())%></tbl:cell>
595                <tbl:cell column="email"><%=HTML.encodeTags(item.getEmail())%></tbl:cell>
596                <tbl:cell column="phone"><%=HTML.encodeTags(item.getPhone())%></tbl:cell>
597                <tbl:cell column="fax"><%=HTML.encodeTags(item.getFax())%></tbl:cell>
598                <tbl:cell column="url"><%=HTML.encodeTags(item.getUrl())%></tbl:cell>
599                <tbl:cell column="quota"
600                  ><base:propertyvalue 
601                    item="<%=item%>" 
602                    property="quota"
603                    enableEditLink="<%=mode.hasEditLink()%>" 
604                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
605                  /></tbl:cell>
606                <tbl:cell column="quotagroup"
607                  ><base:propertyvalue 
608                    item="<%=item%>" 
609                    property="quotaGroup"
610                    enableEditLink="<%=mode.hasEditLink()%>" 
611                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
612                  /></tbl:cell>
613                <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
614                <tbl:xt-cells dc="<%=dc%>" item="<%=item%>">
615                  <tbl:cell column="xt-columns" />
616                </tbl:xt-cells>
617              </tbl:row>
618              <%
619              }
620            }
621            if (numListed == 0)
622            {
623              %>
624              <tbl:panel subclass="bg-filled-50">
625                <div class="messagecontainer note">
626                <%=users == null || users.getTotalCount() == 0 ? "No users were found" : "No users on this page. Please select another page!" %>
627                </div>
628              </tbl:panel>
629              <%
630            }
631          %>
632        </tbl:rows>
633      </tbl:data>
634      </tbl:table>
635    </t:tab>
636    <t:tab id="groups" title="Per group" data-cmd="ListGroups"/>
637    </t:tabcontrol>
638
639  </base:body>
640  </base:page>
641  <%
642}
643finally
644{
645  if (users != null) users.close();
646  if (dc != null) dc.close();
647}
648%>
Note: See TracBrowser for help on using the repository browser.