commit
b12afca9b5
|
@ -2,12 +2,18 @@
|
|||
|
||||
### Bug Fixes
|
||||
1. [#1450](https://github.com/influxdata/chronograf/pull/1450): Fix infinite spinner when using "/chronograf" as a basepath
|
||||
1. [#1455](https://github.com/influxdata/chronograf/issues/1455): Fix backwards sort arrows in tables
|
||||
1. [#1423](https://github.com/influxdata/chronograf/issues/1423): Make logout nav item consistent with design
|
||||
1. [#1426](https://github.com/influxdata/chronograf/issues/1426): Fix graph loading spinner
|
||||
|
||||
### Features
|
||||
|
||||
### UI Improvements
|
||||
1. [#1451](https://github.com/influxdata/chronograf/pull/1451): Refactor scrollbars to support non-webkit browsers
|
||||
1. [#1453](https://github.com/influxdata/chronograf/pull/1453): Give QueryMaker a greater initial height than Visualization
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Make Template Variables Manager more space efficient
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Add page spinners to pages that did not have them
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Denote which source is connected in the Sources table
|
||||
|
||||
## v1.3.0 [2017-05-09]
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ const AdminTabs = ({
|
|||
}) => {
|
||||
let tabs = [
|
||||
{
|
||||
type: 'DB Management',
|
||||
type: 'Databases',
|
||||
component: <DatabaseManagerPage source={source} />,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -176,10 +176,10 @@ class AdminPage extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
{users
|
||||
? <AdminTabs
|
||||
{users
|
||||
? <div className="container-fluid">
|
||||
<div className="row">
|
||||
<AdminTabs
|
||||
users={users}
|
||||
roles={roles}
|
||||
source={source}
|
||||
|
@ -204,9 +204,9 @@ class AdminPage extends Component {
|
|||
onUpdateUserRoles={this.handleUpdateUserRoles}
|
||||
onUpdateUserPassword={this.handleUpdateUserPassword}
|
||||
/>
|
||||
: <span>Loading...</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
: <div className="page-spinner" />}
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -82,68 +82,83 @@ const AlertsTable = React.createClass({
|
|||
<div className="panel panel-minimal">
|
||||
<div className="panel-heading u-flex u-ai-center u-jc-space-between">
|
||||
<h2 className="panel-title">{this.props.alerts.length} Alerts</h2>
|
||||
<SearchBar onSearch={this.filterAlerts} />
|
||||
{this.props.alerts.length
|
||||
? <SearchBar onSearch={this.filterAlerts} />
|
||||
: null}
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<table className="table v-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
onClick={() => this.changeSort('name')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('level')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Level
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('time')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('host')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Host
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('value')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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()}`}
|
||||
{this.props.alerts.length
|
||||
? <table className="table v-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
onClick={() => this.changeSort('name')}
|
||||
className="sortable-header"
|
||||
>
|
||||
{level}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
{new Date(Number(time)).toISOString()}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
<Link to={`/sources/${id}/hosts/${host}`}>
|
||||
{host}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="monotype">{value}</td>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('level')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Level
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('time')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('host')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Host
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('value')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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()}`}
|
||||
>
|
||||
{level}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
{new Date(Number(time)).toISOString()}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
<Link to={`/sources/${id}/hosts/${host}`}>
|
||||
{host}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="monotype">{value}</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
: <div className="generic-empty-state">
|
||||
<h4 className="no-user-select">
|
||||
Alerts appear here when you have Rules
|
||||
</h4>
|
||||
<br />
|
||||
<Link
|
||||
to={`/sources/${id}/alert-rules/new`}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
Create a Rule
|
||||
</Link>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -95,18 +95,18 @@ class AlertsApp extends Component {
|
|||
}
|
||||
|
||||
renderSubComponents() {
|
||||
let component
|
||||
if (this.state.loading) {
|
||||
component = <p>Loading...</p>
|
||||
} else {
|
||||
const {source} = this.props
|
||||
if (this.state.hasKapacitor) {
|
||||
component = <AlertsTable source={source} alerts={this.state.alerts} />
|
||||
} else {
|
||||
component = <NoKapacitorError source={source} />
|
||||
}
|
||||
}
|
||||
return component
|
||||
const {source} = this.props
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
{this.state.hasKapacitor
|
||||
? <AlertsTable source={source} alerts={this.state.alerts} />
|
||||
: <NoKapacitorError source={source} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
handleToggleTime() {
|
||||
|
@ -151,13 +151,7 @@ class AlertsApp extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
{this.renderSubComponents()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderSubComponents()}
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ const TemplateQueryBuilder = ({
|
|||
}) => {
|
||||
switch (selectedType) {
|
||||
case 'csv':
|
||||
return <div className="tvm-csv-instructions">Enter values below</div>
|
||||
return null
|
||||
case 'databases':
|
||||
return <div className="tvm-query-builder--text">SHOW DATABASES</div>
|
||||
case 'measurements':
|
||||
|
|
|
@ -84,9 +84,9 @@ const HostsTable = React.createClass({
|
|||
sortableClasses(key) {
|
||||
if (this.state.sortKey === key) {
|
||||
if (this.state.sortDirection === 'asc') {
|
||||
return 'sortable-header sorting-up'
|
||||
return 'sortable-header sorting-ascending'
|
||||
}
|
||||
return 'sortable-header sorting-down'
|
||||
return 'sortable-header sorting-descending'
|
||||
}
|
||||
return 'sortable-header'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import buildInfluxQLQuery from 'utils/influxql'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import DatabaseList from '../../data_explorer/components/DatabaseList'
|
||||
import MeasurementList from '../../data_explorer/components/MeasurementList'
|
||||
|
@ -76,16 +77,21 @@ export const DataSection = React.createClass({
|
|||
|
||||
render() {
|
||||
const {query, timeRange: {lower}} = this.props
|
||||
const statement =
|
||||
query.rawText ||
|
||||
buildInfluxQLQuery({lower}, query) ||
|
||||
'Build a query below'
|
||||
const statement = query.rawText || buildInfluxQLQuery({lower}, query)
|
||||
|
||||
return (
|
||||
<div className="kapacitor-rule-section kapacitor-metric-selector">
|
||||
<h3 className="rule-section-heading">Select a Time Series</h3>
|
||||
<div className="rule-section-body">
|
||||
<pre><code>{statement}</code></pre>
|
||||
<pre>
|
||||
<code
|
||||
className={classnames({
|
||||
'kapacitor-metric-placeholder': !statement,
|
||||
})}
|
||||
>
|
||||
{statement || 'Build a query below'}
|
||||
</code>
|
||||
</pre>
|
||||
{this.renderQueryBuilder()}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -127,10 +127,11 @@ class KapacitorForm extends Component {
|
|||
<h2 className="panel-title">Configure Alert Endpoints</h2>
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<br />
|
||||
<p className="text-center">
|
||||
Connect to an active Kapacitor instance to configure alerting endpoints.
|
||||
</p>
|
||||
<div className="generic-empty-state">
|
||||
<h4 className="no-user-select">
|
||||
Connect to an active Kapacitor instance to configure alerting endpoints
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -81,9 +81,7 @@ const SideNav = React.createClass({
|
|||
</NavBlock>
|
||||
{showLogout
|
||||
? <NavBlock icon="user-outline" className="sidebar__square-last">
|
||||
<a className="sidebar__menu-item" href={logoutLink}>
|
||||
Logout
|
||||
</a>
|
||||
<NavHeader link={logoutLink} title="Logout" />
|
||||
</NavBlock>
|
||||
: null}
|
||||
</NavBar>
|
||||
|
|
|
@ -120,12 +120,16 @@ const InfluxTable = ({
|
|||
)}
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<Link
|
||||
className="btn btn-success btn-xs"
|
||||
to={`/sources/${s.id}/hosts`}
|
||||
>
|
||||
Connect
|
||||
</Link>
|
||||
{s.id === source.id
|
||||
? <span className="currently-connected-source">
|
||||
<span className="icon checkmark" /> Connected
|
||||
</span>
|
||||
: <Link
|
||||
className="btn btn-success btn-xs"
|
||||
to={`/sources/${s.id}/hosts`}
|
||||
>
|
||||
Connect
|
||||
</Link>}
|
||||
<button
|
||||
className="btn btn-danger btn-xs"
|
||||
onClick={() => handleDeleteSource(s)}
|
||||
|
|
|
@ -107,8 +107,8 @@ $graph-gutter: 16px;
|
|||
justify-content: center;
|
||||
}
|
||||
.graph-spinner {
|
||||
width: 121px;
|
||||
height: 121px;
|
||||
width: 121px !important;
|
||||
height: 121px !important;
|
||||
background-image: url(assets/images/laser-spinner.png);
|
||||
background-size: 100% 100%;
|
||||
background-position: center center;
|
||||
|
@ -123,4 +123,4 @@ $graph-gutter: 16px;
|
|||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* This is a hack to tell the browser to use the GPU when rendering the spinner. */
|
||||
transform: translateZ(0);
|
||||
animation: spinner 0.5s infinite linear;
|
||||
animation: spinner 0.6s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes spinner {
|
||||
|
|
|
@ -56,7 +56,7 @@ table {
|
|||
padding: 6px 8px !important;
|
||||
}
|
||||
tbody tr:hover {
|
||||
background-color: $g5-pepper;
|
||||
background-color: $g4-onyx;
|
||||
|
||||
td {
|
||||
color: $g19-ghost !important;
|
||||
|
@ -125,13 +125,9 @@ table .monotype {
|
|||
cursor: pointer;
|
||||
color: $g19-ghost;
|
||||
background-color: $g5-pepper;
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.sorting-down,
|
||||
&.sorting-up {
|
||||
&.sorting-ascending,
|
||||
&.sorting-descending {
|
||||
background-color: $g5-pepper;
|
||||
color: $g19-ghost;
|
||||
|
||||
|
@ -139,11 +135,11 @@ table .monotype {
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.sorting-down {
|
||||
|
||||
&:after {
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
}
|
||||
&.sorting-ascending:after {
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
}
|
||||
&.sorting-descending:after {
|
||||
transform: translateY(-50%) rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ $tvmp-table-gutter: 8px;
|
|||
border-radius: $radius;
|
||||
border: 2px solid $g5-pepper;
|
||||
background-color: $g2-kevlar;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
border-color 0.25s ease;
|
||||
|
||||
|
|
|
@ -185,6 +185,11 @@ $kapacitor-font-sm: 13px;
|
|||
pre code {
|
||||
line-height: ($kapacitor-font-sm + 3px);
|
||||
white-space: pre-wrap;
|
||||
|
||||
&.kapacitor-metric-placeholder {
|
||||
color: $g8-storm;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
.query-builder {
|
||||
height: 240px;
|
||||
|
|
|
@ -198,6 +198,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.currently-connected-source {
|
||||
color: $c-rainforest;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
margin: 0 4px;
|
||||
@include no-user-select();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue