Changeset 12435


Ignore:
Timestamp:
06/12/15 14:59:54 (4 years ago)
Author:
dglaser
Message:

#2394: Improved PluginManager and updated hive status monitor.

Location:
trunk/sources
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs

    r12428 r12435  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223using System.Collections.Generic;
    324using System.Linq;
     
    2142        SELECT
    2243          DISTINCT UserId,
    23           ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Calculating' AND UserId = ut.UserId), 0) AS CalculatingTasks,
    24           ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Waiting' AND UserId = ut.UserId), 0) AS WaitingTasks
     44          (SELECT Count FROM UserTasks WHERE TaskState = 'Calculating' AND UserId = ut.UserId) AS CalculatingTasks,
     45          (SELECT Count FROM UserTasks WHERE TaskState = 'Waiting' AND UserId = ut.UserId) AS WaitingTasks
    2546        FROM UserTasks ut;";
    2647
     
    4162        CalculatingTasks = uts.CalculatingTasks,
    4263        WaitingTasks = uts.WaitingTasks
    43       });
     64      }).OrderBy(x => x.User.Name);
    4465    }
    4566    // end temporary quickfix
     
    5071                            where slave.SlaveState == SlaveState.Calculating || slave.SlaveState == SlaveState.Idle
    5172                            select slave).ToList();
     73        var activeSlaves = onlineSlaves.Where(s => s.IsAllowedToCalculate).ToList();
     74        var calculatingSlaves = activeSlaves.Where(s => s.SlaveState == SlaveState.Calculating).ToList();
     75
     76        int calculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.Memory) / 1024 : 0;
     77        int freeCalculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.FreeMemory) / 1024 : 0;
     78
    5279        return new DTO.Status {
    5380          CoreStatus = new DTO.CoreStatus {
    5481            TotalCores = onlineSlaves.Sum(s => s.Cores ?? 0),
    55             AvailableCores = onlineSlaves.Where(s => s.IsAllowedToCalculate).Sum(s => s.Cores ?? 0),
    56             FreeCores = onlineSlaves.Sum(s => s.FreeCores ?? 0)
     82            FreeCores = onlineSlaves.Sum(s => s.FreeCores ?? 0), // temporary for old chart data
     83            ActiveCores = activeSlaves.Sum(s => s.Cores ?? 0),
     84            CalculatingCores = calculatingSlaves.Sum(s => s.Cores ?? 0)
    5785          },
    5886          CpuUtilizationStatus = new DTO.CpuUtilizationStatus {
     
    6088                                  ? Math.Round(onlineSlaves.Average(s => s.CpuUtilization), 2)
    6189                                  : 0.0,
    62             UsedCpuUtilization = onlineSlaves.Any(x => x.IsAllowedToCalculate)
    63                                  ? Math.Round(onlineSlaves.Where(x => x.IsAllowedToCalculate).Average(s => s.CpuUtilization), 2)
    64                                  : 0.0
     90            ActiveCpuUtilization = activeSlaves.Any()
     91                                   ? Math.Round(activeSlaves.Average(s => s.CpuUtilization), 2)
     92                                   : 0.0,
     93            CalculatingCpuUtilization = calculatingSlaves.Any()
     94                                        ? Math.Round(calculatingSlaves.Average(s => s.CpuUtilization), 2)
     95                                        : 0.0
    6596          },
    6697          MemoryStatus = new DTO.MemoryStatus {
    6798            TotalMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.Memory) / 1024 : 0,
    68             FreeMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.FreeMemory) / 1024 : 0
     99            FreeMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.FreeMemory) / 1024 : 0,
     100            ActiveMemory = activeSlaves.Any() ? (int)activeSlaves.Sum(s => s.Memory) / 1024 : 0,
     101            UsedMemory = calculatingMemory - freeCalculatingMemory
    69102          },
    70103          TasksStatus = GetTaskStatus(db),
    71           SlavesCpuStatus = onlineSlaves.Select(x => new DTO.SlaveCpuStatus {
    72             CpuUtilization = Math.Round(x.CpuUtilization, 2),
     104          SlavesStatus = onlineSlaves.Select(x => new DTO.SlaveStatus {
    73105            Slave = new DTO.Slave {
    74106              Id = x.ResourceId.ToString(),
    75107              Name = x.Name
    76             }
    77           }),
     108            },
     109            CpuUtilization = x.CpuUtilization,
     110            Cores = x.Cores ?? 0,
     111            FreeCores = x.FreeCores ?? 0,
     112            Memory = (x.Memory ?? 0) / 1024,
     113            FreeMemory = (x.FreeMemory ?? 0) / 1024,
     114            IsAllowedToCalculate = x.IsAllowedToCalculate,
     115            State = x.SlaveState.ToString()
     116          }).OrderBy(x => x.Slave.Name),
    78117          Timestamp = JavascriptUtils.ToTimestamp(DateTime.Now)
    79118        };
     
    82121
    83122    public IEnumerable<DTO.Status> GetStatusHistory(DateTime start, DateTime end) {
     123      TimeSpan ts = end - start;
     124      int increment = 1;
     125      double totalMinutes = ts.TotalMinutes;
     126      while (totalMinutes > 5761) {
     127        totalMinutes -= 5761;
     128        increment += 5;
     129      }
    84130      using (var db = new HiveDataContext()) {
    85         var statistics = db.Statistics.Where(s => s.Timestamp >= start && s.Timestamp <= end)
    86                                       .OrderBy(x => x.Timestamp)
    87                                       .ToList();
     131        var statistics = db.Statistics.Where(s => s.Timestamp >= start && s.Timestamp <= end);
     132        var status = new DTO.Status {
     133          CoreStatus = new DTO.CoreStatus(),
     134          CpuUtilizationStatus = new DTO.CpuUtilizationStatus(),
     135          MemoryStatus = new DTO.MemoryStatus()
     136        };
     137        int freeCores = 0;
     138        int freeMemory = 0;
     139        int i = 1;
    88140        foreach (var statistic in statistics) {
    89           yield return new DTO.Status {
    90             CoreStatus = new DTO.CoreStatus {
    91               TotalCores = statistic.SlaveStatistics.Sum(x => x.Cores),
    92               AvailableCores = 0,
    93               FreeCores = statistic.SlaveStatistics.Sum(x => x.FreeCores)
    94             },
    95             CpuUtilizationStatus = new DTO.CpuUtilizationStatus {
    96               TotalCpuUtilization = 0.0,
    97               UsedCpuUtilization = statistic.SlaveStatistics.Any() ? statistic.SlaveStatistics.Average(x => x.CpuUtilization) : 0.0
    98             },
    99             MemoryStatus = new DTO.MemoryStatus {
    100               TotalMemory = statistic.SlaveStatistics.Sum(x => x.Memory) / 1024,
    101               FreeMemory = statistic.SlaveStatistics.Sum(x => x.FreeMemory) / 1024
    102             },
    103             Timestamp = JavascriptUtils.ToTimestamp(statistic.Timestamp)
    104           };
     141          status.CoreStatus.TotalCores += statistic.SlaveStatistics.Sum(x => x.Cores);
     142          freeCores += statistic.SlaveStatistics.Sum(x => x.FreeCores);
     143          status.CpuUtilizationStatus.TotalCpuUtilization += statistic.SlaveStatistics.Any()
     144                                                             ? statistic.SlaveStatistics.Average(x => x.CpuUtilization)
     145                                                             : 0.0;
     146          status.MemoryStatus.TotalMemory += statistic.SlaveStatistics.Sum(x => x.Memory) / 1024;
     147          freeMemory += statistic.SlaveStatistics.Sum(x => x.FreeMemory) / 1024;
     148          if (i >= increment) {
     149            status.Timestamp = JavascriptUtils.ToTimestamp(statistic.Timestamp);
     150            status.CoreStatus.TotalCores /= i;
     151            freeCores /= i;
     152            status.CpuUtilizationStatus.TotalCpuUtilization /= i;
     153            status.MemoryStatus.TotalMemory /= i;
     154            freeMemory /= i;
     155            status.CoreStatus.ActiveCores = status.CoreStatus.TotalCores;
     156            status.MemoryStatus.ActiveMemory = status.MemoryStatus.TotalMemory;
     157            status.CpuUtilizationStatus.ActiveCpuUtilization = status.CpuUtilizationStatus.TotalCpuUtilization;
     158            status.CpuUtilizationStatus.CalculatingCpuUtilization = status.CpuUtilizationStatus.CalculatingCpuUtilization;
     159            status.CoreStatus.CalculatingCores = status.CoreStatus.TotalCores - freeCores;
     160            status.MemoryStatus.UsedMemory = status.MemoryStatus.TotalMemory - freeMemory;
     161            yield return status;
     162            status = new DTO.Status {
     163              CoreStatus = new DTO.CoreStatus(),
     164              CpuUtilizationStatus = new DTO.CpuUtilizationStatus(),
     165              MemoryStatus = new DTO.MemoryStatus()
     166            };
     167            freeCores = 0;
     168            freeMemory = 0;
     169            i = 1;
     170          } else {
     171            i++;
     172          }
    105173        }
    106174      }
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataTransfer/Slave.cs

    r12428 r12435  
    1 namespace HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer {
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22namespace HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer {
    223  public class Slave {
    324    public string Id { get; set; } // currently unused
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataTransfer/Status.cs

    r12428 r12435  
    1 using System.Collections.Generic;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Collections.Generic;
    223
    324namespace HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer {
     
    526  public class CoreStatus {
    627    public int TotalCores { get; set; }
    7     public int AvailableCores { get; set; }
    8     public int FreeCores { get; set; }
     28    public int FreeCores { get; set; } // temporary quickfix for old chart data
     29    public int ActiveCores { get; set; }
     30    public int CalculatingCores { get; set; }
    931  }
    1032
    1133  public class CpuUtilizationStatus {
    1234    public double TotalCpuUtilization { get; set; }
    13     public double UsedCpuUtilization { get; set; }
     35    public double ActiveCpuUtilization { get; set; }
     36    public double CalculatingCpuUtilization { get; set; }
    1437  }
    1538
    1639  public class MemoryStatus {
    1740    public int TotalMemory { get; set; }
    18     public int FreeMemory { get; set; }
     41    public int FreeMemory { get; set; } // temporary quickfix for old chart data
     42    public int ActiveMemory { get; set; }
     43    public int UsedMemory { get; set; }
    1944  }
    2045
     
    2550  }
    2651
    27   public class SlaveCpuStatus {
     52  public class SlaveStatus {
    2853    public Slave Slave { get; set; }
    2954    public double CpuUtilization { get; set; }
     55    public int Cores { get; set; }
     56    public int FreeCores { get; set; }
     57    public int Memory { get; set; }
     58    public int FreeMemory { get; set; }
     59    public bool IsAllowedToCalculate { get; set; }
     60    public string State { get; set; }
    3061  }
    3162
     
    3566    public MemoryStatus MemoryStatus { get; set; }
    3667    public IEnumerable<TaskStatus> TasksStatus { get; set; }
    37     public IEnumerable<SlaveCpuStatus> SlavesCpuStatus { get; set; }
     68    public IEnumerable<SlaveStatus> SlavesStatus { get; set; }
    3869    public long Timestamp { get; set; }
    3970  }
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataTransfer/User.cs

    r12428 r12435  
    1 
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
    222namespace HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer {
    323  public class User {
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/JavascriptUtils.cs

    r12428 r12435  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223
    324namespace HeuristicLab.Services.WebApp.Status.WebApi {
     
    627      var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    728      var time = input.Subtract(new TimeSpan(epoch.Ticks));
    8       return (long)(time.Ticks / 10000);
     29      return time.Ticks / 10000;
    930    }
    1031  }
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/history/history.cshtml

    r12428 r12435  
    5656                <div class="panel-body">
    5757                    <flot dataset="coreSeries" options="fillChartOptions"></flot>
     58                    <p>{{maxUpper}}</p>
     59                    <p>{{fromDateTime}}</p>
     60                    <p>{{toDateTime}}</p>
    5861                </div>
    5962            </div>
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/history/historyCtrl.js

    r12428 r12435  
    44        ['$scope', '$interval', 'app.status.data.service',
    55        function ($scope, $interval, dataService) {
    6 
    76            $scope.chartOptions = {
    87                grid: {
     
    5958            };
    6059
     60
    6161            $scope.fromDate = new Date();
    6262            $scope.toDate = new Date();
     
    8989
    9090            var updateCharts = function () {
    91                 dataService.getStatusHistory({start: ConvertFromDate($scope.fromDate), end: ConvertToDate($scope.toDate)}, function (status) {
     91                dataService.getStatusHistory({ start: ConvertFromDate($scope.fromDate), end: ConvertToDate($scope.toDate) }, function (status) {
    9292                    var noOfStatus = status.length;
    9393                    var cpuSeries = [];
     
    9696                    for (var i = 0; i < noOfStatus; ++i) {
    9797                        var curStatus = status[i];
    98                         var cpuData = Math.round(curStatus.CpuUtilizationStatus.UsedCpuUtilization);
    99                         var usedCores = curStatus.CoreStatus.TotalCores - curStatus.CoreStatus.FreeCores;
    100                         var usedMemory = curStatus.MemoryStatus.TotalMemory - curStatus.MemoryStatus.FreeMemory;
     98                        var cpuData = Math.round(curStatus.CpuUtilizationStatus.ActiveCpuUtilization);
    10199                        cpuSeries.push([curStatus.Timestamp, cpuData]);
    102                         coreSeries[0].push([curStatus.Timestamp, curStatus.CoreStatus.TotalCores]);
    103                         coreSeries[1].push([curStatus.Timestamp, usedCores]);
    104                         memorySeries[0].push([curStatus.Timestamp, curStatus.MemoryStatus.TotalMemory]);
    105                         memorySeries[1].push([curStatus.Timestamp, usedMemory]);
     100                        coreSeries[0].push([curStatus.Timestamp, curStatus.CoreStatus.ActiveCores]);
     101                        coreSeries[1].push([curStatus.Timestamp, curStatus.CoreStatus.CalculatingCores]);
     102                        memorySeries[0].push([curStatus.Timestamp, curStatus.MemoryStatus.ActiveMemory]);
     103                        memorySeries[1].push([curStatus.Timestamp, curStatus.MemoryStatus.UsedMemory]);
    106104                    }
    107105                    $scope.cpuSeries = [{ data: cpuSeries, label: "&nbsp;CPU Utilization", color: "#f7921d" }];
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/status/status.cshtml

    r12428 r12435  
    1111
    1212<div class="default-view-container">
    13     <div class="row">
    14         <div class="col-lg-3 col-md-6">
    15             <div class="panel panel-default">
    16                 <div class="panel-heading">
    17                     <h3 class="panel-title">Cores</h3>
    18                 </div>
    19                 <div class="panel-body">
    20                     <center>
    21                         <knob knob-data="core.knobData" knob-options="knobOptions"></knob>
    22                     </center>
    23                     <p>Total Cores: {{status.CoreStatus.TotalCores}}</p>
    24                     <p>Used Cores: {{status.CoreStatus.TotalCores - status.CoreStatus.FreeCores}}</p>
    25                 </div>
    26             </div>
    27         </div>
    28 
    29         <div class="col-lg-3 col-md-6">
    30             <div class="panel panel-default">
    31                 <div class="panel-heading">
    32                     <h3 class="panel-title">CPU Utilization</h3>
    33                 </div>
    34                 <div class="panel-body">
    35                     <center>
    36                         <knob knob-data="cpu.knobData" knob-options="knobOptions"></knob>
    37                     </center>
    38                     <p>Total Utilization: {{status.CpuUtilizationStatus.TotalCpuUtilization}} %</p>
    39                     <p>Used Utilization: {{status.CpuUtilizationStatus.UsedCpuUtilization}} %</p>
    40                 </div>
    41             </div>
    42         </div>
    43 
    44         <div class="col-lg-3 col-md-6">
    45             <div class="panel panel-default">
    46                 <div class="panel-heading">
    47                     <h3 class="panel-title">Memory</h3>
    48                 </div>
    49                 <div class="panel-body">
    50                     <center>
    51                         <knob knob-data="memory.knobData" knob-options="knobOptions"></knob>
    52                     </center>
    53                     <p>TotalMemory: {{status.MemoryStatus.TotalMemory}} GB</p>
    54                     <p>UsedMemory: {{status.MemoryStatus.TotalMemory - status.MemoryStatus.FreeMemory}} GB</p>
    55                 </div>
    56             </div>
    57         </div>
    58 
    59         <div class="col-lg-3 col-md-6">
    60             <div class="panel panel-default">
    61                 <div class="panel-heading">
    62                     <h3 class="panel-title">Tasks</h3>
    63                 </div>
    64                 <div class="panel-body">
    65                     <p>Total: {{tasks.WaitingTasks + tasks.CalculatingTasks}}</p>
    66                     <p>Waiting: {{tasks.WaitingTasks}}</p>
    67                     <p>Calculating: {{tasks.CalculatingTasks}}</p>
    68                 </div>
    69             </div>
    70         </div>
    71     </div>
    72 
    73     <div class="row">
    74         <div class="col-lg-12">
    75             <div class="panel panel-default">
    76                 <div class="panel-heading">
    77                     <h3 class="panel-title">CPU Utilization Chart</h3>
    78                 </div>
    79                 <div class="panel-body">
    80                     <flot dataset="cpu.series" options="chartOptions"></flot>
    81                 </div>
    82             </div>
    83         </div>
    84     </div>
    85 
    86     <div class="row">
    87         <div class="col-lg-12">
    88             <div class="panel panel-default">
    89                 <div class="panel-heading">
    90                     <h3 class="panel-title">Core Chart</h3>
    91                 </div>
    92                 <div class="panel-body">
    93                     <flot dataset="core.series" options="fillChartOptions"></flot>
    94                 </div>
    95             </div>
    96         </div>
    97     </div>
    98 
    99     <div class="row">
    100         <div class="col-lg-12">
    101             <div class="panel panel-default">
    102                 <div class="panel-heading">
    103                     <h3 class="panel-title">Memory Chart</h3>
    104                 </div>
    105                 <div class="panel-body">
    106                     <flot dataset="memory.series" options="fillChartOptions"></flot>
    107                 </div>
    108             </div>
    109         </div>
    110     </div>
    111 
    112     <div class="row">
    113         <div class="col-lg-12">
    114             <div class="panel panel-default">
    115                 <div class="panel-heading">
    116                     <h3 class="panel-title">Tasks by User</h3>
    117                 </div>
     13<div class="row">
     14    <div class="col-lg-3 col-md-6">
     15        <div class="panel panel-default">
     16            <div class="panel-heading">
     17                <h3 class="panel-title">Cores</h3>
     18            </div>
     19            <div class="panel-body">
     20                <div class="text-center">
     21                    <knob knob-data="core.knobData" knob-options="knobOptions"></knob>
     22                </div>
     23                <table class="table table-no-border table-condensed table-auto-width table-content">
     24                    <tr data-toggle="tooltip" data-placement="bottom" title="All online slaves">
     25                        <td class="text-left">
     26                            Total:
     27                        </td>
     28                        <td class="text-right">{{status.CoreStatus.TotalCores | number}}</td>
     29                    </tr>
     30                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating and idle slaves that are allowed to calculate">
     31                        <td class="text-left">Active:</td>
     32                        <td class="text-right">{{status.CoreStatus.ActiveCores | number}}</td>
     33                    </tr>
     34                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating slaves that are allowed to calculate">
     35                        <td class="text-left">Calculating:</td>
     36                        <td class="text-right">{{status.CoreStatus.CalculatingCores | number}}</td>
     37                    </tr>
     38                </table>
     39            </div>
     40        </div>
     41    </div>
     42
     43    <div class="col-lg-3 col-md-6">
     44        <div class="panel panel-default">
     45            <div class="panel-heading">
     46                <h3 class="panel-title">CPU Utilization</h3>
     47            </div>
     48            <div class="panel-body">
     49                <div class="text-center">
     50                    <knob knob-data="cpu.knobData" knob-options="knobOptions"></knob>
     51                </div>
     52                <table class="table table-no-border table-condensed table-auto-width table-content">
     53                    <tr data-toggle="tooltip" data-placement="bottom" title="All online slaves">
     54                        <td class="text-left">Total:</td>
     55                        <td class="text-right">{{status.CpuUtilizationStatus.TotalCpuUtilization | number: 2}} %</td>
     56                    </tr>
     57                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating and idle slaves that are allowed to calculate">
     58                        <td class="text-left">Active:</td>
     59                        <td class="text-right">{{status.CpuUtilizationStatus.ActiveCpuUtilization | number: 2}} %</td>
     60                    </tr>
     61                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating slaves that are allowed to calculate">
     62                        <td class="text-left">Calculating:</td>
     63                        <td class="text-right">{{status.CpuUtilizationStatus.CalculatingCpuUtilization | number: 2}} %</td>
     64                    </tr>
     65                </table>
     66            </div>
     67        </div>
     68    </div>
     69
     70    <div class="col-lg-3 col-md-6">
     71        <div class="panel panel-default">
     72            <div class="panel-heading">
     73                <h3 class="panel-title">Memory</h3>
     74            </div>
     75            <div class="panel-body">
     76                <div class="text-center">
     77                    <knob knob-data="memory.knobData" knob-options="knobOptions"></knob>
     78                </div>
     79                <table class="table table-no-border table-condensed table-auto-width table-content">
     80                    <tr data-toggle="tooltip" data-placement="bottom" title="All online slaves">
     81                        <td class="text-left">Total:</td>
     82                        <td class="text-right">{{status.MemoryStatus.TotalMemory | number}} GB</td>
     83                    </tr>
     84                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating and idle slaves that are allowed to calculate">
     85                        <td class="text-left">Active:</td>
     86                        <td class="text-right">{{status.MemoryStatus.ActiveMemory | number}} GB</td>
     87                    </tr>
     88                    <tr data-toggle="tooltip" data-placement="bottom" title="All calculating slaves that are allowed to calculate">
     89                        <td class="text-left">Calculating:</td>
     90                        <td class="text-right">{{status.MemoryStatus.UsedMemory | number}} GB</td>
     91                    </tr>
     92                </table>
     93            </div>
     94        </div>
     95    </div>
     96
     97    <div class="col-lg-3 col-md-6">
     98        <div class="panel panel-default">
     99            <div class="panel-heading">
     100                <h3 class="panel-title">Tasks</h3>
     101            </div>
     102            <div class="panel-body">
     103                <table class="table table-no-border table-condensed table-auto-width table-content">
     104                    <tr>
     105                        <td class="text-left">Total:</td>
     106                        <td class="text-right">{{tasks.WaitingTasks + tasks.CalculatingTasks | number}}</td>
     107                    </tr>
     108                    <tr>
     109                        <td class="text-left">Waiting:</td>
     110                        <td class="text-right">{{tasks.WaitingTasks | number}}</td>
     111                    </tr>
     112                    <tr>
     113                        <td class="text-left">Calculating:</td>
     114                        <td class="text-right">{{tasks.CalculatingTasks | number}}</td>
     115                    </tr>
     116                </table>
     117            </div>
     118        </div>
     119    </div>
     120</div>
     121
     122<div class="row">
     123    <div class="col-lg-12">
     124        <div class="panel panel-default">
     125            <div class="panel-heading">
     126                <h3 class="panel-title">CPU Utilization Chart</h3>
     127            </div>
     128            <div class="panel-body">
     129                <flot dataset="cpu.series" options="chartOptions"></flot>
     130            </div>
     131        </div>
     132    </div>
     133</div>
     134
     135<div class="row">
     136    <div class="col-lg-12">
     137        <div class="panel panel-default">
     138            <div class="panel-heading">
     139                <h3 class="panel-title">Core Chart</h3>
     140            </div>
     141            <div class="panel-body">
     142                <flot dataset="core.series" options="fillChartOptions"></flot>
     143            </div>
     144        </div>
     145    </div>
     146</div>
     147
     148<div class="row">
     149    <div class="col-lg-12">
     150        <div class="panel panel-default">
     151            <div class="panel-heading">
     152                <h3 class="panel-title">Memory Chart</h3>
     153            </div>
     154            <div class="panel-body">
     155                <flot dataset="memory.series" options="fillChartOptions"></flot>
     156            </div>
     157        </div>
     158    </div>
     159</div>
     160
     161<div class="row">
     162    <div class="col-lg-12">
     163        <div class="panel panel-default">
     164            <div class="panel-heading">
     165                <h3 class="panel-title">Tasks by User</h3>
     166            </div>
     167            <div class="panel-body">
     168                <table class="table table-hover">
     169                    <thead>
     170                    <tr>
     171                        <th>Username</th>
     172                        <th>Calculating Tasks</th>
     173                        <th>Waiting Tasks</th>
     174                    </tr>
     175                    </thead>
     176                    <tr ng-repeat="task in status.TasksStatus">
     177                        <td>{{task.User.Name}}</td>
     178                        <td>{{task.CalculatingTasks | number}}</td>
     179                        <td>{{task.WaitingTasks | number}}</td>
     180                    </tr>
     181                    <tr ng-hide="status.TasksStatus.length">
     182                        <td colspan="3" class="text-center">
     183                            There are no waiting or calculating tasks available!
     184                        </td>
     185                    </tr>
     186                </table>
     187            </div>
     188        </div>
     189    </div>
     190</div>
     191
     192<div class="row">
     193    <div class="col-lg-12">
     194        <div class="panel panel-default">
     195            <div class="panel-heading">
     196                <h3 class="panel-title">
     197                    <a data-toggle="collapse" data-target="#collapseActiveCalculatingSlaves"
     198                       ng-href="#/status">
     199                        Active Calculating Slaves
     200                    </a>
     201                </h3>
     202            </div>
     203            <div id="collapseActiveCalculatingSlaves"
     204                 class="panel-collapse collapse in">
    118205                <div class="panel-body">
    119206                    <table class="table table-hover">
    120207                        <thead>
    121                             <tr>
    122                                 <th>Username</th>
    123                                 <th>Calculating Tasks</th>
    124                                 <th>Waiting Tasks</th>
    125                             </tr>
     208                        <tr>
     209                            <th ng-click="activeCalculatingSlavesOrderColumn='Slave.Name';
     210                                                  activeCalculatingSlavesReverseSort=!activeCalculatingSlavesReverseSort">
     211                                Slave
     212                            </th>
     213                            <th ng-click="activeCalculatingSlavesOrderColumn='CpuUtilization';
     214                                                  activeCalculatingSlavesReverseSort=!activeCalculatingSlavesReverseSort">
     215                                CPU Utilization
     216                            </th>
     217                            <th ng-click="activeCalculatingSlavesOrderColumn='Cores';
     218                                                  activeCalculatingSlavesReverseSort=!activeCalculatingSlavesReverseSort">
     219                                Cores
     220                            </th>
     221                            <th ng-click="activeCalculatingSlavesOrderColumn='Memory';
     222                                                  activeCalculatingSlavesReverseSort=!activeCalculatingSlavesReverseSort">
     223                                Memory
     224                            </th>
     225                        </tr>
    126226                        </thead>
    127                         <tr ng-repeat="task in status.TasksStatus">
    128                             <td>{{task.User.Name}}</td>
    129                             <td>{{task.CalculatingTasks}}</td>
    130                             <td>{{task.WaitingTasks}}</td>
     227                        <tr ng-repeat="slave in activeCalculatingSlaves = (status.SlavesStatus
     228                                | filter: {
     229                                    IsAllowedToCalculate: true,
     230                                    State: 'Calculating'
     231                                  }
     232                                | orderBy: activeCalculatingSlavesOrderColumn:activeCalculatingSlavesReverseSort)">
     233                            <td>{{slave.Slave.Name}}</td>
     234                            <td>{{slave.CpuUtilization | number: 2}} %</td>
     235                            <td>{{slave.Cores | number}}</td>
     236                            <td>{{slave.Memory | number}} GB</td>
     237                        </tr>
     238                        <tr ng-hide="activeCalculatingSlaves.length">
     239                            <td colspan="4" class="text-center">
     240                                There are no active calculating slaves available!
     241                            </td>
    131242                        </tr>
    132243                    </table>
     
    135246        </div>
    136247    </div>
    137 
    138     <div class="row">
    139         <div class="col-lg-12">
    140             <div class="panel panel-default">
    141                 <div class="panel-heading">
    142                     <h3 class="panel-title">CPU Utilization by Slave</h3>
    143                 </div>
     248</div>
     249
     250<div class="row">
     251    <div class="col-lg-12">
     252        <div class="panel panel-default">
     253            <div class="panel-heading">
     254                <h3 class="panel-title">
     255                    <a data-toggle="collapse" data-target="#collapseActiveIdleSlaves"
     256                       ng-href="#/status" class="collapsed">
     257                        Active Idle Slaves
     258                    </a>
     259                </h3>
     260            </div>
     261            <div id="collapseActiveIdleSlaves"
     262                 class="panel-collapse collapse">
    144263                <div class="panel-body">
    145264                    <table class="table table-hover">
    146265                        <thead>
    147                             <tr>
    148                                 <th>Slave</th>
    149                                 <th>CPU Utilization</th>
    150                             </tr>
     266                        <tr>
     267                            <th ng-click="activeIdleSlavesOrderColumn='Slave.Name';
     268                                                  activeIdleSlavesReverseSort=!activeIdleSlavesReverseSort">
     269                                Slave
     270                            </th>
     271                            <th ng-click="activeIdleSlavesOrderColumn='CpuUtilization';
     272                                                  activeIdleSlavesReverseSort=!activeIdleSlavesReverseSort">
     273                                CPU Utilization
     274                            </th>
     275                            <th ng-click="activeIdleSlavesOrderColumn='Cores';
     276                                                  activeIdleSlavesReverseSort=!activeIdleSlavesReverseSort">
     277                                Cores
     278                            </th>
     279                            <th ng-click="activeIdleSlavesOrderColumn='Memory';
     280                                                  activeIdleSlavesReverseSort=!activeIdleSlavesReverseSort">
     281                                Memory
     282                            </th>
     283                        </tr>
    151284                        </thead>
    152                         <tr ng-repeat="slave in status.SlavesCpuStatus">
     285                        <tr ng-repeat="slave in activeIdleSlaves = (status.SlavesStatus
     286                                | filter: {
     287                                    IsAllowedToCalculate: true,
     288                                    State: 'Idle'
     289                                  }
     290                                | orderBy: activeIdleSlavesOrderColumn:activeIdleSlavesReverseSort)">
    153291                            <td>{{slave.Slave.Name}}</td>
    154                             <td>{{slave.CpuUtilization}} %</td>
     292                            <td>{{slave.CpuUtilization | number: 2}} %</td>
     293                            <td>{{slave.Cores | number}}</td>
     294                            <td>{{slave.Memory | number}} GB</td>
     295                        </tr>
     296                        <tr ng-hide="activeIdleSlaves.length">
     297                            <td colspan="4" class="text-center">
     298                            There are no active idle slaves available!
     299                            <td>
    155300                        </tr>
    156301                    </table>
     
    160305    </div>
    161306</div>
     307
     308<div class="row">
     309    <div class="col-lg-12">
     310        <div class="panel panel-default">
     311            <div class="panel-heading">
     312                <h3 class="panel-title">
     313                    <a data-toggle="collapse" data-target="#collapseInactiveSlaves"
     314                       ng-href="#/status" class="collapsed">
     315                        Inactive Slaves
     316                    </a>
     317                </h3>
     318            </div>
     319            <div id="collapseInactiveSlaves"
     320                 class="panel-collapse collapse">
     321                <div class="panel-body">
     322                    <table class="table table-hover">
     323                        <thead>
     324                        <tr>
     325                            <th ng-click="inactiveSlavesOrderColumn='Slave.Name';
     326                                                  inactiveSlavesReverseSort=!inactiveSlavesReverseSort">
     327                                Slave
     328                            </th>
     329                            <th ng-click="inactiveSlavesOrderColumn='CpuUtilization';
     330                                                  inactiveSlavesReverseSort=!inactiveSlavesReverseSort">
     331                                CPU Utilization
     332                            </th>
     333                            <th ng-click="inactiveSlavesOrderColumn='Cores';
     334                                                  inactiveSlavesReverseSort=!inactiveSlavesReverseSort">
     335                                Cores
     336                            </th>
     337                            <th ng-click="inactiveSlavesOrderColumn='Memory';
     338                                                  inactiveSlavesReverseSort=!inactiveSlavesReverseSort">
     339                                Memory
     340                            </th>
     341                        </tr>
     342                        </thead>
     343                        <tr ng-repeat="slave in inactiveSlaves = (status.SlavesStatus
     344                                | filter: {
     345                                    IsAllowedToCalculate: false
     346                                  }
     347                                | orderBy: inactiveSlavesOrderColumn:inactiveSlavesReverseSort)">
     348                            <td>{{slave.Slave.Name}}</td>
     349                            <td>{{slave.CpuUtilization | number: 2}} %</td>
     350                            <td>{{slave.Cores | number}}</td>
     351                            <td>{{slave.Memory | number}} GB</td>
     352                        </tr>
     353                        <tr ng-hide="inactiveSlaves.length">
     354                            <td colspan="4" class="text-center">No inactive slaves available!</td>
     355                        </tr>
     356                    </table>
     357                </div>
     358            </div>
     359        </div>
     360    </div>
     361</div>
     362</div>
     363
     364<script>
     365    $(document).ready(function () {
     366        $('[data-toggle="tooltip"]').tooltip();
     367    });
     368</script>
  • trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/status/statusCtrl.js

    r12428 r12435  
    5353                    mode: "time",
    5454                    twelveHourClock: false
     55                },
     56                yaxis: {
     57                    min: 0
    5558                }
    5659            };
     
    8285            };
    8386
     87            $scope.activeIdleSlaveFilter = function (slave) {
     88                return (slave.IsAllowedToCalculate == true) && (slave.State == 'Idle');
     89            };
     90
     91            $scope.activeCalculatingSlavesReverseSort = false;
     92            $scope.activeCalculatingSlavesOrderColumn = 'slave.Slave.Name';
     93
     94            $scope.activeIdleSlavesReverseSort = false;
     95            $scope.activeIdleSlavesOrderColumn = 'slave.Slave.Name';
     96
     97            $scope.inactiveSlavesReverseSort = false;
     98            $scope.inactiveSlavesOrderColumn = 'slave.Slave.Name';
     99
     100
    84101            var updateStatus = function () {
    85102                // update status data
    86103                dataService.getStatus({}, function (status) {
     104                    var oneDayInMs = 24 * 60 * 60 * 1000;
     105                    var today = new Date().getTime() - oneDayInMs;
    87106                    // raw status data
    88107                    $scope.status = status;
     
    96115                    }
    97116                    // knobs
    98                     $scope.cpu.knobData = Math.round(status.CpuUtilizationStatus.UsedCpuUtilization);
    99                     var usedCores = status.CoreStatus.TotalCores - status.CoreStatus.FreeCores;
    100                     $scope.core.knobData = Math.round(usedCores / status.CoreStatus.TotalCores * 100);
    101                     var usedMemory = status.MemoryStatus.TotalMemory - status.MemoryStatus.FreeMemory;
    102                     $scope.memory.knobData = Math.round(usedMemory / status.MemoryStatus.TotalMemory * 100);
     117                    $scope.cpu.knobData = Math.round(status.CpuUtilizationStatus.ActiveCpuUtilization);
     118                    $scope.core.knobData = Math.round(status.CoreStatus.CalculatingCores / status.CoreStatus.ActiveCores * 100);
     119                    $scope.memory.knobData = Math.round(status.MemoryStatus.UsedMemory / status.MemoryStatus.ActiveMemory * 100);
    103120                    // chart series
    104121                    var cpuSeries = $scope.cpu.series[0].data.splice(0);
    105                     if (cpuSeries.length > 2) {
    106                         cpuSeries.splice(0, 1);
    107                     }
    108122                    var coreSeries = [$scope.core.series[0].data, $scope.core.series[1].data];
    109                     if (coreSeries[0].length > 2) {
    110                         coreSeries[0].splice(0, 1);
    111                     }
    112                     if (coreSeries[1].length > 2) {
    113                         coreSeries[1].splice(0, 1);
    114                     }
    115123                    var memorySeries = [$scope.memory.series[0].data, $scope.memory.series[1].data];
    116                     if (memorySeries[0].length > 2) {
    117                         memorySeries[0].splice(0, 1);
    118                     }
    119                     if (memorySeries[1].length > 2) {
    120                         memorySeries[1].splice(0, 1);
     124                    if ($scope.status.Timestamp < today) {
     125                        if (cpuSeries.length > 2) {
     126                            cpuSeries.splice(0, 1);
     127                        }
     128                        if (coreSeries[0].length > 2) {
     129                            coreSeries[0].splice(0, 1);
     130                        }
     131                        if (coreSeries[1].length > 2) {
     132                            coreSeries[1].splice(0, 1);
     133                        }
     134                        if (memorySeries[0].length > 2) {
     135                            memorySeries[0].splice(0, 1);
     136                        }
     137                        if (memorySeries[1].length > 2) {
     138                            memorySeries[1].splice(0, 1);
     139                        }
    121140                    }
    122141                    cpuSeries.push([$scope.status.Timestamp, $scope.cpu.knobData]);
     142
     143                    // charts are currently filled with old total/used data
     144                    // start temporary
     145                    var usedCores = status.CoreStatus.TotalCores - status.getCoreStatus.FreeCores;
     146                    var usedMemory = status.MemoryStatus.TotalMemory - status.MemoryStatus.FreeMemory;
     147                    // end temporary
    123148                    coreSeries[0].push([$scope.status.Timestamp, status.CoreStatus.TotalCores]);
    124149                    coreSeries[1].push([$scope.status.Timestamp, usedCores]);
     
    149174                    for (var i = 0; i < noOfStatus; ++i) {
    150175                        var curStatus = status[i];
    151                         var cpuData = Math.round(curStatus.CpuUtilizationStatus.UsedCpuUtilization);
    152                         var usedCores = curStatus.CoreStatus.TotalCores - curStatus.CoreStatus.FreeCores;
    153                         var usedMemory = curStatus.MemoryStatus.TotalMemory - curStatus.MemoryStatus.FreeMemory;
     176                        var cpuData = Math.round(curStatus.CpuUtilizationStatus.ActiveCpuUtilization);
    154177                        cpuSeries.push([curStatus.Timestamp, cpuData]);
    155                         coreSeries[0].push([curStatus.Timestamp, curStatus.CoreStatus.TotalCores]);
    156                         coreSeries[1].push([curStatus.Timestamp, usedCores]);
    157                         memorySeries[0].push([curStatus.Timestamp, curStatus.MemoryStatus.TotalMemory]);
    158                         memorySeries[1].push([curStatus.Timestamp, usedMemory]);
     178                        coreSeries[0].push([curStatus.Timestamp, curStatus.CoreStatus.ActiveCores]);
     179                        coreSeries[1].push([curStatus.Timestamp, curStatus.CoreStatus.CalculatingCores]);
     180                        memorySeries[0].push([curStatus.Timestamp, curStatus.MemoryStatus.ActiveMemory]);
     181                        memorySeries[1].push([curStatus.Timestamp, curStatus.MemoryStatus.UsedMemory]);
    159182                    }
    160183                    $scope.cpu.series = [{ data: cpuSeries, label: "&nbsp;CPU Utilization", color: "#f7921d" }];
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Configs/BundleConfig.cs

    r12428 r12435  
    1 using System.Collections.Generic;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Collections.Generic;
    223using System.IO;
    3 using System.Linq;
    4 using System.Web;
    524using System.Web.Optimization;
    625
    726namespace HeuristicLab.Services.WebApp.Configs {
    827  public class BundleConfig {
     28
    929    public static void RegisterBundles(BundleCollection bundles) {
    1030      bundles.IgnoreList.Clear();
     
    6181        "~/WebApp/app.css"
    6282      ));
    63       AddOrUpdateWebAppBundle();
     83
     84      bundles.Add(new ScriptBundle("~/Bundles/WebApp/Main").Include(
     85        "~/WebApp/main.js"
     86      ));
     87
     88      bundles.Add(new ScriptBundle("~/Bundles/WebApp/Shared")
     89        .IncludeDirectory("~/WebApp/shared/services", "*.js", true)
     90        .IncludeDirectory("~/WebApp/shared/directives", "*.js", true)
     91        .IncludeDirectory("~/WebApp/shared/menu", "*.js", true)
     92      );
    6493    }
    6594
    66     public static void AddOrUpdateWebAppBundle() {
    67       var jsBundle = BundleTable.Bundles.GetBundleFor("~/Bundles/WebApp/js");
    68       if (jsBundle != null) {
    69         BundleTable.Bundles.Remove(jsBundle);
     95    public static IEnumerable<string> GetWebAppScripts() {
     96      var jsFiles = new List<string> {
     97        "WebApp/helper.js",
     98        "WebApp/app.js"
     99      };
     100      PluginManager pluginManager = PluginManager.Instance;
     101      foreach (var plugin in pluginManager.GetPlugins()) {
     102        if (File.Exists(string.Format(@"{0}\{1}\{1}.js", PluginManager.PluginsDirectory, plugin.Name))) {
     103          jsFiles.Add(string.Format("WebApp/plugins/{0}/{0}.js", plugin.Name));
     104        }
    70105      }
    71       var jsFiles = new List<string> {
    72         "~/WebApp/helper.js",
    73         "~/WebApp/app.js"
    74       };
    75       var directories = Directory.GetDirectories(string.Format(@"{0}WebApp\plugins", HttpRuntime.AppDomainAppPath));
    76       jsFiles.AddRange(directories.Select(Path.GetFileName).Select(directory => string.Format("~/WebApp/plugins/{0}/{0}.js", directory)));
    77       jsFiles.Add("~/WebApp/main.js");
    78       jsBundle = new ScriptBundle("~/Bundles/WebApp/js");
    79       jsBundle.Include(jsFiles.ToArray());
    80       jsBundle.IncludeDirectory("~/WebApp/shared/", "*.js", true);
    81       BundleTable.Bundles.Add(jsBundle);
     106      jsFiles.Add("WebApp/main.js");
     107      return jsFiles;
    82108    }
    83109  }
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Configs/FilterConfig.cs

    r12428 r12435  
    1 using System.Web.Mvc;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Web.Mvc;
    223
    324namespace HeuristicLab.Services.WebApp.Configs {
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Configs/RouteConfig.cs

    r12428 r12435  
    1 using System.Web.Mvc;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Web.Mvc;
    223using System.Web.Routing;
    324
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Configs/WebApiConfig.cs

    r12428 r12435  
    1 
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
    222using System.Net.Http.Formatting;
    323using System.Web.Http;
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/AppController.cs

    r12428 r12435  
    2121
    2222using System.Web.Mvc;
    23 using HeuristicLab.Services.WebApp.Configs;
    2423
    2524namespace HeuristicLab.Services.WebApp.Controllers {
     
    3130        return RedirectPermanent(Request.Url + "/");
    3231      }
    33       BundleConfig.AddOrUpdateWebAppBundle();
    3432      return View("~/WebApp/shared/layout/layout.cshtml");
    3533    }
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/AuthenticationController.cs

    r12428 r12435  
    1 using System.Web.Http;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Web.Http;
    223using System.Web.Security;
    324using HeuristicLab.Services.WebApp.Controllers.DataTransfer;
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/DataTransfer/Plugin.cs

    r12428 r12435  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223
    324namespace HeuristicLab.Services.WebApp.Controllers.DataTransfer {
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/DataTransfer/User.cs

    r12428 r12435  
    1 namespace HeuristicLab.Services.WebApp.Controllers.DataTransfer {
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22namespace HeuristicLab.Services.WebApp.Controllers.DataTransfer {
    223  public class User {
    324    public string Username { get; set; }
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/PluginController.cs

    r12428 r12435  
    1 using System.Collections.Generic;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Collections.Generic;
    223using System.Linq;
    324using System.Web.Http;
     25using HeuristicLab.Services.Hive;
    426using DTO = HeuristicLab.Services.WebApp.Controllers.DataTransfer;
    527
    628namespace HeuristicLab.Services.WebApp.Controllers {
    729
    8   [Authorize(Roles = "Hive Administrator")]
     30  [Authorize(Roles = HiveRoles.Administrator)]
    931  public class PluginController : ApiController {
    1032
     
    2143
    2244    public bool ReloadPlugin(string name) {
    23       var plugin = PluginManager.Instance.GetPlugin(name);
     45      var plugin = pluginManager.GetPlugin(name);
     46      if (plugin == null)
     47        return false;
    2448      plugin.ReloadControllers();
    2549      return true;
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Controllers/WebAppControllerSelector.cs

    r12428 r12435  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223using System.Collections.Concurrent;
    324using System.Collections.Generic;
     
    1839      : base(configuration) {
    1940      this.configuration = configuration;
    20       pluginManager.Configuration = configuration;
    2141      controllers = new ConcurrentDictionary<string, HttpControllerDescriptor>();
    2242      LoadAppControllers();
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Global.asax.cs

    r12428 r12435  
    88  public class MvcApplication : System.Web.HttpApplication {
    99    protected void Application_Start() {
     10      var pluginManager = PluginManager.Instance;
     11      pluginManager.Configuration = GlobalConfiguration.Configuration;
     12      pluginManager.DiscoverPlugins();
    1013      AreaRegistration.RegisterAllAreas();
    1114      GlobalConfiguration.Configure(WebApiConfig.Register);
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/Plugin.cs

    r12428 r12435  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223using System.Collections.Concurrent;
    324using System.Collections.Generic;
     
    526using System.Linq;
    627using System.Reflection;
    7 using System.Text;
    828using System.Web.Http;
    929using System.Web.Http.Controllers;
     
    5676        AssemblyName = Path.GetFileName(assemblyPath);
    5777      }
    58       catch (ReflectionTypeLoadException ex) {
    59         StringBuilder sb = new StringBuilder();
    60         foreach (Exception exSub in ex.LoaderExceptions) {
    61           sb.AppendLine(exSub.Message);
    62           FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
    63           if (exFileNotFound != null) {
    64             if (!string.IsNullOrEmpty(exFileNotFound.FusionLog)) {
    65               sb.AppendLine("Fusion Log:");
    66               sb.AppendLine(exFileNotFound.FusionLog);
    67             }
    68           }
    69           sb.AppendLine();
    70         }
    71         AssemblyName = "Error loading assembly: " + sb.ToString();
     78      catch (Exception) {
     79        AssemblyName = "Error loading assembly";
    7280        Controllers.Clear();
    7381      }
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/PluginManager.cs

    r12428 r12435  
    1 using System.Collections.Concurrent;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System.Collections.Concurrent;
    223using System.Collections.Generic;
    324using System.IO;
     
    1738    public HttpConfiguration Configuration { get; set; }
    1839
    19     private string PluginsDirectory {
     40    public static string PluginsDirectory {
    2041      get { return string.Format(@"{0}WebApp\plugins", HttpRuntime.AppDomainAppPath); }
    2142    }
     
    2344    public PluginManager() {
    2445      plugins = new ConcurrentDictionary<string, Plugin>();
     46      var fileWatcher = new FileSystemWatcher(PluginsDirectory, "*") {
     47        IncludeSubdirectories = true,
     48        EnableRaisingEvents = true
     49      };
     50      fileWatcher.Created += OnFilesChanged;
     51      fileWatcher.Changed += OnFilesChanged;
     52      fileWatcher.Deleted += OnFilesChanged;
     53      fileWatcher.Renamed += OnFilesChanged;
     54    }
     55
     56    private void OnFilesChanged(object sender, FileSystemEventArgs args) {
     57      string path = args.FullPath.Remove(0, PluginsDirectory.Length + 1);
     58      var pathParts = path.Split('\\');
     59      string pluginName = pathParts[0];
     60      if (pathParts.Length == 1) {
     61        switch (args.ChangeType) {
     62          case WatcherChangeTypes.Created:
     63            GetPlugin(pluginName);
     64            break;
     65
     66          case WatcherChangeTypes.Deleted:
     67            plugins.Remove(pluginName);
     68            break;
     69
     70          case WatcherChangeTypes.Renamed:
     71            RenamedEventArgs renamedArgs = (RenamedEventArgs)args;
     72            string oldPath = renamedArgs.OldFullPath.Remove(0, PluginsDirectory.Length + 1);
     73            var oldPathParts = oldPath.Split('\\');
     74            string oldPluginName = oldPathParts[0];
     75            plugins.Remove(oldPluginName);
     76            GetPlugin(pluginName);
     77            break;
     78
     79          case WatcherChangeTypes.Changed:
     80            Plugin plugin = LookupPlugin(pluginName);
     81            if (plugin != null) {
     82              plugin.ReloadControllers();
     83            }
     84            break;
     85        }
     86      }
    2587    }
    2688
    2789    public Plugin GetPlugin(string name) {
    28       Plugin plugin;
    29       plugins.TryGetValue(name, out plugin);
     90      Plugin plugin = LookupPlugin(name);
    3091      if (plugin == null) {
    3192        string directory = string.Format(@"{0}\{1}", PluginsDirectory, name);
     
    43104
    44105    public IEnumerable<Plugin> GetPlugins() {
    45       DiscoverPlugins();
    46106      return plugins.Values;
    47107    }
    48108
    49     private void DiscoverPlugins() {
     109    public void DiscoverPlugins() {
    50110      var pluginDirectories = Directory.GetDirectories(PluginsDirectory);
    51111      foreach (var directory in pluginDirectories) {
    52112        string pluginName = Path.GetFileName(directory);
    53         Plugin plugin;
    54         plugins.TryGetValue(pluginName, out plugin);
     113        Plugin plugin = LookupPlugin(pluginName);
    55114        if (plugin == null) {
    56115          plugin = new Plugin {
     
    63122      }
    64123    }
     124
     125    private Plugin LookupPlugin(string name) {
     126      Plugin plugin;
     127      plugins.TryGetValue(name, out plugin);
     128      return plugin;
     129    }
    65130  }
    66131}
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/WebApp/app.css

    r12428 r12435  
    7979
    8080#menu {
    81   position: absolute;
    82   min-height: inherit;
    83   width: 250px;
     81  position: relative;
    8482  background: #FAFAFA;
    8583  display: block;
    8684  overflow: hidden;
    87   border-right: 1px solid #D3D3D3;
     85  z-index: 10000;
     86  width: 100%;
    8887}
    8988
     
    101100#view {
    102101  position: relative;
    103   left: 0px;
    104   margin-left: 250px;
     102  left: 0;
     103  margin-left: 0px;
    105104  display: block;
    106105  overflow: hidden;
    107106}
     107
    108108
    109109.view-header {
     
    124124}
    125125
    126 .navbar-header{
    127   width: 250px;
     126.navbar-header {
     127  width: 100%;
    128128  background: #3c3a39;
    129129  color: #FFFFFF;
     130  float: left;
     131}
     132
     133
     134@media (min-width: 768px) {
     135  #view {
     136    margin-left: 250px;
     137  }
     138
     139  #menu {
     140    visibility: visible;
     141    position: absolute;
     142    width: 250px;
     143    min-height: inherit;
     144    border-right: 1px solid #D3D3D3;
     145    z-index: 0;
     146  }
     147
     148  .navbar-header {
     149    width: 250px;
     150  }
     151}
     152.container-fluid .navbar-header {
     153  margin: 0;
     154  padding: 0;
     155}
     156
     157.navbar-nav {
     158  margin: 0;
     159  padding: 0;
     160}
     161
     162.navbar-right {
     163  float: right!important
     164}
     165
     166.navbar-nav>li>a {
     167  padding-top: 15px;
     168  padding-bottom: 15px;
     169}
     170
     171.navbar-content {
     172  padding-right: 15px;
     173}
     174
     175.navbar-nav > li {
     176  float: left;
    130177}
    131178
     
    140187.nav-sidebar {
    141188  font-size: 12px;
     189  padding-bottom: 30px;
    142190}
    143191
     
    279327}
    280328
     329.table-no-border>thead>tr>th,
     330.table-no-border>tbody>tr>th,
     331.table-no-border>tfoot>tr>th,
     332.table-no-border>thead>tr>td,
     333.table-no-border>tbody>tr>td,
     334.table-no-border>tfoot>tr>td,
     335.table-no-border>tbody,
     336.table-no-border>thead,
     337.table-no-border>tfoot{
     338  border-top: none !important;
     339  border-bottom: none !important;
     340}
     341
     342.table-auto-width {
     343  width: auto !important;
     344}
     345
     346.center-element {
     347  margin: 0 auto;
     348}
     349
     350.table-content {
     351  margin-bottom: 0;
     352}
    281353
    282354#top-navbar {
     
    311383
    312384.navbar-default .navbar-text {
     385  display: block;
    313386  color: #ffffff;
    314387  text-shadow: none !important;
    315 }
    316 
     388  margin: 0;
     389  padding: 15px;
     390}
     391
     392.navbar-nav {
     393  float:left;
     394  margin:0
     395}
     396
     397.navbar-nav>li {
     398  float:left
     399}
     400
     401.navbar-nav>li>a {
     402  padding-top:15px;
     403  padding-bottom:15px
     404}
     405
     406.navbar-toggle {
     407  border: none !important;
     408}
     409
     410.navbar-toggle:focus {
     411  background-color: transparent !important;
     412}
     413
     414.navbar-toggle:hover {
     415  background-color: #D3D3D3 !important;
     416}
     417
     418#menu .navbar-collapse {
     419  padding: 0;
     420  margin: 0;
     421}
    317422
    318423.default-view-container {
    319424  padding: 30px;
    320425}
     426
     427.panel-heading a:after {
     428    font-family:'Glyphicons Halflings';
     429    content:"\e114";
     430    float: right;
     431    color: grey;
     432}
     433.panel-heading a.collapsed:after {
     434    content:"\e080";
     435}
     436
     437.panel-heading a:focus, a:hover {
     438  text-decoration: none;
     439}
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/WebApp/shared/directives/flot.js

    r12428 r12435  
    66            link: function (scope, element, attrs) {
    77                var chart = null, opts = scope[attrs.options];
     8                var div = null;
    89
    910                scope.$watchCollection(attrs.dataset, function (newData, oldData) {
    1011                    if (!chart) {
    11                         var div = element.append("<div>");
     12                        div = element.append("<div>");
    1213                        div.bind("plotselected", function (event, ranges) {
    1314                            $.each(chart.getXAxes(), function (_, axis) {
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/WebApp/shared/layout/layout.cshtml

    r12428 r12435  
    1 @using HeuristicLab.Services.WebApp.Configs
     1@* HeuristicLab
     2 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 *
     4 * This file is part of HeuristicLab.
     5 *
     6 * HeuristicLab is free software: you can redistribute it and/or modify
     7 * it under the terms of the GNU General Public License as published by
     8 * the Free Software Foundation, either version 3 of the License, or
     9 * (at your option) any later version.
     10 *
     11 * HeuristicLab is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     18*@
     19
     20@using HeuristicLab.Services.WebApp.Configs
    221<!DOCTYPE html>
    322<html lang="en" ng-app="app">
     
    1534    <![endif]-->
    1635    @Scripts.Render("~/Bundles/Vendors/js")
    17     @{
    18         BundleTable.EnableOptimizations = false;
     36    @foreach (var script in BundleConfig.GetWebAppScripts()) {
     37        <script src="@script"></script>
    1938    }
    20     @Scripts.Render("~/Bundles/WebApp/js")
    21     @{
    22         BundleTable.EnableOptimizations = true;
    23     }
     39
     40    @Scripts.Render("~/Bundles/WebApp/Shared")
    2441</head>
    25 <body>
    26     <div id="app">
    27         <header id="toolbar" class="navbar navbar-default navbar-static-top no-border no-padding-margin"
    28                 ng-controller="app.menu.ctrl">
    29             <nav>
    30                 <div class="container-fluid">
    31                     <div class="navbar-header">
    32                         <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#top-navbar">
     42<body ngcloak>
     43<div id="app">
     44    <header id="toolbar" class="navbar navbar-default navbar-static-top no-border no-padding-margin"
     45            ng-controller="app.menu.ctrl">
     46        <nav>
     47            <div class="container-fluid">
     48                <div class="navbar-header">
     49                    <div class="center-block">
     50                        <a class="navbar-brand" href="#">
     51                            <img src="~/WebApp/shared/images/HeuristicLab-Logo.png" style="float: left; height: 100%; margin-right: 5px;"/>
     52                            <span style="color: #f7921d">HeuristicLab</span>
     53                        </a>
     54                        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#menu .navbar-collapse">
    3355                            <span class="sr-only">Toggle navigation</span>
    3456                            <span class="icon-bar"></span>
     
    3658                            <span class="icon-bar"></span>
    3759                        </button>
    38                         <a class="navbar-brand" href="#">
    39                             <img src="~/WebApp/shared/images/HeuristicLab-Logo.png" style="float: left; height: 100%; margin-left: 25px; margin-right: 5px;" />
    40                             Heuristic<span style="color: #f7921d">Lab</span>
    41                         </a>
    42                     </div>
    43 
    44                     <div class="collapse navbar-collapse" id="top-navbar">
    45                         <ul class="nav navbar-nav navbar-right">
    46                             @if (Request.IsAuthenticated) {
    47                                 <li>
    48                                     <p class="navbar-text">Hello @User.Identity.Name!</p>
    49                                 </li>
    50                                 <li>
    51                                     <a ng-href="" data-ng-click="logout()">Logout</a>
    52                                 </li>
    53                             } else {
    54                                 <li>
    55                                     <a ng-href="#/login">Login</a>
    56                                 </li>
    57                             }
    58                         </ul>
    5960                    </div>
    6061                </div>
    61             </nav>
    62         </header>
    6362
    64         <aside id="menu" ng-controller="app.menu.ctrl">
     63                <div class="navbar-content">
     64                    <ul class="nav navbar-nav navbar-right">
     65                        @if (Request.IsAuthenticated)
     66                        {
     67                            <li>
     68                                <span class="navbar-text">Hello @User.Identity.Name!</span>
     69                            </li>
     70                            <li>
     71                                <a ng-href="" data-ng-click="logout()">Logout</a>
     72                            </li>
     73                        }
     74                        else
     75                        {
     76                            <li>
     77                                <a ng-href="#/login" data-ng-click="hideMenu()">Login</a>
     78                            </li>
     79                        }
     80                    </ul>
     81                </div>
     82            </div>
     83        </nav>
     84    </header>
     85
     86    <aside id="menu" ng-controller="app.menu.ctrl">
     87        <div class="navbar-collapse collapse">
    6588            <ul class="nav nav-sidebar"
    6689                ng-include="'App/LoadSharedView?directory=menu&view=menu.cshtml&dateTime=@DateTime.Now'"
    6790                ng-init="entries = menuEntries;"></ul>
    68         </aside>
     91        </div>
     92    </aside>
    6993
    70         <section id="view">
    71             <ui-view/>
    72         </section>
    73     </div>
     94    <section id="view">
     95        <ui-view/>
     96    </section>
     97</div>
    7498</body>
    7599</html>
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/WebApp/shared/menu/menu.cshtml

    r12428 r12435  
    11<li ng-repeat="section in entries" ng-class="{'category':section.isCategory === true, 'active': isActive(section.route)}">
    2     <a ng-href="{{section.route}}" ng-if="!section.isCategory">
     2    <a ng-href="{{section.route}}" ng-if="!section.isCategory"
     3       data-toggle="collapse" data-target="#menu .navbar-collapse">
    34        <span ng-if="section.icon != ''" ng-class="section.icon" style="padding-right: 10px;"></span>
    45        <span>{{section.name}}</span>
  • trunk/sources/HeuristicLab.Services.WebApp/3.3/WebApp/shared/menu/menuCtrl.js

    r12428 r12435  
    2727                });
    2828            };
     29
     30            $scope.hideMenu = function() {
     31                $(".navbar-collapse").collapse('hide');
     32            };
    2933        }]
    3034    );
Note: See TracChangeset for help on using the changeset viewer.