diff --git a/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx b/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx index e8595e9f59..d260c78b6e 100644 --- a/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx +++ b/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx @@ -4,6 +4,7 @@ interface Field { internalName: string displayName: string visible: boolean + order?: number } interface Props { diff --git a/ui/src/dashboards/components/GraphOptionsCustomizeFields.tsx b/ui/src/dashboards/components/GraphOptionsCustomizeFields.tsx index d67a7923a6..988a787e49 100644 --- a/ui/src/dashboards/components/GraphOptionsCustomizeFields.tsx +++ b/ui/src/dashboards/components/GraphOptionsCustomizeFields.tsx @@ -1,8 +1,7 @@ -import React, {PureComponent} from 'react' +import React, {SFC} from 'react' import GraphOptionsSortableField from 'src/dashboards/components/GraphOptionsSortableField' // import FancyScrollbar from 'src/shared/components/FancyScrollbar' -import _ from 'lodash' import {DragDropContext} from 'react-dnd' import HTML5Backend from 'react-dnd-html5-backend' @@ -10,69 +9,37 @@ interface Field { internalName: string displayName: string visible: boolean - displayOrder: number + order?: number } interface Props { fields: Field[] onFieldUpdate: (field: Field) => void + moveField: (dragIndex: number, hoverIndex: number) => void } -interface State { - fields: Field[] -} - -class GraphOptionsCustomizeFields extends PureComponent { - constructor(props) { - super(props) - this.state = { - fields: this.props.fields || [], - } - this.moveField = this.moveField.bind(this) - } - - componentWillReceiveProps(nextProps) { - if (nextProps.fields == this.props.fields) { - return - } - this.setState({fields: nextProps.fields}) - } - 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 ( -
- -
- {fields.map((field, i) => ( - - ))} -
+const GraphOptionsCustomizeFields: SFC = ({ + fields, + onFieldUpdate, + moveField, +}) => { + return ( +
+ +
+ {fields.map((field, i) => ( + + ))}
- ) - } +
+ ) } export default DragDropContext(HTML5Backend)(GraphOptionsCustomizeFields) diff --git a/ui/src/dashboards/components/GraphOptionsSortableField.tsx b/ui/src/dashboards/components/GraphOptionsSortableField.tsx index 8dc5fd51dc..700afd6634 100644 --- a/ui/src/dashboards/components/GraphOptionsSortableField.tsx +++ b/ui/src/dashboards/components/GraphOptionsSortableField.tsx @@ -5,7 +5,7 @@ import GraphOptionsCustomizableField from 'src/dashboards/components/GraphOption const FieldType = 'field' -const cardSource = { +const fieldSource = { beginDrag(props) { return { id: props.id, @@ -14,7 +14,7 @@ const cardSource = { }, } -const cardTarget = { +const fieldTarget = { hover(props, monitor, component) { const dragIndex = monitor.getItem().index const hoverIndex = props.index @@ -49,7 +49,6 @@ const cardTarget = { if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { return } - // Time to actually perform the action props.moveField(dragIndex, hoverIndex) @@ -61,6 +60,13 @@ const cardTarget = { }, } +interface Field { + internalName: string + displayName: string + visible: boolean + order?: number +} + interface Props { internalName: string displayName: string @@ -68,15 +74,16 @@ interface Props { id: string key: string isDragging: boolean + onFieldUpdate?: (field: Field) => void connectDragSource: any connectDropTarget: any moveField: (dragIndex: number, hoverIndex: number) => void } -@DropTarget(FieldType, cardTarget, connect => ({ +@DropTarget(FieldType, fieldTarget, connect => ({ connectDropTarget: connect.dropTarget(), })) -@DragSource(FieldType, cardSource, (connect, monitor) => ({ +@DragSource(FieldType, fieldSource, (connect, monitor) => ({ connectDragSource: connect.dragSource(), isDragging: monitor.isDragging(), })) @@ -86,10 +93,10 @@ export default class GraphOptionsSortableField extends PureComponent { internalName, displayName, isDragging, + onFieldUpdate, connectDragSource, connectDropTarget, } = this.props - const opacity = isDragging ? 0 : 1 return connectDragSource( connectDropTarget( @@ -98,6 +105,8 @@ export default class GraphOptionsSortableField extends PureComponent { internalName={internalName} displayName={displayName} visible={true} + onFieldUpdate={onFieldUpdate} + opacity={isDragging ? 0 : 1} />
) diff --git a/ui/src/dashboards/components/TableOptions.tsx b/ui/src/dashboards/components/TableOptions.tsx index f6433e9862..576c2148b9 100644 --- a/ui/src/dashboards/components/TableOptions.tsx +++ b/ui/src/dashboards/components/TableOptions.tsx @@ -26,6 +26,7 @@ interface RenamableField { internalName: string displayName: string visible: boolean + order?: number } interface Options { @@ -46,6 +47,7 @@ interface Props { export class TableOptions extends PureComponent { constructor(props) { super(props) + this.moveField = this.moveField.bind(this) } get fieldNames() { @@ -99,7 +101,7 @@ export class TableOptions extends PureComponent { handleUpdateTableOptions({...tableOptions, fixFirstColumn}) } - public handleFieldUpdate = field => { + public handleSingleFieldUpdate = field => { const {handleUpdateTableOptions, tableOptions, dataLabels} = this.props const {sortBy, fieldNames} = tableOptions const fields = @@ -109,6 +111,11 @@ export class TableOptions extends PureComponent { const updatedFields = fields.map( f => (f.internalName === field.internalName ? field : f) ) + + _.sortBy(updatedFields, f => { + f.order + }) + const updatedSortBy = sortBy.internalName === field.internalName ? {...sortBy, displayName: field.displayName} @@ -140,6 +147,31 @@ export class TableOptions extends PureComponent { 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() { const { tableOptions: {timeFormat, fieldNames, verticalTimeAxis, fixFirstColumn}, @@ -182,7 +214,8 @@ export class TableOptions extends PureComponent {
diff --git a/ui/src/utils/timeSeriesTransformers.js b/ui/src/utils/timeSeriesTransformers.js index 0a5db50ba3..341caefcaa 100644 --- a/ui/src/utils/timeSeriesTransformers.js +++ b/ui/src/utils/timeSeriesTransformers.js @@ -198,6 +198,17 @@ export const filterTableColumns = (data, fieldNames) => { 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 = ( data, sortFieldName, @@ -212,7 +223,8 @@ export const processTableData = ( ] const sortedTimeVals = map(sortedData, r => r[0]) 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} } diff --git a/ui/test/dashboards/components/GraphOptionsCustomizableField.test.tsx b/ui/test/dashboards/components/GraphOptionsCustomizableField.test.tsx index 52dc1d214b..27c0961839 100644 --- a/ui/test/dashboards/components/GraphOptionsCustomizableField.test.tsx +++ b/ui/test/dashboards/components/GraphOptionsCustomizableField.test.tsx @@ -74,7 +74,7 @@ describe('Dashboards.Components.GraphOptionsCustomizableField', () => { }) describe('instance methods', () => { - describe('#handleFieldUpdate', () => { + describe('#handleSingleFieldUpdate', () => { it('calls onFieldUpdate once with internalName, new name, and visible', () => { const onFieldUpdate = jest.fn() const internalName = 'test'