Merge pull request #1644 from influxdata/sticky-alert-table

Sticky Alert Table
pull/10616/head
Alex Paxton 2017-06-22 16:07:40 -07:00 committed by GitHub
commit 7b3d6906b3
6 changed files with 171 additions and 66 deletions

View File

@ -4,6 +4,7 @@
1. [#1645](https://github.com/influxdata/chronograf/pull/1645): Add Auth0 as a supported OAuth2 provider
### UI Improvements
1. [#1644](https://github.com/influxdata/chronograf/pull/1644): Redesign Alerts History table to have sticky headers
1. [#1581](https://github.com/influxdata/chronograf/pull/1581): Refresh template variable values on dashboard page load
## v1.3.3.3 [2017-06-21]

View File

@ -2,6 +2,10 @@ import React, {Component, PropTypes} from 'react'
import _ from 'lodash'
import {Link} from 'react-router'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {ALERTS_TABLE} from 'src/alerts/constants/tableSizing'
class AlertsTable extends Component {
constructor(props) {
super(props)
@ -55,11 +59,11 @@ class AlertsTable extends Component {
sortableClasses(key) {
if (this.state.sortKey === key) {
if (this.state.sortDirection === 'asc') {
return 'sortable-header sorting-ascending'
return 'alert-history-table--th sortable-header sorting-ascending'
}
return 'sortable-header sorting-descending'
return 'alert-history-table--th sortable-header sorting-descending'
}
return 'sortable-header'
return 'alert-history-table--th sortable-header'
}
sort(alerts, key, direction) {
@ -80,64 +84,93 @@ class AlertsTable extends Component {
this.state.sortKey,
this.state.sortDirection
)
const {colName, colLevel, colTime, colHost, colValue} = ALERTS_TABLE
return this.props.alerts.length
? <table className="table v-center table-highlight">
<thead>
<tr>
<th
onClick={() => this.changeSort('name')}
className={this.sortableClasses('name')}
>
Name
</th>
<th
onClick={() => this.changeSort('level')}
className={this.sortableClasses('level')}
>
Level
</th>
<th
onClick={() => this.changeSort('time')}
className={this.sortableClasses('time')}
>
Time
</th>
<th
onClick={() => this.changeSort('host')}
className={this.sortableClasses('host')}
>
Host
</th>
<th
onClick={() => this.changeSort('value')}
className={this.sortableClasses('value')}
>
Value
</th>
</tr>
</thead>
<tbody>
? <div className="alert-history-table">
<div className="alert-history-table--thead">
<div
onClick={() => this.changeSort('name')}
className={this.sortableClasses('name')}
style={{width: colName}}
>
Name
</div>
<div
onClick={() => this.changeSort('level')}
className={this.sortableClasses('level')}
style={{width: colLevel}}
>
Level
</div>
<div
onClick={() => this.changeSort('time')}
className={this.sortableClasses('time')}
style={{width: colTime}}
>
Time
</div>
<div
onClick={() => this.changeSort('host')}
className={this.sortableClasses('host')}
style={{width: colHost}}
>
Host
</div>
<div
onClick={() => this.changeSort('value')}
className={this.sortableClasses('value')}
style={{width: colValue}}
>
Value
</div>
</div>
<FancyScrollbar
className="alert-history-table--tbody"
autoHide={false}
>
{alerts.map(({name, level, time, host, value}) => {
return (
<tr key={`${name}-${level}-${time}-${host}-${value}`}>
<td className="monotype">{name}</td>
<td className={`monotype alert-level-${level.toLowerCase()}`}>
<div
className="alert-history-table--tr"
key={`${name}-${level}-${time}-${host}-${value}`}
>
<div
className="alert-history-table--td"
style={{width: colName}}
>
{name}
</div>
<div
className={`alert-history-table--td alert-level-${level.toLowerCase()}`}
style={{width: colLevel}}
>
{level}
</td>
<td className="monotype">
</div>
<div
className="alert-history-table--td"
style={{width: colTime}}
>
{new Date(Number(time)).toISOString()}
</td>
<td className="monotype">
</div>
<div
className="alert-history-table--td"
style={{width: colHost}}
>
<Link to={`/sources/${id}/hosts/${host}`}>
{host}
</Link>
</td>
<td className="monotype">{value}</td>
</tr>
</div>
<div
className="alert-history-table--td"
style={{width: colValue}}
>
{value}
</div>
</div>
)
})}
</tbody>
</table>
</FancyScrollbar>
</div>
: this.renderTableEmpty()
}
@ -239,7 +272,7 @@ class SearchBar extends Component {
<input
type="text"
className="form-control"
placeholder="Filter Alerts by Name..."
placeholder="Filter Alerts..."
onChange={this.handleChange}
value={this.state.searchTerm}
/>

View File

@ -0,0 +1,7 @@
export const ALERTS_TABLE = {
colName: '15%',
colLevel: '10%',
colTime: '25%',
colHost: '25%',
colValue: '25%',
}

View File

@ -4,7 +4,6 @@ import SourceIndicator from 'shared/components/SourceIndicator'
import AlertsTable from 'src/alerts/components/AlertsTable'
import NoKapacitorError from 'shared/components/NoKapacitorError'
import CustomTimeRangeDropdown from 'shared/components/CustomTimeRangeDropdown'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {getAlerts} from 'src/alerts/apis'
import AJAX from 'utils/ajax'
@ -160,10 +159,8 @@ class AlertsApp extends Component {
}
return isWidget
? <FancyScrollbar autoHide={false}>
{this.renderSubComponents()}
</FancyScrollbar>
: <div className="page">
? this.renderSubComponents()
: <div className="page alert-history-page">
<div className="page-header">
<div className="page-header__container">
<div className="page-header__left">
@ -183,7 +180,7 @@ class AlertsApp extends Component {
</div>
</div>
</div>
<FancyScrollbar className="page-contents">
<div className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
@ -191,7 +188,7 @@ class AlertsApp extends Component {
</div>
</div>
</div>
</FancyScrollbar>
</div>
</div>
}
}

View File

@ -50,7 +50,8 @@
Sortable Tables
----------------------------------------------
*/
table.table thead th.sortable-header {
table.table thead th.sortable-header,
.alert-history-table--th.sortable-header {
transition:
color 0.25s ease,
background-color 0.25s ease;
@ -172,15 +173,69 @@ $table-tab-scrollbar-height: 6px;
.table.table-highlight > tbody > tr.highlight {
background-color: $g4-onyx;
}
/*
Responsive Tables
Alert History "Page"
----------------------------------------------
*/
.alert-history-page {
.page-contents > .container-fluid,
.page-contents > .container-fluid > .row,
.page-contents > .container-fluid > .row > .col-md-12,
.page-contents > .container-fluid > .row > .col-md-12 > .panel {
height: 100%;
}
.col-md-12 > .panel {
display: flex;
flex-direction: column;
align-items: stretch;
> .panel-body {flex: 1 0 0;}
.generic-empty-state {height: 100%;}
}
}
/*
Alert History "Table"
----------------------------------------------
*/
@media screen and (max-width: 767px) {
.table-responsive {
border-radius: 3px;
border-color: $g5-pepper;
@include custom-scrollbar($g5-pepper, $c-pool);
.alert-history-table {
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
}
.alert-history-table--thead {
display: flex;
width: 100%;
border-bottom: 2px solid $g5-pepper;
}
.alert-history-table--th {
@include no-user-select();
padding: 8px;
font-size: 13px;
font-weight: 500;
color: $g17-whisper;
}
.alert-history-table--tbody {
flex: 1 0 0;
width: 100%;
}
.alert-history-table--tr {
display: flex;
width: 100%;
&:hover {
background-color: $g4-onyx;
}
}
.alert-history-table--td {
font-size: 12px;
font-family: $code-font;
font-weight: 500;
padding: 4px 8px;
line-height: 1.42857143em;
color: $g13-mist;
white-space: pre-wrap;
word-break: break-all;
}

View File

@ -192,3 +192,15 @@ br {
p {font-size: 13px;}
}
.alerts-widget {
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
> .btn {margin: 20px 0;}
.alert-history-table {
flex: 1 0 0;
}
}