Revert "Allow user to set auto-refresh interval"
parent
0c461552df
commit
ed85ba9029
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -2,8 +2,8 @@ import queryConfigs from './queryConfigs';
|
|||
import timeRange from './timeRange';
|
||||
import dataExplorer from './ui';
|
||||
|
||||
export default {
|
||||
export {
|
||||
queryConfigs,
|
||||
timeRange,
|
||||
dataExplorer,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
})
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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),
|
||||
})
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
})
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'}
|
||||
]
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
Loading…
Reference in New Issue