Merge branch 'master' into misc-polish

# Conflicts:
#	ui/src/data_explorer/components/MeasurementList.js
#	ui/src/sources/containers/SourcePage.js
pull/10616/head
Alex P 2017-05-11 10:46:53 -07:00
commit ed2b9b9c90
41 changed files with 668 additions and 779 deletions

View File

@ -6,6 +6,8 @@
### 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
## v1.3.0 [2017-05-09]

View File

@ -101,6 +101,7 @@
"react": "^15.0.2",
"react-addons-shallow-compare": "^15.0.2",
"react-addons-update": "^15.1.0",
"react-custom-scrollbars": "^4.1.1",
"react-dimensions": "^1.2.0",
"react-dom": "^15.0.2",
"react-grid-layout": "^0.13.9",

View File

@ -25,7 +25,8 @@ import {
} from 'src/admin/actions'
import AdminTabs from 'src/admin/components/AdminTabs'
import SourceIndicator from '../../shared/components/SourceIndicator'
import SourceIndicator from 'src/shared/components/SourceIndicator'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {publishAutoDismissingNotification} from 'shared/dispatchers'
@ -174,11 +175,19 @@ class AdminPage extends Component {
</div>
</div>
</div>
<<<<<<< HEAD
<div className="page-contents">
{users
? <div className="container-fluid">
<div className="row">
<AdminTabs
=======
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
{users
? <AdminTabs
>>>>>>> master
users={users}
roles={roles}
source={source}
@ -203,10 +212,17 @@ class AdminPage extends Component {
onUpdateUserRoles={this.handleUpdateUserRoles}
onUpdateUserPassword={this.handleUpdateUserPassword}
/>
<<<<<<< HEAD
</div>
</div>
: <div className="page-spinner"/>}
</div>
=======
: <span>Loading...</span>}
</div>
</div>
</FancyScrollbar>
>>>>>>> master
</div>
)
}

View File

@ -1,8 +1,10 @@
import React, {PropTypes, Component} from 'react'
import SourceIndicator from '../../shared/components/SourceIndicator'
import AlertsTable from '../components/AlertsTable'
import NoKapacitorError from '../../shared/components/NoKapacitorError'
import SourceIndicator from 'src/shared/components/SourceIndicator'
import AlertsTable from 'src/alerts/components/AlertsTable'
import NoKapacitorError from 'src/shared/components/NoKapacitorError'
import CustomTimeRangeDropdown from 'shared/components/CustomTimeRangeDropdown'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {getAlerts} from '../apis'
import AJAX from 'utils/ajax'
@ -148,9 +150,21 @@ class AlertsApp extends Component {
</div>
</div>
</div>
<<<<<<< HEAD
<div className="page-contents">
{this.renderSubComponents()}
</div>
=======
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
{this.renderSubComponents()}
</div>
</div>
</div>
</FancyScrollbar>
>>>>>>> master
</div>
)
}

View File

@ -12,7 +12,7 @@ import * as queryModifiers from 'src/utils/queryTransitions'
import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import buildInfluxQLQuery from 'utils/influxql'
import {getQueryConfig} from 'shared/apis'
import {MINIMUM_HEIGHTS} from 'src/data_explorer/constants'
import {MINIMUM_HEIGHTS, INITIAL_HEIGHTS} from 'src/data_explorer/constants'
import {removeUnselectedTemplateValues} from 'src/dashboards/constants'
class CellEditorOverlay extends Component {
@ -159,6 +159,8 @@ class CellEditorOverlay extends Component {
containerClass="resizer--full-size"
minTopHeight={MINIMUM_HEIGHTS.visualization}
minBottomHeight={MINIMUM_HEIGHTS.queryMaker}
initialTopHeight={INITIAL_HEIGHTS.visualization}
initialBottomHeight={INITIAL_HEIGHTS.queryMaker}
>
<Visualization
autoRefresh={autoRefresh}

View File

@ -3,6 +3,7 @@ import classnames from 'classnames'
import TemplateControlBar from 'src/dashboards/components/TemplateControlBar'
import LayoutRenderer from 'shared/components/LayoutRenderer'
import FancyScrollbar from 'shared/components/FancyScrollbar'
const Dashboard = ({
source,
@ -40,37 +41,37 @@ const Dashboard = ({
})
return (
<div
className={classnames(
'dashboard container-fluid full-width page-contents',
{'presentation-mode': inPresentationMode}
)}
>
<TemplateControlBar
templates={dashboard.templates}
onSelectTemplate={onSelectTemplate}
onOpenTemplateManager={onOpenTemplateManager}
/>
{cells.length
? <LayoutRenderer
templates={templatesIncludingDashTime}
cells={cells}
autoRefresh={autoRefresh}
source={source.links.proxy}
onPositionChange={onPositionChange}
onEditCell={onEditCell}
onRenameCell={onRenameCell}
onUpdateCell={onUpdateCell}
onDeleteCell={onDeleteCell}
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
/>
: <div className="dashboard__empty">
<p>This Dashboard has no Graphs</p>
<button className="btn btn-primary btn-m" onClick={onAddCell}>
Add Graph
</button>
</div>}
</div>
<FancyScrollbar className={classnames(
'page-contents',
{'presentation-mode': inPresentationMode}
)}>
<div className="dashboard container-fluid full-width">
<TemplateControlBar
templates={dashboard.templates}
onSelectTemplate={onSelectTemplate}
onOpenTemplateManager={onOpenTemplateManager}
/>
{cells.length
? <LayoutRenderer
templates={templatesIncludingDashTime}
cells={cells}
autoRefresh={autoRefresh}
source={source.links.proxy}
onPositionChange={onPositionChange}
onEditCell={onEditCell}
onRenameCell={onRenameCell}
onUpdateCell={onUpdateCell}
onDeleteCell={onDeleteCell}
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
/>
: <div className="dashboard__empty">
<p>This Dashboard has no Graphs</p>
<button className="btn btn-primary btn-m" onClick={onAddCell}>
Add Graph
</button>
</div>}
</div>
</FancyScrollbar>
)
}

View File

@ -292,7 +292,7 @@ class DashboardPage extends Component {
>
{dashboards
? dashboards.map((d, i) => (
<li key={i}>
<li className="dropdown-item" key={i}>
<Link
to={`/sources/${sourceID}/dashboards/${d.id}`}
className="role-option"

View File

@ -5,6 +5,7 @@ import {bindActionCreators} from 'redux'
import SourceIndicator from 'shared/components/SourceIndicator'
import DeleteConfirmTableCell from 'shared/components/DeleteConfirmTableCell'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {createDashboard} from 'src/dashboards/apis'
import {getDashboardsAsync, deleteDashboardAsync} from 'src/dashboards/actions'
@ -63,7 +64,7 @@ const DashboardsPage = React.createClass({
<div className="page-header">
<div className="page-header__container">
<div className="page-header__left">
<h1>
<h1 className="page-header__title">
Dashboards
</h1>
</div>
@ -72,7 +73,7 @@ const DashboardsPage = React.createClass({
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
@ -130,7 +131,7 @@ const DashboardsPage = React.createClass({
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)
},

View File

@ -6,6 +6,8 @@ import {showDatabases, showRetentionPolicies} from 'shared/apis/metaQuery'
import showDatabasesParser from 'shared/parsing/showDatabases'
import showRetentionPoliciesParser from 'shared/parsing/showRetentionPolicies'
import FancyScrollbar from 'shared/components/FancyScrollbar'
const {func, shape, string} = PropTypes
const DatabaseList = React.createClass({
@ -67,24 +69,26 @@ const DatabaseList = React.createClass({
<div className="query-builder--column query-builder--column-db">
<div className="query-builder--heading">Databases</div>
<div className="query-builder--list">
{this.state.namespaces.map(namespace => {
const {database, retentionPolicy} = namespace
const isActive =
database === query.database &&
retentionPolicy === query.retentionPolicy
<FancyScrollbar>
{this.state.namespaces.map(namespace => {
const {database, retentionPolicy} = namespace
const isActive =
database === query.database &&
retentionPolicy === query.retentionPolicy
return (
<div
className={classnames('query-builder--list-item', {
active: isActive,
})}
key={`${database}..${retentionPolicy}`}
onClick={_.wrap(namespace, onChooseNamespace)}
>
{database}.{retentionPolicy}
</div>
)
})}
return (
<div
className={classnames('query-builder--list-item', {
active: isActive,
})}
key={`${database}..${retentionPolicy}`}
onClick={_.wrap(namespace, onChooseNamespace)}
>
{database}.{retentionPolicy}
</div>
)
})}
</FancyScrollbar>
</div>
</div>
)

View File

@ -1,7 +1,8 @@
import React, {PropTypes} from 'react'
import FieldListItem from './FieldListItem'
import GroupByTimeDropdown from './GroupByTimeDropdown'
import FieldListItem from 'src/data_explorer/components/FieldListItem'
import GroupByTimeDropdown from 'src/data_explorer/components/GroupByTimeDropdown'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {showFieldKeys} from 'shared/apis/metaQuery'
import showFieldKeysParser from 'shared/parsing/showFieldKeys'
@ -109,21 +110,23 @@ const FieldList = React.createClass({
return (
<div className="query-builder--list">
{this.state.fields.map(fieldFunc => {
const selectedField = this.props.query.fields.find(
f => f.field === fieldFunc.field
)
return (
<FieldListItem
key={fieldFunc.field}
onToggleField={this.props.onToggleField}
onApplyFuncsToField={this.props.applyFuncsToField}
isSelected={!!selectedField}
fieldFunc={selectedField || fieldFunc}
isKapacitorRule={this.props.isKapacitorRule}
/>
)
})}
<FancyScrollbar>
{this.state.fields.map(fieldFunc => {
const selectedField = this.props.query.fields.find(
f => f.field === fieldFunc.field
)
return (
<FieldListItem
key={fieldFunc.field}
onToggleField={this.props.onToggleField}
onApplyFuncsToField={this.props.applyFuncsToField}
isSelected={!!selectedField}
fieldFunc={selectedField || fieldFunc}
isKapacitorRule={this.props.isKapacitorRule}
/>
)
})}
</FancyScrollbar>
</div>
)
},

View File

@ -3,7 +3,9 @@ import classnames from 'classnames'
import {showMeasurements} from 'shared/apis/metaQuery'
import showMeasurementsParser from 'shared/parsing/showMeasurements'
import TagList from './TagList'
import TagList from 'src/data_explorer/components/TagList'
import FancyScrollbar from 'shared/components/FancyScrollbar'
const {func, shape, string} = PropTypes
@ -119,52 +121,54 @@ const MeasurementList = React.createClass({
return (
<div className="query-builder--list">
{measurements.map(measurement => {
const isActive = measurement === this.props.query.measurement
const numTagsActive = Object.keys(this.props.query.tags).length
<FancyScrollbar>
{measurements.map(measurement => {
const isActive = measurement === this.props.query.measurement
const numTagsActive = Object.keys(this.props.query.tags).length
return (
<div
key={measurement}
onClick={
isActive
? () => {}
: () => this.props.onChooseMeasurement(measurement)
}
>
return (
<div
className={classnames('query-builder--list-item', {
active: isActive,
})}
key={measurement}
onClick={
isActive
? () => {}
: () => this.props.onChooseMeasurement(measurement)
}
>
<span>
<div className="query-builder--caret icon caret-right" />
{measurement}
</span>
{isActive && numTagsActive >= 1
? <div
className={classnames('flip-toggle', {
flipped: this.props.query.areTagsAccepted,
})}
onClick={this.handleAcceptReject}
>
<div className="flip-toggle--container">
<div className="flip-toggle--front">!=</div>
<div className="flip-toggle--back">=</div>
<div
className={classnames('query-builder--list-item', {
active: isActive,
})}
>
<span>
<div className="query-builder--caret icon caret-right" />
{measurement}
</span>
{isActive && numTagsActive >= 1
? <div
className={classnames('flip-toggle', {
flipped: this.props.query.areTagsAccepted,
})}
onClick={this.handleAcceptReject}
>
<div className="flip-toggle--container">
<div className="flip-toggle--front">!=</div>
<div className="flip-toggle--back">=</div>
</div>
</div>
</div>
: null}
</div>
{isActive
? <TagList
query={this.props.query}
onChooseTag={this.props.onChooseTag}
onGroupByTag={this.props.onGroupByTag}
/>
: null}
</div>
{isActive
? <TagList
query={this.props.query}
onChooseTag={this.props.onChooseTag}
onGroupByTag={this.props.onGroupByTag}
/>
: null}
</div>
)
})}
)
})}
</FancyScrollbar>
</div>
)
},

View File

@ -15,6 +15,10 @@ export const MINIMUM_HEIGHTS = {
queryMaker: 350,
visualization: 200,
}
export const INITIAL_HEIGHTS = {
queryMaker: '66.666%',
visualization: '33.334%',
}
const SEPARATOR = 'SEPARATOR'

View File

@ -10,7 +10,7 @@ import Header from '../containers/Header'
import ResizeContainer from 'src/shared/components/ResizeContainer'
import {VIS_VIEWS} from 'src/shared/constants'
import {MINIMUM_HEIGHTS} from '../constants'
import {MINIMUM_HEIGHTS, INITIAL_HEIGHTS} from '../constants'
import {setAutoRefresh} from 'shared/actions/app'
import * as viewActions from 'src/data_explorer/actions/view'
@ -93,6 +93,8 @@ const DataExplorer = React.createClass({
containerClass="page-contents"
minTopHeight={MINIMUM_HEIGHTS.queryMaker}
minBottomHeight={MINIMUM_HEIGHTS.visualization}
initialTopHeight={INITIAL_HEIGHTS.queryMaker}
initialBottomHeight={INITIAL_HEIGHTS.visualization}
>
<QueryMaker
source={source}

View File

@ -39,7 +39,7 @@ const Header = React.createClass({
} = this.props
return (
<div className="page-header full-width-no-scrollbar">
<div className="page-header full-width">
<div className="page-header__container">
<div className="page-header__left">
<h1 className="page-header__title">

View File

@ -7,6 +7,8 @@ import classnames from 'classnames'
import LayoutRenderer from 'shared/components/LayoutRenderer'
import DashboardHeader from 'src/dashboards/components/DashboardHeader'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import timeRanges from 'hson!../../shared/data/timeRanges.hson'
import {
getMappings,
@ -199,16 +201,14 @@ export const HostPage = React.createClass({
)
})}
</DashboardHeader>
<div
className={classnames({
'page-contents': true,
'presentation-mode': inPresentationMode,
})}
>
<FancyScrollbar className={classnames({
'page-contents': true,
'presentation-mode': inPresentationMode,
})}>
<div className="container-fluid full-width dashboard">
{layouts.length > 0 ? this.renderLayouts(layouts) : ''}
</div>
</div>
</FancyScrollbar>
</div>
)
},

View File

@ -1,7 +1,10 @@
import React, {PropTypes} from 'react'
import _ from 'lodash'
import HostsTable from '../components/HostsTable'
import SourceIndicator from '../../shared/components/SourceIndicator'
import HostsTable from 'src/hosts/components/HostsTable'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import SourceIndicator from 'src/shared/components/SourceIndicator'
import {getCpuAndLoadForHosts, getMappings, getAppsForHosts} from '../apis'
export const HostsPage = React.createClass({
@ -87,7 +90,7 @@ export const HostsPage = React.createClass({
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
@ -100,7 +103,7 @@ export const HostsPage = React.createClass({
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)
},

View File

@ -1,5 +1,7 @@
import React, {Component, PropTypes} from 'react'
import AlertTabs from './AlertTabs'
import AlertTabs from 'src/kapacitor/components/AlertTabs'
import FancyScrollbar from 'shared/components/FancyScrollbar'
class KapacitorForm extends Component {
render() {
@ -17,7 +19,7 @@ class KapacitorForm extends Component {
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-3">
@ -100,7 +102,7 @@ class KapacitorForm extends Component {
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)
}

View File

@ -1,9 +1,12 @@
import React, {PropTypes} from 'react'
import DataSection from '../components/DataSection'
import ValuesSection from '../components/ValuesSection'
import DataSection from 'src/kapacitor/components/DataSection'
import ValuesSection from 'src/kapacitor/components/ValuesSection'
import RuleHeader from 'src/kapacitor/components/RuleHeader'
import RuleGraph from 'src/kapacitor/components/RuleGraph'
import RuleMessage from 'src/kapacitor/components/RuleMessage'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {createRule, editRule} from 'src/kapacitor/apis'
import buildInfluxQLQuery from 'utils/influxql'
import timeRanges from 'hson!../../shared/data/timeRanges.hson'
@ -57,7 +60,7 @@ export const KapacitorRule = React.createClass({
timeRange={timeRange}
source={source}
/>
<div className="page-contents page-contents--green-scrollbar">
<FancyScrollbar className="page-contents fancy-scroll--kapacitor">
<div className="container-fluid">
<div className="row">
<div className="col-xs-12">
@ -89,7 +92,7 @@ export const KapacitorRule = React.createClass({
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)
},

View File

@ -1,9 +1,10 @@
import React, {PropTypes} from 'react'
import {Link} from 'react-router'
import NoKapacitorError from '../../shared/components/NoKapacitorError'
import SourceIndicator from '../../shared/components/SourceIndicator'
import NoKapacitorError from 'src/shared/components/NoKapacitorError'
import SourceIndicator from 'src/shared/components/SourceIndicator'
import KapacitorRulesTable from 'src/kapacitor/components/KapacitorRulesTable'
import FancyScrollbar from 'shared/components/FancyScrollbar'
const KapacitorRules = ({
source,
@ -62,7 +63,7 @@ const PageContents = ({children, source}) => (
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents fancy-scroll--kapacitor">
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
@ -72,7 +73,7 @@ const PageContents = ({children, source}) => (
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)

View File

@ -112,7 +112,7 @@ export const RuleHeader = React.createClass({
placeholder="Name your rule"
/>
: <h1
className="page-header--editable kapacitor-theme"
className="page-header__title page-header--editable kapacitor-theme"
onClick={this.toggleEditName}
data-for="rename-kapacitor-tooltip"
data-tip="Click to Rename"

View File

@ -44,7 +44,7 @@ const AutoRefreshDropdown = React.createClass({
const {milliseconds, inputValue} = this.findAutoRefreshItem(selected)
return (
<div className="dropdown dropdown-160">
<div className={classnames('dropdown dropdown-160', {open: isOpen})}>
<div
className="btn btn-sm btn-info dropdown-toggle"
onClick={() => self.toggleMenu()}
@ -55,14 +55,14 @@ const AutoRefreshDropdown = React.createClass({
+milliseconds > 0 ? 'refresh' : 'pause'
)}
/>
<span className="selected-time-range">{inputValue}</span>
<span className="dropdown-selected">{inputValue}</span>
<span className="caret" />
</div>
<ul className={classnames('dropdown-menu', {show: isOpen})}>
<ul className="dropdown-menu">
<li className="dropdown-header">AutoRefresh Interval</li>
{autoRefreshItems.map(item => {
return (
<li key={item.menuOption}>
<li className="dropdown-item" key={item.menuOption}>
<a
href="#"
onClick={() => self.handleSelection(item.milliseconds)}

View File

@ -2,6 +2,8 @@ import React, {Component, PropTypes} from 'react'
import {Link} from 'react-router'
import classnames from 'classnames'
import OnClickOutside from 'shared/components/OnClickOutside'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {DROPDOWN_MENU_MAX_HEIGHT, DROPDOWN_MENU_ITEM_THRESHOLD} from 'shared/constants/index'
class Dropdown extends Component {
constructor(props) {
@ -52,17 +54,116 @@ class Dropdown extends Component {
action.handler(item)
}
renderShortMenu() {
const {actions, addNew, items, menuWidth, menuLabel} = this.props
return (
<ul className="dropdown-menu" style={{width: menuWidth}}>
{menuLabel
? <li className="dropdown-header">{menuLabel}</li>
: null
}
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li className="dropdown-item">
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</ul>
)
}
renderLongMenu() {
const {actions, addNew, items, menuWidth, menuLabel} = this.props
return (
<ul className="dropdown-menu" style={{width: menuWidth, height: DROPDOWN_MENU_MAX_HEIGHT}}>
<FancyScrollbar autoHide={false}>
{menuLabel
? <li className="dropdown-header">{menuLabel}</li>
: null
}
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li>
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</FancyScrollbar>
</ul>
)
}
render() {
const {
items,
selected,
className,
iconName,
actions,
addNew,
buttonSize,
buttonColor,
menuWidth,
} = this.props
const {isOpen} = this.state
@ -78,47 +179,11 @@ class Dropdown extends Component {
<span className="dropdown-selected">{selected}</span>
<span className="caret" />
</div>
{isOpen
? <ul className="dropdown-menu" style={{width: menuWidth}}>
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li>
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</ul>
{(isOpen && items.length < DROPDOWN_MENU_ITEM_THRESHOLD)
? this.renderShortMenu()
: null}
{(isOpen && items.length >= DROPDOWN_MENU_ITEM_THRESHOLD)
? this.renderLongMenu()
: null}
</div>
)
@ -152,6 +217,7 @@ Dropdown.propTypes = {
buttonSize: string,
buttonColor: string,
menuWidth: string,
menuLabel: string,
}
export default OnClickOutside(Dropdown)

View File

@ -0,0 +1,42 @@
import React, {Component, PropTypes} from 'react'
import classnames from 'classnames'
import {Scrollbars} from 'react-custom-scrollbars'
class FancyScrollbar extends Component {
constructor(props) {
super(props)
}
static defaultProps = {
autoHide: true,
}
render() {
const {autoHide, children, className} = this.props
return (
<Scrollbars
className={classnames('fancy-scroll--container', {[className]: className})}
autoHide={autoHide}
autoHideTimeout={1000}
autoHideDuration={250}
renderTrackHorizontal={props => <div {...props} className="fancy-scroll--track-h"/>}
renderTrackVertical={props => <div {...props} className="fancy-scroll--track-v"/>}
renderThumbHorizontal={props => <div {...props} className="fancy-scroll--thumb-h"/>}
renderThumbVertical={props => <div {...props} className="fancy-scroll--thumb-v"/>}
>
{children}
</Scrollbars>
)
}
}
const {bool, node, string} = PropTypes
FancyScrollbar.propTypes = {
children: node.isRequired,
className: string,
autoHide: bool,
}
export default FancyScrollbar

View File

@ -1,47 +1,47 @@
import React, {PropTypes} from 'react'
import ResizeHandle from 'shared/components/ResizeHandle'
import React, {Component, PropTypes} from 'react'
import classnames from 'classnames'
const {node, number, string} = PropTypes
import ResizeHandle from 'shared/components/ResizeHandle'
const maximumNumChildren = 2
const minimumTopHeight = 200
const minimumBottomHeight = 200
const defaultMinTopHeight = 200
const defaultMinBottomHeight = 200
const defaultInitialTopHeight = '50%'
const defaultInitialBottomHeight = '50%'
const ResizeContainer = React.createClass({
propTypes: {
children: node.isRequired,
containerClass: string.isRequired,
minTopHeight: number,
minBottomHeight: number,
},
getDefaultProps() {
return {
minTopHeight: minimumTopHeight,
minBottomHeight: minimumBottomHeight,
}
},
getInitialState() {
return {
topHeight: '60%',
bottomHeight: '40%',
class ResizeContainer extends Component {
constructor(props) {
super(props)
this.state = {
isDragging: false,
topHeight: props.initialTopHeight,
bottomHeight: props.initialBottomHeight,
}
},
handleStopDrag() {
this.setState({isDragging: false})
},
this.handleStartDrag = ::this.handleStartDrag
this.handleStopDrag = ::this.handleStopDrag
this.handleMouseLeave = ::this.handleMouseLeave
this.handleDrag = ::this.handleDrag
}
static defaultProps = {
minTopHeight: defaultMinTopHeight,
minBottomHeight: defaultMinBottomHeight,
initialTopHeight: defaultInitialTopHeight,
initialBottomHeight: defaultInitialBottomHeight,
}
handleStartDrag() {
this.setState({isDragging: true})
},
}
handleStopDrag() {
this.setState({isDragging: false})
}
handleMouseLeave() {
this.setState({isDragging: false})
},
}
handleDrag(e) {
if (!this.state.isDragging) {
@ -71,7 +71,8 @@ const ResizeContainer = React.createClass({
}
const topHeightPixels = newTopPanelPercent / oneHundred * containerHeight
const bottomHeightPixels = newBottomPanelPercent / oneHundred * containerHeight
const bottomHeightPixels =
newBottomPanelPercent / oneHundred * containerHeight
// Don't trigger a resize if the new sizes are too small
if (
@ -85,31 +86,24 @@ const ResizeContainer = React.createClass({
topHeight: `${newTopPanelPercent}%`,
bottomHeight: `${newBottomPanelPercent}%`,
})
},
renderHandle() {
const {isDragging, topHeight} = this.state
return (
<ResizeHandle
isDragging={isDragging}
onHandleStartDrag={this.handleStartDrag}
top={topHeight}
/>
)
},
}
render() {
const {topHeight, bottomHeight, isDragging} = this.state
const {containerClass, children} = this.props
if (React.Children.count(children) > maximumNumChildren) {
console.error(`There cannot be more than ${maximumNumChildren}' children in ResizeContainer`)
console.error(
`There cannot be more than ${maximumNumChildren}' children in ResizeContainer`
)
return
}
return (
<div
className={classnames(`resize--container ${containerClass}`, {'resize--dragging': isDragging})}
className={classnames(`resize--container ${containerClass}`, {
'resize--dragging': isDragging,
})}
onMouseLeave={this.handleMouseLeave}
onMouseUp={this.handleStopDrag}
onMouseMove={this.handleDrag}
@ -118,13 +112,31 @@ const ResizeContainer = React.createClass({
<div className="resize--top" style={{height: topHeight}}>
{React.cloneElement(children[0])}
</div>
{this.renderHandle()}
<div className="resize--bottom" style={{height: bottomHeight, top: topHeight}}>
<ResizeHandle
isDragging={isDragging}
onHandleStartDrag={this.handleStartDrag}
top={topHeight}
/>
<div
className="resize--bottom"
style={{height: bottomHeight, top: topHeight}}
>
{React.cloneElement(children[1])}
</div>
</div>
)
},
})
}
}
const {node, number, string} = PropTypes
ResizeContainer.propTypes = {
children: node.isRequired,
containerClass: string.isRequired,
minTopHeight: number,
minBottomHeight: number,
initialTopHeight: string,
initialBottomHeight: string,
}
export default ResizeContainer

View File

@ -1,9 +1,10 @@
import React from 'react'
import classnames from 'classnames'
import OnClickOutside from 'shared/components/OnClickOutside'
import moment from 'moment'
import OnClickOutside from 'shared/components/OnClickOutside'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import timeRanges from 'hson!../data/timeRanges.hson'
const TimeRangeDropdown = React.createClass({
@ -55,28 +56,30 @@ const TimeRangeDropdown = React.createClass({
const {isOpen} = self.state
return (
<div className="dropdown dropdown-160">
<div className={classnames('dropdown dropdown-160', {open: isOpen})}>
<div
className="btn btn-sm btn-info dropdown-toggle"
onClick={() => self.toggleMenu()}
>
<span className="icon clock" />
<span className="selected-time-range">
<span className="dropdown-selected">
{self.findTimeRangeInputValue(selected)}
</span>
<span className="caret" />
</div>
<ul className={classnames('dropdown-menu', {show: isOpen})}>
<li className="dropdown-header">Time Range</li>
{timeRanges.map(item => {
return (
<li key={item.menuOption}>
<a href="#" onClick={() => self.handleSelection(item)}>
{item.menuOption}
</a>
</li>
)
})}
<ul className="dropdown-menu" style={{height: '270px'}}>
<FancyScrollbar>
<li className="dropdown-header">Time Range</li>
{timeRanges.map(item => {
return (
<li className="dropdown-item" key={item.menuOption}>
<a href="#" onClick={() => self.handleSelection(item)}>
{item.menuOption}
</a>
</li>
)
})}
</FancyScrollbar>
</ul>
</div>
)

View File

@ -379,6 +379,9 @@ export const STROKE_WIDTH = {
light: 1.5,
}
export const DROPDOWN_MENU_MAX_HEIGHT = '270px'
export const DROPDOWN_MENU_ITEM_THRESHOLD = 10
export const HEARTBEAT_INTERVAL = 10000 // ms
export const PRESENTATION_MODE_ANIMATION_DELAY = 0 // In milliseconds.

View File

@ -34,7 +34,7 @@ const kapacitorDropdown = (
return (
<Dropdown
className="sources--kapacitor-selector"
className="dropdown-160"
buttonColor="btn-info"
buttonSize="btn-xs"
items={kapacitorItems}

View File

@ -9,8 +9,9 @@ import {
deleteKapacitorAsync,
} from 'src/shared/actions/sources'
import SourceIndicator from '../../shared/components/SourceIndicator'
import InfluxTable from '../components/InfluxTable'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import SourceIndicator from 'src/shared/components/SourceIndicator'
import InfluxTable from 'src/sources/components/InfluxTable'
class ManageSources extends Component {
constructor(props) {
@ -61,7 +62,7 @@ class ManageSources extends Component {
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<InfluxTable
handleDeleteSource={this.handleDeleteSource}
@ -71,7 +72,7 @@ class ManageSources extends Component {
handleDeleteKapacitor={deleteKapacitor}
/>
</div>
</div>
</FancyScrollbar>
</div>
)
}

View File

@ -9,7 +9,8 @@ import {
import {connect} from 'react-redux'
import SourceForm from 'src/sources/components/SourceForm'
import SourceIndicator from '../../shared/components/SourceIndicator'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import SourceIndicator from 'src/shared/components/SourceIndicator'
const {func, shape, string} = PropTypes
@ -128,7 +129,7 @@ export const SourcePage = React.createClass({
</div>
</div>
</div>
<div className="page-contents">
<FancyScrollbar className="page-contents">
<div className="container-fluid">
<div className="row">
<div className="col-md-8 col-md-offset-2">
@ -144,7 +145,7 @@ export const SourcePage = React.createClass({
</div>
</div>
</div>
</div>
</FancyScrollbar>
</div>
)
},

View File

@ -46,6 +46,7 @@
@import 'components/source-indicator';
@import 'components/tables';
@import 'components/function-selector';
@import 'components/fancy-scrollbars';
// Pages

View File

@ -6,7 +6,7 @@
*/
$dropdown-menu-default-width: 100%;
$dropdown-menu-max-height: 290px;
$dropdown-menu-max-height: 270px;
/*
Generic width modifiers
@ -39,6 +39,8 @@ $dropdown-menu-max-height: 290px;
.dropdown-toggle {
position: relative;
text-align: left;
display: flex;
align-items: center;
.caret {
position: absolute;
@ -47,13 +49,23 @@ $dropdown-menu-max-height: 290px;
transform: translateY(-50%);
}
> .icon {
font-size: 16px;
display: inline-block;
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}
.dropdown-selected {
display: inline-block;
flex: 1 0 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 15px;
}
}
.dropdown .dropdown-toggle.btn-xs {
height: 22px !important;
line-height: 22px !important;
padding: 0 9px !important;
}
/*
@ -61,27 +73,26 @@ $dropdown-menu-max-height: 290px;
----------------------------------------------
*/
.dropdown-menu {
float: none !important;
width: $dropdown-menu-default-width;
min-width: $dropdown-menu-default-width;
max-width: $dropdown-menu-default-width;
margin: 0 !important;
padding: 0 !important;
min-width: initial;
margin: 0;
padding: 0;
overflow: hidden;
max-height: $dropdown-menu-max-height;
overflow: auto;
@include custom-scrollbar-round($c-pool, $c-laser);
@include gradient-h($c-ocean, $c-pool);
box-shadow: 0 2px 5px 0.6px fade-out($g0-obsidian, 0.8);
> li {
li.dropdown-item {
position: relative;
width: 100%;
font-size: 0px;
&:hover {
@include gradient-h($c-laser, $c-pool);
}
}
> li > a {
li.dropdown-item > a {
position: relative;
@include no-user-select();
width: 100%;
border-radius: 0 !important;
display: inline-block;
@ -107,12 +118,6 @@ $dropdown-menu-max-height: 290px;
@include gradient-h($c-ocean, $c-pool);
}
}
> li:last-child a {
border-radius: 0 0 3px 3px;
}
> li:first-child a {
border-radius: 3px 3px 0 0;
}
}
.dropdown.dropdown-kapacitor .dropdown-toggle {
color: $c-rainforest !important;
@ -123,10 +128,10 @@ $dropdown-menu-max-height: 290px;
@include custom-scrollbar($c-rainforest, $c-honeydew);
@include gradient-h($c-pool, $c-rainforest);
> li:hover {
li.dropdown-item:hover {
@include gradient-h($c-laser, $c-rainforest);
}
> li > a {
li.dropdown-item > a {
color: $c-mint !important;
&:hover {
color: $g20-white !important;
@ -137,10 +142,10 @@ $dropdown-menu-max-height: 290px;
@include custom-scrollbar($c-comet, $c-potassium);
@include gradient-h($c-ocean, $c-comet);
> li:hover {
li.dropdown-item:hover {
@include gradient-h($c-laser, $c-comet);
}
> li > a {
li.dropdown-item > a {
color: $c-twilight !important;
&:hover {
color: $g20-white !important;
@ -175,14 +180,6 @@ $dropdown-menu-max-height: 290px;
Dropdown Actions
----------------------------------------------
*/
.dropdown-item {
position: relative;
> a {
position: relative;
z-index: 1;
}
}
.dropdown-item__actions {
z-index: 2;
position: absolute;

View File

@ -0,0 +1,65 @@
/*
Fancy Scrollbars
------------------------------------------------------
*/
$scrollbar-track-size: 12px;
$scrollbar-thumb-size: 6px;
$scrollbar-color-a: $c-pool;
$scrollbar-color-b: $c-comet;
.fancy-scroll--track-h,
.fancy-scroll--track-v {
&:hover {cursor: pointer;}
}
/* Horizontal Scrollbar Styles */
.fancy-scroll--track-h {
padding: ($scrollbar-track-size - $scrollbar-thumb-size) / 2;
width: 100%;
height: $scrollbar-track-size !important;
bottom: 0;
left: 0;
}
.fancy-scroll--thumb-h {
height: $scrollbar-thumb-size !important;
border-radius: ($scrollbar-thumb-size / 2);
@include gradient-h($scrollbar-color-a,$scrollbar-color-b);
}
/* Vertical Scrollbar Styles */
.fancy-scroll--track-v {
padding: ($scrollbar-track-size - $scrollbar-thumb-size) / 2;
width: $scrollbar-track-size !important;
height: 100%;
top: 0;
right: 0;
}
.fancy-scroll--thumb-v {
width: $scrollbar-thumb-size !important;
border-radius: ($scrollbar-thumb-size / 2);
@include gradient-v($scrollbar-color-a,$scrollbar-color-b);
}
/* Kapacitor Theme Scrollbars */
$scrollbar-color-kap-a: $c-rainforest;
$scrollbar-color-kap-b: $c-pool;
.fancy-scroll--kapacitor {
.fancy-scroll--thumb-h { @include gradient-h($scrollbar-color-kap-a,$scrollbar-color-kap-b); }
.fancy-scroll--thumb-v { @include gradient-v($scrollbar-color-kap-a,$scrollbar-color-kap-b); }
}
/* Dropdown Theme Scrollbars */
ul.dropdown-menu {
.fancy-scroll--thumb-h { @include gradient-h($c-neutrino,$c-laser); }
.fancy-scroll--thumb-v { @include gradient-v($c-neutrino,$c-laser); }
}
/* Hacky Fix to make this work in Safari */
.query-builder--list {
position: relative;
.fancy-scroll--container {
position: absolute !important;
}
}

View File

@ -43,10 +43,6 @@
}
.query-builder--list {
padding: 0;
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
@include custom-scrollbar($query-builder--list-bg,$c-pool);
background-color: $query-builder--list-bg;
}
.query-builder--list-empty {

View File

@ -85,7 +85,7 @@ table .monotype {
background-color: $c-pool;
}
&.dot-warning {
background-color: $c-comet;
background-color: $c-pineapple;
}
&.dot-danger {
background-color: $c-dreamsicle;

View File

@ -59,14 +59,15 @@ $template-control--min-height: 52px;
@include gradient-h($c-star,$c-pool);
@include custom-scrollbar-round($c-pool,$c-laser);
> li > a {
&, &:active {background-color: transparent !important;}
li.dropdown-item {
&:hover {@include gradient-h($c-comet,$c-pool);}
}
li.dropdown-item > a {
&, &:focus {background: none;}
&:active, &:active:focus {@include gradient-h($c-amethyst,$c-pool);}
font-size: 12px;
font-family: $code-font;
}
> li {
&:hover {@include gradient-h($c-comet,$c-pool);}
}
}
}
.template-control--label {

View File

@ -5,11 +5,10 @@
$page-header-size: 19px;
$page-header-weight: 400 !important;
.page-header {
height: $chronograf-page-header-height;
width: 100%;
padding: 0 ($page-wrapper-padding + $scrollbar-width) 0 $page-wrapper-padding;
padding: 0 $page-wrapper-padding;
display: flex;
justify-content: center;
align-items: center;
@ -20,6 +19,9 @@ $page-header-weight: 400 !important;
border: none;
margin: 0;
}
.page-header.full-width .page-header__container {
max-width: 100%;
}
.page-header__container {
width: 100%;
display: flex;
@ -50,16 +52,6 @@ $page-header-weight: 400 !important;
margin: 0 0 0 4px;
}
}
.page-header.full-width .page-header__container {
max-width: 100%;
}
.page-header.full-width-no-scrollbar {
padding-right: $page-wrapper-padding;
.page-header__container {
max-width: 100%;
}
}
.page-header__title {
text-transform: none;
font-size: $page-header-size;

View File

@ -16,26 +16,15 @@
flex-grow: 1;
}
.page-contents {
position: absolute;
position: absolute !important;
top: $chronograf-page-header-height;
left: 0;
width: 100%;
height: calc(100% - #{$chronograf-page-header-height});
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
@include custom-scrollbar($g2-kevlar,$c-pool);
height: calc(100% - #{$chronograf-page-header-height}) !important;
@include gradient-v($g2-kevlar,$g0-obsidian);
&--green-scrollbar {
@include custom-scrollbar($g2-kevlar,$c-rainforest);
}
&--purple-scrollbar {
@include custom-scrollbar($g2-kevlar,$c-comet);
}
}
.container-fluid {
padding: ($chronograf-page-header-height / 2) $page-wrapper-padding ($chronograf-page-header-height / 2) $page-wrapper-padding;
padding: ($chronograf-page-header-height / 2) $page-wrapper-padding;
max-width: $page-wrapper-max-width;
&.full-width {
@ -43,416 +32,11 @@
}
}
/*
Page Header
----------------------------------------------
*/
.page-header {
height: $chronograf-page-header-height;
width: 100%;
padding: 0 ($page-wrapper-padding + $scrollbar-width) 0 $page-wrapper-padding;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
/* Presentation Mode */
.page-contents.presentation-mode {
top: 0;
left: 0;
background-color: $g0-obsidian;
border: none;
margin: 0;
&__container {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: ($page-wrapper-max-width - $page-wrapper-padding - $page-wrapper-padding);
}
h1 {
text-transform: uppercase;
font-size: 17px;
font-weight: 400;
margin: 0;
display: inline-block;
vertical-align: middle;
}
&__left,
&__right {
display: flex;
align-items: center;
> *:only-child {
margin: 0;
}
}
&__left {
> * {
margin: 0 4px 0 0;
}
}
&__right {
> * {
margin: 0 0 0 4px;
}
}
&.full-width .page-header__container {
max-width: 100%;
}
}
/*
Custom Search Widget
----------------------------------------------
*/
.users__search-widget {
position: relative;
input.form-control {
position: relative;
width: 100%;
z-index: 1;
padding-left: 34px;
border-radius: 4px !important;
&:focus + .input-group-addon {
color: $c-pool;
}
}
.input-group-addon {
padding: 0;
text-align: center;
line-height: 38px;
position: absolute;
color: $g10-wolf;
top: 0;
left: 0;
height: 100%;
z-index: 4;
border: 0;
width: 40px;
background-color: transparent;
transition:
color 0.25s ease;
}
}
/*
Unsorted
----------------------------------------------
*/
.select-source-page {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
@include custom-scrollbar($g2-kevlar, $c-pool);
@include gradient-v($g2-kevlar, $g0-obsidian);
}
.text-right .btn {
margin: 0 0 0 4px;
}
.text-center .btn {
margin: 0 2px;
}
.default-source-label {
display: inline-block;
vertical-align: middle;
font-size: 13px;
font-weight: 500;
background-color: $g5-pepper;
color: $c-pool;
border-radius: 3px;
padding: 2px 6px;
margin-left: 4px;
}
.progress-label {
margin-bottom: 4px;
color: $g11-sidewalk;
width: 100%;
strong {
font-weight: 500;
color: $g8-storm;
}
}
.btn-block.dropdown-toggle {
text-align: left;
position: relative;
.caret {
position: absolute;
top: 50%;
right: 18px;
transform: translateY(-50%);
}
& + .dropdown-menu {
width: 100%;
}
}
.modal {
form {
padding: 0;
margin: 0;
background-color: transparent;
}
.form-grid {
width: 100%;
display: inline-block;
&.padding-top {
padding-top: 15px;
}
}
}
/*
Custom Tabs
----------------------------------------------
*/
.tab-group {
display: flex;
justify-content: flex-start;
margin-bottom: 20px;
display: inline-block;
.btn.tab {
border: 2px solid $g17-whisper;
border-right-width: 0;
padding: 10px 20px;
margin: 0 !important;
font-weight: 400;
color: $g11-sidewalk;
background-color: $g17-whisper;
box-shadow: none;
transition:
color 0.25s ease,
background-color 0.25s ease;
&:hover {
cursor: pointer;
background-color: $g18-cloud;
color: $g9-mountain;
}
&:first-child {
border-radius: 5px 0 0 5px;
}
&:last-child {
border-radius: 0 5px 5px 0;
border-right-width: 2px;
}
&.active {
background-color: white;
color: $g8-storm;
}
}
}
/*
Error Pages
----------------------------------------------
*/
.panel-error {
margin-top: $page-wrapper-padding;
margin-bottom: $page-wrapper-padding;
}
table.table.error-table {
margin-bottom: 0;
.label {
padding: 4px 7px;
font-size: 14px;
font-weight: 700;
}
tbody {
td {
border: none;
}
}
tbody tr:nth-child(odd) {
background-color: $g19-ghost;
td:last-child {
background-color: $g5-pepper;
}
}
tbody tr:nth-child(even) {
background-color: $g18-cloud;
td:last-child {
background-color: $g4-onyx;
}
}
pre {
border: none;
background-color: transparent;
color: $c-moonstone;
font-weight: 600;
border-radius: 0;
padding: 4px;
}
}
/*
Generic Empty State
----------------------------------------------
*/
.generic-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: $g12-forge;
padding: 20px 0;
.icon {
margin-bottom: 11px;
}
}
/*
Static Form Controls
----------------------------------------------
*/
$form-static-checkbox-size: 16px;
.form-control-static {
border: 2px solid $g5-pepper;
height: auto;
border-radius: 4px;
padding: 7px 12px;
position: relative;
input[type="checkbox"] {
position: relative;
left: -9999px;
visibility: hidden;
width: 0;
height: 0;
margin: 0;
// Faux Checkbox
& + label {
font-size: 14px !important;
line-height: 16px;
color: $g11-sidewalk;
font-weight: 500;
transition: color 0.25s ease;
margin: 0;
padding: 0 0 0 (12px + $form-static-checkbox-size + 6px);
user-select: none;
-ms-user-select: none;
-moz-user-selct: none;
-webkit-user-select: none;
&:before {
content: '';
position: absolute;
top: 50%;
left: 12px;
transform: translateY(-50%);
width: $form-static-checkbox-size;
height: $form-static-checkbox-size;
background-color: $g2-kevlar;
border: 2px solid $g5-pepper;
border-radius: 3px;
z-index: 2;
transition:
border-color 0.25s ease;
}
&:after {
content: '';
position: absolute;
top: 50%;
left: (12px + ($form-static-checkbox-size / 2));
transform: translate(-50%,-50%) scale(2,2);
opacity: 0;
width: 6px;
height: 6px;
border-radius: 50%;
background-color: $c-pool;
z-index: 3;
transition:
opacity 0.25s ease,
transform 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
&:hover {
cursor: pointer;
color: $g20-white;
&:before {
border-color: $g6-smoke;
}
}
}
// Faux Checkbox (Checked)
&:checked + label {
color: $g20-white;
&:after {
opacity: 1;
transform: translate(-50%,-50%) scale(1,1);
}
}
}
}
/*
Stuff for making Tables of Data more readable
----------------------------------------------
*/
table .monotype {
font-family: 'RobotoMono', monospace !important;
letter-spacing: 0.69px;
font-size: 12px;
font-weight: 500;
color: $g9-mountain;
}
.table-dot {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: $g17-whisper;
&.dot-success {
background-color: $c-rainforest;
}
&.dot-primary {
background-color: $c-pool;
}
&.dot-warning {
background-color: $c-comet;
}
&.dot-danger {
background-color: $c-dreamsicle;
}
&.dot-critical {
background-color: $c-fire;
}
}
/*
Empty State for Tables
----------------------------------------------
*/
.table-empty-state {
> th {
text-align: center;
> p {
font-weight: 400;
font-size: 18px;
color: $g9-mountain;
margin-bottom: 16px;
}
> *:first-child {
margin-top: 75px;
}
> *:last-child {
margin-bottom: 75px;
}
}
}
height: 100% !important;
.container-fluid {padding: 8px !important;}
.template-control--manage {display: none;}
}

View File

@ -58,11 +58,7 @@ $sidebar-logo-color: $g8-storm;
display: flex;
flex-direction: column;
width: $sidebar-width;
background: $sidebar-light;
background: -moz-linear-gradient(top, $sidebar-light 0%, $sidebar-dark 100%);
background: -webkit-linear-gradient(top, $sidebar-light 0%,$sidebar-dark 100%);
background: linear-gradient(to bottom, $sidebar-light 0%,$sidebar-dark 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$sidebar-light', endColorstr='$sidebar-dark',GradientType=0 );
@include gradient-v($sidebar-light,$sidebar-dark);
&__logo {
width: $sidebar-width;
@ -283,11 +279,7 @@ $sidebar-logo-color: $g8-storm;
}
}
&.active {
background: $sidebar-active-bg;
background: -moz-linear-gradient(left, $sidebar-active-bg 0%, $sidebar-active-accent 100%);
background: -webkit-linear-gradient(left, $sidebar-active-bg 0%,$sidebar-active-accent 100%);
background: linear-gradient(to right, $sidebar-active-bg 0%,$sidebar-active-accent 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$sidebar-active-bg', endColorstr='$sidebar-active-accent',GradientType=1 );
@include gradient-h($sidebar-active-bg,$sidebar-active-accent);
color: $sidebar-icon-hover;
&:link,

View File

@ -41,18 +41,6 @@ $dash-graph-options-arrow: 8px;
}
.dashboard {
&.container-fluid.full-width.page-contents {
padding-top: 8px;
}
&.presentation-mode {
top: 0;
height: 100%;
padding: 12px;
.template-control--manage {
display: none;
}
}
.react-grid-item {
@extend .cell-shell;
}

View File

@ -156,25 +156,45 @@
/*
Kapacitor selector dropdown
Custom Tabs
----------------------------------------------
*/
.dropdown .dropdown-toggle.btn-xs {
height: 22px !important;
line-height: 22px !important;
padding: 0 9px !important;
}
.dropdown-selected {
.tab-group {
display: flex;
justify-content: flex-start;
display: inline-block;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 15px;
}
.dropdown.sources--kapacitor-selector {
.dropdown-toggle {
width: 160px;
.btn.tab {
border: 2px solid $g17-whisper;
border-right-width: 0;
padding: 10px 20px;
margin: 0 !important;
font-weight: 400;
color: $g11-sidewalk;
background-color: $g17-whisper;
box-shadow: none;
transition:
color 0.25s ease,
background-color 0.25s ease;
&:hover {
cursor: pointer;
background-color: $g18-cloud;
color: $g9-mountain;
}
&:first-child {
border-radius: 5px 0 0 5px;
}
&:last-child {
border-radius: 0 5px 5px 0;
border-right-width: 2px;
}
&.active {
background-color: white;
color: $g8-storm;
}
}
}
@ -186,3 +206,15 @@
@include no-user-select();
}
.select-source-page {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
@include custom-scrollbar($g2-kevlar, $c-pool);
@include gradient-v($g2-kevlar, $g0-obsidian);
}

View File

@ -144,6 +144,10 @@ acorn@^4.0.1:
version "4.0.4"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a"
add-px-to-style@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/add-px-to-style/-/add-px-to-style-1.0.0.tgz#d0c135441fa8014a8137904531096f67f28f263a"
after@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627"
@ -2380,6 +2384,14 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
dom-css@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/dom-css/-/dom-css-2.1.0.tgz#fdbc2d5a015d0a3e1872e11472bbd0e7b9e6a202"
dependencies:
add-px-to-style "1.0.0"
prefix-style "2.0.1"
to-camel-case "1.0.0"
dom-serialize@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
@ -5151,6 +5163,10 @@ pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
phantomjs-prebuilt@^2.1.7:
version "2.1.14"
resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz#d53d311fcfb7d1d08ddb24014558f1188c516da0"
@ -5628,6 +5644,10 @@ precss@^1.4.0:
postcss-selector-matches "^2.0.0"
postcss-selector-not "^2.0.0"
prefix-style@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/prefix-style/-/prefix-style-2.0.1.tgz#66bba9a870cfda308a5dc20e85e9120932c95a06"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -5673,7 +5693,7 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.6:
prop-types@^15.5.6, prop-types@^15.5.8:
version "15.5.8"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394"
dependencies:
@ -5737,6 +5757,12 @@ querystringify@0.0.x:
version "0.0.4"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c"
raf@^3.1.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.2.tgz#0c13be0b5b49b46f76d6669248d527cf2b02fe27"
dependencies:
performance-now "^2.1.0"
randomatic@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb"
@ -5781,6 +5807,14 @@ react-addons-update@^15.1.0:
version "15.4.1"
resolved "https://registry.yarnpkg.com/react-addons-update/-/react-addons-update-15.4.1.tgz#00c07f45243aa9715e1706bbfd1f23d3d8d80bd1"
react-custom-scrollbars@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/react-custom-scrollbars/-/react-custom-scrollbars-4.1.1.tgz#cf08cd43b1297ab11e6fcc5c9a800e7b70b6f248"
dependencies:
dom-css "^2.0.0"
prop-types "^15.5.8"
raf "^3.1.0"
react-dimensions@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/react-dimensions/-/react-dimensions-1.3.0.tgz#f5dec8e7b84644a605a900cae0f4a6654acf4e9f"
@ -6960,6 +6994,12 @@ to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
to-camel-case@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46"
dependencies:
to-space-case "^1.0.0"
to-fast-properties@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
@ -6968,6 +7008,16 @@ to-iso-string@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1"
to-no-case@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a"
to-space-case@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17"
dependencies:
to-no-case "^1.0.0"
toposort@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.0.tgz#b66cf385a1a8a8e68e45b8259e7f55875e8b06ef"