Merge branch 'master' into feature/graph-table
commit
9afed4099e
|
@ -249,6 +249,10 @@ class CellEditorOverlay extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleResetFocus = () => {
|
||||
this.overlayRef.focus()
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
onCancel,
|
||||
|
@ -313,6 +317,7 @@ class CellEditorOverlay extends Component {
|
|||
queryConfigs={queriesWorkingDraft}
|
||||
onToggleStaticLegend={this.handleToggleStaticLegend}
|
||||
staticLegend={staticLegend}
|
||||
onResetFocus={this.handleResetFocus}
|
||||
/>
|
||||
: <QueryMaker
|
||||
source={this.getSource()}
|
||||
|
|
|
@ -36,12 +36,17 @@ class DisplayOptions extends Component {
|
|||
}
|
||||
|
||||
renderOptions = () => {
|
||||
const {cell: {type}, staticLegend, onToggleStaticLegend} = this.props
|
||||
const {
|
||||
cell: {type},
|
||||
staticLegend,
|
||||
onToggleStaticLegend,
|
||||
onResetFocus,
|
||||
} = this.props
|
||||
switch (type) {
|
||||
case 'gauge':
|
||||
return <GaugeOptions />
|
||||
return <GaugeOptions onResetFocus={onResetFocus} />
|
||||
case 'single-stat':
|
||||
return <SingleStatOptions />
|
||||
return <SingleStatOptions onResetFocus={onResetFocus} />
|
||||
case 'table':
|
||||
return <TableOptions />
|
||||
default:
|
||||
|
@ -80,6 +85,7 @@ DisplayOptions.propTypes = {
|
|||
queryConfigs: arrayOf(shape()).isRequired,
|
||||
onToggleStaticLegend: func.isRequired,
|
||||
staticLegend: bool,
|
||||
onResetFocus: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = ({cellEditorOverlay: {cell, cell: {axes}}}) => ({
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
|
||||
class GaugeOptions extends Component {
|
||||
handleAddThreshold = () => {
|
||||
const {gaugeColors, handleUpdateGaugeColors} = this.props
|
||||
const {gaugeColors, handleUpdateGaugeColors, onResetFocus} = this.props
|
||||
const sortedColors = _.sortBy(gaugeColors, color => color.value)
|
||||
|
||||
if (sortedColors.length <= MAX_THRESHOLDS) {
|
||||
|
@ -47,16 +47,19 @@ class GaugeOptions extends Component {
|
|||
}
|
||||
|
||||
handleUpdateGaugeColors([...gaugeColors, newThreshold])
|
||||
} else {
|
||||
onResetFocus()
|
||||
}
|
||||
}
|
||||
|
||||
handleDeleteThreshold = threshold => () => {
|
||||
const {handleUpdateGaugeColors} = this.props
|
||||
const {handleUpdateGaugeColors, onResetFocus} = this.props
|
||||
const gaugeColors = this.props.gaugeColors.filter(
|
||||
color => color.id !== threshold.id
|
||||
)
|
||||
|
||||
handleUpdateGaugeColors(gaugeColors)
|
||||
onResetFocus()
|
||||
}
|
||||
|
||||
handleChooseColor = threshold => chosenColor => {
|
||||
|
@ -217,6 +220,7 @@ GaugeOptions.propTypes = {
|
|||
handleUpdateGaugeColors: func.isRequired,
|
||||
handleUpdateAxes: func.isRequired,
|
||||
axes: shape({}).isRequired,
|
||||
onResetFocus: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = ({cellEditorOverlay: {gaugeColors, cell: {axes}}}) => ({
|
||||
|
|
|
@ -42,6 +42,7 @@ class SingleStatOptions extends Component {
|
|||
singleStatColors,
|
||||
singleStatType,
|
||||
handleUpdateSingleStatColors,
|
||||
onResetFocus,
|
||||
} = this.props
|
||||
|
||||
const randomColor = _.random(0, GAUGE_COLORS.length - 1)
|
||||
|
@ -67,16 +68,18 @@ class SingleStatOptions extends Component {
|
|||
}
|
||||
|
||||
handleUpdateSingleStatColors([...singleStatColors, newThreshold])
|
||||
onResetFocus()
|
||||
}
|
||||
|
||||
handleDeleteThreshold = threshold => () => {
|
||||
const {handleUpdateSingleStatColors} = this.props
|
||||
const {handleUpdateSingleStatColors, onResetFocus} = this.props
|
||||
|
||||
const singleStatColors = this.props.singleStatColors.filter(
|
||||
color => color.id !== threshold.id
|
||||
)
|
||||
|
||||
handleUpdateSingleStatColors(singleStatColors)
|
||||
onResetFocus()
|
||||
}
|
||||
|
||||
handleChooseColor = threshold => chosenColor => {
|
||||
|
@ -242,6 +245,7 @@ SingleStatOptions.propTypes = {
|
|||
handleUpdateSingleStatColors: func.isRequired,
|
||||
handleUpdateAxes: func.isRequired,
|
||||
axes: shape({}).isRequired,
|
||||
onResetFocus: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = ({
|
||||
|
|
|
@ -19,6 +19,7 @@ const Annotation = ({
|
|||
annotation={annotation}
|
||||
mode={mode}
|
||||
dygraph={dygraph}
|
||||
staticLegendHeight={staticLegendHeight}
|
||||
/>
|
||||
: <AnnotationSpan
|
||||
lastUpdated={lastUpdated}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import {DYGRAPH_CONTAINER_MARGIN} from 'shared/constants'
|
||||
import {
|
||||
DYGRAPH_CONTAINER_H_MARGIN,
|
||||
DYGRAPH_CONTAINER_V_MARGIN,
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN,
|
||||
} from 'shared/constants'
|
||||
import {ANNOTATION_MIN_DELTA, EDITING} from 'shared/annotations/helpers'
|
||||
import * as schema from 'shared/schemas'
|
||||
import * as actions from 'shared/actions/annotations'
|
||||
|
@ -85,7 +89,7 @@ class AnnotationPoint extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {annotation, mode, dygraph} = this.props
|
||||
const {annotation, mode, dygraph, staticLegendHeight} = this.props
|
||||
const {isDragging} = this.state
|
||||
|
||||
const isEditing = mode === EDITING
|
||||
|
@ -100,11 +104,16 @@ class AnnotationPoint extends React.Component {
|
|||
? 'annotation--click-area editing'
|
||||
: 'annotation--click-area'
|
||||
|
||||
const left = `${dygraph.toDomXCoord(annotation.startTime) +
|
||||
DYGRAPH_CONTAINER_MARGIN}px`
|
||||
const markerStyles = {
|
||||
left: `${dygraph.toDomXCoord(annotation.startTime) +
|
||||
DYGRAPH_CONTAINER_H_MARGIN}px`,
|
||||
height: `calc(100% - ${staticLegendHeight +
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN +
|
||||
DYGRAPH_CONTAINER_V_MARGIN * 2}px)`,
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={markerClass} style={{left}}>
|
||||
<div className={markerClass} style={markerStyles}>
|
||||
<div
|
||||
className={clickClass}
|
||||
draggable={true}
|
||||
|
@ -127,12 +136,19 @@ class AnnotationPoint extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const {func, number, shape, string} = PropTypes
|
||||
|
||||
AnnotationPoint.defaultProps = {
|
||||
staticLegendHeight: 0,
|
||||
}
|
||||
|
||||
AnnotationPoint.propTypes = {
|
||||
annotation: schema.annotation.isRequired,
|
||||
mode: PropTypes.string.isRequired,
|
||||
dygraph: PropTypes.shape({}).isRequired,
|
||||
updateAnnotation: PropTypes.func.isRequired,
|
||||
updateAnnotationAsync: PropTypes.func.isRequired,
|
||||
mode: string.isRequired,
|
||||
dygraph: shape({}).isRequired,
|
||||
updateAnnotation: func.isRequired,
|
||||
updateAnnotationAsync: func.isRequired,
|
||||
staticLegendHeight: number.isRequired,
|
||||
}
|
||||
|
||||
const mdtp = {
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import {DYGRAPH_CONTAINER_MARGIN} from 'shared/constants'
|
||||
import {
|
||||
DYGRAPH_CONTAINER_H_MARGIN,
|
||||
DYGRAPH_CONTAINER_V_MARGIN,
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN,
|
||||
} from 'shared/constants'
|
||||
import {ANNOTATION_MIN_DELTA, EDITING} from 'shared/annotations/helpers'
|
||||
import * as schema from 'shared/schemas'
|
||||
import * as actions from 'shared/actions/annotations'
|
||||
|
@ -92,7 +96,7 @@ class AnnotationSpan extends React.Component {
|
|||
renderLeftMarker(startTime, dygraph) {
|
||||
const isEditing = this.props.mode === EDITING
|
||||
const {isDragging, isMouseOver} = this.state
|
||||
const {annotation} = this.props
|
||||
const {annotation, staticLegendHeight} = this.props
|
||||
|
||||
const flagClass = isDragging
|
||||
? 'annotation-span--left-flag dragging'
|
||||
|
@ -108,10 +112,15 @@ class AnnotationSpan extends React.Component {
|
|||
}
|
||||
const showTooltip = isDragging === 'left' || isMouseOver === 'left'
|
||||
|
||||
const left = dygraph.toDomXCoord(startTime) + DYGRAPH_CONTAINER_MARGIN
|
||||
const markerStyles = {
|
||||
left: `${dygraph.toDomXCoord(startTime) + DYGRAPH_CONTAINER_H_MARGIN}px`,
|
||||
height: `calc(100% - ${staticLegendHeight +
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN +
|
||||
DYGRAPH_CONTAINER_V_MARGIN * 2}px)`,
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={markerClass} style={{left: `${left}px`}}>
|
||||
<div className={markerClass} style={markerStyles}>
|
||||
{showTooltip &&
|
||||
<AnnotationTooltip
|
||||
isEditing={isEditing}
|
||||
|
@ -136,9 +145,8 @@ class AnnotationSpan extends React.Component {
|
|||
|
||||
renderRightMarker(endTime, dygraph) {
|
||||
const isEditing = this.props.mode === EDITING
|
||||
const humanTime = `${new Date(+endTime)}`
|
||||
const {isDragging, isMouseOver} = this.state
|
||||
const {annotation} = this.props
|
||||
const {annotation, staticLegendHeight} = this.props
|
||||
|
||||
const flagClass = isDragging
|
||||
? 'annotation-span--right-flag dragging'
|
||||
|
@ -154,15 +162,15 @@ class AnnotationSpan extends React.Component {
|
|||
}
|
||||
const showTooltip = isDragging === 'right' || isMouseOver === 'right'
|
||||
|
||||
const left = `${dygraph.toDomXCoord(endTime) + DYGRAPH_CONTAINER_MARGIN}px`
|
||||
const markerStyles = {
|
||||
left: `${dygraph.toDomXCoord(endTime) + DYGRAPH_CONTAINER_H_MARGIN}px`,
|
||||
height: `calc(100% - ${staticLegendHeight +
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN +
|
||||
DYGRAPH_CONTAINER_V_MARGIN * 2}px)`,
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={markerClass}
|
||||
style={{left}}
|
||||
data-time-ms={endTime}
|
||||
data-time-local={humanTime}
|
||||
>
|
||||
<div className={markerClass} style={markerStyles}>
|
||||
{showTooltip &&
|
||||
<AnnotationTooltip
|
||||
isEditing={isEditing}
|
||||
|
@ -204,13 +212,19 @@ class AnnotationSpan extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const {func, number, shape, string} = PropTypes
|
||||
|
||||
AnnotationSpan.defaultProps = {
|
||||
staticLegendHeight: 0,
|
||||
}
|
||||
|
||||
AnnotationSpan.propTypes = {
|
||||
annotation: schema.annotation.isRequired,
|
||||
mode: PropTypes.string.isRequired,
|
||||
dygraph: PropTypes.shape({}).isRequired,
|
||||
staticLegendHeight: PropTypes.number.isRequired,
|
||||
updateAnnotationAsync: PropTypes.func.isRequired,
|
||||
updateAnnotation: PropTypes.func.isRequired,
|
||||
mode: string.isRequired,
|
||||
dygraph: shape({}).isRequired,
|
||||
staticLegendHeight: number.isRequired,
|
||||
updateAnnotationAsync: func.isRequired,
|
||||
updateAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
const mdtp = {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
|
||||
import {DYGRAPH_CONTAINER_MARGIN} from 'shared/constants'
|
||||
import {
|
||||
DYGRAPH_CONTAINER_H_MARGIN,
|
||||
DYGRAPH_CONTAINER_V_MARGIN,
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN,
|
||||
} from 'shared/constants'
|
||||
import * as schema from 'shared/schemas'
|
||||
|
||||
const windowDimensions = (anno, dygraph, staticLegendHeight) => {
|
||||
|
@ -14,10 +18,12 @@ const windowDimensions = (anno, dygraph, staticLegendHeight) => {
|
|||
const windowWidth = Math.abs(windowEndXCoord - windowStartXCoord)
|
||||
|
||||
const windowLeftXCoord =
|
||||
Math.min(windowStartXCoord, windowEndXCoord) + DYGRAPH_CONTAINER_MARGIN
|
||||
Math.min(windowStartXCoord, windowEndXCoord) + DYGRAPH_CONTAINER_H_MARGIN
|
||||
|
||||
const height = staticLegendHeight
|
||||
? `calc(100% - ${staticLegendHeight + 36}px)`
|
||||
? `calc(100% - ${staticLegendHeight +
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN +
|
||||
DYGRAPH_CONTAINER_V_MARGIN * 2}px)`
|
||||
: 'calc(100% - 36px)'
|
||||
|
||||
return {
|
||||
|
|
|
@ -8,6 +8,8 @@ import AnnotationWindow from 'shared/components/AnnotationWindow'
|
|||
import * as schema from 'shared/schemas'
|
||||
import * as actions from 'shared/actions/annotations'
|
||||
|
||||
import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'shared/constants'
|
||||
|
||||
class NewAnnotation extends Component {
|
||||
state = {
|
||||
isMouseOver: false,
|
||||
|
@ -123,6 +125,8 @@ class NewAnnotation extends Component {
|
|||
|
||||
const crosshairOne = Math.max(-1000, dygraph.toDomXCoord(startTime))
|
||||
const crosshairTwo = dygraph.toDomXCoord(endTime)
|
||||
const crosshairHeight = `calc(100% - ${staticLegendHeight +
|
||||
DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
|
||||
|
||||
const isDragging = startTime !== endTime
|
||||
const flagOneClass =
|
||||
|
@ -158,7 +162,7 @@ class NewAnnotation extends Component {
|
|||
{isDragging &&
|
||||
<div
|
||||
className="new-annotation--crosshair"
|
||||
style={{left: crosshairTwo}}
|
||||
style={{left: crosshairTwo, height: crosshairHeight}}
|
||||
>
|
||||
{isMouseOver &&
|
||||
isDragging &&
|
||||
|
@ -167,7 +171,7 @@ class NewAnnotation extends Component {
|
|||
</div>}
|
||||
<div
|
||||
className="new-annotation--crosshair"
|
||||
style={{left: crosshairOne}}
|
||||
style={{left: crosshairOne, height: crosshairHeight}}
|
||||
>
|
||||
{isMouseOver &&
|
||||
!isDragging &&
|
||||
|
|
|
@ -55,6 +55,7 @@ const RefreshingGraph = ({
|
|||
cellHeight={cellHeight}
|
||||
prefix={prefix}
|
||||
suffix={suffix}
|
||||
inView={inView}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -73,6 +74,7 @@ const RefreshingGraph = ({
|
|||
cellID={cellID}
|
||||
prefix={prefix}
|
||||
suffix={suffix}
|
||||
inView={inView}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -415,7 +415,9 @@ export const PAGE_CONTAINER_MARGIN = 30 // TODO: get this dynamically to ensure
|
|||
export const LAYOUT_MARGIN = 4
|
||||
export const DASHBOARD_LAYOUT_ROW_HEIGHT = 83.5
|
||||
|
||||
export const DYGRAPH_CONTAINER_MARGIN = 16
|
||||
export const DYGRAPH_CONTAINER_H_MARGIN = 16
|
||||
export const DYGRAPH_CONTAINER_V_MARGIN = 8
|
||||
export const DYGRAPH_CONTAINER_XLABEL_MARGIN = 20
|
||||
|
||||
export const DEFAULT_SOURCE = {
|
||||
url: 'http://localhost:8086',
|
||||
|
|
Loading…
Reference in New Issue