Revert "Allow user to set auto-refresh interval"

pull/10616/head
Andrew Watkins 2017-03-03 14:22:07 -08:00 committed by GitHub
parent 0c461552df
commit ed85ba9029
28 changed files with 125 additions and 329 deletions

View File

@ -21,7 +21,6 @@
4. [#892](https://github.com/influxdata/chronograf/issues/891): Make dashboard visualizations resizable
5. [#893](https://github.com/influxdata/chronograf/issues/893): Persist dashboard visualization position
6. [#922](https://github.com/influxdata/chronograf/issues/922): Additional OAuth2 support for [Heroku](https://github.com/influxdata/chronograf/blob/master/docs/auth.md#heroku) and [Google](https://github.com/influxdata/chronograf/blob/master/docs/auth.md#google)
7. [#781](https://github.com/influxdata/chronograf/issues/781): Add global auto-refresh dropdown to all graph dashboards
### UI Improvements
1. [#905](https://github.com/influxdata/chronograf/pull/905): Make scroll bar thumb element bigger

View File

@ -10,7 +10,6 @@ const Dashboard = ({
inPresentationMode,
onPositionChange,
source,
autoRefresh,
timeRange,
}) => {
if (dashboard.id === 0) {
@ -21,13 +20,14 @@ const Dashboard = ({
<div className={classnames({'page-contents': true, 'presentation-mode': inPresentationMode})}>
<div className={classnames('container-fluid full-width dashboard', {'dashboard-edit': isEditMode})}>
{isEditMode ? <Visualizations/> : null}
{Dashboard.renderDashboard(dashboard, autoRefresh, timeRange, source, onPositionChange)}
{Dashboard.renderDashboard(dashboard, timeRange, source, onPositionChange)}
</div>
</div>
)
}
Dashboard.renderDashboard = (dashboard, autoRefresh, timeRange, source, onPositionChange) => {
Dashboard.renderDashboard = (dashboard, timeRange, source, onPositionChange) => {
const autoRefreshMs = 15000
const cells = dashboard.cells.map((cell, i) => {
i = `${i}`
const dashboardCell = {...cell, i}
@ -42,7 +42,7 @@ Dashboard.renderDashboard = (dashboard, autoRefresh, timeRange, source, onPositi
<LayoutRenderer
timeRange={timeRange}
cells={cells}
autoRefresh={autoRefresh}
autoRefreshMs={autoRefreshMs}
source={source.links.proxy}
onPositionChange={onPositionChange}
/>
@ -54,7 +54,6 @@ const {
func,
shape,
string,
number,
} = PropTypes
Dashboard.propTypes = {
@ -67,7 +66,6 @@ Dashboard.propTypes = {
proxy: string,
}).isRequired,
}).isRequired,
autoRefresh: number.isRequired,
timeRange: shape({}).isRequired,
}

View File

@ -2,7 +2,6 @@ import React, {PropTypes} from 'react'
import ReactTooltip from 'react-tooltip'
import {Link} from 'react-router';
import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from 'shared/components/TimeRangeDropdown'
const DashboardHeader = ({
@ -11,10 +10,8 @@ const DashboardHeader = ({
dashboard,
headerText,
timeRange,
autoRefresh,
isHidden,
handleChooseTimeRange,
handleChooseAutoRefresh,
handleClickPresentationButton,
sourceID,
}) => isHidden ? null : (
@ -48,7 +45,6 @@ const DashboardHeader = ({
Graph Tips
</div>
<ReactTooltip id="graph-tips-tooltip" effect="solid" html={true} offset={{top: 2}} place="bottom" class="influx-tooltip place-bottom" />
<AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
<TimeRangeDropdown onChooseTimeRange={handleChooseTimeRange} selected={timeRange.inputValue} />
<div className="btn btn-info btn-sm" onClick={handleClickPresentationButton}>
<span className="icon expand-a" style={{margin: 0}}></span>
@ -59,12 +55,11 @@ const DashboardHeader = ({
)
const {
array,
bool,
func,
number,
shape,
array,
string,
func,
bool,
} = PropTypes
DashboardHeader.propTypes = {
@ -74,10 +69,8 @@ DashboardHeader.propTypes = {
dashboard: shape({}),
headerText: string,
timeRange: shape({}).isRequired,
autoRefresh: number.isRequired,
isHidden: bool.isRequired,
handleChooseTimeRange: func.isRequired,
handleChooseAutoRefresh: func.isRequired,
handleClickPresentationButton: func.isRequired,
}

View File

@ -51,7 +51,6 @@ const DashboardPage = React.createClass({
id: number.isRequired,
cells: arrayOf(shape({})).isRequired,
}).isRequired,
autoRefresh: number.isRequired,
timeRange: shape({}).isRequired,
inPresentationMode: bool.isRequired,
isEditMode: bool.isRequired,
@ -101,7 +100,6 @@ const DashboardPage = React.createClass({
isEditMode,
handleClickPresentationButton,
source,
autoRefresh,
timeRange,
} = this.props
@ -112,7 +110,6 @@ const DashboardPage = React.createClass({
<EditHeader dashboard={dashboard} onSave={() => {}} /> :
<Header
buttonText={dashboard ? dashboard.name : ''}
autoRefresh={autoRefresh}
timeRange={timeRange}
handleChooseTimeRange={this.handleChooseTimeRange}
isHidden={inPresentationMode}
@ -136,7 +133,6 @@ const DashboardPage = React.createClass({
isEditMode={isEditMode}
inPresentationMode={inPresentationMode}
source={source}
autoRefresh={autoRefresh}
timeRange={timeRange}
onPositionChange={this.handleUpdatePosition}
/>
@ -147,10 +143,7 @@ const DashboardPage = React.createClass({
const mapStateToProps = (state) => {
const {
app: {
ephemeral: {inPresentationMode},
persisted: {autoRefresh},
},
appUI,
dashboardUI: {
dashboards,
dashboard,
@ -160,12 +153,11 @@ const mapStateToProps = (state) => {
} = state
return {
inPresentationMode: appUI.presentationMode,
dashboards,
dashboard,
autoRefresh,
timeRange,
isEditMode,
inPresentationMode,
}
}

View File

@ -15,7 +15,6 @@ const {
const Visualization = React.createClass({
propTypes: {
autoRefresh: number.isRequired,
timeRange: shape({
upper: string,
lower: string,
@ -46,7 +45,7 @@ const Visualization = React.createClass({
},
render() {
const {queryConfigs, autoRefresh, timeRange, activeQueryIndex, height, heightPixels} = this.props;
const {queryConfigs, timeRange, activeQueryIndex, height, heightPixels} = this.props;
const {source} = this.context;
const proxyLink = source.links.proxy;
@ -58,6 +57,7 @@ const Visualization = React.createClass({
const queries = statements.filter((s) => s.text !== null).map((s) => {
return {host: [proxyLink], text: s.text, id: s.id};
});
const autoRefreshMs = 10000;
const isInDataExplorer = true;
return (
@ -77,7 +77,7 @@ const Visualization = React.createClass({
{isGraphInView ? (
<RefreshingLineGraph
queries={queries}
autoRefresh={autoRefresh}
autoRefresh={autoRefreshMs}
activeQueryIndex={activeQueryIndex}
isInDataExplorer={isInDataExplorer}
/>

View File

@ -1,18 +1,17 @@
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import QueryBuilder from '../components/QueryBuilder';
import Visualization from '../components/Visualization';
import Header from '../containers/Header';
import ResizeContainer from 'src/shared/components/ResizeContainer';
import {setAutoRefresh} from 'shared/actions/app'
import {setTimeRange as setTimeRangeAction} from '../actions/view';
import {
setTimeRange as setTimeRangeAction,
} from '../actions/view';
const {
arrayOf,
func,
number,
shape,
string,
} = PropTypes;
@ -26,8 +25,6 @@ const DataExplorer = React.createClass({
}).isRequired,
}).isRequired,
queryConfigs: PropTypes.shape({}),
autoRefresh: number.isRequired,
handleChooseAutoRefresh: func.isRequired,
timeRange: shape({
upper: string,
lower: string,
@ -62,20 +59,18 @@ const DataExplorer = React.createClass({
},
render() {
const {autoRefresh, handleChooseAutoRefresh, timeRange, setTimeRange, queryConfigs, dataExplorer} = this.props;
const {timeRange, setTimeRange, queryConfigs, dataExplorer} = this.props;
const {activeQueryID} = this.state;
const queries = dataExplorer.queryIDs.map((qid) => queryConfigs[qid]);
return (
<div className="data-explorer">
<Header
actions={{handleChooseAutoRefresh, setTimeRange}}
autoRefresh={autoRefresh}
actions={{setTimeRange}}
timeRange={timeRange}
/>
<ResizeContainer>
<Visualization
autoRefresh={autoRefresh}
timeRange={timeRange}
queryConfigs={queries}
activeQueryID={this.state.activeQueryID}
@ -83,7 +78,6 @@ const DataExplorer = React.createClass({
/>
<QueryBuilder
queries={queries}
autoRefresh={autoRefresh}
timeRange={timeRange}
setActiveQuery={this.handleSetActiveQuery}
activeQueryID={activeQueryID}
@ -95,21 +89,15 @@ const DataExplorer = React.createClass({
});
function mapStateToProps(state) {
const {app: {persisted: {autoRefresh}}, timeRange, queryConfigs, dataExplorer} = state;
const {timeRange, queryConfigs, dataExplorer} = state;
return {
autoRefresh,
timeRange,
queryConfigs,
dataExplorer,
};
}
function mapDispatchToProps(dispatch) {
return {
handleChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
setTimeRange: bindActionCreators(setTimeRangeAction, dispatch),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(DataExplorer);
export default connect(mapStateToProps, {
setTimeRange: setTimeRangeAction,
})(DataExplorer);

View File

@ -1,35 +1,23 @@
import React, {PropTypes} from 'react';
import moment from 'moment';
import {withRouter} from 'react-router';
import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown';
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
const {
func,
number,
shape,
string,
} = PropTypes
const Header = React.createClass({
propTypes: {
autoRefresh: number.isRequired,
timeRange: shape({
upper: string,
lower: string,
timeRange: PropTypes.shape({
upper: PropTypes.string,
lower: PropTypes.string,
}).isRequired,
actions: shape({
handleChooseAutoRefresh: func.isRequired,
setTimeRange: func.isRequired,
actions: PropTypes.shape({
setTimeRange: PropTypes.func.isRequired,
}),
},
contextTypes: {
source: shape({
name: string,
source: PropTypes.shape({
name: PropTypes.string,
}),
},
@ -48,7 +36,7 @@ const Header = React.createClass({
},
render() {
const {autoRefresh, actions: {handleChooseAutoRefresh}, timeRange} = this.props;
const {timeRange} = this.props;
return (
<div className="page-header">
@ -62,7 +50,6 @@ const Header = React.createClass({
<span className="icon cpu"></span>
{this.context.source.name}
</div>
<AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
<TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={this.findSelected(timeRange)} />
</div>
</div>

View File

@ -2,8 +2,8 @@ import queryConfigs from './queryConfigs';
import timeRange from './timeRange';
import dataExplorer from './ui';
export default {
export {
queryConfigs,
timeRange,
dataExplorer,
}
};

View File

@ -1,7 +1,6 @@
import React, {PropTypes} from 'react'
import {Link} from 'react-router'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import _ from 'lodash'
import classnames from 'classnames';
@ -10,8 +9,6 @@ import DashboardHeader from 'src/dashboards/components/DashboardHeader';
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
import {getMappings, getAppsForHosts, getMeasurementsForHost, getAllHosts} from 'src/hosts/apis';
import {fetchLayouts} from 'shared/apis';
import {setAutoRefresh} from 'shared/actions/app'
import {presentationButtonDispatcher} from 'shared/dispatchers'
const {
@ -19,7 +16,6 @@ const {
string,
bool,
func,
number,
} = PropTypes
export const HostPage = React.createClass({
@ -39,8 +35,6 @@ export const HostPage = React.createClass({
app: string,
}),
}),
autoRefresh: number.isRequired,
handleChooseAutoRefresh: func.isRequired,
inPresentationMode: bool,
handleClickPresentationButton: func,
},
@ -93,8 +87,9 @@ export const HostPage = React.createClass({
},
renderLayouts(layouts) {
const autoRefreshMs = 15000;
const {timeRange} = this.state;
const {source, autoRefresh} = this.props;
const {source} = this.props;
const autoflowLayouts = layouts.filter((layout) => !!layout.autoflow);
@ -142,7 +137,7 @@ export const HostPage = React.createClass({
<LayoutRenderer
timeRange={timeRange}
cells={layoutCells}
autoRefresh={autoRefresh}
autoRefreshMs={autoRefreshMs}
source={source.links.proxy}
host={this.props.params.hostID}
/>
@ -150,7 +145,7 @@ export const HostPage = React.createClass({
},
render() {
const {params: {hostID}, location: {query: {app}}, source: {id}, autoRefresh, handleChooseAutoRefresh, inPresentationMode, handleClickPresentationButton} = this.props
const {params: {hostID}, location: {query: {app}}, source: {id}, inPresentationMode, handleClickPresentationButton} = this.props
const {layouts, timeRange, hosts} = this.state
const appParam = app ? `?app=${app}` : ''
@ -158,11 +153,9 @@ export const HostPage = React.createClass({
<div className="page">
<DashboardHeader
buttonText={hostID}
autoRefresh={autoRefresh}
timeRange={timeRange}
isHidden={inPresentationMode}
handleChooseTimeRange={this.handleChooseTimeRange}
handleChooseAutoRefresh={handleChooseAutoRefresh}
handleClickPresentationButton={handleClickPresentationButton}
>
{Object.keys(hosts).map((host, i) => {
@ -188,13 +181,11 @@ export const HostPage = React.createClass({
},
});
const mapStateToProps = ({app: {ephemeral: {inPresentationMode}, persisted: {autoRefresh}}}) => ({
inPresentationMode,
autoRefresh,
const mapStateToProps = (state) => ({
inPresentationMode: state.appUI.presentationMode,
})
const mapDispatchToProps = (dispatch) => ({
handleChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
handleClickPresentationButton: presentationButtonDispatcher(dispatch),
})

View File

@ -19,7 +19,7 @@ import configureStore from 'src/store/configureStore';
import {getMe, getSources} from 'shared/apis';
import {receiveMe} from 'shared/actions/me';
import {receiveAuth} from 'shared/actions/auth';
import {disablePresentationMode} from 'shared/actions/app';
import {disablePresentationMode} from 'shared/actions/ui';
import {loadLocalStorage} from './localStorage';
import 'src/style/chronograf.scss';

View File

@ -6,12 +6,11 @@ import DashboardHeader from 'src/dashboards/components/DashboardHeader';
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
const {
shape,
string,
arrayOf,
bool,
func,
number,
shape,
string,
} = PropTypes
export const KubernetesDashboard = React.createClass({
@ -23,8 +22,6 @@ export const KubernetesDashboard = React.createClass({
telegraf: string.isRequired,
}),
layouts: arrayOf(shape().isRequired).isRequired,
autoRefresh: number.isRequired,
handleChooseAutoRefresh: func.isRequired,
inPresentationMode: bool.isRequired,
handleClickPresentationButton: func,
},
@ -37,8 +34,9 @@ export const KubernetesDashboard = React.createClass({
},
renderLayouts(layouts) {
const autoRefreshMs = 15000;
const {timeRange} = this.state;
const {source, autoRefresh} = this.props;
const {source} = this.props;
let layoutCells = [];
layouts.forEach((layout) => {
@ -58,7 +56,7 @@ export const KubernetesDashboard = React.createClass({
<LayoutRenderer
timeRange={timeRange}
cells={layoutCells}
autoRefresh={autoRefresh}
autoRefreshMs={autoRefreshMs}
source={source.links.proxy}
/>
);
@ -70,7 +68,7 @@ export const KubernetesDashboard = React.createClass({
},
render() {
const {layouts, autoRefresh, handleChooseAutoRefresh, inPresentationMode, handleClickPresentationButton} = this.props;
const {layouts, inPresentationMode, handleClickPresentationButton} = this.props;
const {timeRange} = this.state;
const emptyState = (
<div className="generic-empty-state">
@ -83,8 +81,6 @@ export const KubernetesDashboard = React.createClass({
<div className="page">
<DashboardHeader
headerText="Kubernetes Dashboard"
autoRefresh={autoRefresh}
handleChooseAutoRefresh={handleChooseAutoRefresh}
timeRange={timeRange}
handleChooseTimeRange={this.handleChooseTimeRange}
isHidden={inPresentationMode}

View File

@ -1,19 +1,15 @@
import React, {PropTypes} from 'react';
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import {fetchLayouts} from 'shared/apis';
import KubernetesDashboard from 'src/kubernetes/components/KubernetesDashboard';
import {setAutoRefresh} from 'shared/actions/app'
import {presentationButtonDispatcher} from 'shared/dispatchers'
const {
bool,
func,
number,
shape,
string,
bool,
func,
} = PropTypes
export const KubernetesPage = React.createClass({
@ -23,8 +19,6 @@ export const KubernetesPage = React.createClass({
proxy: string.isRequired,
}).isRequired,
}),
autoRefresh: number.isRequired,
handleChooseAutoRefresh: func.isRequired,
inPresentationMode: bool.isRequired,
handleClickPresentationButton: func,
},
@ -44,14 +38,12 @@ export const KubernetesPage = React.createClass({
render() {
const {layouts} = this.state
const {source, autoRefresh, handleChooseAutoRefresh, inPresentationMode, handleClickPresentationButton} = this.props
const {source, inPresentationMode, handleClickPresentationButton} = this.props
return (
<KubernetesDashboard
layouts={layouts}
source={source}
autoRefresh={autoRefresh}
handleChooseAutoRefresh={handleChooseAutoRefresh}
inPresentationMode={inPresentationMode}
handleClickPresentationButton={handleClickPresentationButton}
/>
@ -59,13 +51,11 @@ export const KubernetesPage = React.createClass({
},
});
const mapStateToProps = ({app: {ephemeral: {inPresentationMode}, persisted: {autoRefresh}}}) => ({
inPresentationMode,
autoRefresh,
const mapStateToProps = (state) => ({
inPresentationMode: state.appUI.presentationMode,
})
const mapDispatchToProps = (dispatch) => ({
handleChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
handleClickPresentationButton: presentationButtonDispatcher(dispatch),
})

View File

@ -9,12 +9,9 @@ export const loadLocalStorage = () => {
}
};
export const saveToLocalStorage = ({app: {persisted}, queryConfigs, timeRange, dataExplorer}) => {
export const saveToLocalStorage = ({queryConfigs, timeRange, dataExplorer}) => {
try {
const appPersisted = Object.assign({}, {app: {persisted}})
window.localStorage.setItem('state', JSON.stringify({
...appPersisted,
queryConfigs,
timeRange,
dataExplorer,

View File

@ -1,22 +0,0 @@
import {PRESENTATION_MODE_ANIMATION_DELAY} from '../constants'
// ephemeral state reducers
export const enablePresentationMode = () => ({
type: 'ENABLE_PRESENTATION_MODE',
})
export const disablePresentationMode = () => ({
type: 'DISABLE_PRESENTATION_MODE',
})
export const delayEnablePresentationMode = () => (dispatch) => {
setTimeout(() => dispatch(enablePresentationMode()), PRESENTATION_MODE_ANIMATION_DELAY)
}
// persistent state reducers
export const setAutoRefresh = (milliseconds) => ({
type: 'SET_AUTOREFRESH',
payload: {
milliseconds,
},
})

View File

@ -0,0 +1,19 @@
import {PRESENTATION_MODE_ANIMATION_DELAY} from '../constants'
export function enablePresentationMode() {
return {
type: 'ENABLE_PRESENTATION_MODE',
}
}
export function disablePresentationMode() {
return {
type: 'DISABLE_PRESENTATION_MODE',
}
}
export function delayEnablePresentationMode() {
return (dispatch) => {
setTimeout(() => dispatch(enablePresentationMode()), PRESENTATION_MODE_ANIMATION_DELAY)
}
}

View File

@ -6,34 +6,25 @@ function _fetchTimeSeries(source, db, rp, query) {
return proxy({source, db, rp, query});
}
const {
element,
number,
arrayOf,
shape,
oneOfType,
string,
} = PropTypes
export default function AutoRefresh(ComposedComponent) {
const wrapper = React.createClass({
displayName: `AutoRefresh_${ComposedComponent.displayName}`,
propTypes: {
children: element,
autoRefresh: number.isRequired,
queries: arrayOf(shape({
host: oneOfType([string, arrayOf(string)]),
text: string,
children: PropTypes.element,
autoRefresh: PropTypes.number,
queries: PropTypes.arrayOf(PropTypes.shape({
host: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
text: PropTypes.string,
}).isRequired).isRequired,
},
getInitialState() {
return {timeSeries: []};
},
componentDidMount() {
const {queries, autoRefresh} = this.props;
const {queries} = this.props;
this.executeQueries(queries);
if (autoRefresh) {
this.intervalID = setInterval(() => this.executeQueries(queries), autoRefresh);
if (this.props.autoRefresh) {
this.intervalID = setInterval(() => this.executeQueries(queries), this.props.autoRefresh);
}
},
componentWillReceiveProps(nextProps) {

View File

@ -1,72 +0,0 @@
import React, {PropTypes} from 'react';
import classnames from 'classnames';
import OnClickOutside from 'shared/components/OnClickOutside';
import autoRefreshItems from 'hson!../data/autoRefreshes.hson';
const {
number,
func,
} = PropTypes
const AutoRefreshDropdown = React.createClass({
autobind: false,
propTypes: {
selected: number.isRequired,
onChoose: func.isRequired,
},
getInitialState() {
return {
isOpen: false,
};
},
findAutoRefreshItem(milliseconds) {
return autoRefreshItems.find((values) => values.milliseconds === milliseconds)
},
handleClickOutside() {
this.setState({isOpen: false});
},
handleSelection(milliseconds) {
this.props.onChoose(milliseconds);
this.setState({isOpen: false});
},
toggleMenu() {
this.setState({isOpen: !this.state.isOpen});
},
render() {
const self = this;
const {selected} = self.props;
const {isOpen} = self.state;
return (
<div className="dropdown time-range-dropdown">
<div className="btn btn-sm btn-info dropdown-toggle" onClick={() => self.toggleMenu()}>
<span className="icon refresh"></span>
<span className="selected-time-range">{this.findAutoRefreshItem(selected).inputValue}</span>
<span className="caret" />
</div>
<ul className={classnames("dropdown-menu", {show: isOpen})}>
<li className="dropdown-header">AutoRefresh Interval</li>
{autoRefreshItems.map((item) => {
return (
<li key={item.menuOption}>
<a href="#" onClick={() => self.handleSelection(item.milliseconds)}>
{item.menuOption}
</a>
</li>
);
})}
</ul>
</div>
);
},
});
export default OnClickOutside(AutoRefreshDropdown);

View File

@ -1,23 +1,14 @@
import React, {PropTypes} from 'react';
import classnames from 'classnames';
import OnClickOutside from 'shared/components/OnClickOutside';
const {
arrayOf,
shape,
string,
func,
} = PropTypes
const Dropdown = React.createClass({
propTypes: {
items: arrayOf(shape({
text: string.isRequired,
items: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string.isRequired,
})).isRequired,
onChoose: func.isRequired,
selected: string.isRequired,
iconName: string,
className: string,
onChoose: PropTypes.func.isRequired,
selected: PropTypes.string.isRequired,
className: PropTypes.string,
},
getInitialState() {
return {
@ -48,12 +39,11 @@ const Dropdown = React.createClass({
},
render() {
const self = this;
const {items, selected, className, iconName, actions} = self.props;
const {items, selected, className, actions} = self.props;
return (
<div onClick={this.toggleMenu} className={`dropdown ${className}`}>
<div className="btn btn-sm btn-info dropdown-toggle">
{iconName ? <span className={classnames("icon", {[iconName]: true})}></span> : null}
<span className="dropdown-selected">{selected}</span>
<span className="caret" />
</div>

View File

@ -18,7 +18,6 @@ const {
export const LayoutRenderer = React.createClass({
propTypes: {
autoRefresh: number.isRequired,
timeRange: shape({
defaultGroupBy: string.isRequired,
queryValue: string.isRequired,
@ -47,6 +46,7 @@ export const LayoutRenderer = React.createClass({
name: string.isRequired,
}).isRequired
),
autoRefreshMs: number.isRequired,
host: string,
source: string,
onPositionChange: func,
@ -84,7 +84,7 @@ export const LayoutRenderer = React.createClass({
},
generateVisualizations() {
const {autoRefresh, source, cells} = this.props;
const {autoRefreshMs, source, cells} = this.props;
return cells.map((cell) => {
const qs = cell.queries.map((q) => {
@ -100,7 +100,7 @@ export const LayoutRenderer = React.createClass({
<div key={cell.i}>
<h2 className="dash-graph--heading">{cell.name || `Graph`}</h2>
<div className="dash-graph--container">
<RefreshingSingleStat queries={[qs[0]]} autoRefresh={autoRefresh} />
<RefreshingSingleStat queries={[qs[0]]} autoRefresh={autoRefreshMs} />
</div>
</div>
);
@ -117,7 +117,7 @@ export const LayoutRenderer = React.createClass({
<div className="dash-graph--container">
<RefreshingLineGraph
queries={qs}
autoRefresh={autoRefresh}
autoRefresh={autoRefreshMs}
showSingleStat={cell.type === "line-plus-single-stat"}
displayOptions={displayOptions}
/>

View File

@ -1,5 +1,5 @@
import React from 'react';
import classnames from 'classnames';
import cN from 'classnames';
import OnClickOutside from 'shared/components/OnClickOutside';
import timeRanges from 'hson!../data/timeRanges.hson';
@ -48,7 +48,7 @@ const TimeRangeDropdown = React.createClass({
<span className="selected-time-range">{selected}</span>
<span className="caret" />
</div>
<ul className={classnames("dropdown-menu", {show: isOpen})}>
<ul className={cN("dropdown-menu", {show: isOpen})}>
<li className="dropdown-header">Time Range</li>
{timeRanges.map((item) => {
return (

View File

@ -470,5 +470,3 @@ export const STROKE_WIDTH = {
export const PRESENTATION_MODE_ANIMATION_DELAY = 0 // In milliseconds.
export const PRESENTATION_MODE_NOTIFICATION_DELAY = 2000 // In milliseconds.
export const AUTOREFRESH_DEFAULT = 15000 // in milliseconds

View File

@ -1,7 +0,0 @@
[
{milliseconds: 5000, inputValue: 'Every 5 seconds', menuOption: 'Every 5 seconds'},
{milliseconds: 10000, inputValue: 'Every 10 seconds', menuOption: 'Every 10 seconds'},
{milliseconds: 15000, inputValue: 'Every 15 seconds', menuOption: 'Every 15 seconds'},
{milliseconds: 30000, inputValue: 'Every 30 seconds', menuOption: 'Every 30 seconds'},
{milliseconds: 60000, inputValue: 'Every 60 seconds', menuOption: 'Every 60 seconds'}
]

View File

@ -1,4 +1,4 @@
import {delayEnablePresentationMode} from 'shared/actions/app'
import {delayEnablePresentationMode} from 'shared/actions/ui'
import {publishNotification, delayDismissNotification} from 'shared/actions/notifications'
import {PRESENTATION_MODE_NOTIFICATION_DELAY} from 'shared/constants'

View File

@ -1,57 +0,0 @@
import {combineReducers} from 'redux';
import {AUTOREFRESH_DEFAULT} from 'src/shared/constants'
const initialState = {
ephemeral: {
inPresentationMode: false,
},
persisted: {
autoRefresh: AUTOREFRESH_DEFAULT,
},
}
const {
ephemeral: initialEphemeralState,
persisted: initialPersistedState,
} = initialState
const ephemeralReducer = (state = initialEphemeralState, action) => {
switch (action.type) {
case 'ENABLE_PRESENTATION_MODE': {
return {
...state,
inPresentationMode: true,
}
}
case 'DISABLE_PRESENTATION_MODE': {
return {
...state,
inPresentationMode: false,
}
}
default:
return state
}
}
const persistedReducer = (state = initialPersistedState, action) => {
switch (action.type) {
case 'SET_AUTOREFRESH': {
return {
...state,
autoRefresh: action.payload.milliseconds,
}
}
default:
return state
}
}
export default combineReducers({
ephemeral: ephemeralReducer,
persisted: persistedReducer,
})

View File

@ -1,13 +1,13 @@
import appUI from './ui';
import me from './me';
import app from './app';
import auth from './auth';
import notifications from './notifications';
import sources from './sources';
export default {
export {
appUI,
me,
app,
auth,
notifications,
sources,
}
};

View File

@ -0,0 +1,23 @@
const initialState = {
presentationMode: false,
};
export default function ui(state = initialState, action) {
switch (action.type) {
case 'ENABLE_PRESENTATION_MODE': {
return {
...state,
presentationMode: true,
}
}
case 'DISABLE_PRESENTATION_MODE': {
return {
...state,
presentationMode: false,
}
}
}
return state
}

View File

@ -34,9 +34,11 @@ const SideNavApp = React.createClass({
},
});
const mapStateToProps = ({me, app: {ephemeral: {inPresentationMode}}}) => ({
me,
inPresentationMode,
})
function mapStateToProps(state) {
return {
me: state.me,
inPresentationMode: state.appUI.presentationMode,
};
}
export default connect(mapStateToProps)(SideNavApp);

View File

@ -3,8 +3,8 @@ import {combineReducers} from 'redux';
import thunkMiddleware from 'redux-thunk';
import makeQueryExecuter from 'src/shared/middleware/queryExecuter';
import resizeLayout from 'src/shared/middleware/resizeLayout';
import sharedReducers from 'src/shared/reducers';
import dataExplorerReducers from 'src/data_explorer/reducers';
import * as dataExplorerReducers from 'src/data_explorer/reducers';
import * as sharedReducers from 'src/shared/reducers';
import rulesReducer from 'src/kapacitor/reducers/rules';
import dashboardUI from 'src/dashboards/reducers/ui';
import persistStateEnhancer from './persistStateEnhancer';