WebUI: Sensors page modifications

Modified sensors page to use Redfish as backend.
Also added threshold sensor values in page view.

Tested By:
 Loaded webui page and tested all operations.
  - Sensors page load and layout.
  - Search Filter and Severity filters.
  - Export functionality.

Change-Id: Ic799453ffcd17e9a69e073a12173b4e97a928458
Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index 211f6d7..7643a4e 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -931,158 +931,55 @@
 
           return deferred.promise;
         },
-        getAllSensorStatus: function(callback) {
+        getSensorsInfo: function(url) {
+          return $http({
+                   method: 'GET',
+                   url: DataService.getHost() + url,
+                   withCredentials: true
+                 })
+              .then(
+                  function(response) {
+                    return response.data;
+                  },
+                  function(error) {
+                    console.log(JSON.stringify(error));
+                  });
+        },
+        getAllChassisCollection: function() {
+          var deferred = $q.defer();
+          var promises = [];
           $http({
             method: 'GET',
-            url: DataService.getHost() +
-                '/xyz/openbmc_project/sensors/enumerate',
+            url: DataService.getHost() + '/redfish/v1/Chassis',
             withCredentials: true
           })
               .then(
                   function(response) {
-                    var json = JSON.stringify(response.data);
-                    var content = JSON.parse(json);
-                    var dataClone = JSON.parse(JSON.stringify(content.data));
-                    var sensorData = [];
-                    var severity = {};
-                    var title = '';
-                    var tempKeyParts = [];
-                    var order = 0;
-                    var customOrder = 0;
-
-                    function getSensorStatus(reading) {
-                      var severityFlags = {
-                        critical: false,
-                        warning: false,
-                        normal: false
-                      },
-                          severityText = '', order = 0;
-
-                      if (reading.hasOwnProperty('CriticalLow') &&
-                          reading.Value < reading.CriticalLow) {
-                        severityFlags.critical = true;
-                        severityText = 'critical';
-                        order = 2;
-                      } else if (
-                          reading.hasOwnProperty('CriticalHigh') &&
-                          reading.Value > reading.CriticalHigh) {
-                        severityFlags.critical = true;
-                        severityText = 'critical';
-                        order = 2;
-                      } else if (
-                          reading.hasOwnProperty('CriticalLow') &&
-                          reading.hasOwnProperty('WarningLow') &&
-                          reading.Value >= reading.CriticalLow &&
-                          reading.Value <= reading.WarningLow) {
-                        severityFlags.warning = true;
-                        severityText = 'warning';
-                        order = 1;
-                      } else if (
-                          reading.hasOwnProperty('WarningHigh') &&
-                          reading.hasOwnProperty('CriticalHigh') &&
-                          reading.Value >= reading.WarningHigh &&
-                          reading.Value <= reading.CriticalHigh) {
-                        severityFlags.warning = true;
-                        severityText = 'warning';
-                        order = 1;
-                      } else {
-                        severityFlags.normal = true;
-                        severityText = 'normal';
-                      }
-                      return {
-                        flags: severityFlags,
-                        severityText: severityText,
-                        order: order
-                      };
-                    }
-
-                    for (var key in content.data) {
-                      if (content.data.hasOwnProperty(key) &&
-                          content.data[key].hasOwnProperty('Unit')) {
-                        severity = getSensorStatus(content.data[key]);
-
-                        if (!content.data[key].hasOwnProperty('CriticalLow')) {
-                          content.data[key].CriticalLow = '--';
-                          content.data[key].CriticalHigh = '--';
-                        }
-
-                        if (!content.data[key].hasOwnProperty('WarningLow')) {
-                          content.data[key].WarningLow = '--';
-                          content.data[key].WarningHigh = '--';
-                        }
-
-                        tempKeyParts = key.split('/');
-                        title = tempKeyParts.pop();
-                        title = tempKeyParts.pop() + '_' + title;
-                        title = title.split('_')
-                                    .map(function(item) {
-                                      return item.toLowerCase()
-                                                 .charAt(0)
-                                                 .toUpperCase() +
-                                          item.slice(1);
-                                    })
-                                    .reduce(function(prev, el) {
-                                      return prev + ' ' + el;
-                                    });
-
-                        content.data[key].Value = getScaledValue(
-                            content.data[key].Value, content.data[key].Scale);
-                        content.data[key].CriticalLow = getScaledValue(
-                            content.data[key].CriticalLow,
-                            content.data[key].Scale);
-                        content.data[key].CriticalHigh = getScaledValue(
-                            content.data[key].CriticalHigh,
-                            content.data[key].Scale);
-                        content.data[key].WarningLow = getScaledValue(
-                            content.data[key].WarningLow,
-                            content.data[key].Scale);
-                        content.data[key].WarningHigh = getScaledValue(
-                            content.data[key].WarningHigh,
-                            content.data[key].Scale);
-                        if (Constants.SENSOR_SORT_ORDER.indexOf(
-                                content.data[key].Unit) > -1) {
-                          customOrder = Constants.SENSOR_SORT_ORDER.indexOf(
-                              content.data[key].Unit);
-                        } else {
-                          customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
-                        }
-
-                        sensorData.push(Object.assign(
-                            {
-                              path: key,
-                              selected: false,
-                              confirm: false,
-                              copied: false,
-                              title: title,
-                              unit:
-                                  Constants
-                                      .SENSOR_UNIT_MAP[content.data[key].Unit],
-                              severity_flags: severity.flags,
-                              status: severity.severityText,
-                              order: severity.order,
-                              custom_order: customOrder,
-                              search_text:
-                                  (title + ' ' + content.data[key].Value + ' ' +
-                                   Constants.SENSOR_UNIT_MAP[content.data[key]
-                                                                 .Unit] +
-                                   ' ' + severity.severityText + ' ' +
-                                   content.data[key].CriticalLow + ' ' +
-                                   content.data[key].CriticalHigh + ' ' +
-                                   content.data[key].WarningLow + ' ' +
-                                   content.data[key].WarningHigh + ' ')
-                                      .toLowerCase(),
-                              original_data:
-                                  {key: key, value: content.data[key]}
+                    var members = response.data['Members'];
+                    angular.forEach(
+                        members,
+                        function(member) {
+                          promises.push($http({
+                                          method: 'GET',
+                                          url: DataService.getHost() +
+                                              member['@odata.id'],
+                                          withCredentials: true
+                                        }).then(function(res) {
+                            return res.data;
+                          }));
+                        }),
+                        $q.all(promises).then(
+                            function(results) {
+                              deferred.resolve(results);
                             },
-                            content.data[key]));
-                      }
-                    }
-
-                    callback(sensorData, dataClone);
+                            function(errors) {
+                              deferred.reject(errors);
+                            });
                   },
                   function(error) {
-                    console.log(error);
+                    console.log(JSON.stringify(error));
                   });
+          return deferred.promise;
         },
         getActivation: function(imageId) {
           return $http({
diff --git a/app/server-health/controllers/sensors-overview-controller.html b/app/server-health/controllers/sensors-overview-controller.html
index 5a6f95a..3ad4aa6 100644
--- a/app/server-health/controllers/sensors-overview-controller.html
+++ b/app/server-health/controllers/sensors-overview-controller.html
@@ -5,12 +5,11 @@
   </div>
   <section class="row column">
     <div class="page-header">
-      <h2 class="inline">All sensors present in the system</h2>
-      <a ng-href="data:text/json;charset=utf-8,{{export_data}}" class="inline btn-export float-right" download="{{export_name}}">Export</a>
+      <h2 class="inline">All Sensors information </h2>
+      <a ng-href="data:text/json;charset=utf-8,{{fullSensorsInfo}}" class="inline btn-export float-right" download="{{export_name}}">Export</a>
     </div>
   </section>
   <section class="row column">
-    <!-- search -->
     <p class="content-label" aria-label="sensors filter">Filter sensors</p>
     <div class="content__search">
       <label for="content__search-input">Sensors Search</label>
@@ -19,7 +18,7 @@
         <button class="clear-input" ng-click="clear()">&#10005;</button>
         <input id="content__search-submit" type="submit" class="btn btn-primary content__search-submit" value="Filter" ng-click="doSearchOnClick()"/>
       </div>
-    </div>  <!-- end search -->
+    </div>
 
     <div class="toggle-filter">
       <p class="content-label">FILTER BY SEVERITY</p>
@@ -32,41 +31,74 @@
       <button class="inline" ng-click="toggleSeverity('warning')"
           ng-class="selectedSeverity.warning ? 'btn-primary' : 'btn-secondary'">Warning
       </button>
-      <button class="inline" ng-click="toggleSeverity('normal')"
-          ng-class="selectedSeverity.normal ? 'btn-primary' : 'btn-secondary'">Normal
+      <button class="inline" ng-click="toggleSeverity('ok')"
+          ng-class="selectedSeverity.ok ? 'btn-primary' : 'btn-secondary'">OK
       </button>
     </div>
-
+    <div class="select__filter">
+      <p class="content-label">Select Component</p>
+      <div class="inline dropdown__wrapper" >
+        <button type="button" class="dropdown__button" ng-click="showCompDropdown = !showCompDropdown" ng-disabled="fullSensorsInfo.length <= 1"><strong>{{selectedComponent.Name}}</strong></button>
+        <ul class="dropdown__list inline" ng-show="showCompDropdown">
+          <li>
+            <button type="button" ng-click="selectComponent(-1);">All</button>
+          </li>
+          <li ng-repeat="component in fullSensorsInfo track by $index">
+            <button type="button" ng-click="selectComponent($index);">{{component.Name}}</button>
+          </li>
+        </ul>
+      </div>
+    </div>
   </section>
 
-  <section class="row column" ng-show="filteredSensorData.length == 0">
-    <!-- message -->
+  <section class="row column" ng-show="(filteredVoltSensors.length + filteredTempSensors.length + filteredFanSensors.length) == 0">
     <span ng-if="selectedSeverity.all">{{messages.NO_SENSOR_DATA}}</span>
     <span ng-if="selectedSeverity.critical">{{messages.CRITICAL_NO_SENSOR_DATA}}</span>
     <span ng-if="selectedSeverity.warning">{{messages.WARNING_NO_SENSOR_DATA}}</span>
-    <span ng-if="selectedSeverity.normal">{{messages.NORMAL_NO_SENSOR_DATA}}</span>
-    <!-- end message -->
+    <span ng-if="selectedSeverity.ok">{{messages.NORMAL_NO_SENSOR_DATA}}</span>
   </section>
-
-  <section id="sensor-categories" class="row column" ng-show="filteredSensorData.length">
-    <div class="row column header-row fixed-table-header">
-      <div class="column large-12 header__actions-bar">
-        <p class="inline sensor__title">Sensors ({{filteredSensorData.length}})</p>
-        <p class="inline sensor__reading">Low critical</p>
-        <p class="inline sensor__reading">Low warning</p>
-        <p class="inline sensor__reading sensor__heading-current">Current</p>
-        <p class="inline sensor__reading">High warning</p>
-        <p class="inline sensor__reading">High critical</p>
+  <section id="sensor-categories" class="table row column" ng-hide="(filteredVoltSensors.length + filteredTempSensors.length + filteredFanSensors.length) == 0">
+      <div class="table row column sensor__table" ng-hide="loading">
+        <div class="table__head fixed-table-header">
+          <div class="table__row">
+            <div class="table__cell sensor__title">Name</div>
+            <div class="table__cell sensor__status">Status</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">LC</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">LW</div>
+            <div class="table__cell sensor__reading">Reading</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">HW</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">HC</div>
+          </div>
+        </div>
+        <div class="table__body">
+          <div class="table__row" ng-repeat="sensor in (filteredVoltSensors = (sensorsInfo.Voltages | filter:filterBySearchTerms | filter:filterBySeverity))">
+            <div class="table__cell sensor__title">{{sensor.Name}}</div>
+            <div class="table__cell sensor__status sensor__{{sensor.Status.Health}}">{{sensor.Status.Health}}</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdCritical | number:2}} Volts</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdNonCritical | number:2}} Volts</div>
+            <div class="table__cell sensor__reading">{{sensor.ReadingVolts | number:2}} Volts</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.UpperThresholdNonCritical | number:2}} Volts</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.UpperThresholdCritical | number:2}} Volts</div>
+          </div>
+          <div class="table__row" ng-repeat="sensor in (filteredTempSensors = (sensorsInfo.Temperatures | filter:filterBySearchTerms | filter:filterBySeverity))">
+            <div class="table__cell sensor__title">{{sensor.Name}}</div>
+            <div class="table__cell sensor__status sensor__{{sensor.Status.Health}}">{{sensor.Status.Health}}</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdCritical | number:2}} &deg;C</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdNonCritical | number:2}} &deg;C</div>
+            <div class="table__cell sensor__reading">{{sensor.ReadingCelsius | number:2}} &deg;C</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.UpperThresholdNonCritical | number:2}} &deg;C</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.UpperThresholdCritical | number:2}} &deg;C</div>
+          </div>
+          <div class="table__row" ng-repeat="sensor in (filteredFanSensors = (sensorsInfo.Fans | filter:filterBySearchTerms | filter:filterBySeverity))">
+            <div class="table__cell sensor__title">{{sensor.Name}}</div>
+            <div class="table__cell sensor__status sensor__{{sensor.Status.Health}}">{{sensor.Status.Health}}</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdCritical | number:2}} {{sensor.ReadingUnits}}</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">{{sensor.LowerThresholdNonCritical | number:2}} {{sensor.ReadingUnits}}</div>
+            <div class="table__cell sensor__reading">{{sensor.Reading | number:2}} {{sensor.ReadingUnits}}</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">NA</div>
+            <div class="table__cell sensor__threshold" ng-show="showThresholds">NA</div>
+          </div>
+        </div>
       </div>
-    </div>
-    <!-- sensor -->
-    <div class="sensor__readings-row" ng-repeat="sensor in data|filter:filterBySeverity|filter:filterBySearchTerms|orderBy:'+custom_order' as filteredSensorData">
-      <p class="inline sensor__title"><span class="icon" ng-class="{'icon__critical': sensor.status == 'critical', 'icon__warning': sensor.status == 'warning', 'icon__normal': sensor.status == 'normal'}" aria-label="sensor.status" ></span>{{sensor.title}}</p>
-      <p class="inline sensor__reading"><span class="sensor__label">Low critical</span>{{sensor.CriticalLow}}<span class="content-label">{{sensor.unit}}<span ng-if="sensor.unit == 'C'">&deg;</span></p>
-      <p class="inline sensor__reading"><span class="sensor__label">Low warning</span>{{sensor.WarningLow}}<span class="content-label">{{sensor.unit}}<span ng-if="sensor.unit == 'C'">&deg;</span></p>
-      <p class="inline sensor__reading sensor__current" ng-class="{'sensor__critical': sensor.status == 'critical', 'sensor__warn': sensor.status == 'warning', 'sensor__normal': sensor.status == 'normal'}"><span class="sensor__label">Current</span>{{sensor.Value}}<span class="content-label">{{sensor.unit}}<span ng-if="sensor.unit == 'C'">&deg;</span></span></p>
-      <p class="inline sensor__reading"><span class="sensor__label">High warning</span>{{sensor.WarningHigh}}<span class="content-label">{{sensor.unit}}<span ng-if="sensor.unit == 'C'">&deg;</span></p>
-      <p class="inline sensor__reading"><span class="sensor__label">High critical</span>{{sensor.CriticalHigh}}<span class="content-label">{{sensor.unit}}<span ng-if="sensor.unit == 'C'">&deg;</span></p>
-    </div>
   </section>
 </div>
diff --git a/app/server-health/controllers/sensors-overview-controller.js b/app/server-health/controllers/sensors-overview-controller.js
index 40e0b58..96349d2 100644
--- a/app/server-health/controllers/sensors-overview-controller.js
+++ b/app/server-health/controllers/sensors-overview-controller.js
@@ -9,27 +9,27 @@
 window.angular && (function(angular) {
   'use strict';
   angular.module('app.overview').controller('sensorsOverviewController', [
-    '$scope', '$log', '$window', 'APIUtils', 'dataService', 'Constants',
-    function($scope, $log, $window, APIUtils, dataService, Constants) {
+    '$scope', '$q', '$window', 'APIUtils', 'dataService', 'Constants',
+    function($scope, $q, $window, APIUtils, dataService, Constants) {
       $scope.dataService = dataService;
 
-      $scope.dropdown_selected = false;
-
-      $scope.$log = $log;
+      $scope.loading = false;
+      $scope.componentList = [];
+      $scope.sensorsInfo = {};
+      $scope.fullSensorsInfo = [];
+      $scope.selectedComponent = {};
+      $scope.showThresholds = true;  // TODO: add button to toggle this..
+      $scope.showCompDropdown = false;
       $scope.customSearch = '';
       $scope.searchTerms = [];
       $scope.messages = Constants.MESSAGES.SENSOR;
+      $scope.filteredVoltSensors = [];
+      $scope.filteredTempSensors = [];
+      $scope.filteredFanSensors = [];
+
       $scope.selectedSeverity =
-          {all: true, normal: false, warning: false, critical: false};
+          {all: true, ok: false, warning: false, critical: false};
       $scope.export_name = 'sensors.json';
-      $scope.loading = false;
-      $scope.jsonData = function(data) {
-        var dt = {};
-        data.data.forEach(function(item) {
-          dt[item.original_data.key] = item.original_data.value;
-        });
-        return JSON.stringify(dt);
-      };
 
       $scope.clear = function() {
         $scope.customSearch = '';
@@ -64,7 +64,7 @@
         $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
 
         if ($scope.selectedSeverity.all) {
-          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.ok = false;
           $scope.selectedSeverity.warning = false;
           $scope.selectedSeverity.critical = false;
         }
@@ -73,9 +73,9 @@
       $scope.toggleSeverity = function(severity) {
         $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
 
-        if (['normal', 'warning', 'critical'].indexOf(severity) > -1) {
+        if (['ok', 'warning', 'critical'].indexOf(severity) > -1) {
           if ($scope.selectedSeverity[severity] == false &&
-              (!$scope.selectedSeverity.normal &&
+              (!$scope.selectedSeverity.ok &&
                !$scope.selectedSeverity.warning &&
                !$scope.selectedSeverity.critical)) {
             $scope.selectedSeverity.all = true;
@@ -83,10 +83,10 @@
           }
         }
 
-        if ($scope.selectedSeverity.normal && $scope.selectedSeverity.warning &&
+        if ($scope.selectedSeverity.ok && $scope.selectedSeverity.warning &&
             $scope.selectedSeverity.critical) {
           $scope.selectedSeverity.all = true;
-          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.ok = false;
           $scope.selectedSeverity.warning = false;
           $scope.selectedSeverity.critical = false;
         } else {
@@ -98,31 +98,87 @@
         if ($scope.selectedSeverity.all) return true;
 
         return (
-            (sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
-            (sensor.severity_flags.warning &&
+            ((sensor.Status.Health == 'OK') && $scope.selectedSeverity.ok) ||
+            ((sensor.Status.Health == 'Warning') &&
              $scope.selectedSeverity.warning) ||
-            (sensor.severity_flags.critical &&
+            ((sensor.Status.Health == 'Critical') &&
              $scope.selectedSeverity.critical));
       };
       $scope.filterBySearchTerms = function(sensor) {
         if (!$scope.searchTerms.length) return true;
 
         for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
-          if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) ==
-              -1)
+          // TODO: Form it while getting data
+          var search_text = sensor.Name.toLowerCase();
+          if (search_text.indexOf($scope.searchTerms[i].toLowerCase()) == -1)
             return false;
         }
         return true;
       };
 
+      $scope.selectComponent = function(index) {
+        $scope.loading = true;
+        $scope.showCompDropdown = false;
+        if (index == -1) {
+          // Flattened sensor data to display all sensors.
+          $scope.selectedComponent = {'Name': 'All'};
+          $scope.sensorsInfo = {'Temperatures': [], 'Fans': [], 'Voltages': []};
+          // Looping through all chassis collections to flattened sensors data
+          angular.forEach($scope.fullSensorsInfo, function(record) {
+            $scope.sensorsInfo.Temperatures = [].concat(
+                $scope.sensorsInfo.Temperatures, record.sensors.Temperatures);
+            $scope.sensorsInfo.Fans =
+                [].concat($scope.sensorsInfo.Fans, record.sensors.Fans);
+            $scope.sensorsInfo.Voltages =
+                [].concat($scope.sensorsInfo.Voltages, record.sensors.Voltages);
+          });
+        } else {
+          $scope.selectedComponent = $scope.fullSensorsInfo[index];
+          $scope.sensorsInfo = $scope.selectedComponent['sensors'];
+        }
+        $scope.loading = false;
+      };
+
+      function getComponentSensors(component) {
+        var data = component;
+        data['sensors'] = {'Temperatures': [], 'Fans': [], 'Voltages': []};
+        APIUtils.getSensorsInfo(component.Thermal['@odata.id'])
+            .then(function(res) {
+              if (res.hasOwnProperty('Temperatures')) {
+                data.sensors['Temperatures'] = res.Temperatures;
+              }
+              if (res.hasOwnProperty('Fans')) {
+                data.sensors['Fans'] = res.Fans;
+              }
+              return;
+            });
+        APIUtils.getSensorsInfo(component.Power['@odata.id'])
+            .then(function(res) {
+              if (res.hasOwnProperty('Voltages')) {
+                data.sensors['Voltages'] = res.Voltages;
+              }
+              return;
+            });
+        return data;
+      };
+
       $scope.loadSensorData = function() {
         $scope.loading = true;
-        APIUtils.getAllSensorStatus(function(data, originalData) {
-          $scope.data = data;
-          $scope.originalData = originalData;
-          $scope.export_data = JSON.stringify(originalData);
-          $scope.loading = false;
-        });
+        APIUtils.getAllChassisCollection()
+            .then(
+                function(chassisList) {
+                  angular.forEach(chassisList, function(chassis) {
+                    var resData = getComponentSensors(chassis);
+                    $scope.fullSensorsInfo.push(resData);
+                  });
+                },
+                function(error) {
+                  console.log(JSON.stringify(error));
+                })
+            .finally(function() {
+              $scope.selectComponent(0);
+              $scope.loading = false;
+            });
       };
 
       $scope.loadSensorData();
diff --git a/app/server-health/styles/sensors.scss b/app/server-health/styles/sensors.scss
index 041a1e5..074d27b 100644
--- a/app/server-health/styles/sensors.scss
+++ b/app/server-health/styles/sensors.scss
@@ -37,35 +37,15 @@
   }
 }
 
-.sensor__title {
-  min-width: 28%;
-  margin-bottom: 0;
-}
-
-.sensor__reading {
-  width: 100%;
-  text-align: right;
-  margin-bottom: 0;
-  display: none;
-  @include mediaQuery(medium) {
-    display: inline-block;
-    width: auto;
-    min-width: calc(70% * (1 / 5) - 18px);
-  }
-}
-
-.sensor__readings-row {
-  width: 100%;
-  position: relative;
-  display: block;
+.sensor__table {
+  width: auto;
+  min-width: 60%;
   margin: 0;
   background: $white;
   text-decoration: none;
   border: 1px solid $medgrey;
   background: lighten($lightgrey,1%);
-  margin-top: 1em;
   @include mediaQuery(medium) {
-    padding: .3em 1em .3em 1.5em;
     margin-top: 0;
     border-top: 0;
     background: transparent;
@@ -73,75 +53,54 @@
   .sensor__title {
     font-weight: 700;
     background: darken($lightgrey, 5%);
-    min-width: 100%;
-    padding: .8em;
+    min-width: 25%;
+    overflow: visible;
     @include mediaQuery(medium) {
-      min-width: 30%;
+      min-width: 25%;
       background: transparent;
-      padding: .5em .5em .5em 0;
-    }
-    .icon__normal {
-      width: 0;
     }
   }
-  .content-label {
-    font-size: 1em;
-    margin-left: .8em;
-    color: $darkgrey;
-  }
-  .sensor__reading {
-    @include fontCourierBold;
+  .sensor__reading,
+  .sensor__status {
     display: block;
-    padding: .3em .8em;
+    min-width: 15%;
+    overflow: visible;
     @include mediaQuery(medium) {
       display: inline-block;
-      padding: 0;
     }
   }
-  .sensor__current {
-    background: darken($thresh-normal, 3%);
-    margin: 0;
+  .sensor__threshold {
+    display: block;
+    overflow: visible;
     @include mediaQuery(medium) {
-      background: $thresh-normal;
-      padding: .7em .3em;
-      margin-left: 10px;
-      min-width: 109px;
-    }
-    @include mediaQuery(large) {
-      background: $thresh-normal;
-      padding: .7em;
-      margin-left: .3em;
-      margin-right: .3em;
-      min-width: 150px;
-    }
-    .sensor__label {
-      font-weight: 700;
-      @include mediaQuery(medium) {
-        font-weight:300;
-      }
+      display: inline-block;
     }
   }
-  .sensor__critical {
+  .sensor__Critical {
     background: $thresh-critical;
     color: $white;
     .content-label {
       color: $white;
     }
   }
-  .sensor__warn {
+  .sensor__Warning {
     background: $thresh-warning;
     color: $black;
     .content-label {
       color: $black;
     }
   }
-
+  .sensor__OK {
+    background: $thresh-normal;
+    color: $black;
+    .content-label {
+      color: $black;
+    }
+  }
 }
 
 // Sensors
-
 #sensors, #sensors-overview {
-
   .toggle-filter {
     margin-bottom: 20px;
   }
@@ -149,6 +108,27 @@
     padding-left: 0px;
     padding-right: 0px;
   }
+  .dropdown__button {
+    margin-bottom: 1.2em;
+  }
+  .dropdown__list {
+    margin-top: -17px;
+  }
+  .dropdown__button {
+    width: 25em;
+    margin-top: 0;
+    text-align: left;
+    border: 0.1em solid;
+  }
+  .dropdown__wrapper {
+    width: 25em;
+    margin-top: 0.4em;
+    text-align: left;
+  }
+  .select__filter {
+    margin-bottom: 20px;
+    margin-left: 15px;
+  }
 }
 
 //end sensor details