source: trunk/www/my_base/index.jsp @ 5970

Last change on this file since 5970 was 5970, checked in by Nicklas Nordborg, 11 years ago

References #1655: GUI improvements

Avoid line-wrapping of message titles on home/login page. Reduce unused space in the menu.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.8 KB
Line 
1<%-- $Id: index.jsp 5970 2012-02-17 08:55:56Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
5  Copyright (C) 2007 Johan Enell
6
7  This file is part of BASE - BioArray Software Environment.
8  Available at http://base.thep.lu.se/
9
10  BASE is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License
12  as published by the Free Software Foundation; either version 3
13  of the License, or (at your option) any later version.
14
15  BASE is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with BASE. If not, see <http://www.gnu.org/licenses/>.
22  ------------------------------------------------------------------
23  This is the welcome page once the user has logged in to BASE.
24  It should do a lot more than display an empty page....
25
26  ...To be done....
27
28  @author Nicklas
29  @version 2.0
30--%>
31<%@ page pageEncoding="UTF-8" session="false"
32  import="net.sf.basedb.core.SessionControl"
33  import="net.sf.basedb.core.DbControl"
34  import="net.sf.basedb.core.User"
35  import="net.sf.basedb.core.Group"
36  import="net.sf.basedb.core.Message"
37  import="net.sf.basedb.core.Project"
38  import="net.sf.basedb.core.News"
39  import="net.sf.basedb.core.Include"
40  import="net.sf.basedb.core.Location"
41  import="net.sf.basedb.core.Type"
42  import="net.sf.basedb.core.Quota"
43  import="net.sf.basedb.core.QuotaType"
44  import="net.sf.basedb.core.ItemQuery"
45  import="net.sf.basedb.core.ItemResultList"
46  import="net.sf.basedb.core.SystemItems"
47  import="net.sf.basedb.core.query.Orders"
48  import="net.sf.basedb.core.query.Expression"
49  import="net.sf.basedb.core.query.Hql"
50  import="net.sf.basedb.core.query.Restrictions"
51  import="net.sf.basedb.core.query.Expressions"
52  import="net.sf.basedb.clients.web.Base"
53  import="net.sf.basedb.clients.web.util.HTML"
54  import="net.sf.basedb.util.formatter.Formatter"
55  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
56  import="net.sf.basedb.clients.web.servlet.RssNewsFeed"
57  import="net.sf.basedb.util.Values"
58  import="java.util.Date" 
59  import="java.util.List"
60  import="java.util.ArrayList"
61  import="java.util.Set"
62  import="java.util.HashSet"
63%>
64<%@ taglib
65  prefix="base" uri="/WEB-INF/base.tld"
66%>
67<%!
68private String getPrintableQuota(long myQuota, long groupQuota)
69{
70  String printable = "";
71  if (myQuota == Quota.UNDEFINED && groupQuota == Quota.UNDEFINED)
72  {
73    // Both are undefined
74    printable = "";
75  }
76  else if (myQuota < 0 && groupQuota < 0)
77  {
78    // both are unlimited or one is unlimited and the other is undefined
79    printable = "unlimited";
80  }
81  else if (myQuota >= 0 && groupQuota >= 0)
82  {
83    // both are well-defined; use min value
84    printable = Values.formatBytes(Math.min(myQuota, groupQuota));
85  }
86  else
87  {
88    // Only one is well-defined; use max value
89    printable = Values.formatBytes(Math.max(myQuota, groupQuota));
90  }
91  return printable;
92}
93%>
94<%
95SessionControl sc = Base.getExistingSessionControl(pageContext, true);
96String ID = sc.getId();
97
98DbControl dc = null;
99try
100{
101  dc = sc.newDbControl();
102  User user = User.getById(dc, sc.getLoggedInUserId());
103  Quota quota = user.getQuota();
104  Group quotaGroup = user.getQuotaGroup();
105  Quota groupQuota = quotaGroup == null ? null : quotaGroup.getQuota();
106 
107  Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
108  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
109
110  ItemQuery<Message> messageQuery = Message.getQuery(user);
111  messageQuery.order(Orders.desc(Hql.property("timeSent")));
112  messageQuery.restrict(Restrictions.eq(Hql.property("read"), Expressions.parameter("isread", false)));
113  ItemResultList<Message> messages = messageQuery.list(dc);
114 
115  List<Project> projects = new ArrayList<Project>();
116  String tmp = sc.getUserClientSetting("projects.recentActive");
117  Set<Integer> recentProjects = new HashSet<Integer>();
118  if (tmp != null)
119  {
120    for (String id : tmp.split(":"))
121    {
122      try
123      {
124        Project p = Project.getById(dc, Values.getInt(id));
125        if (!p.isRemoved())
126        {
127          recentProjects.add(p.getId());
128          projects.add(p);
129        }
130      }
131      catch (RuntimeException ex)
132      {}
133    }
134  }
135  ItemQuery<Project> projectQuery = Project.getQuery();
136  projectQuery.order(Orders.asc(Hql.property("name")));
137  projectQuery.include(Include.MINE, Include.SHARED);
138  projectQuery.restrict(Restrictions.not(Restrictions.in(Hql.property("id"), Expressions.parameter("projects"))));
139  projectQuery.setParameter("projects", recentProjects, Type.INT);
140  projects.addAll(projectQuery.list(dc));
141 
142  QuotaType totalQuotaType = QuotaType.getById(dc, SystemItems.getId(QuotaType.TOTAL));
143  ItemQuery<QuotaType> quotaTypeQuery = QuotaType.getQuery();
144  quotaTypeQuery.order(Orders.asc(Hql.property("id")));
145  quotaTypeQuery.restrict(
146    Restrictions.neq(
147      Hql.property("id"), 
148      Hql.entity(totalQuotaType)
149    )
150  );
151  ItemResultList<QuotaType> quotaTypes = quotaTypeQuery.list(dc);
152
153  ItemQuery<News> newsQuery = News.getQuery();
154  Expression today = Expressions.parameter("today");
155  newsQuery.restrict(Restrictions.lteq(Hql.property("startDate"), today));
156  newsQuery.restrict(
157    Restrictions.or(
158      Restrictions.gteq(Hql.property("endDate"), today),
159      Restrictions.eq(Hql.property("endDate"), null)
160    )
161  );
162  newsQuery.order(Orders.desc(Hql.property("newsDate")));
163  newsQuery.order(Orders.desc(Hql.property("id")));
164  newsQuery.setParameter("today", new Date(), Type.DATE);
165  ItemResultList<News> news = newsQuery.list(dc);
166 
167  String help = Values.getStringOrNull(sc.getClientDefaultSetting("server.links.help"));
168  String faq = Values.getStringOrNull(sc.getClientDefaultSetting("server.links.faq"));
169  String reportBug = Values.getStringOrNull(sc.getClientDefaultSetting("server.links.reportbug"));
170  boolean hasHelp = help != null || faq != null || reportBug != null;
171%>
172<base:page title="Welcome to BASE">
173<base:head styles="login.css">
174
175<script language="JavaScript">
176
177  function viewMessage(messageId)
178  {
179    Main.viewOrEditItem('<%=ID%>', 'MESSAGE', messageId, false);
180  }
181  function setActiveProject(projectId)
182  {
183    Main.openPopup('projects/set_active.jsp?ID=<%=ID%>&project_id='+projectId, 'ActivateProject', 300, 200)
184  }
185  function viewDiskUsage()
186  {
187    location.href = '../admin/diskusage/details/index.jsp?ID=<%=ID%>&cmd=ViewItem&item_type=USER&item_id=<%=sc.getLoggedInUserId() %>';
188  }
189</script>
190
191</base:head>
192<base:body onload="top.frames['footnote'].location.reload()">
193
194  <h1>Welcome to BASE</h1>
195
196  <div class="content">
197 
198  <div class="absolutefull" style="width: 50%;">
199 
200    <div class="absolutefull" style="left: 1em; right: 0.5em; bottom: <%=hasHelp ? "16em" : "1em" %>;">
201
202    <div class="absolutefull" style="height: 50%;">
203      <div class="absolutefull" style="height: 1.75em; overflow: hidden;"">
204        <h3 style="height: 100%;"><base:icon image="project.png" />Projects (<%=projects.size()%>)</h3>
205      </div>
206      <div id="projects" class="absolutefull welcomesection" style="top: 1.75em; bottom: 0.5em;">
207      <%
208      if (projects.size() == 0)
209      {
210        %>
211        You are not member of any projects.
212        <%
213      }
214      else
215      {
216        int activeProjectId = sc.getActiveProjectId();
217        %>
218        <table border="0" cellspacing="0" cellpadding="2">
219        <%
220        if (activeProjectId == 0)
221        {
222          %>
223          <td><base:icon image="warning.png" /></td>
224          <td><i>No active project</i></td>
225          <td>&nbsp;</td>     
226          <%
227        }
228        for (Project p : projects)
229        {
230          int projectId = p.getId();
231          if (projectId == activeProjectId)
232          {
233            %>
234            <tr>
235              <td><base:icon image="bullet.png" /></td>
236              <td><b><%=Base.getLinkedName(ID, p, false, true)%></b></td>
237              <td>[active]</td>
238            </tr>
239            <%
240          }
241          else
242          {
243            %>
244            <tr>
245              <td>&nbsp;</td>
246              <td><%=Base.getLinkedName(ID, p, false, true)%></td>
247              <td>[<a href="javascript:setActiveProject(<%=projectId%>)">set active</a>]</td>
248            </tr>
249            <%
250          }
251        }
252        %>
253        </table>
254        <%
255      }
256      %>
257      </div>
258    </div>
259
260    <div class="absolutefull" style="height: 50%; top: auto;">
261      <div class="absolutefull" style="height: 1.75em; top: 0.5em; overflow: hidden;">
262        <h3 style="height: 100%;"><base:icon image="message.png" />New messages (<%=messages.size()%>)</h3>
263      </div>
264      <div id="messages" class="absolutefull news welcomesection" style="top: 2.25em;">
265      <%
266      String broadcastTitle = (String)application.getAttribute("broadcast.title");
267      if (broadcastTitle != null)
268      {
269        String broadcastMessage = (String)application.getAttribute("broadcast.message");
270        %>
271        <div class="item">
272          <div class="headline">
273            <base:icon image="warning.png" />
274            <span class="date"><%=dateFormatter.format(new Date())%></span>
275            <%=HTML.encodeTags(broadcastTitle)%>
276          </div>
277          <div class="text"><%=HTML.niceFormat(broadcastMessage)%></div>
278        </div>
279        <% 
280      }
281      if (messages.size() == 0 && broadcastTitle == null)
282      {
283        %>
284        No new messages.
285        <%
286      }
287      else
288      {
289        for (Message m : messages)
290        {
291          String fullName = m.getName();
292          String text = Values.trimString(m.getDescription(), 100);
293          %>
294          <div class="item">
295            <div class="headline">
296              <a href="javascript:viewMessage(<%=m.getId()%>)" title="<%=HTML.encodeTags(fullName)%>">
297              <span class="date"><%=dateTimeFormatter.format(m.getTimeSent())%></span>
298              <%=HTML.encodeTags(fullName)%></a>
299            </div>
300            <div class="text"><%=HTML.encodeTags(text)%></div>
301          </div>
302          <%
303        }
304      }
305      %>
306      </div>
307    </div>
308  </div>
309 
310  <%
311  if (hasHelp)
312  {
313    %>
314    <div class="absolutefull" style="left: 1em; right: 0.5em; top: auto; height: 14em; bottom: 1em; ">
315      <div class="absolutefull" style="height: 1.75em; overflow: hidden;"">
316      <h3 style="height: 100%;"><base:icon image="help.png" />Help</h3>
317      </div>
318      <div id="help" class="absolutefull welcomesection" style="top: 1.75em;">
319      <%
320      if (help != null)
321      {
322        %>
323        <a href="<%=help%>" target="Help"><base:icon image="bullet.png" />&nbsp;Help&hellip;</a><br>
324        <%
325      }
326      %>
327      <%
328      if (faq != null)
329      {
330        %>
331        <a href="<%=faq%>" target="FAQ"><base:icon image="bullet.png" />&nbsp;Frequently asked questions&hellip;</a><br>
332        <%
333      }
334      %>
335      <%
336      if (reportBug != null)
337      {
338        %>
339        <a href="<%=reportBug%>" target="ReportBug"><base:icon image="bug.png" />&nbsp;Report a bug&hellip;</a><br>
340        <%
341      }
342      %>
343      </div>
344    </div>
345    <%
346  }
347  %>
348 
349  </div>
350  <div class="absolutefull" style="width: 50%; left: auto;">
351 
352    <div class="absolutefull" style="left: 0.5em; right: 1em; bottom: 16em;">
353      <div class="absolutefull" style="height: 1.75em; overflow: hidden;"">
354      <h3 style="height: 100%;"><base:icon image="news.png" />News and announcements (<%=news.size()%>)
355        <%
356        if (RssNewsFeed.isEnabled()) 
357        {
358          %>
359          <base:icon image="rss.png" 
360            onclick="location.href='../info/news.rss'"
361            tooltip="Subscribe to news from this BASE server"
362            style="float: right; margin-top: 0.15em;"
363          />
364          <%
365        }
366        %>
367      </h3>
368      </div>
369      <div id="news" class="absolutefull news welcomesection" style="top: 1.75em;">
370        <%
371        if (news.size() == 0)
372        {
373          %>
374          Nothing new.
375          <%
376        }
377        else
378        {
379          for (News n : news)
380          {
381            %>
382            <div class="item">
383              <div class="headline">
384                <span class="date"><%=dateFormatter.format(n.getNewsDate())%></span>
385                <%=HTML.encodeTags(n.getName())%>
386              </div>
387              <div class="text"><%=HTML.niceFormat(n.getDescription())%></div>
388            </div>
389            <%
390          }
391        }
392        %>
393      </div>
394    </div>
395 
396    <div class="absolutefull" style="left: 0.5em; right: 1em; top: auto; height: 14em; bottom: 1em;">
397      <div class="absolutefull" style="height: 1.75em; overflow: hidden;"">
398      <h3 style="height: 100%;"><base:icon image="diskusage.png" />Disk usage</h3>
399      </div>
400      <div id="quota" class="absolutefull welcomesection" style="top: 1.75em;">
401      <%
402      if (quotaGroup != null)
403      {
404        %>
405        Using quota from group: <%=Base.getLinkedName(ID, quotaGroup, false, true)%>
406        <%
407      }
408      %>
409      <table style="width: 100%;">
410      <tr style="text-align: center;">
411        <th></th>
412        <th colspan="2">Primary location</th>
413        <th colspan="2">Secondary location</th>
414        <th>External</th>
415      </tr>
416      <tr style="text-align: center;">
417        <th></th>
418        <th>Used</th>
419        <th>Assigned</th>
420        <th>Used</th>
421        <th>Assigned</th>
422        <th>Used</th>
423      </tr>
424      <%
425        long myPrimaryUsage = user.getDiskUsage(totalQuotaType, Location.PRIMARY);
426        long myPrimaryQuota = quota.getQuotaValue(totalQuotaType, Location.PRIMARY);
427        long groupPrimaryQuota = groupQuota == null ? Quota.UNDEFINED : groupQuota.getQuotaValue(totalQuotaType, Location.PRIMARY);
428        long mySecondaryUsage = user.getDiskUsage(totalQuotaType, Location.SECONDARY);
429        long mySecondaryQuota = quota.getQuotaValue(totalQuotaType, Location.SECONDARY);
430        long groupSecondaryQuota = groupQuota == null ? Quota.UNDEFINED : groupQuota.getQuotaValue(totalQuotaType, Location.SECONDARY);
431        long myExternalUsage = user.getDiskUsage(totalQuotaType, Location.EXTERNAL);
432      %>
433      <tr style="text-align: center;">
434        <th>Total</th>
435        <td><%=getPrintableQuota(myPrimaryUsage, Quota.UNDEFINED)%></td>
436        <td><%=getPrintableQuota(myPrimaryQuota, groupPrimaryQuota)%></td>
437        <td><%=getPrintableQuota(mySecondaryUsage, Quota.UNDEFINED)%></td>
438        <td><%=getPrintableQuota(mySecondaryQuota, groupSecondaryQuota)%></td>
439        <td><%=getPrintableQuota(myExternalUsage, Quota.UNDEFINED)%></td>
440      </tr>
441      <tr>
442        <td colspan="6" style="border-top: 1px dotted #A0A0A0;"></td>
443      </tr>
444      <%
445      for (QuotaType qt : quotaTypes)
446      {
447        myPrimaryUsage = user.getDiskUsage(qt, Location.PRIMARY);
448        myPrimaryQuota = quota.getQuotaValue(qt, Location.PRIMARY);
449        groupPrimaryQuota = groupQuota == null ? Quota.UNDEFINED : groupQuota.getQuotaValue(qt, Location.PRIMARY);
450        mySecondaryUsage = user.getDiskUsage(qt, Location.SECONDARY);
451        mySecondaryQuota = quota.getQuotaValue(qt, Location.SECONDARY);
452        groupSecondaryQuota = groupQuota == null ? Quota.UNDEFINED : groupQuota.getQuotaValue(qt, Location.SECONDARY);
453        myExternalUsage = user.getDiskUsage(qt, Location.EXTERNAL);
454        %>
455        <tr style="text-align: center;">
456          <th><%=HTML.encodeTags(qt.getName())%></th>
457          <td><%=getPrintableQuota(myPrimaryUsage, Quota.UNDEFINED)%></td>
458          <td><%=getPrintableQuota(myPrimaryQuota, groupPrimaryQuota)%></td>
459          <td><%=getPrintableQuota(mySecondaryUsage, Quota.UNDEFINED)%></td>
460          <td><%=getPrintableQuota(mySecondaryQuota, groupSecondaryQuota)%></td>
461          <td><%=getPrintableQuota(myExternalUsage, Quota.UNDEFINED)%></td>
462        </tr>
463        <%
464      }
465      %>
466      <tr>
467        <td colspan="6" style="border-top: 1px dotted #A0A0A0;"></td>
468      </tr>
469      </table>
470      <base:buttongroup>
471        <base:button image="bullet.png" onclick="viewDiskUsage()" title="View details" />
472      </base:buttongroup>
473      </div>
474    </div>
475  </div>
476  </div>
477</base:body>
478</base:page>
479  <%
480}
481finally
482{
483  if (dc != null) dc.close();
484}
485%>
Note: See TracBrowser for help on using the repository browser.