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 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clients.cshtml	(revision 12516)
@@ -1,21 +1,102 @@
 ﻿@using HeuristicLab.Services.Access.DataTransfer
 @using HeuristicLab.Services.Hive
-@if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
 <header class="view-header">
     <ul class="nav nav-list nav-list-topbar pull-left">
-        <li>
-            <a ng-href="#/statistics/jobs">Jobs</a>
-        </li>
+    <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 class="active">
-            <a ng-href="#/statistics/clients">Clients</a>
-        </li>
+    }
+    <li class="active">
+        <a ng-href="#/statistics/clients">Clients</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">Current 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 class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Expired 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 expiredClientPage.Clients">
+                            <td>{{($index + 1)+((curExpiredClientsPage-1)*(expiredClientsPageSize))}}</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="expiredClientPage.Clients.length">
+                            <td colspan="6" class="text-center">No expired clients found!</td>
+                        </tr>
+                    </table>
+                    <div class="row text-center" ng-show="expiredClientPage.TotalClients > expiredClientPage.Clients.length">
+                        <pagination max-size="10" total-items="expiredClientPage.TotalClients" ng-model="curExpiredClientsPage" ng-change="changeExpiredClientsPage()" items-per-page="expiredClientsPageSize"
+                                    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/clients/clientsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clientsCtrl.js	(revision 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clientsCtrl.js	(revision 12516)
@@ -2,6 +2,48 @@
     var module = appStatisticsPlugin.getAngularModule();
     module.controller('app.statistics.clientsCtrl',
-        ['$scope', 'app.statistics.data.service', function($scope, statisticsService) {
-            
+        ['$scope', '$interval', 'app.statistics.clientService',
+        function ($scope, $interval, clientService) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.curClientsPage = 1;
+            $scope.clientsPageSize = 20;
+            $scope.curExpiredClientsPage = 1;
+            $scope.expiredClientsPageSize = 20;
+
+            var getClients = function () {
+                clientService.getClients({ page: $scope.curClientsPage, size: $scope.clientsPageSize, expired: false },
+                    function (clientPage) {
+                        $scope.clientPage = clientPage;
+                    }
+                );
+            };
+
+            var getExpiredClients = function() {
+                clientService.getClients({ page: $scope.curExpiredClientsPage, size: $scope.expiredClientsPageSize, expired: true },
+                    function (clientPage) {
+                        $scope.expiredClientPage = clientPage;
+                    }
+                );
+            };
+
+            var update = function () {
+                getClients();
+                getExpiredClients();
+            };
+
+            $scope.changeClientsPage = function () {
+                update();
+            };
+
+            $scope.changeExpiredClientsPage = 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/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 12516)
@@ -0,0 +1,320 @@
+﻿@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 class="active">
+            <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-9 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Client Details</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="row">
+                        <div class="col-md-6">
+                            <table class="table table-no-border table-condensed table-auto-width table-content">
+                                <tr>
+                                    <td class="text-left">Name:</td>
+                                    <td>{{client.Name}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Group:</td>
+                                    <td ng-show="client.GroupName">{{client.GroupName}}</td>
+                                    <td ng-hide="client.GroupName">None</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">State:</td>
+                                    <td>{{client.State}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Up Time:</td>
+                                    <td>{{client.UpTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Last Update:</td>
+                                    <td>{{client.LastUpdate}}</td>
+                                </tr>
+                            </table>
+                        </div>
+                        <div class="col-md-6">
+                            <table class="table table-no-border table-condensed table-auto-width table-content">
+                                <tr>
+                                    <td class="text-left">Total Unavailable Time:</td>
+                                    <td class="text-right">{{client.TotalUnavailableTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Calculating Time:</td>
+                                    <td class="text-right">{{client.TotalCalculatingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Idle Time:</td>
+                                    <td class="text-right">{{client.TotalIdleTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Transferring Time:</td>
+                                    <td class="text-right">{{client.TotalTransferringTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Offline Time:</td>
+                                    <td class="text-right">{{client.TotalOfflineTime}}</td>
+                                </tr>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div class="col-lg-3 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Tasks Overview</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Total:</td>
+                            <td class="text-right">{{totalClientTasks}}</td>
+                        </tr>
+                        <tr ng-repeat="state in states">
+                            <td class="text-left">{{state.State}}:</td>
+                            <td class="text-right">{{state.Count}}</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="row">
+        <div class="col-lg-3 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Cores</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="text-center">
+                        <knob knob-data="knobData.cores" knob-options="knobOptions"></knob>
+                    </div>
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Total:</td>
+                            <td class="text-right">{{client.TotalCores | number}}</td>
+                        </tr>
+                        <tr>
+                            <td class="text-left">Used:</td>
+                            <td class="text-right">{{client.UsedCores | number}}</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+        <div class="col-lg-3 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">CPU Utilization</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="text-center">
+                        <knob knob-data="knobData.cpu" knob-options="knobOptions"></knob>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div class="col-lg-3 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Memory</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="text-center">
+                        <knob knob-data="knobData.memory" knob-options="knobOptions"></knob>
+                    </div>
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Total:</td>
+                            <td class="text-right">{{client.TotalMemory | number}} GB</td>
+                        </tr>
+                        <tr>
+                            <td class="text-left">Used:</td>
+                            <td class="text-right">{{client.UsedMemory | number}} GB</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+<div id="tasks-filter" class="default-filter-header text-center">
+    <form class="form-inline">
+        <div class="form-group">
+            <div class="btn-group" data-toggle="buttons">
+                <label class="btn btn-default" ng-class="{active: state.Selected}" ng-repeat="state in states"
+                       ng-click="filterTaskState(state)">
+                    <input type="checkbox" autocomplete="off" checked> {{state.State}}
+                </label>
+            </div>
+        </div>
+    </form>
+</div>
+
+ <div class="default-view-container">
+     <div id="taskListContainer" class="row" ng-show="taskPage.Tasks.length">
+         <div class="col-lg-4 col-md-4" ng-repeat="task in taskPage.Tasks">
+             <div class="panel panel-default">
+                 @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+                    <div class="panel-heading cursor-pointer" ng-click="openDialog(($index + 1)+((curTaskPage-1)*(taskPageSize)), task)">
+                        <h3 class="panel-title" style="display: inline">Task {{($index + 1)+((curTaskPage-1)*(taskPageSize))}}</h3>
+                        <span ng-if="task.State == 'Finished'" class="label label-success" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State == 'Aborted' || task.State == 'Failed'" class="label label-danger" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State == 'Waiting'" class="label label-warning" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State != 'Waiting' && task.State != 'Failed' && task.State != 'Aborted' && task.State != 'Finished'" class="label label-default" style="float: right;">{{task.State}}</span>
+                    </div>
+                 } else {
+                    <div class="panel-heading">
+                        <h3 class="panel-title" style="display: inline">Task {{($index + 1)+((curTaskPage-1)*(taskPageSize))}}</h3>
+                        <span ng-if="task.State == 'Finished'" class="label label-success" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State == 'Aborted' || task.State == 'Failed'" class="label label-danger" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State == 'Waiting'" class="label label-warning" style="float: right;">{{task.State}}</span>
+                        <span ng-if="task.State != 'Waiting' && task.State != 'Failed' && task.State != 'Aborted' && task.State != 'Finished'" class="label label-default" style="float: right;">{{task.State}}</span>
+                    </div>
+                 }
+                 
+                 <div class="panel-body">
+                     <table class="table table-condensed table-no-border table-auto-width">
+                         @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator))
+                         {
+                             <tr>
+                                 <td colspan="2"><span data-fittext="0.99">{{task.Id}}</span></td>
+                             </tr>
+                         }
+                         <tr>
+                             <td>Start Time:</td>
+                             <td class="text-right">{{task.StartTime}}</td>
+                         </tr>
+                         <tr>
+                             <td>End Time:</td>
+                             <td class="text-right">{{task.EndTime}}</td>
+                         </tr>
+                         <tr>
+                             <td>Calculating Time:</td>
+                             <td class="text-right">{{task.CalculatingTime}}</td>
+                         </tr>
+                         @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator))
+                         {
+                             <tr>
+                                 <td>User:</td>
+                                 <td class="text-right">
+                                     <a ng-href="#/statistics/users/{{task.UserId}}" ng-show="task.UserName">{{task.UserName}}</a>
+                                     <span ng-hide="task.UserName">Unknown</span>
+                                 </td>
+                             </tr>
+                             <tr>
+                                 <td>Job:</td>
+                                 <td class="text-right">
+                                     <a ng-href="#/statistics/jobs/{{task.JobId}}" ng-show="task.JobName">{{task.JobName}}</a>
+                                     <span ng-hide="task.JobName">Unknown</span>
+                                 </td>
+                             </tr>
+                         }
+                     </table>
+                 </div>
+
+             </div>
+         </div>
+     </div>
+     <div ng-hide="taskPage.Tasks.length">
+         <p class="text-center">Please select at least one state!</p>
+     </div>
+     <div class="row text-center" ng-show="taskPage.TotalTasks > taskPage.Tasks.length">
+         <pagination max-size="10" total-items="taskPage.TotalTasks" ng-model="curTaskPage" ng-change="changeTaskPage()" items-per-page="taskPageSize"
+                     boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+     </div>
+ </div>
+
+ <div class="default-filter-header text-center">
+     <form class="form-inline">
+         <div class="form-group">
+             <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">
+             <label for="fromDate">&nbsp;&nbsp;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="btn-group">
+             <label class="btn btn-default" ng-click="updateCharts()">
+                 Apply
+             </label>
+         </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/clients/details/clientDetailsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetailsCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetailsCtrl.js	(revision 12516)
@@ -0,0 +1,257 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.clientDetailsCtrl',
+        ['$scope', '$stateParams', '$interval', 'app.statistics.clientService', 'app.statistics.taskService', '$modal',
+        function ($scope, $stateParams, $interval, clientService, taskService, $modal) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.curTaskPage = 1;
+            $scope.taskPageSize = 12;
+
+            // details
+            $scope.knobOptions = {
+                'fgColor': "#f7921d",
+                'angleOffset': -125,
+                'angleArc': 250,
+                'readOnly': true,
+                'width': "80%",
+                'targetvalue': "100",
+                'format': function (value) {
+                    return value;
+                },
+                draw: function () {
+                    $(this.i).val(this.cv + '%');
+                }
+            };
+
+            $scope.knobData = {
+                cores: 0,
+                cpu: 0,
+                memory: 0
+            };
+
+            var getClientDetails = function () {
+                clientService.getClientDetails({ id: $stateParams.id }, function (client) {
+                    $scope.client = client;
+                    $scope.client.TotalMemory = Math.round($scope.client.TotalMemory / 1024);
+                    $scope.client.UsedMemory = Math.round($scope.client.UsedMemory / 1024);
+                    $scope.knobData.cores = (client.UsedCores / client.TotalCores) * 100;
+                    $scope.knobData.cpu = client.CpuUtilization;
+                    $scope.knobData.memory = (client.UsedMemory / client.TotalMemory) * 100;
+                    $scope.client.LastUpdate = CSharpDateToString($scope.client.LastUpdate);
+                    $scope.client.UpTime = $scope.client.UpTime.toHHMMSS();
+                    $scope.client.TotalUnavailableTime = $scope.client.TotalUnavailableTime.toHHMMSS();
+                    $scope.client.TotalCalculatingTime = $scope.client.TotalCalculatingTime.toHHMMSS();
+                    $scope.client.TotalIdleTime = $scope.client.TotalIdleTime.toHHMMSS();
+                    $scope.client.TotalOfflineTime = $scope.client.TotalOfflineTime.toHHMMSS();
+                    $scope.client.TotalTransferringTime = $scope.client.TotalTransferringTime.toHHMMSS();
+
+                    var length = client.TasksStates.length;
+                    var total = 0;
+                    var jsStates = [];
+                    for (var i = 0; i < length; ++i) {
+                        var state = client.TasksStates[i];
+                        var selected = true;
+                        if (isDefined($scope.states)) {
+                            for (var j = 0; j < $scope.states.length; ++j) {
+                                if (state.State == $scope.states[j].State) {
+                                    selected = $scope.states[j].Selected;
+                                    break;
+                                }
+                            }
+                        }
+                        jsStates.push({
+                            State: state.State,
+                            Count: state.Count,
+                            Selected: selected
+                        });
+                        total += state.Count;
+                    }
+                    $scope.totalClientTasks = total;
+                    $scope.states = jsStates;
+                    getTasks();
+                });
+            };
+
+            // tasks
+            var getTasks = function () {
+                var states = [];
+                var length = $scope.states.length;
+                for (var i = 0; i < length; ++i) {
+                    var state = $scope.states[i];
+                    if (state.Selected) {
+                        states.push(state.State);
+                    }
+                }
+
+                taskService.getTasksByClientId({ id: $stateParams.id, page: $scope.curTaskPage, size: $scope.taskPageSize }, states,
+                    function (taskPage) {
+                        $scope.taskPage = taskPage;
+                        var length = $scope.taskPage.Tasks.length;
+                        for (var i = 0; i < length; ++i) {
+                            $scope.taskPage.Tasks[i].TotalTime = $scope.taskPage.Tasks[i].TotalTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].InitialWaitingTime = $scope.taskPage.Tasks[i].InitialWaitingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].WaitingTime = $scope.taskPage.Tasks[i].WaitingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].CalculatingTime = $scope.taskPage.Tasks[i].CalculatingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].TransferTime = $scope.taskPage.Tasks[i].TransferTime.toHHMMSS();
+                            var startTime = $scope.taskPage.Tasks[i].StartTime;
+                            if (isDefined(startTime)) {
+                                $scope.taskPage.Tasks[i].StartTime = CSharpDateToString(startTime);
+                            } else {
+                                $scope.taskPage.Tasks[i].StartTime = 'Not started';
+                            }
+                            var endTime = $scope.taskPage.Tasks[i].EndTime;
+                            if (isDefined(endTime)) {
+                                $scope.taskPage.Tasks[i].EndTime = CSharpDateToString(endTime);
+                            } else {
+                                $scope.taskPage.Tasks[i].EndTime = 'Not finished';
+                            }
+                        }
+                    }
+                );
+            };
+
+            $scope.changeTaskPage = function () {
+                getClientDetails();
+                $('html, body').animate({
+                    scrollTop: $("#tasks-filter").offset().top
+                }, 10);
+            };
+
+            $scope.filterTaskState = function (state) {
+                state.Selected = !state.Selected;
+                $scope.curTaskPage = 1;
+                getClientDetails();
+            };
+
+            $scope.openDialog = function (taskNo, task) {
+                $scope.currentTaskNo = taskNo;
+                $scope.currentTask = task;
+                $modal.open({
+                    templateUrl: 'plugin=statistics&view=WebApp/clients/details/clientTaskDetailsDialog.cshtml',
+                    controller: 'app.statistics.clientTaskDetailsDialogCtrl',
+                    windowClass: 'app-modal-window',
+                    resolve: {
+                        task: function () {
+                            return $scope.currentTask;
+                        },
+                        taskNo: function () {
+                            return $scope.currentTaskNo;
+                        }
+                    }
+                });
+            };
+
+            // 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.getClientHistory({ 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 () {
+                getClientDetails();
+            };
+
+            $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/clients/details/clientTaskDetailsDialog.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientTaskDetailsDialog.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientTaskDetailsDialog.cshtml	(revision 12516)
@@ -0,0 +1,114 @@
+﻿@using HeuristicLab.Services.Hive
+@if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+<div class="modal-header">
+    <button type="button" ng-click="close()" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+    <h4 class="modal-title">Task #{{taskNo}} - {{task.Id}}</h4>
+</div>
+<div class="modal-body" style="height: 430px">
+    <tabset>
+        <tab heading="Details">
+            <div style="height: 330px" class="center-block">
+                <div class="row" style="padding-top: 30px">
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Start Time:</td>
+                                <td class="text-right">{{task.StartTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>End Time:</td>
+                                <td class="text-right">{{task.EndTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>State:</td>
+                                <td>{{task.State}}</td>
+                            </tr>
+                        </table>
+                    </div>
+
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Slave:</td>
+                                <td>
+                                    <a ng-click="close()" ng-href="#/statistics/clients/{{task.LastClientId}}" ng-show="task.LastClientName">{{task.LastClientName}}</a>
+                                    <span ng-hide="task.LastClientName">None</span>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>User:</td>
+                                <td>
+                                    <a ng-click="close()" ng-href="#/statistics/users/{{task.UserId}}" ng-show="task.UserName">{{task.UserName}}</a>
+                                    <span ng-hide="task.UserName">Unknown</span>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>Job:</td>
+                                <td>
+                                    <a ng-click="close()" ng-href="#/statistics/jobs/{{task.JobId}}" ng-show="task.JobName">{{task.JobName}}</a>
+                                    <span ng-hide="task.JobName">Unknown</span>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+                <div class="row" style="padding-top: 30px">
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Total Time:</td>
+                                <td>{{task.TotalTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Initial Waiting Time:</td>
+                                <td>{{task.InitialWaitingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Waiting Time:</td>
+                                <td>{{task.WaitingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Calculating Time:</td>
+                                <td>{{task.CalculatingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Transfer Time:</td>
+                                <td>{{task.TransferTime}}</td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Calculation Runs:</td>
+                                <td>{{task.NumCalculationRuns}}</td>
+                            </tr>
+                            <tr>
+                                <td>Retries Runs:</td>
+                                <td>{{task.NumRetries}}</td>
+                            </tr>
+                            <tr>
+                                <td>Cores Required:</td>
+                                <td>{{task.CoresRequired}}</td>
+                            </tr>
+                            <tr>
+                                <td>Memory Required:</td>
+                                <td>{{task.MemoryRequired}}</td>
+                            </tr>
+                            <tr>
+                                <td>Priority:</td>
+                                <td>{{task.Priority}}</td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </tab>
+        <tab heading="Exception" ng-show="task.Exception">
+            <div style="overflow: auto;">
+                <p style="word-wrap: break-word;">{{task.Exception}}</p>
+            </div>
+        </tab>
+    </tabset>
+</div>
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientTaskDetailsDialogCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientTaskDetailsDialogCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientTaskDetailsDialogCtrl.js	(revision 12516)
@@ -0,0 +1,14 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.clientTaskDetailsDialogCtrl',
+        ['$scope', '$modalInstance', 'taskNo', 'task', function ($scope, $modalInstance, taskNo, task) {
+            $scope.taskNo = taskNo;
+            $scope.task = task;
+
+            $scope.close = function () {
+                $modalInstance.dismiss('cancel');
+            };
+
+        }]
+    );
+})();
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 12516)
@@ -0,0 +1,187 @@
+﻿@using HeuristicLab.Services.Access.DataTransfer
+@using HeuristicLab.Services.Hive
+<header class="view-header">
+    <ul class="nav nav-list nav-list-topbar pull-left">
+        <li class="active">
+            <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>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-9 col-md-9">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Job Details</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="row">
+                        <div class="col-md-12">
+                            <table class="table table-no-border table-condensed table-auto-width table-content">
+                                <tr>
+                                    <td class="text-left">Name:</td>
+                                    <td>{{job.Name}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Created at:</td>
+                                    <td>{{job.DateCreated}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Completed at:</td>
+                                    <td>{{job.DateCompleted}}</td>
+                                </tr>
+                                @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+                                    <tr>
+                                        <td class="text-left">User:</td>
+                                        <td>
+                                            <a ng-href="#/statistics/users/{{job.UserId}}" ng-show="job.UserName">{{job.UserName}}</a>
+                                            <span ng-hide="job.UserName">None</span>
+                                        </td>
+                                    </tr>
+                                }
+                            </table>
+                        </div>
+                    </div>
+                    <div class="row" style="height: 20px"></div>
+                    <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">Total Time:</td>
+                                    <td class="text-right">{{job.TotalTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Calculating Time:</td>
+                                    <td class="text-right">{{job.TotalCalculatingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Total Waiting Time:</td>
+                                    <td class="text-right">{{job.TotalWaitingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Calc. / Waiting Ratio:</td>
+                                    <td class="text-right">{{job.CalculatingWaitingRatio | number: 3}}</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">Min Calculating Time:</td>
+                                    <td class="text-right">{{job.MinCalculatingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Max Calculating Time:</td>
+                                    <td class="text-right">{{job.MaxCalculatingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Avg. Calculating Time:</td>
+                                    <td class="text-right">{{job.AvgCalculatingTime}}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-left">Avg. Transferring Time:</td>
+                                    <td class="text-right">{{job.AvgTransferringTime}}</td>
+                                </tr>
+                            </table>
+                        </div>
+
+                        <div class="col-md-2"></div>
+                        </div>
+                </div>
+
+            </div>
+        </div>
+
+        <div class="col-lg-3 col-md-3">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Tasks Overview</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Total:</td>
+                            <td class="text-right">{{totalJobTasks}}</td>
+                        </tr>
+                        <tr ng-repeat="state in states">
+                            <td class="text-left">{{state.State}}:</td>
+                            <td class="text-right">{{state.Count}}</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="job-filter-header" class="text-center">
+    <form class="form-inline">
+        <div class="form-group">
+            <div class="btn-group" data-toggle="buttons">
+                <label class="btn btn-default" ng-class="{active: state.Selected}" ng-repeat="state in states"
+                       ng-click="filterState(state)">
+                    <input type="checkbox" autocomplete="off" checked> {{state.State}}
+                </label>
+            </div>
+        </div>
+    </form>
+</div>
+
+<div class="default-view-container">
+    <div id="taskListContainer" class="row" ng-show="taskPage.Tasks.length">
+        <div class="col-lg-4 col-md-4" ng-repeat="task in taskPage.Tasks">
+            <div class="panel panel-default">
+                <div class="panel-heading cursor-pointer" ng-click="openDialog(($index + 1)+((curTaskPage-1)*(taskPageSize)), task)">
+                    <h3 class="panel-title" style="display: inline">Task {{($index + 1)+((curTaskPage-1)*(taskPageSize))}}</h3>
+                    <span ng-if="task.State == 'Finished'" class="label label-success" style="float: right;">{{task.State}}</span>
+                    <span ng-if="task.State == 'Aborted' || task.State == 'Failed'" class="label label-danger" style="float: right;">{{task.State}}</span>
+                    <span ng-if="task.State == 'Waiting'" class="label label-warning" style="float: right;">{{task.State}}</span>
+                    <span ng-if="task.State != 'Waiting' && task.State != 'Failed' && task.State != 'Aborted' && task.State != 'Finished'" class="label label-default" style="float: right;">{{task.State}}</span>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-condensed table-no-border table-auto-width">
+                        <tr>
+                            <td colspan="2"><span data-fittext="0.99">{{task.Id}}</span></td>
+                        </tr>
+                        <tr>
+                            <td>Start Time:</td>
+                            <td class="text-right">{{task.StartTime}}</td>
+                        </tr>
+                        <tr>
+                            <td>End Time:</td>
+                            <td class="text-right">{{task.EndTime}}</td>
+                        </tr>
+                        <tr>
+                            <td>Calculating Time:</td>
+                            <td class="text-right">{{task.CalculatingTime}}</td>
+                        </tr>
+                        <tr>
+                            <td>Slave:</td>
+                            <td class="text-right">
+                                <a ng-href="#/statistics/clients/{{task.LastClientId}}" ng-show="task.LastClientName">{{task.LastClientName}}</a>
+                                <span ng-hide="task.LastClientName">None</span>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+
+            </div>
+        </div>
+    </div>
+    <div ng-hide="taskPage.Tasks.length">
+        <p class="text-center">Please select at least one state!</p>
+    </div>
+    <div class="row text-center" ng-show="taskPage.TotalTasks > taskPage.Tasks.length">
+        <pagination max-size="10" total-items="taskPage.TotalTasks" ng-model="curTaskPage" ng-change="changeTaskPage()" items-per-page="taskPageSize"
+                    boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+    </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 12516)
@@ -0,0 +1,133 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.jobDetailsCtrl',
+        ['$scope', '$interval', '$stateParams', 'app.statistics.jobService', 'app.statistics.taskService', '$modal',
+        function ($scope, $interval, $stateParams, jobService, taskService, $modal) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.curTaskPage = 1;
+            $scope.taskPageSize = 12;
+
+            var getJobDetails = function () {
+                jobService.getJobDetails({ id: $stateParams.id }, function (job) {
+                    $scope.job = job;
+                    $scope.job.DateCreated = CSharpDateToString($scope.job.DateCreated);
+                    if (isDefined($scope.job.DateCompleted)) {
+                        $scope.job.DateCompleted = CSharpDateToString($scope.job.DateCompleted);
+                    }
+                    $scope.job.CalculatingWaitingRatio = ($scope.job.TotalCalculatingTime / $scope.job.TotalWaitingTime);
+                    $scope.job.AvgTransferringTime = $scope.job.AvgTransferringTime.toHHMMSS();
+                    $scope.job.AvgCalculatingTime = $scope.job.AvgCalculatingTime.toHHMMSS();
+                    $scope.job.MinCalculatingTime = $scope.job.MinCalculatingTime.toHHMMSS();
+                    $scope.job.MaxCalculatingTime = $scope.job.MaxCalculatingTime.toHHMMSS();
+                    $scope.job.TotalCalculatingTime = $scope.job.TotalCalculatingTime.toHHMMSS();
+                    $scope.job.TotalWaitingTime = $scope.job.TotalWaitingTime.toHHMMSS();
+                    $scope.job.TotalTime = $scope.job.TotalTime.toHHMMSS();
+
+                    var length = job.TasksStates.length;
+                    var total = 0;
+                    var jsStates = [];
+                    for (var i = 0; i < length; ++i) {
+                        var state = job.TasksStates[i];
+                        var selected = true;
+                        if (isDefined($scope.states)) {
+                            for (var j = 0; j < $scope.states.length; ++j) {
+                                if (state.State == $scope.states[j].State) {
+                                    selected = $scope.states[j].Selected;
+                                    break;
+                                }
+                            }
+                        }
+                        jsStates.push({
+                            State: state.State,
+                            Count: state.Count,
+                            Selected: selected
+                        });
+                        total += state.Count;
+                    }
+                    $scope.totalJobTasks = total;
+                    $scope.states = jsStates;
+                    getTasks();
+                });
+            };
+
+            var getTasks = function () {
+                var states = [];
+                var length = $scope.states.length;
+                for (var i = 0; i < length; ++i) {
+                    var state = $scope.states[i];
+                    if (state.Selected) {
+                        states.push(state.State);
+                    }
+                }
+
+                taskService.getTasksByJobId({ id: $stateParams.id, page: $scope.curTaskPage, size: $scope.taskPageSize }, states,
+                    function (taskPage) {
+                        $scope.taskPage = taskPage;
+                        var length = $scope.taskPage.Tasks.length;
+                        for (var i = 0; i < length; ++i) {
+                            $scope.taskPage.Tasks[i].TotalTime = $scope.taskPage.Tasks[i].TotalTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].InitialWaitingTime = $scope.taskPage.Tasks[i].InitialWaitingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].WaitingTime = $scope.taskPage.Tasks[i].WaitingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].CalculatingTime = $scope.taskPage.Tasks[i].CalculatingTime.toHHMMSS();
+                            $scope.taskPage.Tasks[i].TransferTime = $scope.taskPage.Tasks[i].TransferTime.toHHMMSS();
+                            var startTime = $scope.taskPage.Tasks[i].StartTime;
+                            if (isDefined(startTime)) {
+                                $scope.taskPage.Tasks[i].StartTime = CSharpDateToString(startTime);
+                            } else {
+                                $scope.taskPage.Tasks[i].StartTime = 'Not started';
+                            }
+                            var endTime = $scope.taskPage.Tasks[i].EndTime;
+                            if (isDefined(endTime)) {
+                                $scope.taskPage.Tasks[i].EndTime = CSharpDateToString(endTime);
+                            } else {
+                                $scope.taskPage.Tasks[i].EndTime = 'Not finished';
+                            }
+                        }
+                    }
+                );
+            };
+
+            $scope.changeTaskPage = function () {
+                getJobDetails();
+                $('html, body').animate({
+                    scrollTop: $("#job-filter-header").offset().top
+                }, 10);
+            };
+
+            $scope.filterState = function (state) {
+                state.Selected = !state.Selected;
+                $scope.curTaskPage = 1;
+                getJobDetails();
+            };
+
+            $scope.openDialog = function (taskNo, task) {
+                $scope.currentTaskNo = taskNo;
+                $scope.currentTask = task;
+                $modal.open({
+                    templateUrl: 'plugin=statistics&view=WebApp/jobs/details/jobTaskDetailsDialog.cshtml',
+                    controller: 'app.statistics.jobTaskDetailsDialogCtrl',
+                    windowClass: 'app-modal-window',
+                    resolve: {
+                        task: function() {
+                            return $scope.currentTask;
+                        },
+                        taskNo: function() {
+                            return $scope.currentTaskNo;
+                        }
+                    }
+                });
+            };
+
+            var update = function () {
+                getJobDetails();
+            };
+
+            $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/jobTaskDetailsDialog.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobTaskDetailsDialog.cshtml	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobTaskDetailsDialog.cshtml	(revision 12516)
@@ -0,0 +1,92 @@
+﻿<div class="modal-header">
+    <button type="button" ng-click="close()" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+    <h4 class="modal-title">Task #{{taskNo}} - {{task.Id}}</h4>
+</div>
+<div class="modal-body" style="height: 430px">
+    <tabset>
+        <tab heading="Details">
+            <div style="height: 330px" class="center-block">
+                <div class="row" style="padding-top: 30px">
+                    <div class="col-md-12">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Start Time:</td>
+                                <td class="text-right">{{task.StartTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>End Time:</td>
+                                <td class="text-right">{{task.EndTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>State:</td>
+                                <td>{{task.State}}</td>
+                            </tr>
+                            <tr>
+                                <td>Slave:</td>
+                                <td>
+                                    <a ng-click="close()" ng-href="#/statistics/clients/{{task.LastClientId}}" ng-show="task.LastClientName">{{task.LastClientName}}</a>
+                                    <span ng-hide="task.LastClientName">None</span>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+                <div class="row" style="padding-top: 30px">
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Total Time:</td>
+                                <td>{{task.TotalTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Initial Waiting Time:</td>
+                                <td>{{task.InitialWaitingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Waiting Time:</td>
+                                <td>{{task.WaitingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Calculating Time:</td>
+                                <td>{{task.CalculatingTime}}</td>
+                            </tr>
+                            <tr>
+                                <td>Transfer Time:</td>
+                                <td>{{task.TransferTime}}</td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div class="col-md-6">
+                        <table class="table table-condensed table-no-border table-auto-width table-content">
+                            <tr>
+                                <td>Calculation Runs:</td>
+                                <td>{{task.NumCalculationRuns}}</td>
+                            </tr>
+                            <tr>
+                                <td>Retries Runs:</td>
+                                <td>{{task.NumRetries}}</td>
+                            </tr>
+                            <tr>
+                                <td>Cores Required:</td>
+                                <td>{{task.CoresRequired}}</td>
+                            </tr>
+                            <tr>
+                                <td>Memory Required:</td>
+                                <td>{{task.MemoryRequired}}</td>
+                            </tr>
+                            <tr>
+                                <td>Priority:</td>
+                                <td>{{task.Priority}}</td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </tab>
+        <tab heading="Exception" ng-show="task.Exception">
+            <div style="overflow:auto;">
+                <p style="word-wrap: break-word;">{{task.Exception}}</p>
+            </div>
+        </tab>
+    </tabset>
+</div>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobTaskDetailsDialogCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobTaskDetailsDialogCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobTaskDetailsDialogCtrl.js	(revision 12516)
@@ -0,0 +1,14 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.jobTaskDetailsDialogCtrl',
+        ['$scope', '$modalInstance', 'taskNo', 'task', function ($scope, $modalInstance, taskNo, task) {
+            $scope.taskNo = taskNo;
+            $scope.task = task;
+
+            $scope.close = function () {
+                $modalInstance.dismiss('cancel');
+            };
+
+        }]
+    );
+})();
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 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobs.cshtml	(revision 12516)
@@ -10,29 +10,28 @@
                 <a ng-href="#/statistics/users">Users</a>
             </li>
-            <li>
-                <a ng-href="#/statistics/clients">Clients</a>
-            </li>
         }
+        <li>
+            <a ng-href="#/statistics/clients">Clients</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">My Jobs</h3>
+                    <h3 class="panel-title">Current Jobs</h3>
                 </div>
                 <div class="panel-body">
                     <table class="table table-hover table-condensed">
                         <thead>
-                            <tr>
-                                <th>#</th>
-                                <th>Job Name</th>
-                                <th>Date Created</th>
-                                <th></th>
-                            </tr>
+                        <tr>
+                            <th>#</th>
+                            <th>Job Name</th>
+                            <th>Date Created</th>
+                            <th>Progress</th>
+                            <th></th>
+                        </tr>
                         </thead>
                         <tr ng-repeat="job in jobs">
@@ -40,8 +39,13 @@
                             <td>{{job.Name}}</td>
                             <td>{{job.DateCreated}}</td>
-                            <td><a ng-href="" data-ng-click="getTasksByJobId(job.Id)">Load Tasks</a></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="jobs.length">
-                            <td colspan="4" class="text-center">No jobs found!</td>
+                            <td colspan="5" class="text-center">No active jobs found!</td>
                         </tr>
                     </table>
@@ -51,61 +55,41 @@
     </div>
 
-    <div class="row" ng-show="tasks.length">
-
-        <div class="col-lg-3 col-md-6" ng-repeat="task in tasks">
+    <div class="row">
+        <div class="col-lg-12">
             <div class="panel panel-default">
-
                 <div class="panel-heading">
-                    <h3 class="panel-title">Task {{$index + 1}}</h3>
+                    <h3 class="panel-title">Completed Jobs</h3>
                 </div>
                 <div class="panel-body">
-                    <table class="table table-hover table-condensed table-no-border table-auto-width">
+                    <table class="table table-hover table-condensed">
+                        <thead>
                         <tr>
-                            <td>Initial Waiting Time:</td>
-                            <td>{{task.InitialWaitingTime}}</td>
+                            <th>#</th>
+                            <th>Job Name</th>
+                            <th>Date Created</th>
+                            <th>Date Completed</th>
+                            <th>Tasks</th>
+                            <th></th>
                         </tr>
-                        <tr>
-                            <td>Waiting Time:</td>
-                            <td>{{task.WaitingTime}}</td>
+                        </thead>
+                        <tr ng-repeat="job in completedJobPage.Jobs">
+                            <td>{{($index + 1)+((completedJobCurPage-1)*(completedJobPageSize))}}</td>
+                            <td>{{job.Name}}</td>
+                            <td>{{job.DateCreated}}</td>
+                            <td>{{job.DateCompleted}}</td>
+                            <td>{{job.TotalTasks}}</td>
+                            <td><a ng-href="#/statistics/jobs/{{job.Id}}">Details</a></td>
                         </tr>
-                        <tr>
-                            <td>Calculating Time:</td>
-                            <td>{{task.CalculatingTime}}</td>
-                        </tr>
-                        <tr>
-                            <td>Transfer Time:</td>
-                            <td>{{task.TransferTime}}</td>
-                        </tr>
-                        <tr>
-                            <td>Start Time:</td>
-                            <td>{{task.StartTime}}</td>
-                        </tr>
-                        <tr>
-                            <td>End Time:</td>
-                            <td>{{task.EndTime}}</td>
-                        </tr>
-                        <tr>
-                            <td>Calculation Runs:</td>
-                            <td>{{task.NumCalculationRuns}}</td>
-                        </tr>
-                        <tr>
-                            <td>Retries Runs:</td>
-                            <td>{{task.NumRetries}}</td>
-                        </tr>
-                        <tr>
-                            <td>Cores Required:</td>
-                            <td>{{task.CoresRequired}}</td>
-                        </tr>
-                        <tr>
-                            <td>Memory Required:</td>
-                            <td>{{task.MemoryRequired}}</td>
-                        </tr>
-                        <tr>
-                            <td>Priority:</td>
-                            <td>{{task.Priority}}</td>
+                        <tr ng-hide="completedJobPage.Jobs.length">
+                            <td colspan="6" class="text-center">No completed jobs found!</td>
                         </tr>
                     </table>
+                    <div class="row text-center" ng-show="completedJobPage.TotalJobs > completedJobPage.Jobs.length">
+                        <pagination max-size="10" total-items="completedJobPage.TotalJobs"
+                                    ng-model="completedJobCurPage" items-per-page="completedJobPageSize"
+                                    ng-change="changeCompletedJobPage()"
+                                    boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+                    </div>
                 </div>
-
             </div>
         </div>
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 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobsCtrl.js	(revision 12516)
@@ -2,18 +2,47 @@
     var module = appStatisticsPlugin.getAngularModule();
     module.controller('app.statistics.jobsCtrl',
-        ['$scope', 'app.statistics.data.service', function($scope, statisticsService) {
-            var getJobs = function() {
-                statisticsService.getJobs({}, function(jobs) {
+        ['$scope', '$interval', 'app.statistics.jobService', function ($scope, $interval, jobService) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.completedJobCurPage = 1;
+            $scope.completedJobPageSize = 20;
+
+            var getAllJobs = function() {
+                jobService.getAllJobs({ completed: false }, function(jobs) {
                     $scope.jobs = jobs;
+                    var length = $scope.jobs.length;
+                    for (var i = 0; i < length; ++i) {
+                        $scope.jobs[i].DateCreated = CSharpDateToString($scope.jobs[i].DateCreated);
+                    }
                 });
             };
 
-            $scope.getTasksByJobId = function(id) {
-                statisticsService.getTasksByJobId({ id: id }, function(tasks) {
-                    $scope.tasks = tasks;
-                });
+            var getCompletedJobs = function() {
+                jobService.getJobs({ page: $scope.completedJobCurPage, size: $scope.completedJobPageSize, completed: true },
+                    function (jobPage) {
+                        $scope.completedJobPage = jobPage;
+                        var length = $scope.completedJobPage.Jobs.length;
+                        for (var i = 0; i < length; ++i) {
+                            $scope.completedJobPage.Jobs[i].DateCreated = CSharpDateToString($scope.completedJobPage.Jobs[i].DateCreated);
+                            $scope.completedJobPage.Jobs[i].DateCompleted = CSharpDateToString($scope.completedJobPage.Jobs[i].DateCompleted);
+                        }
+                    }
+                );
             };
 
-            getJobs();
+            $scope.changeCompletedJobPage = function () {
+                update();
+            };
+
+            var update = function () {
+                getAllJobs();
+                getCompletedJobs();
+            };
+
+            $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/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 12516)
@@ -0,0 +1,13 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/Client/';
+    module.factory('app.statistics.clientService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { id: '@id', page: '@page', size: '@size', states: '@states', expired: '@expired', start: '@start', end: '@end' }, {
+                getClientDetails: { method: 'GET', params: { action: 'GetClientDetails' } },
+                getClients: { method: 'GET', params: { action: 'GetClients' } },
+                getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, 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 12516)
@@ -0,0 +1,16 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/Job/';
+    module.factory('app.statistics.jobService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { id: '@id', page: '@page', size: '@size', states: '@states', completed: '@completed' }, {
+                getJobDetails: { method: 'GET', params: { action: 'GetJobDetails' } },
+                getJobs: { method: 'GET', params: { action: 'GetJobs' } },
+                getAllJobs: { method: 'GET', params: { action: 'GetAllJobs'}, isArray: true },
+                getJobsByUserId: { method: 'GET', params: { action: 'GetJobsByUserId' } },
+                getAllJobsByUserId: { method: 'GET', params: { action: 'GetAllJobsByUserId'}, isArray: true },
+                getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true }
+            });
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/statisticsService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/statisticsService.js	(revision 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/statisticsService.js	(revision 12516)
@@ -4,8 +4,24 @@
     module.factory('app.statistics.data.service',
         ['$resource', function ($resource) {
-            return $resource(apiUrl + ':action', { id: '@id' }, {
+            return $resource(apiUrl + ':action', { id: '@id', page: '@page', size: '@size', states: '@states', expired: '@expired'}, {
+                getJob: { method: 'GET', params: { action: 'GetJob' } },
                 getJobs: { method: 'GET', params: { action: 'GetJobs' }, isArray: true },
+                getCompletedJobs: { method: 'GET', params: { action: 'GetCompletedJobs' }, isArray: true },
+                getCompletedJobsByUserId: { method: 'GET', params: { action: 'GetCompletedJobsByUserId' }, isArray: true },
+                getCompletedJobsCount: { method: 'GET', params: { action: 'GetCompletedJobsCount' } },
+                getCompletedJobsCountByUserId: { method: 'GET', params: { action: 'GetCompletedJobsCountByUserId' } },
                 getJobsByUserId: { method: 'GET', params: { action: 'GetJobsByUserId' }, isArray: true },
-                getTasksByJobId: { method: 'GET', params: { action: 'GetTasksByJobId' }, isArray: true }
+                getTaskCountByJobId: { method: 'GET', params: { action: 'GetTaskCountByJobId' } },
+                getTasksByJobId: { method: 'GET', params: { action: 'GetTasksByJobId' }, isArray: true },
+                getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true },
+                getClient: { method: 'GET', params: { action: 'GetClient' } },
+                getClientCount: { method: 'GET', params: { action: 'GetClientCount' } },
+                getClients: { method: 'GET', params: { action: 'GetClients' }, isArray: true },
+                getTaskCountByClientId: { method: 'GET', params: { action: 'GetTaskCountByClientId' } },
+                getTasksByClientId: { method: 'GET', params: { action: 'GetTasksByClientId' }, isArray: true },
+                getJobTasksStatesByClientId: { method: 'GET', params: { action: 'GetJobTasksStatesByClientId' }, isArray: true },
+                getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, isArray: true },
+                getUsers: { method: 'GET', params: { action: 'GetUsers' }, isArray: true },
+                getUser: { method: 'GET', params: { action: 'GetUser' } }
             });
         }]
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/taskService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/taskService.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/taskService.js	(revision 12516)
@@ -0,0 +1,12 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/Task/';
+    module.factory('app.statistics.taskService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { id: '@id', page: '@page', size: '@size', states: '@states' }, {
+                getTasksByJobId: { method: 'POST', params: { action: 'GetTasksByJobId' } },
+                getTasksByClientId: { method: 'POST', params: { action: 'GetTasksByClientId' } }
+            });
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/userService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/userService.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/userService.js	(revision 12516)
@@ -0,0 +1,12 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/User/';
+    module.factory('app.statistics.userService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { id: '@id' }, {
+                getUser: { method: 'GET', params: { action: 'GetUser' } },
+                getUsers: { method: 'GET', params: { action: 'GetUsers' }, isArray: true }
+            });
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/statistics.css
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/statistics.css	(revision 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/statistics.css	(revision 12516)
@@ -1,1 +1,6 @@
-﻿
+﻿#job-filter-header {
+  padding: 30px;
+  background: #F5F5F5;
+  border-top: 1px solid #D3D3D3;
+  border-bottom: 1px solid #D3D3D3;
+}
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 12516)
@@ -0,0 +1,136 @@
+﻿@using HeuristicLab.Services.Access.DataTransfer
+@using HeuristicLab.Services.Hive
+@if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+<header class="view-header">
+    <ul class="nav nav-list nav-list-topbar pull-left">
+        <li>
+            <a ng-href="#/statistics/jobs">Jobs</a>
+        </li>
+        <li class="active">
+            <a ng-href="#/statistics/users">Users</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-9 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">User Details</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Name:</td>
+                            <td>{{user.Name}}</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+        <div class="col-lg-3 col-md-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Tasks Overview</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-no-border table-condensed table-auto-width table-content">
+                        <tr>
+                            <td class="text-left">Total:</td>
+                            <td class="text-right">{{totalJobTasks}}</td>
+                        </tr>
+                        <tr ng-repeat="state in states">
+                            <td class="text-left">{{state.State}}:</td>
+                            <td class="text-right">{{state.Count}}</td>
+                        </tr>
+                    </table>
+                </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">Current Jobs</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                            <tr>
+                                <th>#</th>
+                                <th>Job Name</th>
+                                <th>Date Created</th>
+                                <th>Progress</th>
+                                <th></th>
+                            </tr>
+                        </thead>
+                        <tr ng-repeat="job in jobs">
+                            <td>{{$index + 1}}</td>
+                            <td>{{job.Name}}</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="jobs.length">
+                            <td colspan="5" class="text-center">No active jobs found!</td>
+                        </tr>
+                    </table>
+                </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">Completed Jobs</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                            <tr>
+                                <th>#</th>
+                                <th>Job Name</th>
+                                <th>Date Created</th>
+                                <th>Date Completed</th>
+                                <th>Tasks</th>
+                                <th></th>
+                            </tr>
+                        </thead>
+                        <tr ng-repeat="job in completedJobPage.Jobs">
+                            <td>{{($index + 1)+((completedJobCurPage-1)*(completedJobPageSize))}}</td>
+                            <td>{{job.Name}}</td>
+                            <td>{{job.DateCreated}}</td>
+                            <td>{{job.DateCompleted}}</td>
+                            <td>{{job.TotalTasks}}</td>
+                            <td><a ng-href="#/statistics/jobs/{{job.Id}}">Details</a></td>
+                        </tr>
+                        <tr ng-hide="completedJobPage.Jobs.length">
+                            <td colspan="6" class="text-center">No completed jobs found!</td>
+                        </tr>
+                    </table>
+                    <div class="row text-center" ng-show="completedJobPage.TotalJobs > completedJobPage.Jobs.length">
+                        <pagination max-size="10" total-items="completedJobPage.TotalJobs"
+                                    ng-model="completedJobCurPage" items-per-page="completedJobPageSize"
+                                    ng-change="changeCompletedJobPage()"
+                                    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/users/details/userDetailsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetailsCtrl.js	(revision 12516)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetailsCtrl.js	(revision 12516)
@@ -0,0 +1,58 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.userDetailsCtrl',
+        ['$scope', '$stateParams', '$interval', 'app.statistics.userService', 'app.statistics.jobService',
+        function ($scope, $stateParams, $interval, userService, jobService) {
+            $scope.interval = defaultPageUpdateInterval;
+            $scope.completedJobCurPage = 1;
+            $scope.completedJobPageSize = 20;
+
+
+            var getUserDetails = function () {
+                userService.getUser({ id: $stateParams.id }, function(user) {
+                    $scope.user = user;
+                });
+            };
+
+            var getAllJobs = function () {
+                jobService.getAllJobsByUserId({ id: $stateParams.id, completed: false }, function (jobs) {
+                    $scope.jobs = jobs;
+                    var length = $scope.jobs.length;
+                    for (var i = 0; i < length; ++i) {
+                        $scope.jobs[i].DateCreated = CSharpDateToString($scope.jobs[i].DateCreated);
+                    }
+                });
+            };
+
+            var getCompletedJobs = function () {
+                jobService.getJobsByUserId({ id: $stateParams.id, page: $scope.completedJobCurPage, size: $scope.completedJobPageSize, completed: true },
+                    function (jobPage) {
+                        $scope.completedJobPage = jobPage;
+                        var length = $scope.completedJobPage.Jobs.length;
+                        for (var i = 0; i < length; ++i) {
+                            $scope.completedJobPage.Jobs[i].DateCreated = CSharpDateToString($scope.completedJobPage.Jobs[i].DateCreated);
+                            $scope.completedJobPage.Jobs[i].DateCompleted = CSharpDateToString($scope.completedJobPage.Jobs[i].DateCompleted);
+                        }
+                    }
+                );
+            };
+
+            $scope.changeCompletedJobPage = function () {
+                update();
+            };
+
+            var update = function () {
+                getUserDetails();
+                getAllJobs();
+                getCompletedJobs();
+            };
+
+            $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/users/users.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml	(revision 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml	(revision 12516)
@@ -17,5 +17,34 @@
 
 <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">Users</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                            <tr>
+                                <th>#</th>
+                                <th>Username</th>
+                                <th></th>
+                            </tr>
+                        </thead>
+                        <tr ng-repeat="user in users">
+                            <td>{{$index + 1}}</td>
+                            <td>{{user.Name}}</td>
+                            <td>
+                                <a ng-href="#/statistics/users/{{user.Id}}">Details</a>
+                            </td>
+                        </tr>
+                        <tr ng-hide="users.length">
+                            <td colspan="4" class="text-center">No users found!</td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
 </div>
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/usersCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/usersCtrl.js	(revision 12484)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/usersCtrl.js	(revision 12516)
@@ -2,6 +2,20 @@
     var module = appStatisticsPlugin.getAngularModule();
     module.controller('app.statistics.usersCtrl',
-        ['$scope', 'app.statistics.data.service', function($scope, statisticsService) {
-            
+        ['$scope', '$interval', 'app.statistics.userService', function ($scope, $interval, userService) {
+            $scope.interval = defaultPageUpdateInterval;
+
+            var getUsers = function() {
+                userService.getUsers({}, function(users) {
+                    users.splice(0, 1);
+                    $scope.users = users;
+                });
+            };
+
+            $scope.updateInterval = $interval(getUsers, $scope.interval);
+            var cancelInterval = $scope.$on('$locationChangeSuccess', function () {
+                $interval.cancel($scope.updateInterval);
+                cancelInterval();
+            });
+            getUsers(); // init page
         }]
     );
