diff options
author | Derick Montague <derick.montague@ibm.com> | 2019-06-23 12:20:17 -0500 |
---|---|---|
committer | Derick Montague <derick.montague@ibm.com> | 2019-06-27 19:27:38 -0500 |
commit | 1f690f3ebee87613ec8213922c9ca1e69e64560a (patch) | |
tree | d86bb365207335d41c4a81e2ccc38cabed657c39 | |
parent | 2c352ed3a7f808c24107d1a71bef9349193a6e13 (diff) | |
download | phosphor-webui-1f690f3ebee87613ec8213922c9ca1e69e64560a.tar.gz phosphor-webui-1f690f3ebee87613ec8213922c9ca1e69e64560a.zip |
Fix sensors table header and body alignment
- Update markup to use semenatic table
- Update table to flex based layout to support responsive
table design
Tested: Small screen and large screen layout in Chrome,
Firefox, and Safari. Safari has issues with the
sticky header, which is an acceptable trade off
and meets cross-browser standards.
Signed-off-by: Derick Montague <derick.montague@ibm.com>
Change-Id: I8ea323e45a2659562f229d4fd6d4e53887664cad
-rw-r--r-- | app/server-health/controllers/sensors-overview-controller.html | 110 | ||||
-rw-r--r-- | app/server-health/styles/sensors.scss | 238 |
2 files changed, 188 insertions, 160 deletions
diff --git a/app/server-health/controllers/sensors-overview-controller.html b/app/server-health/controllers/sensors-overview-controller.html index 90bdcc2..8669c33 100644 --- a/app/server-health/controllers/sensors-overview-controller.html +++ b/app/server-health/controllers/sensors-overview-controller.html @@ -1,16 +1,12 @@ <loader loading="loading"></loader> -<div id="sensors-overview"> - <div class="row column"> - <h1>Sensors</h1> - </div> - <section class="row column"> - <div class="page-header"> - <h2 class="inline">All sensors present in the system</h2> +<div id="sensors" class="sensors"> + <h1>Sensors</h1> + <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="btn btn-tertiary float-right" download="{{export_name}}"><icon file="icon-export.svg"></icon>Export</a> - </div> - </section> - <section class="row column"> - <!-- search --> + </div> + + <div> <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 +15,7 @@ <button class="clear-input" ng-click="clear()">✕</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> @@ -36,37 +32,73 @@ ng-class="selectedSeverity.normal ? 'btn-primary' : 'btn-secondary'">Normal </button> </div> + </div> - </section> - - <section class="row column" ng-show="filteredSensorData.length == 0"> - <!-- message --> + <div ng-show="filteredSensorData.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 --> - </section> + </div> - <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> - </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'">°</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'">°</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'">°</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'">°</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'">°</span></p> - </div> - </section> + <table id="sensor-categories" class="sensors__table" cellpadding="0" cellspacing="0" ng-show="filteredSensorData.length"> + <thead class="sensors__thead fixed-table-header"> + <tr class="sensors__thead-row"> + <th class="sensors__thead-cell">Sensors ({{filteredSensorData.length}})<th> + <th class="sensors__thead-cell">Low critical<th> + <th class="sensors__thead-cell">Low warning<th> + <th class="sensors__thead-cell sensor__heading-current">Current<th> + <th class="sensors__thead-cell">High warning<th> + <th class="sensors__thead-cell">High critical<th> + </tr> + </thead> + <tbody class="sensors__tbody"> + <tr class="sensors__tbody-row" ng-repeat="sensor in data|filter:filterBySeverity|filter:filterBySearchTerms|orderBy:'+custom_order' as filteredSensorData"> + <th class="sensors__tbody-header"> + <span class="icon" ng-class="{'icon__critical': sensor.status == 'critical', 'icon__warning': sensor.status == 'warning', 'icon__normal': sensor.status == 'normal'}" aria-label="Sensor status: {{sensor.status}}" ></span> + <span>{{sensor.title}}</span> + </th> + <td class="sensors__tbody-cell"> + <span class="sensors__tbody-cell__title">Low critical</span> + <span class="sensors__tbody-cell__content"> + <span class="sensors__tbody-info">{{sensor.CriticalLow}}</span> + <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span> + <span class="sensors__tbody-unit">{{sensor.unit}}</span> + </span> + </td> + <td class="sensors__tbody-cell"> + <span class="sensors__tbody-cell__title">Low warning</span> + <span class="sensors__tbody-cell__content"> + <span class="sensors__tbody-info">{{sensor.WarningLow}}</span> + <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span> + <span class="sensors__tbody-unit">{{sensor.unit}}</span> + </span> + </td> + <td class="sensors__tbody-cell sensors__tbody-current" ng-class="{'sensors__tbody-current--critical': sensor.status == 'critical', 'sensors__tbody-current--warn': sensor.status == 'warning', 'sensors__tbody-current--normal': sensor.status == 'normal'}"> + <span class="sensors__tbody-cell__title">Current</span> + <span class="sensors__tbody-cell__content"> + <span class="sensors__tbody-info">{{sensor.Value}}</span> + <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span> + <span class="sensors__tbody-unit">{{sensor.unit}}</span> + </span> + </td> + <td class="sensors__tbody-cell"> + <span class="sensors__tbody-cell__title">High warning</span> + <span class="sensors__tbody-cell__content"> + <span class="sensors__tbody-info">{{sensor.WarningHigh}}</span> + <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span> + <span class="sensors__tbody-unit">{{sensor.unit}}</span> + </span> + </td> + <td class="sensors__tbody-cell"> + <span class="sensors__tbody-cell__title">High critical</span> + <span class="sensors__tbody-cell__content"> + <span class="sensors__tbody-info">{{sensor.CriticalHigh}}</span> + <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span> + <span class="sensors__tbody-unit">{{sensor.unit}}</span> + </span> + </td> + </tr> + </tbody> + </table> </div> diff --git a/app/server-health/styles/sensors.scss b/app/server-health/styles/sensors.scss index 6c81766..260c2a7 100644 --- a/app/server-health/styles/sensors.scss +++ b/app/server-health/styles/sensors.scss @@ -1,155 +1,151 @@ -@mixin state-label { - text-transform: uppercase; - font-weight: 700; - font-size: .8em; +.sensors { + max-width: 1196px; } -$title-minWidth: 210px; +.sensors__table { + display: block; + border-collapse: collapse; +} -.header__actions-bar { - padding-left: 1.5em; - padding-right: 1em; - font-weight: 700; - .sensor__title { - margin-left: 1.5em; - } - .sensor__reading { - margin-right: .2em; - } - .sensor__heading-current { - padding-right: 1em; - } +.sensors__thead { + display: block; } -.sensor__heading-current { - margin: 0; +.sensors__thead-row { + display: block; + background: $darkblue; + color: $white; + margin-bottom: 1rem; + @include mediaQuery(medium) { - margin-left: 10px; - margin-right: 10px; + display: flex; + margin-bottom: 0; } } -.sensor__label { - float: left; - font-weight: 300; - @include mediaQuery(medium) { +.sensors__thead-cell { + display: block; + padding: 1rem; + font-weight: 700; + + &:not(:first-child) { display: none; } + + @include mediaQuery(medium) { + flex: 1; + + &:not(:first-child) { + display: block; + flex-grow: 0; + flex-shrink: 0; + flex-basis: 0; + min-width: 16%; + } + } } -.sensor__title { - min-width: 28%; - margin-bottom: 0; +.sensors__tbody { + display: block; } -.sensor__reading { - width: 100%; - text-align: right; - margin-bottom: 0; - display: none; +.sensors__tbody-row { + display: flex; + flex-direction: column; + border: 1px solid $medgrey; + margin-bottom: 1rem; + @include mediaQuery(medium) { - display: inline-block; - width: auto; - min-width: calc(70% * (1 / 5) - 18px); + display: flex; + flex-direction: row; + margin-bottom: 0; } } -.sensor__readings-row { - width: 100%; - position: relative; +.sensors__tbody-header { display: block; - margin: 0; - background: $white; - text-decoration: none; - border: 1px solid $medgrey; - background: lighten($lightgrey,1%); - margin-top: 1em; + background: darken($lightgrey, 5%); + padding: 0.5rem 1rem; + font-weight: 700; + .icon.icon__normal { + display: none; + } + @include mediaQuery(medium) { - padding: .3em 1em .3em 1.5em; - margin-top: 0; - border-top: 0; + flex: 1; + align-items: center; background: transparent; + font-weight: 400; + margin-top: 0.5rem; + margin-bottom: 0.5rem; } - .sensor__title { - font-weight: 700; - background: darken($lightgrey, 5%); - min-width: 100%; - padding: .8em; - @include mediaQuery(medium) { - min-width: 30%; - 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; - display: block; - padding: .3em .8em; - @include mediaQuery(medium) { - display: inline-block; - padding: 0; - } - } - .sensor__current { - background: darken($thresh-normal, 3%); - margin: 0; - @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; - } - } - } - .sensor__critical { - background: $thresh-critical; - color: $white; - .content-label { - color: $white; - } +} + +.sensors__tbody-cell { + display: flex; + justify-content: space-between; + padding: 0.5rem 1rem; + @include fontCourierBold; + + @include mediaQuery(medium) { + flex-grow: 0; + flex-shrink: 0; + flex-basis: 0; + align-items: center; + min-width: 16%; + justify-content: flex-start; + margin-top: 0.5rem; + margin-bottom: 0.5rem; } - .sensor__warn { - background: $thresh-warning; - color: $black; - .content-label { - color: $black; - } +} + +.sensors__tbody-cell__title { + font-weight: 300; + + @include mediaQuery(medium) { + display: none; } +} + +.sensors__tbody-unit { + display: inline-block; + color: $darkgrey; + margin-left: 0.5em; + font-weight: 700; + text-transform: uppercase; + @include mediaQuery(medium) { + margin-left: 0; + } } -// Sensors +.sensors__tbody-degree { + display: inline-block; + margin-left: -8px; +} -#sensors, #sensors-overview { +.sensors__tbody-current { + background: darken($thresh-normal, 3%); - .toggle-filter { - margin-bottom: 20px; - font-size: 0.9em; + .sensors__tbody-cell__title { + font-weight: 700; } - .column, .columns { - padding-left: 0px; - padding-right: 0px; +} + +.sensors__tbody-current--critical { + background: $thresh-critical; + color: $white; + + .sensors__tbody-unit { + color: $white; } } -//end sensor details +.sensors__tbody-current--warn { + background: $thresh-warning; + color: $black; + + .sensors__tbody-unit { + color: $black; + } +} |