diff options
-rw-r--r-- | app/assets/mocks/sensors.json | 258 | ||||
-rw-r--r-- | app/common/services/api-utils.js | 116 | ||||
-rw-r--r-- | app/common/services/constants.js | 88 | ||||
-rw-r--r-- | app/common/services/dataService.js | 1 | ||||
-rw-r--r-- | app/server-health/controllers/sensors-controller.html | 126 | ||||
-rw-r--r-- | app/server-health/controllers/sensors-controller.js | 117 | ||||
-rw-r--r-- | app/server-health/controllers/sensors-overview-controller.html | 31 | ||||
-rw-r--r-- | app/server-health/controllers/sensors-overview-controller.js | 98 | ||||
-rw-r--r-- | app/server-health/index.js | 2 | ||||
-rw-r--r-- | app/server-health/styles/sensors.scss | 1 |
10 files changed, 708 insertions, 130 deletions
diff --git a/app/assets/mocks/sensors.json b/app/assets/mocks/sensors.json new file mode 100644 index 0000000..8eabd78 --- /dev/null +++ b/app/assets/mocks/sensors.json @@ -0,0 +1,258 @@ +{ + "data": { + "/xyz/openbmc_project/sensors/fan_tach/fan0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.RPMS", + "Value": 2000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/fan_tach/fan1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.RPMS", + "Value": 11000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 4000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/fan_tach/fan2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.RPMS", + "Value": 1000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 4000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/temperature/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.DegreesC", + "Value": 8278, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/temperature/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.DegreesC", + "Value": 11000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 5000, + "CriticalLow": 4000 + }, + "/xyz/openbmc_project/sensors/temperature/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.DegreesC", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/altitude/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Meters", + "Value": 8278, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 8000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/altitude/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Meters", + "Value": 1009, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/altitude/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Meters", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/voltage/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Volts", + "Value": 8278, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/voltage/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Volts", + "Value": 18259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/voltage/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Volts", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/current/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Amperes", + "Value": 11000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/current/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Amperes", + "Value": 11000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/current/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Amperes", + "Value": 11000, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/power/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Watts", + "Value": 8278, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/power/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Watts", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/power/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Watts", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/energy/item0": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Joules", + "Value": 8278, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/energy/item1": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Joules", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 20000, + "CriticalLow": 5000 + }, + "/xyz/openbmc_project/sensors/energy/item2": { + "Scale": 0, + "Target": 0, + "Unit": "xyz.openbmc_project.Sensor.Value.Unit.Joules", + "Value": 8259, + "WarningAlarmHigh": 0, + "WarningAlarmLow": 0, + "WarningHigh": 40000, + "WarningLow": 10000, + "CriticalHigh": 6000, + "CriticalLow": 5000 + } + }, + "message": "200 OK", + "status": "ok" +}
\ No newline at end of file diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js index d177366..120bcb8 100644 --- a/app/common/services/api-utils.js +++ b/app/common/services/api-utils.js @@ -360,6 +360,122 @@ window.angular && (function (angular) { }).error(function(error){ console.log(error); }); + }, + getAllSensorStatus: function(callback){ + /** + GET https://9.3.185.156/xyz/openbmc_project/sensors/enumerate + */ + $http({ + method: 'GET', + url: "/assets/mocks/sensors.json", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + withCredentials: true + }).success(function(response){ + var json = JSON.stringify(response); + var content = JSON.parse(json); + var dataClone = JSON.parse(JSON.stringify(content.data)); + var sensorData = []; + var allSensorSeveries = []; + var allSensorRows = []; + var total = 0; + var status = 'normal'; + var data = { + total: 0, + status: '', + sensors: [{ + title: 'All Sensors', + type: 'all', + status: '', + severity_flags: {}, + search_text: '', + display_headers: ['Sensor (Unit)', 'Reading', 'State'], + data: [] + }] + }; + + function getSensorStatus(reading){ + var severityFlags = {critical: false, warning: false, normal: false}, severityText = ''; + if(reading.Value >= reading.CriticalLow && reading.Value <= reading.CriticalHigh){ + severityFlags.critical = true; + severityText = 'critical'; + } + else if(reading.Value >= reading.WarningLow && reading.Value <= reading.WarningHigh){ + severityFlags.warning = true; + severityText = 'warning'; + }else{ + severityFlags.normal = true; + severityText = 'normal'; + } + return { flags: severityFlags, severityText: severityText}; + } + + for(var key in content.data){ + if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Unit')){ + sensorData.push(Object.assign({ + path: key, + selected: false, + confirm: false, + copied: false, + original_data: {key: key, value: content.data[key]} + }, content.data[key])); + } + } + + Constants.SENSOR_DATA_TEMPLATE.sensors.forEach(function(sensor){ + var rowData = []; + var severities = []; + var thisSensorData = sensorData.filter(function(el){ + return el.path.indexOf('sensors/'+sensor.key_search) > -1; + }); + + for(var i = 0; i < thisSensorData.length; i++){ + + var severity = getSensorStatus(thisSensorData[i]); + severities.push(severity.severityText); + rowData.push(Object.assign({ + title: sensor.sensor_row.title + (i+1), + status: severity.severityText, + severity_flags: severity.flags, + reading: thisSensorData[i].Value + sensor.sensor_row.reading, + search_text: (sensor.sensor_row.title + (i+1) + " " + severity.severityText + " " + thisSensorData[i].Value + sensor.sensor_row.reading).toLowerCase(), + indicator: (severity.flags.critical) ? '90%' : ((severity.flags.warning) ? '15%' : '50%') + }, thisSensorData[i])); + } + + status = (severities.indexOf('critical') > -1) ? 'critical' : ((severities.indexOf('warning') > -1) ? 'warning' : 'normal'); + total += rowData.length; + allSensorSeveries.push(status); + var sevFlags = {critical: false, warning: false, normal: false}; + sevFlags[status] = true; + data.sensors.push({ + title: sensor.title, + type: sensor.type, + status: status, + severity_flags: sevFlags, + search_text: (sensor.title + " " + status).toLowerCase(), + display_headers: sensor.display_headers, + data: rowData + }); + Array.prototype.push.apply(allSensorRows, rowData); + }); + + data.status = (allSensorSeveries.indexOf('critical') > -1) ? 'critical' : ((allSensorSeveries.indexOf('warning') > -1) ? 'warning' : 'normal'); + data.total = total; + if(allSensorRows.length){ + data.sensors[0].status = data.status; + data.sensors[0].data = allSensorRows; + data.sensors[0].search_text = (data.sensors[0].title + " " + data.sensors[0].status).toLowerCase(); + var flags = {critical: false, warning: false, normal: false}; + flags[data.status] = true; + data.sensors[0].severity_flags = flags; + } + callback(data, dataClone); + }).error(function(error){ + console.log(error); + }); } }; return SERVICE; diff --git a/app/common/services/constants.js b/app/common/services/constants.js index 86ba54e..dba4afa 100644 --- a/app/common/services/constants.js +++ b/app/common/services/constants.js @@ -59,6 +59,94 @@ window.angular && (function (angular) { }, PAGINATION: { LOG_ITEMS_PER_PAGE: 4 + }, + SENSOR_DATA_TEMPLATE: { + sensors: [ + { + type: 'fan', + title: 'Fan Speed', + key_search: 'fan_tach', + display_headers: ['Fan Speed(RPM)', 'Reading', 'State'], + sensor_row: { + title: 'Fan Speed ', + reading: ' rpms', + status: '', + indicator: '' + } + }, + { + type: 'temperature', + title: 'Temperature', + 'key_search': 'temperature', + display_headers: ['Temperature (DegreesC)', 'Reading', 'State'], + sensor_row: { + title: 'Temperature ', + reading: ' degreeC', + status: '', + indicator: '' + } + }, + { + type: 'altitude', + title: 'Altitude', + 'key_search': 'altitude', + display_headers: ['Altitude (Meters)', 'Reading', 'State'], + sensor_row: { + title: 'Altitude ', + reading: ' Meters', + status: '', + indicator: '' + } + }, + { + type: 'voltage', + title: 'Voltage', + 'key_search': 'voltage', + display_headers: ['Temperature (Volts)', 'Reading', 'State'], + sensor_row: { + title: 'Voltage ', + reading: ' volts', + status: '', + indicator: '' + } + }, + { + type: 'current', + title: 'Current', + 'key_search': 'current', + display_headers: ['Current (Amperes)', 'Reading', 'State'], + sensor_row: { + title: 'Current ', + reading: ' amperes', + status: '', + indicator: '' + } + }, + { + type: 'power', + title: 'Power', + 'key_search': 'power', + display_headers: ['Power (Watts)', 'Reading', 'State'], + sensor_row: { + title: 'Power ', + reading: ' watts', + status: '', + indicator: '' + } + }, + { + type: 'energy', + title: 'Energy', + 'key_search': 'energy', + display_headers: ['Energy (Joules)', 'Reading', 'State'], + sensor_row: { + title: 'Energy ', + reading: ' joules', + status: '', + indicator: '' + } + } + ] } }; }); diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js index 2affcc4..4cb72c5 100644 --- a/app/common/services/dataService.js +++ b/app/common/services/dataService.js @@ -29,6 +29,7 @@ window.angular && (function (angular) { this.showNavigation = false; this.bodyStyle = {}; this.path = ''; + this.sensorData = []; this.setPowerOnState = function(){ this.server_state = Constants.HOST_STATE_TEXT.on; diff --git a/app/server-health/controllers/sensors-controller.html b/app/server-health/controllers/sensors-controller.html index 15720c1..64a0fff 100644 --- a/app/server-health/controllers/sensors-controller.html +++ b/app/server-health/controllers/sensors-controller.html @@ -5,7 +5,7 @@ <section class="row column"> <div class="page-header"> <h2 class="inline h4">Sensors present in the system</h2> - <button class="inline btn-export float-right">Export</button> + <a ng-href="data:text/json;charset=utf-8,{{export_data}}" class="inline btn-export float-right" download="{{export_name}}" ng-show="filteredSensorData.length">Export</a> </div> </section> @@ -14,20 +14,22 @@ <!-- search --> <div class="content__search"> <label for="content__search-input">Sensors Search</label> - <input id="content__search-input" type="text" placeholder="Filter issues"/> - <input id="content__search-submit" type="submit" class="btn btn-secondary" value="Submit"/> + <input id="content__search-input" type="text" placeholder="Filter issues" ng-model="customSearch" ng-keydown="doSearchOnEnter($event)"/> + <input id="content__search-submit" type="submit" class="btn btn-secondary" value="Submit" ng-click="doSearchOnClick()"/> </div> + <div class="toggle-filter"> - <button class="inline first btn-primary">All + <button class="inline first btn-primary" ng-click="toggleSeverityAll()" + ng-class="selectedSeverity.all ? 'btn-primary' : 'btn-secondary'">All </button> - <button class="inline " ng-click="togglehigh = !togglehigh" - ng-class="togglehigh ? 'btn-primary' : 'btn-secondary'">Critical + <button class="inline " ng-click="toggleSeverity('critical')" + ng-class="selectedSeverity.critical ? 'btn-primary' : 'btn-secondary'">Critical </button> - <button class="inline" ng-click="togglemed = !togglemed" - ng-class="togglemed ? 'btn-primary' : 'btn-secondary'">Warning + <button class="inline" ng-click="toggleSeverity('warning')" + ng-class="selectedSeverity.warning ? 'btn-primary' : 'btn-secondary'">Warning </button> - <button class="inline last" ng-click="togglelow = !togglelow" - ng-class="togglelow ? 'btn-primary' : 'btn-secondary'">Normal + <button class="inline last" ng-click="toggleSeverity('normal')" + ng-class="selectedSeverity.normal ? 'btn-primary' : 'btn-secondary'">Normal </button> </div> </section> <!-- end filter --> @@ -38,25 +40,25 @@ </div> </section> - <section id="sensor__details" class="row column"> + <section id="sensor__details" class="row column" ng-hide="!data.display_headers"> <div class="row column header-row"> <div class="column small-10 large-11 header__actions-bar"> <p class="inline priority-tag-circ high-priority" aria-label="High Priority"></p> - <p class="inline sensor__heading sensor__category">Fan speed (RPMs)</p> - <p class="inline sensor__heading middle">Reading</p> - <p class="inline float-right sensor__heading right">State</p> + <p class="inline sensor__heading sensor__category">{{data.display_headers[0]}}</p> + <p class="inline sensor__heading middle">{{data.display_headers[1]}}</p> + <p class="inline float-right sensor__heading right">{{data.display_headers[2]}}</p> </div> <div class="column small-2 large-1 sensor__heading trigger-col"></div> </div> <!-- Sensor --> - <div class="row column accord-row" ng-class="{'active': sensors__metadatarow, 'selected': sensors__selected}"> + <div ng-repeat="sensor in (filteredSensorData = (data.data|filter:filterBySeverity|filter:filterBySearchTerms))" class="row column accord-row" ng-class="{'active': sensors__metadatarow, 'selected': sensors__selected}"> <div class="row"> <div class="column small-10 large-11 sensor__info" ng-click="sensors__metadatarow = ! sensors__metadatarow"> <p class="inline priority-tag-circ high-priority" aria-label="High Priority"></p> - <p class="inline sensor__title">Fan Speed 1</p> - <p class="inline sensor__reading">6200 <span>rpms</span></p> - <p class="inline float-right sensor__critical-label">Critical</p> + <p class="inline sensor__title">{{sensor.title}}</p> + <p class="inline sensor__reading">{{sensor.reading}}</p> + <p class="inline float-right" ng-class="{'sensor__critical-label': sensor.status == 'critical', 'sensor__warning-label': sensor.status == 'warning', 'sensor__normal-label': sensor.status == 'normal'}">{{sensor.status}}</p> </div> <div class="column small-2 large-1"> <button class="accord-trigger" ng-class="{'active': sensors__metadatarow}" ng-click="sensors__metadatarow = ! sensors__metadatarow"></button> @@ -67,45 +69,7 @@ <div class="threshold-chart__wrapper"> <span class="threshold__label low">Low</span> <div class="threshold-chart"> - <span class="threshold__marker thresh__high-critical" style="left: 90%;"><span class="threshold__value">6200 RPMs</span></span> - <span class="threshold thresh__low-critical"></span> - <span class="threshold thresh__low-warn"></span> - <span class="threshold thresh__normal"></span> - <span class="threshold thresh__high-warn"></span> - <span class="threshold thresh__high-critical"></span> - </div> - <span class="threshold__label high">High</span> - </div> - </div> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Events</p>--> - <!--<a href="#/overview/log">View 5 events related to Fan 1</a>--> - <!--</div>--> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Hardware</p>--> - <!--<a href="">Chassis0</a>--> - <!--</div>--> - </div> - </div> - - <!-- Sensor --> - <div class="row column accord-row" ng-class="{'active': sensors__metadatarow2, 'selected': sensors__selected}"> - <div class="row"> - <div class="column small-10 large-11 sensor__info" ng-click="sensors__metadatarow2 = ! sensors__metadatarow2"> - <p class="inline priority-tag-circ normal-priority" aria-label="Normal Priority"></p> - <p class="inline sensor__title">Fan Speed 2</p> - <p class="inline sensor__reading">4600 <span>rpms</span></p> - </div> - <div class="column small-2 large-1"> - <button class="accord-trigger" ng-class="{'active': sensors__metadatarow2}" ng-click="sensors__metadatarow2 = ! sensors__metadatarow2"></button> - </div> - </div> - <div class="row sensors__metadata-row" ng-class="{'active': sensors__metadatarow2}"> - <div class="column small-12"> - <div class="threshold-chart__wrapper"> - <span class="threshold__label low">Low</span> - <div class="threshold-chart"> - <span class="threshold__marker thresh__normal" style="left: 40%;"><span class="threshold__value">4600 RPMs</span></span> + <span class="threshold__marker" ng-class="{'thresh__high-critical': sensor.status == 'critical', 'thresh__low-warn': sensor.status == 'warning', 'thresh__normal': sensor.status == 'normal'}" style="left: {{sensor.indicator}};"><span class="threshold__value">{{sensor.reading}}</span></span> <span class="threshold thresh__low-critical"></span> <span class="threshold thresh__low-warn"></span> <span class="threshold thresh__normal"></span> @@ -115,56 +79,8 @@ <span class="threshold__label high">High</span> </div> </div> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Events</p>--> - <!--<a href="#/overview/log">View 5 events related to Fan 1</a>--> - <!--</div>--> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Hardware</p>--> - <!--<p>None</p>--> - <!--</div>--> </div> </div> - <!-- Sensor --> - <div class="row column accord-row" ng-class="{'active': sensors__metadatarow3, 'selected': sensors__selected}"> - <div class="row"> - <div class="column small-10 large-11 sensor__info" ng-click="sensors__metadatarow3 = ! sensors__metadatarow3"> - <p class="inline priority-tag-circ warn-priority" aria-label="Medium Priority"></p> - <p class="inline sensor__title">Fan Speed 3</p> - <p class="inline sensor__reading">1200 <span>rpms</span></p> - <p class="inline float-right sensor__warning-label">warning</p> - </div> - <div class="column small-2 large-1"> - <button class="accord-trigger" ng-class="{'active': sensors__metadatarow3}" - ng-click="sensors__metadatarow3 = ! sensors__metadatarow3"></button> - </div> - </div> - <div class="row sensors__metadata-row" ng-class="{'active': sensors__metadatarow3}"> - <div class="column small-12"> - <div class="threshold-chart__wrapper"> - <span class="threshold__label low">Low</span> - <div class="threshold-chart"> - <span class="threshold__marker thresh__low-warn" style="left: 15%;"><span class="threshold__value">1200 RPMs</span></span> - <span class="threshold thresh__low-critical"></span> - <span class="threshold thresh__low-warn"></span> - <span class="threshold thresh__normal"></span> - <span class="threshold thresh__high-warn"></span> - <span class="threshold thresh__high-critical"></span> - </div> - <span class="threshold__label high">High</span> - </div> - </div> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Events</p>--> - <!--<a href="#/overview/log">View 5 events related to Fan 1</a>--> - <!--</div>--> - <!--<div class="column small-12 large-6">--> - <!--<p class="h5 content-header">Associated Hardware</p>--> - <!--<a href="">Chassis0</a>--> - <!--</div>--> - </div> - </div> </section> - <paginate ng-include="paginate"></paginate> </div> <!-- end event log --> diff --git a/app/server-health/controllers/sensors-controller.js b/app/server-health/controllers/sensors-controller.js index aaa5aa6..cf10541 100644 --- a/app/server-health/controllers/sensors-controller.js +++ b/app/server-health/controllers/sensors-controller.js @@ -9,7 +9,7 @@ window.angular && (function (angular) { 'use strict'; - + var sensorData = [], originalData = {}; angular .module('app.overview') .controller('sensorsController', [ @@ -18,13 +18,120 @@ window.angular && (function (angular) { '$window', 'APIUtils', 'dataService', - function($scope, $log, $window, APIUtils, dataService, userModel){ + '$routeParams', + function($scope, $log, $window, APIUtils, dataService, $routeParams){ $scope.dataService = dataService; - + $scope.customSearch = ""; $scope.dropdown_selected = false; - $scope.$log = $log; - $scope.message = 'Hello World!'; + $scope.data = {}; + $scope.searchTerms = []; + + $scope.selectedSeverity = { + all: true, + normal: false, + warning: false, + critical: false + }; + + var sensorType = $routeParams.type; + + $scope.export_name = sensorType + "_sensors.json"; + + $scope.toggleSeverityAll = function(){ + $scope.selectedSeverity.all = !$scope.selectedSeverity.all; + + if($scope.selectedSeverity.all){ + $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.warning = false; + $scope.selectedSeverity.critical = false; + } + } + + $scope.toggleSeverity = function(severity){ + $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity]; + + if($scope.selectedSeverity.normal && + $scope.selectedSeverity.warning && + $scope.selectedSeverity.critical){ + $scope.selectedSeverity.all = true; + $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.warning = false; + $scope.selectedSeverity.critical = false; + }else{ + $scope.selectedSeverity.all = false; + } + } + + $scope.doSearchOnEnter = function (event) { + var search = $scope.customSearch.replace(/^\s+/g,'').replace(/\s+$/g,''); + if (event.keyCode === 13 && + search.length >= 2) { + $scope.searchTerms = $scope.customSearch.split(" "); + }else{ + if(search.length == 0){ + $scope.searchTerms = []; + } + } + }; + + $scope.doSearchOnClick = function() { + var search = $scope.customSearch.replace(/^\s+/g,'').replace(/\s+$/g,''); + if (search.length >= 2) { + $scope.searchTerms = $scope.customSearch.split(" "); + }else{ + if(search.length == 0){ + $scope.searchTerms = []; + } + } + } + + $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.filterBySeverity = function(sensor){ + if($scope.selectedSeverity.all) return true; + + return( (sensor.severity_flags.normal && $scope.selectedSeverity.normal) || + (sensor.severity_flags.warning && $scope.selectedSeverity.warning) || + (sensor.severity_flags.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) return false; + } + return true; + } + + function setSensorData(){ + var data = dataService.sensorData.sensors.filter(function(item){ + return item.type == sensorType; + }); + if(data.length){ + sensorData = data[0]; + $scope.data = sensorData; + $scope.export_data = $scope.jsonData($scope.data); + } + } + + if(!dataService.sensorData.sensors){ + APIUtils.getAllSensorStatus(function(data, originalData){ + dataService.sensorData = data; + setSensorData(); + }); + }else{ + setSensorData(); + } + } ] ); diff --git a/app/server-health/controllers/sensors-overview-controller.html b/app/server-health/controllers/sensors-overview-controller.html index 10ee4fa..6a8f3c4 100644 --- a/app/server-health/controllers/sensors-overview-controller.html +++ b/app/server-health/controllers/sensors-overview-controller.html @@ -5,7 +5,7 @@ <section class="row column"> <div class="page-header"> <h2 class="inline h4">Sensors present in the system</h2> - <button class="inline btn-export float-right">Export</button> + <a ng-href="data:text/json;charset=utf-8,{{export_data}}" class="inline btn-export float-right" download="{{export_name}}" ng-show="filteredSensorData.length">Export</a> </div> </section> @@ -13,20 +13,21 @@ <!-- search --> <div class="content__search"> <label for="content__search-input">Event Log Search</label> - <input id="content__search-input" type="text" placeholder="Filter issues"/> - <input id="content__search-submit" type="submit" class="btn btn-secondary" value="Submit"/> + <input id="content__search-input" type="text" placeholder="Filter issues" ng-model="customSearch" ng-keydown="doSearchOnEnter($event)"/> + <input id="content__search-submit" type="submit" class="btn btn-secondary" value="Submit" ng-click="doSearchOnClick()"/> </div> <div class="toggle-filter"> - <button class="inline first btn-primary">All + <button class="inline first btn-primary" ng-click="toggleSeverityAll()" + ng-class="selectedSeverity.all ? 'btn-primary' : 'btn-secondary'">All </button> - <button class="inline " ng-click="togglehigh = !togglehigh" - ng-class="togglehigh ? 'btn-primary' : 'btn-secondary'">Critical + <button class="inline " ng-click="toggleSeverity('critical')" + ng-class="selectedSeverity.critical ? 'btn-primary' : 'btn-secondary'">Critical </button> - <button class="inline" ng-click="togglemed = !togglemed" - ng-class="togglemed ? 'btn-primary' : 'btn-secondary'">Warning + <button class="inline" ng-click="toggleSeverity('warning')" + ng-class="selectedSeverity.warning ? 'btn-primary' : 'btn-secondary'">Warning </button> - <button class="inline last" ng-click="togglelow = !togglelow" - ng-class="togglelow ? 'btn-primary' : 'btn-secondary'">Normal + <button class="inline last" ng-click="toggleSeverity('normal')" + ng-class="selectedSeverity.normal ? 'btn-primary' : 'btn-secondary'">Normal </button> </div> @@ -39,12 +40,8 @@ <p class="inline float-right sensor__heading right">State</p> </div> </div> - <a class="sensor__group" href="">All Sensors (50)</a> - <a class="sensor__group" href=""><span class="inline priority-tag-circ normal-priority" aria-label="Normal Priority"></span>Temperature (20)</a> - <a class="sensor__group" href="#/server-health/sensors"> <span class="inline priority-tag-circ high-priority" aria-label="High Priority"></span>Fan Speed (15) <p class="inline float-right sensor__critical-label">Critical</p></a> - <a class="sensor__group" href=""><span class="inline priority-tag-circ normal-priority" aria-label="Normal Priority"></span>Altitude (1)</a> - <a class="sensor__group" href=""><span class="inline priority-tag-circ normal-priority" aria-label="Normal Priority"></span>Voltage (6)</a> - <a class="sensor__group" href=""><span class="inline priority-tag-circ warn-priority" aria-label="Warning Priority"></span>Current (5) <p class="inline float-right sensor__warning-label">Warning</p></a> - <a class="sensor__group" href=""><span class="inline priority-tag-circ normal-priority"></span>Power (3)</a> + + <a ng-repeat="sensor in (filteredSensorData = data.sensors|filter:filterBySeverity|filter:filterBySearchTerms)" class="sensor__group" href="#/server-health/sensors/{{sensor.type}}"> <span class="inline priority-tag-circ high-priority" aria-label="High Priority"></span>{{sensor.title}} ({{sensor.data.length}}) <p class="inline float-right" ng-class="{'sensor__critical-label': sensor.status == 'critical', 'sensor__warning-label': sensor.status == 'warning', 'sensor__normal-label': sensor.status == 'normal'}">{{sensor.status}}</p></a> + </section> </div>
\ No newline at end of file diff --git a/app/server-health/controllers/sensors-overview-controller.js b/app/server-health/controllers/sensors-overview-controller.js index 1b7234d..1e53829 100644 --- a/app/server-health/controllers/sensors-overview-controller.js +++ b/app/server-health/controllers/sensors-overview-controller.js @@ -9,7 +9,7 @@ window.angular && (function (angular) { 'use strict'; - + var sensorData = [], originalData = {}; angular .module('app.overview') .controller('sensorsOverviewController', [ @@ -24,7 +24,101 @@ window.angular && (function (angular) { $scope.dropdown_selected = false; $scope.$log = $log; - $scope.message = 'Hello World!'; + $scope.customSearch = ""; + $scope.searchTerms = []; + $scope.selectedSeverity = { + all: true, + normal: false, + warning: false, + critical: false + }; + $scope.export_name = "sensors.json"; + $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.doSearchOnEnter = function (event) { + var search = $scope.customSearch.replace(/^\s+/g,'').replace(/\s+$/g,''); + if (event.keyCode === 13 && + search.length >= 2) { + $scope.searchTerms = $scope.customSearch.split(" "); + }else{ + if(search.length == 0){ + $scope.searchTerms = []; + } + } + }; + + $scope.doSearchOnClick = function() { + var search = $scope.customSearch.replace(/^\s+/g,'').replace(/\s+$/g,''); + if (search.length >= 2) { + $scope.searchTerms = $scope.customSearch.split(" "); + }else{ + if(search.length == 0){ + $scope.searchTerms = []; + } + } + } + + $scope.toggleSeverityAll = function(){ + $scope.selectedSeverity.all = !$scope.selectedSeverity.all; + + if($scope.selectedSeverity.all){ + $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.warning = false; + $scope.selectedSeverity.critical = false; + } + } + + $scope.toggleSeverity = function(severity){ + $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity]; + + if($scope.selectedSeverity.normal && + $scope.selectedSeverity.warning && + $scope.selectedSeverity.critical){ + $scope.selectedSeverity.all = true; + $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.warning = false; + $scope.selectedSeverity.critical = false; + }else{ + $scope.selectedSeverity.all = false; + } + } + + $scope.filterBySeverity = function(sensor){ + if($scope.selectedSeverity.all) return true; + + return( (sensor.severity_flags.normal && $scope.selectedSeverity.normal) || + (sensor.severity_flags.warning && $scope.selectedSeverity.warning) || + (sensor.severity_flags.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) return false; + } + return true; + } + + $scope.loadSensorData = function(){ + APIUtils.getAllSensorStatus(function(data, originalData){ + sensorData = data; + originalData = originalData; + $scope.data = data; + $scope.originalData = originalData; + dataService.sensorData = sensorData; + $scope.export_data = JSON.stringify(originalData); + }); + }; + + $scope.loadSensorData(); } ] ); diff --git a/app/server-health/index.js b/app/server-health/index.js index f64300b..6d00879 100644 --- a/app/server-health/index.js +++ b/app/server-health/index.js @@ -38,7 +38,7 @@ window.angular && (function (angular) { 'controller': 'sensorsOverviewController', authenticated: true }) - .when('/server-health/sensors', { + .when('/server-health/sensors/:type', { 'templateUrl': 'server-health/controllers/sensors-controller.html', 'controller': 'sensorsController', authenticated: true diff --git a/app/server-health/styles/sensors.scss b/app/server-health/styles/sensors.scss index ade2b23..f720c3b 100644 --- a/app/server-health/styles/sensors.scss +++ b/app/server-health/styles/sensors.scss @@ -200,6 +200,7 @@ $title-minWidth: 210px; -webkit-transition: 0.5s linear max-height; transition: 0.5s linear max-height; padding: 0; + @include fastTransition-all; @include mediaQuery(large) { margin-left: 200px; } |