Order fields according to tableoptions

pull/10616/head
ebb-tide 2018-04-07 14:18:22 -07:00
parent bfee0bc3ab
commit 010e6624c9
6 changed files with 90 additions and 68 deletions

View File

@ -4,6 +4,7 @@ interface Field {
internalName: string internalName: string
displayName: string displayName: string
visible: boolean visible: boolean
order?: number
} }
interface Props { interface Props {

View File

@ -1,8 +1,7 @@
import React, {PureComponent} from 'react' import React, {SFC} from 'react'
import GraphOptionsSortableField from 'src/dashboards/components/GraphOptionsSortableField' import GraphOptionsSortableField from 'src/dashboards/components/GraphOptionsSortableField'
// import FancyScrollbar from 'src/shared/components/FancyScrollbar' // import FancyScrollbar from 'src/shared/components/FancyScrollbar'
import _ from 'lodash'
import {DragDropContext} from 'react-dnd' import {DragDropContext} from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend' import HTML5Backend from 'react-dnd-html5-backend'
@ -10,69 +9,37 @@ interface Field {
internalName: string internalName: string
displayName: string displayName: string
visible: boolean visible: boolean
displayOrder: number order?: number
} }
interface Props { interface Props {
fields: Field[] fields: Field[]
onFieldUpdate: (field: Field) => void onFieldUpdate: (field: Field) => void
moveField: (dragIndex: number, hoverIndex: number) => void
} }
interface State { const GraphOptionsCustomizeFields: SFC<Props> = ({
fields: Field[] fields,
} onFieldUpdate,
moveField,
class GraphOptionsCustomizeFields extends PureComponent<Props, State> { }) => {
constructor(props) { return (
super(props) <div className="graph-options-group">
this.state = { <label className="form-label">Customize Fields</label>
fields: this.props.fields || [], <div>
} {fields.map((field, i) => (
this.moveField = this.moveField.bind(this) <GraphOptionsSortableField
} key={field.internalName}
index={i}
componentWillReceiveProps(nextProps) { id={field.internalName}
if (nextProps.fields == this.props.fields) { internalName={field.internalName}
return displayName={field.displayName}
} onFieldUpdate={onFieldUpdate}
this.setState({fields: nextProps.fields}) moveField={moveField}
} />
moveField(dragIndex, hoverIndex) { ))}
const {fields} = this.state
const dragField = fields[dragIndex]
const removedFields = _.concat(
_.slice(fields, 0, dragIndex),
_.slice(fields, dragIndex + 1)
)
const addedFields = _.concat(
_.slice(removedFields, 0, hoverIndex),
[dragField],
_.slice(removedFields, hoverIndex)
)
this.setState({fields: addedFields})
}
public render() {
const {fields} = this.state
const {onFieldUpdate} = this.props
return (
<div className="graph-options-group">
<label className="form-label">Customize Fields</label>
<div>
{fields.map((field, i) => (
<GraphOptionsSortableField
key={field.internalName}
index={i}
id={field.internalName}
internalName={field.internalName}
displayName={field.displayName}
moveField={this.moveField}
onFieldUpdate={onFieldUpdate}
/>
))}
</div>
</div> </div>
) </div>
} )
} }
export default DragDropContext(HTML5Backend)(GraphOptionsCustomizeFields) export default DragDropContext(HTML5Backend)(GraphOptionsCustomizeFields)

View File

@ -5,7 +5,7 @@ import GraphOptionsCustomizableField from 'src/dashboards/components/GraphOption
const FieldType = 'field' const FieldType = 'field'
const cardSource = { const fieldSource = {
beginDrag(props) { beginDrag(props) {
return { return {
id: props.id, id: props.id,
@ -14,7 +14,7 @@ const cardSource = {
}, },
} }
const cardTarget = { const fieldTarget = {
hover(props, monitor, component) { hover(props, monitor, component) {
const dragIndex = monitor.getItem().index const dragIndex = monitor.getItem().index
const hoverIndex = props.index const hoverIndex = props.index
@ -49,7 +49,6 @@ const cardTarget = {
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return return
} }
// Time to actually perform the action // Time to actually perform the action
props.moveField(dragIndex, hoverIndex) props.moveField(dragIndex, hoverIndex)
@ -61,6 +60,13 @@ const cardTarget = {
}, },
} }
interface Field {
internalName: string
displayName: string
visible: boolean
order?: number
}
interface Props { interface Props {
internalName: string internalName: string
displayName: string displayName: string
@ -68,15 +74,16 @@ interface Props {
id: string id: string
key: string key: string
isDragging: boolean isDragging: boolean
onFieldUpdate?: (field: Field) => void
connectDragSource: any connectDragSource: any
connectDropTarget: any connectDropTarget: any
moveField: (dragIndex: number, hoverIndex: number) => void moveField: (dragIndex: number, hoverIndex: number) => void
} }
@DropTarget(FieldType, cardTarget, connect => ({ @DropTarget(FieldType, fieldTarget, connect => ({
connectDropTarget: connect.dropTarget(), connectDropTarget: connect.dropTarget(),
})) }))
@DragSource(FieldType, cardSource, (connect, monitor) => ({ @DragSource(FieldType, fieldSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(), connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(), isDragging: monitor.isDragging(),
})) }))
@ -86,10 +93,10 @@ export default class GraphOptionsSortableField extends PureComponent<Props> {
internalName, internalName,
displayName, displayName,
isDragging, isDragging,
onFieldUpdate,
connectDragSource, connectDragSource,
connectDropTarget, connectDropTarget,
} = this.props } = this.props
const opacity = isDragging ? 0 : 1
return connectDragSource( return connectDragSource(
connectDropTarget( connectDropTarget(
@ -98,6 +105,8 @@ export default class GraphOptionsSortableField extends PureComponent<Props> {
internalName={internalName} internalName={internalName}
displayName={displayName} displayName={displayName}
visible={true} visible={true}
onFieldUpdate={onFieldUpdate}
opacity={isDragging ? 0 : 1}
/> />
</div> </div>
) )

View File

@ -26,6 +26,7 @@ interface RenamableField {
internalName: string internalName: string
displayName: string displayName: string
visible: boolean visible: boolean
order?: number
} }
interface Options { interface Options {
@ -46,6 +47,7 @@ interface Props {
export class TableOptions extends PureComponent<Props, {}> { export class TableOptions extends PureComponent<Props, {}> {
constructor(props) { constructor(props) {
super(props) super(props)
this.moveField = this.moveField.bind(this)
} }
get fieldNames() { get fieldNames() {
@ -99,7 +101,7 @@ export class TableOptions extends PureComponent<Props, {}> {
handleUpdateTableOptions({...tableOptions, fixFirstColumn}) handleUpdateTableOptions({...tableOptions, fixFirstColumn})
} }
public handleFieldUpdate = field => { public handleSingleFieldUpdate = field => {
const {handleUpdateTableOptions, tableOptions, dataLabels} = this.props const {handleUpdateTableOptions, tableOptions, dataLabels} = this.props
const {sortBy, fieldNames} = tableOptions const {sortBy, fieldNames} = tableOptions
const fields = const fields =
@ -109,6 +111,11 @@ export class TableOptions extends PureComponent<Props, {}> {
const updatedFields = fields.map( const updatedFields = fields.map(
f => (f.internalName === field.internalName ? field : f) f => (f.internalName === field.internalName ? field : f)
) )
_.sortBy(updatedFields, f => {
f.order
})
const updatedSortBy = const updatedSortBy =
sortBy.internalName === field.internalName sortBy.internalName === field.internalName
? {...sortBy, displayName: field.displayName} ? {...sortBy, displayName: field.displayName}
@ -140,6 +147,31 @@ export class TableOptions extends PureComponent<Props, {}> {
return tableOptionsDifferent || dataLabelsDifferent return tableOptionsDifferent || dataLabelsDifferent
} }
public moveField(dragIndex, hoverIndex) {
const {handleUpdateTableOptions, tableOptions} = this.props
const {fieldNames} = tableOptions
const fields = fieldNames.length > 1 ? fieldNames : this.computedFieldNames
const dragField = fields[dragIndex]
const removedFields = _.concat(
_.slice(fields, 0, dragIndex),
_.slice(fields, dragIndex + 1)
)
const addedFields = _.concat(
_.slice(removedFields, 0, hoverIndex),
[dragField],
_.slice(removedFields, hoverIndex)
)
const orderedFields = addedFields.map((f, i) => {
return {...f, order: i}
})
console.log('orderedFields', orderedFields)
handleUpdateTableOptions({
...tableOptions,
fieldNames: orderedFields,
})
}
public render() { public render() {
const { const {
tableOptions: {timeFormat, fieldNames, verticalTimeAxis, fixFirstColumn}, tableOptions: {timeFormat, fieldNames, verticalTimeAxis, fixFirstColumn},
@ -182,7 +214,8 @@ export class TableOptions extends PureComponent<Props, {}> {
</div> </div>
<GraphOptionsCustomizeFields <GraphOptionsCustomizeFields
fields={fields} fields={fields}
onFieldUpdate={this.handleFieldUpdate} onFieldUpdate={this.handleSingleFieldUpdate}
moveField={this.moveField}
/> />
<ThresholdsList showListHeading={true} onResetFocus={onResetFocus} /> <ThresholdsList showListHeading={true} onResetFocus={onResetFocus} />
<div className="form-group-wrapper graph-options-group"> <div className="form-group-wrapper graph-options-group">

View File

@ -198,6 +198,17 @@ export const filterTableColumns = (data, fieldNames) => {
return filteredData[0].length ? filteredData : [[]] return filteredData[0].length ? filteredData : [[]]
} }
export const orderTableColumns = (data, fieldNames) => {
const fieldsSortOrder = fieldNames.map(v => {
return data[0].indexOf(v.displayName || v.internalName)
})
const orderedData = map(data, row => {
return row.map((v, j, arr) => {
return arr[fieldsSortOrder[j]]
})
})
return orderedData[0].length ? orderedData : [[]]
export const processTableData = ( export const processTableData = (
data, data,
sortFieldName, sortFieldName,
@ -212,7 +223,8 @@ export const processTableData = (
] ]
const sortedTimeVals = map(sortedData, r => r[0]) const sortedTimeVals = map(sortedData, r => r[0])
const filteredData = filterTableColumns(sortedData, fieldNames) const filteredData = filterTableColumns(sortedData, fieldNames)
const processedData = verticalTimeAxis ? filteredData : _.unzip(filteredData) const orderedData = orderTableColumns(filteredData, fieldNames)
const processedData = verticalTimeAxis ? orderedData : _.unzip(orderedData)
return {processedData, sortedTimeVals} return {processedData, sortedTimeVals}
} }

View File

@ -74,7 +74,7 @@ describe('Dashboards.Components.GraphOptionsCustomizableField', () => {
}) })
describe('instance methods', () => { describe('instance methods', () => {
describe('#handleFieldUpdate', () => { describe('#handleSingleFieldUpdate', () => {
it('calls onFieldUpdate once with internalName, new name, and visible', () => { it('calls onFieldUpdate once with internalName, new name, and visible', () => {
const onFieldUpdate = jest.fn() const onFieldUpdate = jest.fn()
const internalName = 'test' const internalName = 'test'