Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj	(revision 12525)
@@ -146,4 +146,7 @@
     <Compile Include="WebApi\DataTransfer\ClientPage.cs" />
     <Compile Include="WebApi\DataTransfer\ClientStatus.cs" />
+    <Compile Include="WebApi\DataTransfer\Group.cs" />
+    <Compile Include="WebApi\DataTransfer\GroupDetails.cs" />
+    <Compile Include="WebApi\DataTransfer\GroupPage.cs" />
     <Compile Include="WebApi\DataTransfer\Integer.cs" />
     <Compile Include="WebApi\DataTransfer\Job.cs" />
@@ -154,4 +157,5 @@
     <Compile Include="WebApi\DataTransfer\TaskStateCount.cs" />
     <Compile Include="WebApi\DataTransfer\User.cs" />
+    <Compile Include="WebApi\GroupController.cs" />
     <Compile Include="WebApi\JavascriptUtils.cs" />
     <Compile Include="WebApi\JobController.cs" />
@@ -172,4 +176,10 @@
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
+    <Content Include="WebApp\groups\details\groupDetailsCtrl.js">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="WebApp\groups\groupsCtrl.js">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
     <Content Include="WebApp\jobs\details\jobDetailsCtrl.js">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -182,4 +192,7 @@
     </Content>
     <Content Include="WebApp\services\clientService.js">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="WebApp\services\groupService.js">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
@@ -224,4 +237,10 @@
     </None>
     <None Include="WebApp\clients\details\clientTaskDetailsDialog.cshtml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <Content Include="WebApp\groups\groups.cshtml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <None Include="WebApp\groups\details\groupDetails.cshtml">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ClientController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ClientController.cs	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ClientController.cs	(revision 12525)
@@ -86,4 +86,6 @@
                     State = clientInfo.SlaveState.ToString(),
                     LastUpdate = clientInfo.Time,
+                    GroupId = client.ResourceGroupId,
+                    GroupName = client.GroupName,
                     UpTime = offline ? 0 : upTime,
                     TotalUnavailableTime = timeData != null ? timeData.TotalUnavailableTime : 0,
@@ -124,4 +126,6 @@
                          CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
                          State = clientInfo.SlaveState.ToString(),
+                         GroupId = client.ResourceGroupId,
+                         GroupName = client.GroupName
                        });
           return new DT.ClientPage {
@@ -186,4 +190,102 @@
     }
 
+    public DT.ClientPage GetClientsByGroupId(Guid id, int page, int size, bool expired = false) {
+      using (var pm = PersistenceManager) {
+        var dimClientDao = pm.DimClientDao;
+        var factClientInfoDao = pm.FactClientInfoDao;
+        return pm.UseTransaction(() => {
+          var clients = expired ? dimClientDao.GetExpiredClients() : dimClientDao.GetActiveClients();
+          clients = clients.Where(x => x.ResourceGroupId == id);
+          var query = (from client in clients
+                       join info in factClientInfoDao.GetAll()
+                         on client.Id equals info.ClientId into clientInfoJoin
+                       from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
+                       let offline = (expired || clientInfo.SlaveState == SlaveState.Offline)
+                       select new DT.Client {
+                         Id = client.Id,
+                         Name = client.Name,
+                         TotalCores = clientInfo.NumTotalCores,
+                         UsedCores = offline ? 0 : clientInfo.NumUsedCores,
+                         TotalMemory = clientInfo.TotalMemory,
+                         UsedMemory = offline ? 0 : clientInfo.UsedMemory,
+                         CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
+                         State = clientInfo.SlaveState.ToString(),
+                         GroupId = client.ResourceGroupId,
+                         GroupName = client.GroupName
+                       });
+          return new DT.ClientPage {
+            TotalClients = query.Count(),
+            Clients = query.Skip((page - 1) * size)
+              .Take(size)
+              .ToList()
+          };
+        });
+      }
+    }
+
+    public IEnumerable<DT.ClientStatus> GetClientHistoryByGroupId(Guid id, DateTime start, DateTime end) {
+      TimeSpan ts = end - start;
+      int increment = 1;
+      double totalMinutes = ts.TotalMinutes;
+      while (totalMinutes > 5761) {
+        totalMinutes -= 5761;
+        increment += 5;
+      }
+      using (var pm = PersistenceManager) {
+        var factClientInfo = pm.FactClientInfoDao;
+        var dimClientDao = pm.DimClientDao;
+        var clientInfos = factClientInfo.GetAll()
+          .Where(x => x.Time >= start && x.Time <= end)
+          .OrderBy(x => x.Time)
+          .Join(dimClientDao.GetAll(),
+            fact => fact.ClientId,
+            client => client.Id,
+            (fact, client) => new {
+              client.ResourceGroupId,
+              fact.Time,
+              fact.CpuUtilization,
+              fact.NumTotalCores,
+              fact.NumUsedCores,
+              fact.TotalMemory,
+              fact.UsedMemory
+            })
+          .Where(x => x.ResourceGroupId == id)
+          .ToList();
+        var clientStatus = new DT.ClientStatus {
+          CpuUtilization = 0,
+          TotalCores = 0,
+          UsedCores = 0,
+          TotalMemory = 0,
+          UsedMemory = 0
+        };
+        int i = 1;
+        foreach (var clientInfo in clientInfos) {
+          clientStatus.CpuUtilization += clientInfo.CpuUtilization;
+          clientStatus.TotalCores += clientInfo.NumTotalCores;
+          clientStatus.UsedCores += clientInfo.NumUsedCores;
+          clientStatus.TotalMemory += clientInfo.TotalMemory;
+          clientStatus.UsedMemory += clientInfo.UsedMemory;
+          if (i >= increment) {
+            clientStatus.Timestamp = JavascriptUtils.ToTimestamp(clientInfo.Time);
+            clientStatus.CpuUtilization /= i;
+            clientStatus.TotalCores /= i;
+            clientStatus.UsedCores /= i;
+            clientStatus.TotalMemory /= i;
+            clientStatus.UsedMemory /= i;
+            yield return clientStatus;
+            clientStatus = new DT.ClientStatus {
+              CpuUtilization = 0,
+              TotalCores = 0,
+              UsedCores = 0,
+              TotalMemory = 0,
+              UsedMemory = 0
+            };
+            i = 1;
+          } else {
+            ++i;
+          }
+        }
+      }
+    }
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Client.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Client.cs	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Client.cs	(revision 12525)
@@ -33,4 +33,6 @@
     public string State { get; set; }
     public DateTime LastUpdate { get; set; }
+    public Guid? GroupId { get; set; }
+    public string GroupName { get; set; }
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ClientDetails.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ClientDetails.cs	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ClientDetails.cs	(revision 12525)
@@ -34,4 +34,6 @@
     public string State { get; set; }
     public DateTime LastUpdate { get; set; }
+    public Guid? GroupId { get; set; }
+    public string GroupName { get; set; }
     public long UpTime { get; set; }
     public long TotalUnavailableTime { get; set; }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Group.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Group.cs	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Group.cs	(revision 12525)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class Group {
+    public Guid Id { get; set; }
+    public string Name { get; set; }
+    public int TotalCores { get; set; }
+    public int UsedCores { get; set; }
+    public int TotalMemory { get; set; }
+    public int UsedMemory { get; set; }
+    public double CpuUtilization { get; set; }
+    public int Clients { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupDetails.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupDetails.cs	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupDetails.cs	(revision 12525)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class GroupDetails {
+    public Guid Id { get; set; }
+    public string Name { get; set; }
+    public int TotalCores { get; set; }
+    public int UsedCores { get; set; }
+    public int TotalMemory { get; set; }
+    public int UsedMemory { get; set; }
+    public double CpuUtilization { get; set; }
+    public int Clients { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupPage.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupPage.cs	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/GroupPage.cs	(revision 12525)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class GroupPage {
+    public int TotalGroups { get; set; }
+    public IEnumerable<Group> Groups { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/GroupController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/GroupController.cs	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/GroupController.cs	(revision 12525)
@@ -0,0 +1,121 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Web.Http;
+using HeuristicLab.Services.Hive;
+using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using DA = HeuristicLab.Services.Hive.DataAccess;
+using DT = HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi {
+  public class GroupController : ApiController {
+    private IPersistenceManager PersistenceManager {
+      get { return ServiceLocator.Instance.PersistenceManager; }
+    }
+
+    public DT.GroupDetails GetGroupDetails(Guid id) {
+      using (var pm = PersistenceManager) {
+        var dimClientDao = pm.DimClientDao;
+        var factClientInfoDao = pm.FactClientInfoDao;
+        return pm.UseTransaction(() => {
+          return (from client in dimClientDao.GetActiveClients().Where(x => x.ResourceGroupId == id)
+                  join info in factClientInfoDao.GetAll()
+                    on client.Id equals info.ClientId into clientInfoJoin
+                  from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
+                  let offline = (clientInfo.SlaveState == DA.SlaveState.Offline)
+                  select new {
+                    ResourceGroupId = client.ResourceGroupId,
+                    GroupName = client.GroupName,
+                    TotalCores = clientInfo.NumTotalCores,
+                    UsedCores = offline ? 0 : clientInfo.NumUsedCores,
+                    TotalMemory = clientInfo.TotalMemory,
+                    UsedMemory = offline ? 0 : clientInfo.UsedMemory,
+                    CpuUtilization = offline ? 0 : clientInfo.CpuUtilization
+                  })
+            .GroupBy(x => new { x.ResourceGroupId, x.GroupName })
+            .Select(x => new DT.GroupDetails {
+              Id = x.Key.ResourceGroupId ?? default(Guid),
+              Name = x.Key.GroupName,
+              Clients = x.Count(),
+              TotalCores = x.Sum(y => y.TotalCores),
+              UsedCores = x.Sum(y => y.UsedCores),
+              TotalMemory = x.Sum(y => y.TotalMemory),
+              UsedMemory = x.Sum(y => y.UsedMemory),
+              CpuUtilization = x.Average(y => y.CpuUtilization)
+            }).FirstOrDefault();
+        });
+      }
+    }
+
+    public DT.GroupPage GetGroups(int page, int size) {
+      using (var pm = PersistenceManager) {
+        var dimClientDao = pm.DimClientDao;
+        var factClientInfoDao = pm.FactClientInfoDao;
+        var data = (from client in dimClientDao.GetActiveClients()
+                    join info in factClientInfoDao.GetAll()
+                      on client.Id equals info.ClientId into clientInfoJoin
+                    from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
+                    let offline = (clientInfo.SlaveState == DA.SlaveState.Offline)
+                    select new {
+                      ResourceGroupId = client.ResourceGroupId,
+                      TotalCores = clientInfo.NumTotalCores,
+                      UsedCores = offline ? 0 : clientInfo.NumUsedCores,
+                      TotalMemory = clientInfo.TotalMemory,
+                      UsedMemory = offline ? 0 : clientInfo.UsedMemory,
+                      CpuUtilization = offline ? 0 : clientInfo.CpuUtilization
+                    }).GroupBy(x => x.ResourceGroupId).Select(x => new {
+                      GroupId = x.Key,
+                      Count = x.Count(),
+                      TotalCores = x.Sum(y => y.TotalCores),
+                      UsedCores = x.Sum(y => y.UsedCores),
+                      TotalMemory = x.Sum(y => y.TotalMemory),
+                      UsedMemory = x.Sum(y => y.UsedMemory),
+                      CpuUtilization = x.Average(y => y.CpuUtilization)
+                    });
+        var query = dimClientDao.GetAll()
+          .GroupBy(x => new { x.ResourceGroupId, x.GroupName })
+          .Select(x => new {
+            Id = x.Key.ResourceGroupId ?? default(Guid),
+            Name = x.Key.GroupName
+          });
+        return pm.UseTransaction(() => new DT.GroupPage {
+          TotalGroups = query.Count(),
+          Groups = query
+          .Skip((page - 1) * size)
+          .Take(size)
+          .Join(data, x => x.Id, y => y.GroupId,
+            (group, info) => new DT.Group {
+              Id = group.Id,
+              Name = group.Name,
+              Clients = info.Count,
+              TotalCores = info.TotalCores,
+              UsedCores = info.UsedCores,
+              TotalMemory = info.TotalMemory,
+              UsedMemory = info.UsedMemory,
+              CpuUtilization = info.CpuUtilization
+            }).ToList()
+        });
+      }
+    }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/JobController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/JobController.cs	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/JobController.cs	(revision 12525)
@@ -135,4 +135,18 @@
     }
 
+    [Authorize(Roles = HiveRoles.Administrator)]
+    public IEnumerable<DT.Job> GetAllActiveJobsFromAllUsers() {
+      using (var pm = PersistenceManager) {
+        var dimJobDao = pm.DimJobDao;
+        return pm.UseTransaction(() => {
+          return dimJobDao.GetAll()
+            .Where(x => x.DateCompleted == null)
+            .OrderByDescending(x => x.DateCreated)
+            .Select(x => ConvertToDT(x))
+            .ToList();
+        });
+      }
+    }
+
     private DT.Job ConvertToDT(DA.DimJob job) {
       return new DT.Job {
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/TaskController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/TaskController.cs	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/TaskController.cs	(revision 12525)
@@ -143,5 +143,5 @@
                        Exception = isAdministrator ? factTask.Exception : string.Empty
                      })
-                  .OrderByDescending(x => x.EndTime)
+                  .OrderByDescending(x => x.EndTime ?? DateTime.MaxValue)
                   .Skip((page - 1) * size)
                   .Take(size)
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clients.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clients.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clients.cshtml	(revision 12525)
@@ -14,4 +14,7 @@
     <li class="active">
         <a ng-href="#/statistics/clients">Clients</a>
+    </li>
+    <li>
+        <a ng-href="#/statistics/groups">Groups</a>
     </li>
     </ul>
@@ -31,4 +34,5 @@
                             <th>#</th>
                             <th>Client Name</th>
+                            <th>Group Name</th>
                             <th>Cores</th>
                             <th>Cpu Utilization</th>
@@ -40,4 +44,8 @@
                             <td>{{($index + 1)+((curClientsPage-1)*(clientsPageSize))}}</td>
                             <td>{{client.Name}}</td>
+                            <td>
+                                <a ng-show="client.GroupName" ng-href="#/statistics/groups/{{client.GroupId}}">{{client.GroupName}}</a>
+                                <span ng-hide="client.GroupName">No Group</span>
+                            </td>
                             <td>{{client.UsedCores}} / {{client.TotalCores}}</td>
                             <td>{{client.CpuUtilization | number: 2}} %</td>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetails.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetails.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetails.cshtml	(revision 12525)
@@ -14,4 +14,7 @@
             <a ng-href="#/statistics/clients">Clients</a>
         </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
+        </li>
     </ul>
 </header>
@@ -34,5 +37,5 @@
                                 <tr>
                                     <td class="text-left">Group:</td>
-                                    <td ng-show="client.GroupName">{{client.GroupName}}</td>
+                                    <td ng-show="client.GroupName"><a ng-href="#/statistics/groups/{{client.GroupId}}">{{client.GroupName}}</a></td>
                                     <td ng-hide="client.GroupName">None</td>
                                 </tr>
@@ -253,5 +256,5 @@
  <div class="default-filter-header text-center">
      <form class="form-inline">
-         <div class="form-group">
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
              <label for="fromDate">From:&nbsp;</label>
              <div class="input-group">
@@ -262,8 +265,8 @@
              </div>
          </div>
-         <div class="form-group">
-             <label for="fromDate">&nbsp;&nbsp;To:&nbsp;</label>
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
+             <label for="fromDate">To:&nbsp;</label>
              <div class="input-group">
-                 <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="toIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close"/>
+                 <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="toIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
                  <span class="input-group-btn">
                      <button type="button" class="btn btn-default" ng-click="openToDateSelection($event)"><i class="glyphicon glyphicon-calendar"></i></button>
@@ -271,8 +274,8 @@
              </div>
          </div>
-         <div class="btn-group">
-             <label class="btn btn-default" ng-click="updateCharts()">
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
+             <button type="button" class="btn btn-default" ng-click="updateCharts()">
                  Apply
-             </label>
+             </button>
          </div>
      </form>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetails.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetails.cshtml	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetails.cshtml	(revision 12525)
@@ -0,0 +1,183 @@
+﻿@using HeuristicLab.Services.Access.DataTransfer
+@using HeuristicLab.Services.Hive
+<header class="view-header">
+    <ul class="nav nav-list nav-list-topbar pull-left">
+        <li>
+            <a ng-href="#/statistics/jobs">Jobs</a>
+        </li>
+        @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+            <li>
+                <a ng-href="#/statistics/users">Users</a>
+            </li>
+        }
+        <li>
+            <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li class="active">
+            <a ng-href="#/statistics/groups">Groups</a>
+        </li>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Group Details</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="row">
+                        <div class="col-md-5">
+                            <table class="table table-no-border table-condensed table-auto-width table-content">
+                                <tr>
+                                    <td class="text-left">Name:</td>
+                                    <td class="text-right">{{group.Name}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Clients:</td>
+                                    <td class="text-right">{{group.Clients}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Cpu Utilization:</td>
+                                    <td class="text-right">{{group.CpuUtilization | number: 2}} %</td>
+                                </tr>
+                            </table>
+                        </div>
+                        <div class="col-md-5">
+                            <table class="table table-no-border table-condensed table-auto-width table-content">
+                                <tr>
+                                    <td class="text-left">TotalCores:</td>
+                                    <td class="text-right">{{group.TotalCores}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">UsedCores:</td>
+                                    <td class="text-right">{{group.UsedCores}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Memory:</td>
+                                    <td class="text-right">{{group.TotalMemory}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Used Memory:</td>
+                                    <td class="text-right">{{group.UsedMemory}}</td>
+                                </tr>
+                            </table>
+                        </div>
+
+                        <div class="col-md-2"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Clients</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                            <tr>
+                                <th>#</th>
+                                <th>Client Name</th>
+                                <th>Cores</th>
+                                <th>Cpu Utilization</th>
+                                <th>State</th>
+                                <th></th>
+                            </tr>
+                        </thead>
+                        <tr ng-repeat="client in clientPage.Clients">
+                            <td>{{($index + 1)+((curClientsPage-1)*(clientsPageSize))}}</td>
+                            <td>{{client.Name}}</td>
+                            <td>{{client.UsedCores}} / {{client.TotalCores}}</td>
+                            <td>{{client.CpuUtilization | number: 2}} %</td>
+                            <td>{{client.State}}</td>
+                            <td>
+                                <a ng-href="#/statistics/clients/{{client.Id}}">Details</a>
+                            </td>
+                        </tr>
+                        <tr ng-hide="clientPage.Clients.length">
+                            <td colspan="6" class="text-center">No clients found!</td>
+                        </tr>
+                    </table>
+                    <div class="row text-center" ng-show="clientPage.TotalClients > clientPage.Clients.length">
+                        <pagination max-size="10" total-items="clientPage.TotalClients" ng-model="curClientsPage" ng-change="changeClientsPage()" items-per-page="clientsPageSize"
+                                    boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+ </div>
+
+ <div class="default-filter-header text-center">
+     <form class="form-inline">
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
+             <label for="fromDate">From:&nbsp;</label>
+             <div class="input-group">
+                 <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="fromDate" is-open="fromIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
+                 <span class="input-group-btn">
+                     <button type="button" class="btn btn-default" ng-click="openFromDateSelection($event)"><i class="glyphicon glyphicon-calendar"></i></button>
+                 </span>
+             </div>
+         </div>
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
+             <label for="fromDate">To:&nbsp;</label>
+             <div class="input-group">
+                 <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="toIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
+                 <span class="input-group-btn">
+                     <button type="button" class="btn btn-default" ng-click="openToDateSelection($event)"><i class="glyphicon glyphicon-calendar"></i></button>
+                 </span>
+             </div>
+         </div>
+         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
+             <button type="button" class="btn btn-default" ng-click="updateCharts()">
+                 Apply
+             </button>
+         </div>
+     </form>
+ </div>
+
+ <div class="default-view-container">
+     <div class="row">
+         <div class="col-lg-12">
+             <div class="panel panel-default">
+                 <div class="panel-heading">
+                     <h3 class="panel-title">CPU Utilization Chart</h3>
+                 </div>
+                 <div class="panel-body">
+                     <flot dataset="cpuSeries" options="chartOptions"></flot>
+                 </div>
+             </div>
+         </div>
+     </div>
+
+     <div class="row">
+         <div class="col-lg-12">
+             <div class="panel panel-default">
+                 <div class="panel-heading">
+                     <h3 class="panel-title">Core Chart</h3>
+                 </div>
+                 <div class="panel-body">
+                     <flot dataset="coreSeries" options="fillChartOptions"></flot>
+                 </div>
+             </div>
+         </div>
+     </div>
+
+     <div class="row">
+         <div class="col-lg-12">
+             <div class="panel panel-default">
+                 <div class="panel-heading">
+                     <h3 class="panel-title">Memory Chart</h3>
+                 </div>
+                 <div class="panel-body">
+                     <flot dataset="memorySeries" options="fillChartOptions"></flot>
+                 </div>
+             </div>
+         </div>
+     </div>
+ </div>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetailsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetailsCtrl.js	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/details/groupDetailsCtrl.js	(revision 12525)
@@ -0,0 +1,138 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.groupDetailsCtrl',
+        ['$scope', '$stateParams', '$interval', 'app.statistics.clientService', 'app.statistics.groupService',
+        function ($scope, $stateParams, $interval, clientService, groupService) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.curClientsPage = 1;
+            $scope.clientsPageSize = 20;
+
+            var getGroupDetails = function() {
+                groupService.getGroupDetails({ id: $stateParams.id }, function (group) {
+                    $scope.group = group;
+                });
+            };
+
+            var getClients = function () {
+                clientService.getClientsByGroupId({id: $stateParams.id, page: $scope.curClientsPage, size: $scope.clientsPageSize, expired: false },
+                    function (clientPage) {
+                        $scope.clientPage = clientPage;
+                    }
+                );
+            };
+
+            // charts
+            $scope.chartOptions = {
+                grid: {
+                    borderWidth: 1,
+                    labelMargin: 15
+                },
+                series: {
+                    shadowSize: 0
+                },
+                yaxis: {
+                    min: 0,
+                    max: 100,
+                    zoomRange: false,
+                    panRange: false
+                },
+                xaxis: {
+                    mode: "time",
+                    twelveHourClock: false
+                }
+            };
+
+            $scope.fillChartOptions = {
+                grid: {
+                    borderWidth: 1,
+                    labelMargin: 15
+                },
+                series: {
+                    shadowSize: 0,
+                    lines: {
+                        show: true,
+                        fill: true
+                    }
+                },
+                yaxis: {
+                    zoomRange: false,
+                    panRange: false
+                },
+                xaxis: {
+                    mode: "time",
+                    twelveHourClock: false
+                }
+            };
+
+            $scope.fromDate = new Date();
+            $scope.toDate = new Date();
+
+            $scope.fromIsOpen = false;
+            $scope.toIsOpen = false;
+
+            $scope.openFromDateSelection = function ($event) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                $scope.toIsOpen = false;
+                $scope.fromIsOpen = true;
+            };
+
+            $scope.openToDateSelection = function ($event) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                $scope.fromIsOpen = false;
+                $scope.toIsOpen = true;
+            };
+
+            $scope.dateOptions = {
+                formatYear: 'yy',
+                startingDay: 1
+            };
+
+            $scope.cpuSeries = [[]];
+            $scope.coreSeries = [[]];
+            $scope.memorySeries = [[]];
+
+            $scope.updateCharts = function () {
+                clientService.getClientHistoryByGroupId({ id: $stateParams.id, start: ConvertFromDate($scope.fromDate), end: ConvertToDate($scope.toDate) }, function (status) {
+                    var noOfStatus = status.length;
+                    var cpuSeries = [];
+                    var coreSeries = [[], []];
+                    var memorySeries = [[], []];
+                    for (var i = 0; i < noOfStatus; ++i) {
+                        var curStatus = status[i];
+                        var cpuData = Math.round(curStatus.CpuUtilization);
+                        cpuSeries.push([curStatus.Timestamp, cpuData]);
+                        coreSeries[0].push([curStatus.Timestamp, curStatus.TotalCores]);
+                        coreSeries[1].push([curStatus.Timestamp, curStatus.UsedCores]);
+                        memorySeries[0].push([curStatus.Timestamp, curStatus.TotalMemory]);
+                        memorySeries[1].push([curStatus.Timestamp, curStatus.UsedMemory]);
+                    }
+                    $scope.cpuSeries = [{ data: cpuSeries, label: "&nbsp;CPU Utilization", color: "#f7921d" }];
+                    $scope.coreSeries = [
+                        { data: coreSeries[0], label: "&nbsp;Total Cores", color: "LightGreen" },
+                        { data: coreSeries[1], label: "&nbsp;Used Cores", color: "LightPink" }
+                    ];
+                    $scope.memorySeries = [
+                        { data: memorySeries[0], label: "&nbsp;Total Memory", color: "LightGreen" },
+                        { data: memorySeries[1], label: "&nbsp;Used Memory", color: "LightPink" }
+                    ];
+
+                });
+            };
+
+            var update = function () {
+                getGroupDetails();
+                getClients();
+            };
+
+            $scope.updateInterval = $interval(update, $scope.interval);
+            var cancelInterval = $scope.$on('$locationChangeSuccess', function () {
+                $interval.cancel($scope.updateInterval);
+                cancelInterval();
+            });
+            update(); // init page
+            $scope.updateCharts();
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groups.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groups.cshtml	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groups.cshtml	(revision 12525)
@@ -0,0 +1,63 @@
+﻿@using HeuristicLab.Services.Access.DataTransfer
+@using HeuristicLab.Services.Hive
+<header class="view-header">
+    <ul class="nav nav-list nav-list-topbar pull-left">
+        <li>
+            <a ng-href="#/statistics/jobs">Jobs</a>
+        </li>
+        @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+            <li>
+                <a ng-href="#/statistics/users">Users</a>
+            </li>
+        }
+        <li>
+            <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li class="active">
+            <a ng-href="#/statistics/groups">Groups</a>
+        </li>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Groups</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                        <tr>
+                            <th>#</th>
+                            <th>Group Name</th>
+                            <th>Cores</th>
+                            <th>Cpu Utilization</th>
+                            <th>Clients</th>
+                            <th></th>
+                        </tr>
+                        </thead>
+                        <tr ng-repeat="group in groupPage.Groups">
+                            <td>{{($index + 1)+((curGroupsPage-1)*(groupsPageSize))}}</td>
+                            <td>{{group.Name}}</td>
+                            <td>{{group.UsedCores}} / {{group.TotalCores}}</td>
+                            <td>{{group.CpuUtilization | number: 2}} %</td>
+                            <td>{{group.Clients}}</td>
+                            <td>
+                                <a ng-href="#/statistics/groups/{{group.Id}}">Details</a>
+                            </td>
+                        </tr>
+                        <tr ng-hide="groupPage.Groups.length">
+                            <td colspan="6" class="text-center">No groups found!</td>
+                        </tr>
+                    </table>
+                    <div class="row text-center" ng-show="groupPage.TotalGroups > groupPage.Groups.length">
+                        <pagination max-size="10" total-items="groupPage.TotalGroups" ng-model="curGroupsPage" ng-change="changeGroupsPage()" items-per-page="groupsPageSize"
+                                    boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groupsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groupsCtrl.js	(revision 12525)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/groups/groupsCtrl.js	(revision 12525)
@@ -0,0 +1,34 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.groupsCtrl',
+        ['$scope', '$interval', 'app.statistics.groupService',
+        function ($scope, $interval, groupService) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.curGroupsPage = 1;
+            $scope.groupsPageSize = 20;
+
+            var getGroups = function () {
+                groupService.getGroups({ page: $scope.curGroupsPage, size: $scope.groupsPageSize },
+                    function (groupPage) {
+                        $scope.groupPage = groupPage;
+                    }
+                );
+            };
+
+            var update = function () {
+                getGroups();
+            };
+
+            $scope.changeGroupsPage = function () {
+                update();
+            };
+
+            $scope.updateInterval = $interval(update, $scope.interval);
+            var cancelInterval = $scope.$on('$locationChangeSuccess', function () {
+                $interval.cancel($scope.updateInterval);
+                cancelInterval();
+            });
+            update(); // init page
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetails.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetails.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetails.cshtml	(revision 12525)
@@ -13,4 +13,7 @@
         <li>
             <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
         </li>
     </ul>
@@ -97,5 +100,5 @@
                         <div class="col-md-2"></div>
                         </div>
-                </div>
+                    </div>
 
             </div>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetailsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetailsCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetailsCtrl.js	(revision 12525)
@@ -14,4 +14,6 @@
                     if (isDefined($scope.job.DateCompleted)) {
                         $scope.job.DateCompleted = CSharpDateToString($scope.job.DateCompleted);
+                    } else {
+                        $scope.job.DateCompleted = 'Not completed yet';
                     }
                     $scope.job.CalculatingWaitingRatio = ($scope.job.TotalCalculatingTime / $scope.job.TotalWaitingTime);
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobs.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobs.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobs.cshtml	(revision 12525)
@@ -13,4 +13,7 @@
         <li>
             <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
         </li>
     </ul>
@@ -54,5 +57,46 @@
         </div>
     </div>
-
+    @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+        <div class="row">
+            <div class="col-lg-12">
+                <div class="panel panel-default">
+                    <div class="panel-heading">
+                        <h3 class="panel-title">Current Active Jobs</h3>
+                    </div>
+                    <div class="panel-body">
+                        <table class="table table-hover table-condensed">
+                            <thead>
+                                <tr>
+                                    <th>#</th>
+                                    <th>Job Name</th>
+                                    <th>User Name</th>
+                                    <th>Date Created</th>
+                                    <th>Progress</th>
+                                    <th></th>
+                                </tr>
+                            </thead>
+                            <tr ng-repeat="job in allUsersJobs">
+                                <td>{{$index + 1}}</td>
+                                <td>{{job.Name}}</td>
+                                <td>
+                                    <a ng-href="#/statistics/users/{{job.UserId}}" ng-show="job.UserName">{{job.UserName}}</a>
+                                </td>
+                                <td>{{job.DateCreated}}</td>
+                                <td>
+                                    <progressbar class="progress active" max="job.TotalTasks" value="job.CompletedTasks" type="success"><i style="color:black; white-space:nowrap;">{{job.CompletedTasks}} / {{job.TotalTasks}}</i></progressbar>
+                                </td>
+                                <td>
+                                    <a ng-href="#/statistics/jobs/{{job.Id}}">Details</a>
+                                </td>
+                            </tr>
+                            <tr ng-hide="allUsersJobs.length">
+                                <td colspan="6" class="text-center">No active jobs found!</td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    }
     <div class="row">
         <div class="col-lg-12">
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobsCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobsCtrl.js	(revision 12525)
@@ -3,4 +3,6 @@
     module.controller('app.statistics.jobsCtrl',
         ['$scope', '$interval', 'app.statistics.jobService', function ($scope, $interval, jobService) {
+            var first = true;
+            $scope.isAdministrator = false;
             $scope.interval = defaultPageUpdateInterval;
             $scope.completedJobCurPage = 1;
@@ -30,4 +32,15 @@
             };
 
+            var getAllActiveJobsFromAllUsers = function () {
+                jobService.getAllActiveJobsFromAllUsers({}, function (jobs) {
+                    $scope.isAdministrator = true;
+                    $scope.allUsersJobs = jobs;
+                    var length = $scope.allUsersJobs.length;
+                    for (var i = 0; i < length; ++i) {
+                        $scope.allUsersJobs[i].DateCreated = CSharpDateToString($scope.allUsersJobs[i].DateCreated);
+                    }
+                });
+            };
+
             $scope.changeCompletedJobPage = function () {
                 update();
@@ -36,6 +49,10 @@
             var update = function () {
                 getAllJobs();
+                if (first || $scope.isAdministrator) {
+                    getAllActiveJobsFromAllUsers();
+                }
                 getCompletedJobs();
             };
+
 
             $scope.updateInterval = $interval(update, $scope.interval);
@@ -45,4 +62,5 @@
             });
             update(); // init page
+            first = false;
         }]
     );
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/clientService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/clientService.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/clientService.js	(revision 12525)
@@ -7,5 +7,7 @@
                 getClientDetails: { method: 'GET', params: { action: 'GetClientDetails' } },
                 getClients: { method: 'GET', params: { action: 'GetClients' } },
-                getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, isArray: true }
+                getClientsByGroupId: { method: 'GET', params: { action: 'GetClientsByGroupId' } },
+                getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, isArray: true },
+                getClientHistoryByGroupId: { method: 'GET', params: { action: 'GetClientHistoryByGroupId' }, isArray: true }
             });
         }]
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/jobService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/jobService.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/jobService.js	(revision 12525)
@@ -10,5 +10,6 @@
                 getJobsByUserId: { method: 'GET', params: { action: 'GetJobsByUserId' } },
                 getAllJobsByUserId: { method: 'GET', params: { action: 'GetAllJobsByUserId'}, isArray: true },
-                getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true }
+                getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true },
+                getAllActiveJobsFromAllUsers: { method: 'GET', params: { action: 'GetAllActiveJobsFromAllUsers' }, isArray: true }
             });
         }]
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetails.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetails.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetails.cshtml	(revision 12525)
@@ -12,4 +12,7 @@
         <li>
             <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
         </li>
     </ul>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml	(revision 12525)
@@ -12,4 +12,7 @@
         <li>
             <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
         </li>
     </ul>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js	(revision 12525)
@@ -10,4 +10,5 @@
         'WebApp/services/userService.js',
         'WebApp/services/clientService.js',
+        'WebApp/services/groupService.js',
         'WebApp/jobs/jobsCtrl.js',
         'WebApp/jobs/details/jobDetailsCtrl.js',
@@ -17,5 +18,7 @@
         'WebApp/clients/details/clientTaskDetailsDialogCtrl.js',
         'WebApp/users/usersCtrl.js',
-        'WebApp/users/details/userDetailsCtrl.js'
+        'WebApp/users/details/userDetailsCtrl.js',
+        'WebApp/groups/groupsCtrl.js',
+        'WebApp/groups/details/groupDetailsCtrl.js'
     ];
     plugin.view = 'WebApp/jobs/jobs.cshtml';
@@ -27,5 +30,7 @@
         new Route('clients/:id', 'WebApp/clients/details/clientDetails.cshtml', 'app.statistics.clientDetailsCtrl'),
         new Route('users', 'WebApp/users/users.cshtml', 'app.statistics.usersCtrl'),
-        new Route('users/:id', 'WebApp/users/details/userDetails.cshtml', 'app.statistics.userDetailsCtrl')
+        new Route('users/:id', 'WebApp/users/details/userDetails.cshtml', 'app.statistics.userDetailsCtrl'),
+        new Route('groups', 'WebApp/groups/groups.cshtml', 'app.statistics.groupsCtrl'),
+        new Route('groups/:id', 'WebApp/groups/details/groupDetails.cshtml', 'app.statistics.groupDetailsCtrl')
     ];
     var menu = app.getMenu();
@@ -33,5 +38,5 @@
     section.addEntry({
         name: 'Statistics',
-        route: '#/statistics/jobs',
+        route: '#/statistics',
         icon: 'glyphicon glyphicon-stats',
         entries: []
