Merge pull request #1124 from influxdata/some-amount-of-polish

Some Amount of Polish
pull/10616/head
Andrew Watkins 2017-03-31 16:56:45 -07:00 committed by GitHub
commit 1c2457dabb
25 changed files with 252 additions and 124 deletions

View File

@ -5,6 +5,8 @@
1. [#1125](https://github.com/influxdata/chronograf/pull/1125): Fix visualizations not showing graph name
1. [#1133](https://github.com/influxdata/chronograf/issue/1133): Fix Enterprise Kapacitor authentication.
1. [#1142](https://github.com/influxdata/chronograf/issue/1142): Fix Kapacitor Telegram config to display correct disableNotification setting
1. [#1097](https://github.com/influxdata/chronograf/issues/1097): Fix broken graph spinner in the Data Explorer & Dashboard Cell Edit
1. [#1106](https://github.com/influxdata/chronograf/issues/1106): Fix obscured legends in dashboards
1. [#1051](https://github.com/influxdata/chronograf/issue/1051): Exit presentation mode when using the browser back button
### Features
@ -19,6 +21,7 @@
1. [#1135](https://github.com/influxdata/chronograf/pull/1135): Clarify Kapacitor Alert configuration for Telegram
1. [#1137](https://github.com/influxdata/chronograf/pull/1137): Clarify Kapacitor Alert configuration for HipChat
1. [#1079](https://github.com/influxdata/chronograf/issues/1079): Remove series highlighting in line graphs
1. [#1124](https://github.com/influxdata/chronograf/pull/1124): Polished dashboard cell drag interaction, use Hover-To-Reveal UI pattern in all tables, Source Indicator & Graph Tips are no longer misleading, and aesthetic improvements to the DB Management page
## v1.2.0-beta7 [2017-03-28]
### Bug Fixes

View File

@ -52,22 +52,22 @@ class ChangePassRow extends Component {
if (this.state.showForm) {
return (
<div>
<input
className="form-control"
name="password"
type="password"
value={user.password || ''}
placeholder="Password"
onChange={this.handleEdit(user)}
onKeyPress={this.handleKeyPress(user)}
autoFocus={true}
/>
<ConfirmButtons
onConfirm={this.handleSubmit}
item={user}
onCancel={this.handleCancel}
/>
<div className="admin-change-pw">
<input
className="form-control"
name="password"
type="password"
value={user.password || ''}
placeholder="Password"
onChange={this.handleEdit(user)}
onKeyPress={this.handleKeyPress(user)}
autoFocus={true}
/>
<ConfirmButtons
onConfirm={this.handleSubmit}
item={user}
onCancel={this.handleCancel}
/>
</div>
)
}

View File

@ -51,7 +51,7 @@ class DatabaseRow extends Component {
className="form-control"
type="text"
defaultValue={name}
placeholder="give it a name"
placeholder="Name this RP"
onKeyDown={(e) => this.handleKeyDown(e, database)}
ref={(r) => this.name = r}
autoFocus={true}
@ -69,7 +69,7 @@ class DatabaseRow extends Component {
name="name"
type="text"
defaultValue={formattedDuration}
placeholder="how long should data last"
placeholder="How long should Data last"
onKeyDown={(e) => this.handleKeyDown(e, database)}
ref={(r) => this.duration = r}
autoFocus={!isNew}
@ -84,7 +84,7 @@ class DatabaseRow extends Component {
type="number"
min="1"
defaultValue={replication || 1}
placeholder="how many nodes do you have"
placeholder="# of Nodes"
onKeyDown={(e) => this.handleKeyDown(e, database)}
ref={(r) => this.replication = r}
/>

View File

@ -59,16 +59,16 @@ const Header = ({
}
const buttons = (
<div className="text-right">
<div className="text-right db-manager-header--actions">
<button className="btn btn-xs btn-primary" disabled={isAddRPDisabled} onClick={() => onAddRetentionPolicy(database)}>
Add Retention Policy
</button>
{
database.name === '_internal' ? null :
<button className="btn btn-xs btn-danger" onClick={() => onStartDelete(database)}>
Delete
</button>
}
<button className="btn btn-xs btn-primary" disabled={isAddRPDisabled} onClick={() => onAddRetentionPolicy(database)}>
Add retention policy
</button>
</div>
)
@ -107,13 +107,13 @@ const Header = ({
}
const EditHeader = ({database, onEdit, onKeyDown, onConfirm, onCancel}) => (
<div className="db-manager-header-edit">
<div className="db-manager-header db-manager-header--edit">
<input
className="form-control"
name="name"
type="text"
value={database.name}
placeholder="Database name"
placeholder="Name this database"
onChange={(e) => onEdit(database, {name: e.target.value})}
onKeyDown={(e) => onKeyDown(e, database)}
autoFocus={true}

View File

@ -40,7 +40,7 @@ class FilterBar extends Component {
<span className="icon search" aria-hidden="true"></span>
</div>
</div>
<button className="btn btn-primary" disabled={isEditing} onClick={() => onClickCreate(type)}>Create {placeholderText.substring(0, placeholderText.length - 1)}</button>
<button className="btn btn-sm btn-primary" disabled={isEditing} onClick={() => onClickCreate(type)}>Create {placeholderText.substring(0, placeholderText.length - 1)}</button>
</div>
)
}

View File

@ -4,7 +4,7 @@ const QueriesTable = ({queries, onKillQuery, onConfirm}) => (
<div>
<div className="panel panel-minimal">
<div className="panel-body">
<table className="table v-center">
<table className="table v-center admin-table">
<thead>
<tr>
<th>Database</th>
@ -21,7 +21,7 @@ const QueriesTable = ({queries, onKillQuery, onConfirm}) => (
<td><code>{q.query}</code></td>
<td>{q.duration}</td>
<td className="text-right">
<button className="btn btn-xs btn-link-danger" onClick={onKillQuery} data-toggle="modal" data-query-id={q.id} data-target="#killModal">
<button className="btn btn-xs btn-danger admin-table--hidden" onClick={onKillQuery} data-toggle="modal" data-query-id={q.id} data-target="#killModal">
Kill
</button>
</td>

View File

@ -30,6 +30,7 @@ const UsersTable = ({
{hasRoles && <th>Roles</th>}
<th>Permissions</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>

View File

@ -1,9 +1,9 @@
import React, {PropTypes} from 'react'
import ReactTooltip from 'react-tooltip'
import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from 'shared/components/TimeRangeDropdown'
import SourceIndicator from '../../shared/components/SourceIndicator'
import GraphTips from '../../shared/components/GraphTips'
const DashboardHeader = ({
children,
@ -39,26 +39,22 @@ const DashboardHeader = ({
}
</div>
<div className="page-header__right">
<GraphTips />
<SourceIndicator sourceName={source.name} />
{
dashboard ?
<button className="btn btn-info btn-sm" onClick={onAddCell}>
<button className="btn btn-primary btn-sm" onClick={onAddCell}>
<span className="icon plus" />
&nbsp;Add Cell
Add Cell
</button> : null
}
{
dashboard ?
<button className="btn btn-info btn-sm" onClick={onEditDashboard}>
<span className="icon pencil" />
&nbsp;Edit
Rename
</button> : null
}
<div className="btn btn-info btn-sm" data-for="graph-tips-tooltip" data-tip="<p><code>Click + Drag</code> Zoom in (X or Y)</p><p><code>Shift + Click</code> Pan Graph Window</p><p><code>Double Click</code> Reset Graph Window</p>">
<span className="icon heart"></span>
Graph Tips
</div>
<ReactTooltip id="graph-tips-tooltip" effect="solid" html={true} offset={{top: 2}} place="bottom" class="influx-tooltip place-bottom" />
<SourceIndicator sourceName={source.name} />
<AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
<TimeRangeDropdown onChooseTimeRange={handleChooseTimeRange} selected={timeRange} />
<div className="btn btn-info btn-sm" onClick={handleClickPresentationButton}>

View File

@ -87,10 +87,11 @@ const DashboardsPage = React.createClass({
<button className="btn btn-sm btn-primary" onClick={this.handleCreateDashbord}>Create Dashboard</button>
</div>
<div className="panel-body">
<table className="table v-center">
<table className="table v-center admin-table">
<thead>
<tr>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
@ -116,6 +117,7 @@ const DashboardsPage = React.createClass({
{'Kubernetes'}
</Link>
</td>
<td></td>
</tr>
</tbody>
</table>

View File

@ -4,6 +4,7 @@ import {withRouter} from 'react-router'
import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown'
import SourceIndicator from '../../shared/components/SourceIndicator'
import GraphTips from '../../shared/components/GraphTips'
const {
func,
@ -42,9 +43,10 @@ const Header = React.createClass({
<div className="page-header">
<div className="page-header__container">
<div className="page-header__left">
<h1>Explorer</h1>
<h1>Data Explorer</h1>
</div>
<div className="page-header__right">
<GraphTips />
<SourceIndicator sourceName={this.context.source.name} />
<AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
<TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={timeRange} />

View File

@ -1,8 +1,8 @@
const telegramChatIDLink = 'https://docs.influxdata.com/kapacitor/latest/guides/event-handler-setup/#telegram-chat-id'
export const TELEGRAM_CHAT_ID_TIP = `<p>Need help finding your chat id? Check out <a target='_blank' href='${telegramChatIDLink}'>these steps</a>.</p>`
export const TELEGRAM_CHAT_ID_TIP = `<p>Need help finding your chat id?<br/>Check out <a target='_blank' href='${telegramChatIDLink}'>these steps</a>.</p>`
const telegramTokenLink = 'https://docs.influxdata.com/kapacitor/latest/guides/event-handler-setup/#telegram-api-access-token'
export const TELEGRAM_TOKEN_TIP = `<p>Need help finding your token? Check out <a target='_blank' href='${telegramTokenLink}'>these steps</a>.</p>`
export const TELEGRAM_TOKEN_TIP = `<p>Need help finding your token?<br/>Check out <a target='_blank' href='${telegramTokenLink}'>these steps</a>.</p>`
const hipchatTokenLink = 'https://docs.influxdata.com/kapacitor/latest/guides/event-handler-setup/#hipchat-api-access-token'
export const HIPCHAT_TOKEN_TIP = `<p>Need help creating a token? Check out <a href='${hipchatTokenLink}' target='_blank'>these steps</a>.</p>`
export const HIPCHAT_TOKEN_TIP = `<p>Need help creating a token?<br/>Check out <a href='${hipchatTokenLink}' target='_blank'>these steps</a>.</p>`

View File

@ -0,0 +1,16 @@
import React from 'react'
import ReactTooltip from 'react-tooltip'
const GraphTips = React.createClass({
render() {
const graphTipsText = `<p><b>Graph Tips:</b><br/><br/><code>Click + Drag</code> Zoom in (X or Y)</p><p><code>Shift + Click</code> Pan Graph Window</p><p><code>Double Click</code> Reset Graph Window</p>`
return (
<div className="graph-tips" data-for="graph-tips-tooltip" data-tip={graphTipsText}>
<span>?</span>
<ReactTooltip id="graph-tips-tooltip" effect="solid" html={true} offset={{top: 2}} place="bottom" class="influx-tooltip place-bottom" />
</div>
)
},
})
export default GraphTips

View File

@ -187,7 +187,7 @@ export const LayoutRenderer = React.createClass({
useCSSTransforms={false}
onResize={this.triggerWindowResize}
onLayoutChange={this.handleLayoutChange}
draggableHandle={'.dash-graph--heading'}
draggableHandle={'.dash-graph--drag-handle'}
isDraggable={isDashboard}
isResizable={isDashboard}
>

View File

@ -100,6 +100,7 @@ const NameableGraph = React.createClass({
<div className="dash-graph">
<div className="dash-graph--heading">
<div onClick={onClickHandler(x, y, isEditing)}>{nameOrField}</div>
{shouldNotBeEditable ? null : <div className="dash-graph--drag-handle"></div>}
{
shouldNotBeEditable ?
null :

View File

@ -5,8 +5,8 @@ const QuestionMarkTooltip = ({
tipID,
tipContent,
}) => (
<div style={{display: "inline-block"}}>
<div data-for={`${tipID}-tooltip`} data-tip={tipContent} style={{margin: "0 5px"}}>?</div>
<div className="question-mark-tooltip">
<div className="question-mark-tooltip--icon" data-for={`${tipID}-tooltip`} data-tip={tipContent}>?</div>
<ReactTooltip
id={`${tipID}-tooltip`}
effect="solid"

View File

@ -1,4 +1,5 @@
import React, {PropTypes} from 'react'
import ReactTooltip from 'react-tooltip'
const SourceIndicator = React.createClass({
propTypes: {
@ -10,13 +11,14 @@ const SourceIndicator = React.createClass({
if (!sourceName) {
return null
}
const sourceNameTooltip = `Connected to <code>${sourceName}</code>`
return (
<div className="source-indicator">
<div className="source-indicator" data-for="source-indicator-tooltip" data-tip={sourceNameTooltip}>
<span className="icon server2"></span>
{sourceName}
<ReactTooltip id="source-indicator-tooltip" effect="solid" html={true} offset={{top: 2}} place="bottom" class="influx-tooltip place-bottom" />
</div>
)
},
})
export default SourceIndicator
export default SourceIndicator

View File

@ -39,6 +39,7 @@
@import 'components/tables';
@import 'components/resizer';
@import 'components/source-indicator';
@import 'components/graph-tips';
@import 'components/confirm-buttons';
@import 'components/custom-time-range';

View File

@ -0,0 +1,24 @@
/*
Graph Tips component styles
----------------------------------------------------------------
*/
.graph-tips {
@include no-user-select();
display: inline-block;
padding: 0 4px;
border: 0;
height: 30px;
line-height: 30px;
> span {
display: inline-block;
text-align: center;
width: 17px;
height: 17px;
border-radius: 50%;
background-color: $g13-mist;
color: $g0-obsidian;
line-height: 18px;
font-weight: 900;
}
}

View File

@ -31,6 +31,7 @@ $tooltip-code-color: $c-potassium;
border: 2px solid $tooltip-accent !important;
border-radius: $tooltip-radius !important;
text-transform: none !important;
cursor: $cc-default;
p {
margin: 0;
@ -95,3 +96,37 @@ $tooltip-code-color: $c-potassium;
opacity: 1!important;
}
}
/*
Question Mark Tooltip
----------------------------------------------
*/
$qmark-tooltip-size: 15px;
.question-mark-tooltip {
display: inline-block;
}
.question-mark-tooltip--icon {
position: relative;
top: -1px;
vertical-align: middle;
display: inline-block;
width: $qmark-tooltip-size;
height: $qmark-tooltip-size;
border-radius: 50%;
text-align: center;
line-height: ($qmark-tooltip-size + 1px);
font-weight: 900;
background-color: $g10-wolf;
color: $g0-obsidian;
margin: 0 5px;
transition:
background-color 0.25s ease;
}
.question-mark-tooltip:hover {
cursor: $cc-default;
.question-mark-tooltip--icon {
background-color: $c-pool;
}
}

View File

@ -5,23 +5,17 @@
.source-indicator {
@include no-user-select();
display: inline-block;
padding: 0 9px;
padding: 0 4px;
border: 0;
background-color: $g5-pepper;
height: 30px;
line-height: 30px;
color: $g13-mist;
font-weight: 700;
font-size: 12px;
border-radius: 3px;
margin-right: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
> .icon {
display: inline-block;
font-size: 16px;
margin: 0 4px 0 -2px;
margin: 0 4px;
}
}

View File

@ -19,6 +19,14 @@
.panel {
border-top-left-radius: 0;
}
.panel-body {
min-height: 300px;
}
.panel-title {
font-size: 17px;
font-weight: 400 !important;
color: $g12-forge;
}
}
}
.admin-tabs .btn-group {
@ -134,61 +142,81 @@
justify-content: space-between;
> input {
height: 30px;
padding: 0 9px;
height: 22px;
padding: 0 6px;
flex-grow: 1;
margin: 0 2px;
margin: 0 4px 0 0;
min-width: 110px;
font-size: 12px;
}
&:first-child {margin-left: 0;}
&:last-child {margin-right: 0;}
& + .confirm-buttons .btn {
display: block !important;
}
}
.db-manager {
margin-bottom: 8px;
.db-manager-header--actions {
display: none;
}
&:last-child {
margin-bottom: 0;
}
&:hover .db-manager-header--actions {
display: block;
}
}
.db-manager-header {
height: 32px;
padding: 0 11px;
height: 42px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 11px;
background-color: $g4-onyx;
border-radius: $radius-small $radius-small 0 0;
h4 {
margin: 0px;
color: $g15-platinum;
color: $c-potassium;
font-size: 17px;
font-family: $code-font;
padding-left: 6px;
}
& .btn {display: none;}
&:hover .btn {display: inline-block;}
}
.db-manager-header-edit {
height: 32px;
display: flex;
align-items: center;
.db-manager-header--edit {
justify-content: flex-start;
margin-bottom: 11px;
> .form-control {
width: 300px;
margin-right: 8px;
}
.btn {
height: 40px;
width: 40px;
padding: 0;
margin: 0 2px 0 0;
font-size: 18px;
.form-control {
height: 22px;
padding: 0 6px;
margin: 0 4px 0 0;
min-width: 110px;
font-size: 12px;
width: 50%;
}
}
.db-manager {
margin-top: 18px;
}
.db-manager:first-child {
margin-top: 0;
}
.db-manager-table {
background-color: $g4-onyx;
padding: 9px 11px;
border-radius: $radius-small;
}
border-radius: 0 0 $radius-small $radius-small;
}
.admin-change-pw {
float: right;
display: flex !important;
flex-wrap: nowrap;
.form-control {
height: 22px;
padding: 0 6px;
margin: 0 4px 0 0;
min-width: 110px;
font-size: 12px;
width: 120px;
}
}

View File

@ -38,6 +38,10 @@ $dash-graph-heading: 30px;
border-radius: $radius;
border: 2px solid $g3-castle;
transition-property: left, top, border-color, background-color;
&:hover {
z-index: 8000;
}
}
.graph-empty {
background-color: transparent;
@ -116,6 +120,29 @@ $dash-graph-heading: 30px;
cursor: $cc-default;
}
}
.dash-graph--drag-handle {
height: $dash-graph-heading;
width: 100%;
&:before {
content: '';
position: absolute;
width: 100%;
left: 0;
height: $dash-graph-heading;
background-color: $g5-pepper;
border-radius: 3px;
z-index: -1;
opacity: 0;
transition: opacity 0.25s ease;
}
&:hover {
cursor: $cc-move;
}
&:hover:before {
opacity: 1;
}
}
.dash-graph--name-edit,
.dash-graph--name {
display: inline-block;
@ -136,7 +163,7 @@ $dash-graph-heading: 30px;
color 0.25s ease,
background-color 0.25s ease,
border-color 0.25s ease;
border: 2px solid $g3-castle;
border: 2px solid transparent;
top: 2px;
&.editable {
@ -269,7 +296,8 @@ $dash-graph-options-arrow: 8px;
position: absolute;
top: -18px !important;
transform: translate(0,0);
right: 50px !important;
right: 50%;
transform: translateX(50%);
width: 16px;
height: 18px;
@ -292,20 +320,12 @@ $dash-graph-options-arrow: 8px;
Dashboard Edit Mode
------------------------------------------------------
*/
// .dash-graph--heading:hover {
// background-color: $g4-onyx;
// color: $g18-cloud;
// cursor: $cc-move;
// .dash-graph--name {
// border-color: $g4-onyx;
// }
// }
.react-grid-placeholder {
@include gradient-diag-down($c-pool,$c-comet);
border: 0;
border: 0 !important;
opacity: 0.3;
z-index: 2;
border-radius: $radius !important;
}
.react-grid-item {
&.resizing {
@ -337,12 +357,11 @@ $dash-graph-options-arrow: 8px;
cursor: $cc-move;
}
// & > .dash-graph--heading,
// & > .dash-graph--heading:hover {
// background-color: $g4-onyx;
// color: $g18-cloud;
// cursor: $cc-move;
// }
.dash-graph--drag-handle:before,
.dash-graph--drag-handle:hover:before {
opacity: 1 !important;
cursor: $cc-move;
}
}
& > .react-resizable-handle {
background-image: none;

View File

@ -84,26 +84,26 @@
height: calc(100% - #{$de-graph-heading-height} - #{($de-vertical-margin * 2)});
padding: 0;
& > div {
& > div:not(.graph-panel__refreshing) {
position: absolute;
width: 100%;
height: 100%;
}
& > div > div {
& > div:not(.graph-panel__refreshing) > div:not(.graph-panel__refreshing) {
position: absolute;
width: 100%;
height: 100%;
padding: 8px 16px;
// width: calc(100% - #{($de-vertical-margin * 2)});
// height: calc(100% - #{$de-vertical-margin});
// top: ($de-vertical-margin / 2);
// left: $de-vertical-margin;
}
& > div > div > div:first-child {
& > div:not(.graph-panel__refreshing) > div:not(.graph-panel__refreshing) > div:first-child {
height: 100% !important;
}
}
.data-explorer .graph-panel__refreshing {
top: -31px !important;
}
/* Active State */
.graph.active {

View File

@ -91,7 +91,7 @@ a.btn.btn-sm > span.icon,
div.btn.btn-sm > span.icon,
button.btn.btn-sm > span.icon {
font-size: 16px;
margin: 0 4px 0 0 ;
margin: 0 6px 0 0 ;
}
.btn.btn-xs > .icon {
position: relative;
@ -215,10 +215,10 @@ button.btn.btn-sm > span.icon {
.form-control,
textarea,
input {
&::-webkit-input-placeholder { color: $g10-wolf; }
&::-moz-placeholder { color: $g10-wolf; }
&:-ms-input-placeholder { color: $g10-wolf; }
&:-moz-placeholder { color: $g10-wolf; }
&::-webkit-input-placeholder { color: $g10-wolf; font-weight: 500 !important; }
&::-moz-placeholder { color: $g10-wolf; font-weight: 500 !important; }
&:-ms-input-placeholder { color: $g10-wolf; font-weight: 500 !important; }
&:-moz-placeholder { color: $g10-wolf; font-weight: 500 !important; }
}
/* Text Selection Styling */

View File

@ -23,7 +23,7 @@
vertical-align: middle;
font-size: 13px;
font-weight: 500;
background-color: $g5-pepper;
background-color: $g2-kevlar;
color: $c-pool;
border-radius: 3px;
padding: 2px 6px;
@ -69,6 +69,10 @@
}
}
}
.form-group label,
.form-group label:hover {
cursor: $cc-default;
}
/*
Generic Empty State