add logic for renaming table columns in tableoptiomns

pull/2996/head
Iris Scholten 2018-03-13 14:45:01 -07:00
parent a83f01affe
commit ba1312169a
4 changed files with 80 additions and 150 deletions

View File

@ -1,33 +1,45 @@
import React from 'react' import React, {Component} from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import InputClickToEdit from 'shared/components/InputClickToEdit' import InputClickToEdit from 'shared/components/InputClickToEdit'
const GraphOptionsCustomizableColumn = ({ class GraphOptionsCustomizableColumn extends Component {
originalColumnName, constructor(props) {
newColumnName, super(props)
onColumnRename,
}) => { this.handleColumnRename = this.handleColumnRename.bind(this)
}
handleColumnRename(rename) {
const {onColumnRename, internalName} = this.props
onColumnRename({internalName, displayName: rename})
}
render() {
const {internalName, displayName} = this.props
return ( return (
<div className="column-controls--section"> <div className="column-controls--section">
<div className="column-controls--label"> <div className="column-controls--label">
{originalColumnName} {internalName}
</div> </div>
<InputClickToEdit <InputClickToEdit
value={newColumnName} value={displayName}
wrapperClass="column-controls-input" wrapperClass="column-controls-input"
onBlur={onColumnRename} onBlur={this.handleColumnRename}
placeholder="Rename..." placeholder="Rename..."
appearAsNormalInput={true} appearAsNormalInput={true}
/> />
</div> </div>
) )
} }
}
const {func, string} = PropTypes const {func, string} = PropTypes
GraphOptionsCustomizableColumn.propTypes = { GraphOptionsCustomizableColumn.propTypes = {
originalColumnName: string, internalName: string,
newColumnName: string, displayName: string,
onColumnRename: func, onColumnRename: func,
} }

View File

@ -12,8 +12,8 @@ const GraphOptionsCustomizeColumns = ({columns, onColumnRename}) => {
return ( return (
<GraphOptionsCustomizableColumn <GraphOptionsCustomizableColumn
key={uuid.v4()} key={uuid.v4()}
originalColumnName={col.name} internalName={col.internalName}
newColumnName={col.newName} displayName={col.displayName}
onColumnRename={onColumnRename} onColumnRename={onColumnRename}
/> />
) )
@ -26,8 +26,8 @@ const {arrayOf, func, shape, string} = PropTypes
GraphOptionsCustomizeColumns.propTypes = { GraphOptionsCustomizeColumns.propTypes = {
columns: arrayOf( columns: arrayOf(
shape({ shape({
name: string, internalName: string,
newName: string, displayName: string,
}) })
), ),
onColumnRename: func, onColumnRename: func,

View File

@ -28,7 +28,34 @@ const formatColor = color => {
} }
class TableOptions extends Component { class TableOptions extends Component {
state = {TimeAxis: 'VERTICAL', TimeFormat: 'mm/dd/yyyy HH:mm:ss.ss'} constructor(props) {
super(props)
this.state = {
TimeAxis: 'VERTICAL',
TimeFormat: 'mm/dd/yyyy HH:mm:ss.ss',
columns: [],
}
}
componentWillMount() {
const {queries} = this.props
let columns = [{internalName: 'time', displayName: ''}]
for (let i = 0; i < queries.length; i++) {
const q = queries[i]
const measurement = q.queryConfig.measurement
const fields = q.queryConfig.fields
for (let j = 0; j < fields.length; j++) {
columns = [
...columns,
{internalName: `${measurement}.${fields[j].alias}`, displayName: ''},
]
}
}
this.setState({columns})
}
handleToggleSingleStatType = () => {} handleToggleSingleStatType = () => {}
@ -46,7 +73,13 @@ class TableOptions extends Component {
handleToggleTextWrapping = () => {} handleToggleTextWrapping = () => {}
handleColumnRename = () => {} handleColumnRename = column => {
// NOTE: should use redux state instead of component state
const columns = this.state.columns.map(
op => (op.internalName === column.internalName ? column : op)
)
this.setState({columns})
}
handleUpdateColorValue = () => {} handleUpdateColorValue = () => {}
@ -59,27 +92,18 @@ class TableOptions extends Component {
// axes: {y: {prefix, suffix}}, // axes: {y: {prefix, suffix}},
} = this.props } = this.props
const {TimeFormat, TimeAxis} = this.state const {TimeFormat, TimeAxis, columns} = this.state
const disableAddThreshold = singleStatColors.length > MAX_THRESHOLDS
const sortedColors = _.sortBy(singleStatColors, color => color.value)
const columns = [
'cpu.mean_usage_system',
'cpu.mean_usage_idle',
'cpu.mean_usage_user',
].map(col => ({
text: col,
name: col,
newName: '',
}))
const tableSortByOptions = [ const tableSortByOptions = [
'cpu.mean_usage_system', 'cpu.mean_usage_system',
'cpu.mean_usage_idle', 'cpu.mean_usage_idle',
'cpu.mean_usage_user', 'cpu.mean_usage_user',
].map(col => ({text: col})) ].map(col => ({text: col}))
const disableAddThreshold = singleStatColors.length > MAX_THRESHOLDS
const sortedColors = _.sortBy(singleStatColors, color => color.value)
return ( return (
<FancyScrollbar <FancyScrollbar
className="display-options--cell y-axis-controls" className="display-options--cell y-axis-controls"
@ -152,14 +176,16 @@ TableOptions.propTypes = {
handleUpdateSingleStatColors: func.isRequired, handleUpdateSingleStatColors: func.isRequired,
handleUpdateAxes: func.isRequired, handleUpdateAxes: func.isRequired,
axes: shape({}).isRequired, axes: shape({}).isRequired,
queries: arrayOf(shape()),
} }
const mapStateToProps = ({ const mapStateToProps = ({
cellEditorOverlay: {singleStatType, singleStatColors, cell: {axes}}, cellEditorOverlay: {singleStatType, singleStatColors, cell: {axes, queries}},
}) => ({ }) => ({
singleStatType, singleStatType,
singleStatColors, singleStatColors,
axes, axes,
queries,
}) })
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View File

@ -1,108 +0,0 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
class InputClickToEdit extends Component {
constructor(props) {
super(props)
this.state = {
isEditing: null,
value: this.props.value,
}
}
handleCancel = () => {
this.setState({
isEditing: false,
value: this.props.value,
})
}
handleInputClick = () => {
this.setState({isEditing: true})
}
handleInputBlur = e => {
const {onUpdate, value} = this.props
if (value !== e.target.value) {
onUpdate(e.target.value)
}
this.setState({isEditing: false, value: e.target.value})
}
handleKeyDown = e => {
if (e.key === 'Enter') {
this.handleInputBlur(e)
}
if (e.key === 'Escape') {
this.handleCancel()
}
}
handleFocus = e => {
e.target.select()
}
render() {
const {isEditing, value} = this.state
const {
wrapperClass: wrapper,
disabled,
tabIndex,
placeholder,
appearAsNormalInput,
} = this.props
const wrapperClass = `${wrapper}${appearAsNormalInput
? ' input-cte__normal'
: ''}`
const defaultStyle = value ? 'input-cte' : 'input-cte__empty'
return disabled
? <div className={wrapperClass}>
<div className="input-cte__disabled">
{value}
</div>
</div>
: <div className={wrapperClass}>
{isEditing
? <input
type="text"
className="form-control input-sm provider--input"
defaultValue={value}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
autoFocus={true}
onFocus={this.handleFocus}
ref={r => (this.inputRef = r)}
tabIndex={tabIndex}
spellCheck={false}
/>
: <div
className={defaultStyle}
onClick={this.handleInputClick}
onFocus={this.handleInputClick}
tabIndex={tabIndex}
>
{value || placeholder}
{appearAsNormalInput || <span className="icon pencil" />}
</div>}
</div>
}
}
const {func, bool, number, string} = PropTypes
InputClickToEdit.propTypes = {
wrapperClass: string.isRequired,
value: string,
onUpdate: func.isRequired,
disabled: bool,
tabIndex: number,
placeholder: string,
appearAsNormalInput: bool,
}
export default InputClickToEdit