Order fields according to tableoptions
parent
bfee0bc3ab
commit
010e6624c9
|
@ -4,6 +4,7 @@ interface Field {
|
||||||
internalName: string
|
internalName: string
|
||||||
displayName: string
|
displayName: string
|
||||||
visible: boolean
|
visible: boolean
|
||||||
|
order?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Loading…
Reference in New Issue