Changeset 5465


Ignore:
Timestamp:
Nov 1, 2010, 3:01:57 PM (12 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1540: Save list of recently active projects

The 'select project' menu has been changed to display the most recent projects at the top. If the user is a member of more projects those are displayed below a separator. The max number has been reduced from 20 to 15 to allow for some of the extra space needed. The '..x more' entry now applies a filter (temporary thanks to #1531) so that only those projects that are not in the menu are displayed in the list.

The fix also reorders the projects on the View->Home page so that the most recently used are listed first.

Location:
branches/2.16-stable
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/2.16-stable/src/clients/web/net/sf/basedb/clients/web/resources/menu.properties

    r5413 r5465  
    4747menu.projects.tooltip.1 Switch active project
    4848menu.projects.tooltip.0 Set active project
     49recentprojects.title Recently used projects
    4950noactiveproject.title no active project
    5051noactiveproject.tooltip.1 No project is active
  • branches/2.16-stable/www/include/menu.jsp

    r5452 r5465  
    5151  import="net.sf.basedb.core.Include"
    5252  import="net.sf.basedb.core.ItemResultList"
     53  import="net.sf.basedb.core.Type"
    5354  import="net.sf.basedb.core.query.Orders"
    5455  import="net.sf.basedb.core.query.Order"
    5556  import="net.sf.basedb.core.query.Hql"
     57  import="net.sf.basedb.core.query.Restrictions"
     58  import="net.sf.basedb.core.query.Expressions"
    5659  import="net.sf.basedb.clients.web.Base"
    5760  import="net.sf.basedb.clients.web.util.HTML"
     
    7376  import="java.util.Arrays"
    7477  import="java.util.Iterator"
     78  import="java.util.Set"
     79  import="java.util.HashSet"
    7580%>
    7681<%@ taglib prefix="m" uri="/WEB-INF/menu.tld" %>
     
    97102    style="display: none"
    98103    >
     104    <%
     105    final DbControl dc = sc.newDbControl();
     106    boolean menuSeparatorBeforeDeactivate = true;
     107    try
     108    {
     109      List<Project> projects = new ArrayList<Project>();
     110      int lastRecentActiveIndex = 0;
     111      // 1. Load the most recently active projects
     112      String tmp = sc.getUserClientSetting("projects.recentActive");
     113      Set<Integer> recentProjects = new HashSet<Integer>();
     114      if (tmp != null)
     115      {
     116        for (String id : tmp.split(":"))
     117        {
     118          try
     119          {
     120            Project p = Project.getById(dc, Values.getInt(id));
     121            if (!p.isRemoved())
     122            {
     123              recentProjects.add(p.getId());
     124              projects.add(p);
     125              lastRecentActiveIndex++;
     126            }
     127          }
     128          catch (RuntimeException ex)
     129          {}
     130        }
     131      }
     132     
     133      // 2. Load more projects
     134      final ItemContext projectCC = sc.getCurrentContext(Item.PROJECT);
     135      final ItemQuery<Project> projectQuery = Project.getQuery();
     136      projectQuery.include(Include.MINE, Include.SHARED);
     137      projectQuery.restrict(Restrictions.not(Restrictions.in(Hql.property("id"), Expressions.parameter("projects"))));
     138      projectQuery.setParameter("projects", recentProjects, Type.INT);
     139      Order projectSortOrder = projectCC.getSortOrder();
     140      if (projectSortOrder != null) projectQuery.order(projectSortOrder);
     141      projectQuery.order(Orders.asc(Hql.property("name")));
     142      projectQuery.setCacheResult(true);
     143      projects.addAll(projectQuery.list(dc));
     144      boolean breakAt15 = projects.size() > 16;
     145      int index = 0;
     146      String thisIsTheActiveProject = menu.getString("activeproject.tooltip");
     147      String thisIsNotTheActiveProject = menu.getString("inactiveproject.tooltip");
     148      if (lastRecentActiveIndex > 0)
     149      {
     150        %>
     151        <m:menuitem
     152          title="<%=menu.getString("recentprojects.title")%>"
     153          style="font-weight: bold; color: #000000; background: #e8e8e8;"
     154          enabled="false"
     155        />
     156        <m:menuseparator />
     157        <%
     158      }
     159      Set<Integer> shownProjects = new HashSet<Integer>();
     160      for (Project p : projects)
     161      {
     162        if (index == 15 && breakAt15) break;
     163        index++;
     164        int projectId = p.getId();
     165        boolean active = activeProjectId == projectId;
     166        String prefix = index <= lastRecentActiveIndex ? index + ". " : "";
     167        shownProjects.add(p.getId());
     168        String link = active ?
     169          "Menu.openUrl('"+root+"my_base/projects/index.jsp?ID="+ID+"&cmd=ViewItem&item_id=" + projectId + "')" :
     170          "Main.openPopup('"+root+"my_base/projects/set_active.jsp?ID="+ID+"&project_id="+p.getId()+"', 'ActivateProject', 300, 140)";
     171        %>
     172        <m:menuitem
     173          title="<%=prefix + HTML.encodeTags(p.getName())%>"
     174          style="<%=active ? "color: #000000; font-weight: bold;" : null %>"
     175          onclick="<%=link%>"
     176          icon="<%=active ? "checkedmenu.gif" : null%>"
     177          tooltip="<%=active ? thisIsTheActiveProject : thisIsNotTheActiveProject%>"
     178        />
     179        <%
     180        if (index == lastRecentActiveIndex)
     181        {
     182          %>
     183          <m:menuseparator />
     184          <%
     185          menuSeparatorBeforeDeactivate = false;
     186        }
     187        else
     188        {
     189          menuSeparatorBeforeDeactivate = true;
     190        }
     191      }
     192      if (breakAt15)
     193      {
     194        int more = projects.size() - 15;
     195        %>
     196        <m:menuitem
     197          title="<%="…" + menu.getString("moreprojects.title", Integer.toString(more))%>"
     198          onclick="<%="Menu.openUrl('"+root+"my_base/projects/index.jsp?ID="+ID+"&cmd=UpdateContext&tmpfilter:INT:id=<>"+Values.getString(shownProjects, "|", true)+"')"%>"
     199          tooltip="<%=menu.getString("moreprojects.tooltip")%>"
     200        />
     201        <%
     202      }
     203    }
     204    catch (Throwable t)
     205    {
     206      t.printStackTrace();
     207      menuSeparatorBeforeDeactivate = false;
     208      %>
     209      <m:menuseparator />
     210      <m:menuitem
     211        title="<%=menu.getString("projects.error.title")%>"
     212        tooltip="<%=menu.getString("projects.error.tooltip", t.getMessage())%>"
     213        enabled="false"
     214        icon="error.gif"
     215      />
     216      <%
     217    }
     218    finally
     219    {
     220      if (dc != null) dc.close();
     221    }
     222    if (menuSeparatorBeforeDeactivate)
     223    {
     224      %>
     225      <m:menuseparator />
     226      <%
     227    }
     228    %>
    99229    <m:menuitem
    100230      title="<%="<i>- " + menu.getString("noactiveproject.title") + " -</i>"%>"
     
    104234      tooltip="<%=menu.getString("noactiveproject.tooltip", activeProjectId == 0)%>"
    105235    />
    106     <%
    107     final DbControl dc = sc.newDbControl();
    108     try
    109     {
    110       final ItemContext projectCC = sc.getCurrentContext(Item.PROJECT);
    111       final ItemQuery<Project> projectQuery = Project.getQuery();
    112       projectQuery.include(Include.MINE, Include.SHARED);
    113       Order projectSortOrder = projectCC.getSortOrder();
    114       if (projectSortOrder != null) projectQuery.order(projectSortOrder);
    115       projectQuery.order(Orders.asc(Hql.property("name")));
    116       projectQuery.setCacheResult(true);
    117       ItemResultList<Project> projects = projectQuery.list(dc);
    118       boolean breakAt20 = projects.size() > 25;
    119       int index = 0;
    120       String thisIsTheActiveProject = menu.getString("activeproject.tooltip");
    121       String thisIsNotTheActiveProject = menu.getString("inactiveproject.tooltip");
    122       for (Project p : projects)
    123       {
    124         if (index == 20 && breakAt20) break;
    125         index++;
    126         int projectId = p.getId();
    127         boolean active = activeProjectId == projectId;
    128         %>
    129         <m:menuitem
    130           title="<%=HTML.encodeTags(p.getName())%>"
    131           style="<%=active ? "color: #000000; font-weight: bold;" : null %>"
    132           onclick="<%="Main.openPopup('"+root+"my_base/projects/set_active.jsp?ID="+ID+"&project_id="+p.getId()+"', 'ActivateProject', 300, 140)"%>"
    133           icon="<%=active ? "checkedmenu.gif" : null%>"
    134           enabled="<%=!active%>"
    135           tooltip="<%=active ? thisIsTheActiveProject : thisIsNotTheActiveProject%>"
    136         />
    137         <%
    138       }
    139       if (breakAt20)
    140       {
    141         int more = projects.size() - 20;
    142         %>
    143         <m:menuseparator />
    144         <m:menuitem
    145           title="<%=menu.getString("moreprojects.title", Integer.toString(more))%>"
    146           onclick="<%="Menu.openUrl('"+root+"my_base/projects/index.jsp?ID="+ID+"')"%>"
    147           tooltip="<%=menu.getString("moreprojects.tooltip")%>"
    148         />
    149         <%
    150       }
    151     }
    152     catch (Throwable t)
    153     {
    154       t.printStackTrace();
    155       %>
    156       <m:menuseparator />
    157       <m:menuitem
    158         title="<%=menu.getString("projects.error.title")%>"
    159         tooltip="<%=menu.getString("projects.error.tooltip", t.getMessage())%>"
    160         enabled="false"
    161         icon="error.gif"
    162       />
    163       <%
    164     }
    165     finally
    166     {
    167       if (dc != null) dc.close();
    168     }
    169     %>
    170236  </m:menu>
    171237  <%
  • branches/2.16-stable/www/my_base/index.jsp

    r5426 r5465  
    5555  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
    5656  import="net.sf.basedb.util.Values"
    57   import="java.util.Date"
     57  import="java.util.Date"
     58  import="java.util.List"
     59  import="java.util.ArrayList"
     60  import="java.util.Set"
     61  import="java.util.HashSet"
    5862%>
    5963<%@ taglib
     
    108112  ItemResultList<Message> messages = messageQuery.list(dc);
    109113 
     114  List<Project> projects = new ArrayList<Project>();
     115  String tmp = sc.getUserClientSetting("projects.recentActive");
     116  Set<Integer> recentProjects = new HashSet<Integer>();
     117  if (tmp != null)
     118  {
     119    for (String id : tmp.split(":"))
     120    {
     121      try
     122      {
     123        Project p = Project.getById(dc, Values.getInt(id));
     124        if (!p.isRemoved())
     125        {
     126          recentProjects.add(p.getId());
     127          projects.add(p);
     128        }
     129      }
     130      catch (RuntimeException ex)
     131      {}
     132    }
     133  }
    110134  ItemQuery<Project> projectQuery = Project.getQuery();
    111135  projectQuery.order(Orders.asc(Hql.property("name")));
    112136  projectQuery.include(Include.MINE, Include.SHARED);
    113   ItemResultList<Project> projects = projectQuery.list(dc);
     137  projectQuery.restrict(Restrictions.not(Restrictions.in(Hql.property("id"), Expressions.parameter("projects"))));
     138  projectQuery.setParameter("projects", recentProjects, Type.INT);
     139  projects.addAll(projectQuery.list(dc));
    114140 
    115141  QuotaType totalQuotaType = QuotaType.getById(dc, SystemItems.getId(QuotaType.TOTAL));
  • branches/2.16-stable/www/my_base/projects/set_active.jsp

    r5426 r5465  
    3232  import="net.sf.basedb.core.Include"
    3333  import="net.sf.basedb.core.ItemContext"
     34  import="net.sf.basedb.core.StringUtil"
    3435  import="net.sf.basedb.clients.web.Base"
    3536  import="net.sf.basedb.util.Values"
    3637  import="net.sf.basedb.clients.web.util.HTML"
     38  import="java.util.List"
     39  import="java.util.ArrayList"
     40  import="java.util.Arrays"
    3741%>
    3842<%@ taglib
     
    6064  sc.setActiveProject(p);
    6165  sc.setUserClientSetting("projects.lastactive", projectId == 0 ? null : Integer.toString(projectId));
     66  if (projectId != 0)
     67  {
     68    String recent = sc.getUserClientSetting("projects.recentActive");
     69    List<String> recentActive = null;
     70    if (recent == null)
     71    {
     72      recentActive = new ArrayList<String>();
     73    }
     74    else
     75    {
     76      // Need a new list since Arrays.asList returns a read-only list
     77      recentActive = new ArrayList<String>(Arrays.asList(recent.split(":")));
     78    }
     79    String thisProject = Integer.toString(projectId);
     80    recentActive.remove(thisProject);
     81    recentActive.add(0, thisProject);
     82    int maxRecent = Values.getInt(sc.getUserClientSetting("menu.mostRecent.maxViewed"), 6);
     83    if (recentActive.size() > maxRecent) recentActive = recentActive.subList(0, maxRecent);
     84    sc.setUserClientSetting("projects.recentActive", StringUtil.join(recentActive, ":", true));
     85  }
    6286  sc.setSessionSetting("menu.standard.html", null);
    6387  if (p == null)
Note: See TracChangeset for help on using the changeset viewer.