Skip to content

DetailsList: adding an optional column re-ordering feature#4857

Merged
betrue-final-final merged 20 commits intomicrosoft:masterfrom
laxmikankanala:laxmika/colreorder
Jun 21, 2018
Merged

DetailsList: adding an optional column re-ordering feature#4857
betrue-final-final merged 20 commits intomicrosoft:masterfrom
laxmikankanala:laxmika/colreorder

Conversation

@laxmikankanala
Copy link
Copy Markdown
Contributor

Pull request checklist

  • Addresses an existing issue: Fixes #0000
  • Include a change request file using $ npm run change

Description of changes

Column Reorder support in DetailsList using drag and drop
Based on the mouse position of the event, column target position will be decided.
There is an optional parameter to specify frozen columns to keep the position of those columns intact.

Pending things:

  1. Need to test this with all different options/types of DetailsList
  2. Need to fix the hit area for drag, that is being impacted by marquee selection
  3. Add CSS changes to show the drag items and drop hints

Focus areas to test

Functionality of Column reorder

@msftclas
Copy link
Copy Markdown

msftclas commented May 13, 2018

CLA assistant check
All CLA requirements met.

@dzearing dzearing changed the title Laxmika/colreorder DetailsList: adding an optional column re-ordering feature May 14, 2018
@JasonGore
Copy link
Copy Markdown
Member

This would definitely be a minor change since it touches multiple interfaces.

Please add tests for the new DetailsColumn component and consider making test cases for DetailsHeader and/or DetailsList components to exercise the new functionality. This will help ensure nobody breaks the functionality you've added. 😃

frozenColumnCount?: number;

/** Callback to handle the column reorder
* draggaedIndex is the source column index, that need to be placed in targetIndex
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

dragDropEvents={ this._getDragDropEvents() }
/>
</MarqueeSelection>
{/* <MarqueeSelection selection={ this._selection }> */ }
Copy link
Copy Markdown
Member

@JasonGore JasonGore May 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was MarqueeSelection removed? Is there a reason to leave it the codebase commented out?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted these changes in latest commit, after resolving marquee selection issue

@shre-verse
Copy link
Copy Markdown
Member

@amitdh is added to the review. #Closed

onDrop?: (item?: any, event?: DragEvent) => void;
onDragStart?: (item?: any, itemIndex?: number, selectedItems?: any[], event?: MouseEvent) => void;
onDragEnd?: (item?: any, event?: DragEvent) => void;
onDragOver?: (item?: any, event?: DragEvent) => void;
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onDragOver?: (item?: any, event?: DragEvent) => void; [](start = 2, length = 53)

Do we have to expose this in IDragDropEvents interface? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as this is the only event that gets triggered while dragging on a cell, and the drop hint status needs to be changed while crossing the 50% of cell width

&.isDropping {
background: rgb(82, 79, 79);
}
}
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this according to the UX? Or is this just a placeholder for now? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, just a placeholder


In reply to: 188871768 [](ancestors = 188871768)

>
{ column.ariaLabel }
</label>
) : null,*/
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

) : null,*/ [](start = 18, length = 11)

Please remove commented code from this file. #Closed

onClick={ this._onColumnClick.bind(this, column) }
aria-haspopup={ column.columnActionsMode === ColumnActionsMode.hasDropdown }
>
(columnReorderOptions && _isDraggable) && this._renderDropHint(columnIndex),
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

columnReorderOptions && [](start = 17, length = 23)

Required? #Closed

]
);
})
}) }
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} [](start = 13, length = 1)

Please fix formating. This should go to next line. #Closed

// TODO - Handle CSS changes
}

private _getDragDropColumnEvents(): IDragDropEvents {
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private _getDragDropColumnEvents(): IDragDropEvents [](start = 2, length = 51)

Why is this required? We can do whatever we are doing here inside IDragDropOptions. #Closed

Copy link
Copy Markdown
Member

@shre-verse shre-verse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

this._events.on(activeTarget.target.root, 'mouseleave', this._onMouseLeave.bind(this, activeTarget.target));
}
}
// To prevent marquee selection on draggable targets
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent [](start = 9, length = 10)

Or simply -
'Prevent marquee selection on draggable targets' #Closed

const { column, columnIndex, parentId } = this.props;
const { onRenderColumnHeaderTooltip = this._onRenderColumnHeaderTooltip
} = this.props;
const isDraggable = this.props.isDraggable;
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const isDraggable = this.props.isDraggable; [](start = 4, length = 43)

merge this with 2 above ? #Closed


private _onDragEnd(item?: any, event?: MouseEvent): void {
this.props.setDraggedItemIndex!(-1);
event!.preventDefault();
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event!.preventDefault(); [](start = 4, length = 24)

Why is this required? #Closed

private _updateDroppingState(newValue: boolean, event: DragEvent): void {
if ((newValue === false || this._draggedColumnIndex === -1) && event.type !== 'drop') {
const newDropHintState = this.state.dropHintsState!.map(state => false);
this.setState({ dropHintsState: newDropHintState });
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.setState({ dropHintsState: newDropHintState }); [](start = 6, length = 52)

Pass in a function instead. This way of updating the state is not reliable. #Closed

onColumnContextMenu?: (column: IColumn, ev: React.MouseEvent<HTMLElement>) => void;
dragDropHelper?: IDragDropHelper | null;
isDraggable?: boolean;
setDraggedItemIndex?: (itemIndex: number) => void;
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setDraggedItemIndex?: (itemIndex: number) => void; [](start = 2, length = 50)

Rather than this, the notification should be simple - like 'onColumnDragStart' with no params. The params (index) can be handled inside the DetailsHeader, where this callback is binded to a function. #Closed

@betrue-final-final
Copy link
Copy Markdown
Member

Hey @dzearing and @aditima, can you peeps check this one out?

Copy link
Copy Markdown
Contributor

@erichdev erichdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When dragging columns, I'm seeing a big performance hit if the drag lasts more than a ~second (i.e. try dragging for a few seconds before releasing). setState is called as you drag, forcing constant rerendering. Quick testing locally shows adding shouldComponentUpdate to DetailsHeader fixes it -- return true if dropHintsState doesn't exists or if new dropHintsState != current dropHintsState.

@laxmikankanala
Copy link
Copy Markdown
Contributor Author

@erichdev, the issue of frequent renders has been fixed in the latest commit. Now DetailsHeader will get re-rendered only when there is a change in the drop hints.

onRenderColumnHeaderTooltip = this._onRenderColumnHeaderTooltip
} = this.props;

if (!this._dragDropHelper) {
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!this._dragDropHelper) [](start = 4, length = 26)

if (!this._dragDropHelper && this.props.columenReorderOptions) {
this._dragDropHelper = new DragDropHelper();
} #Closed

this._draggedColumnIndex = -1;
}

}
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the extra line. #Closed

}

private _onDrop(item?: any, event?: DragEvent): void {
if (this._draggedColumnIndex !== -1 && event! instanceof DragEvent) {
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this._draggedColumnIndex !== -1 [](start = 8, length = 31)

A better check for 'valid' draggedColumnIndex would be a non-negative check. #Closed

let indexToUpdate = -1;
if (eventXposition <= this._dropHintOriginXValues[currentIndex]) {

indexToUpdate = currentIndex;
Copy link
Copy Markdown
Member

@shre-verse shre-verse May 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT - Extra line. #Closed

@betrue-final-final
Copy link
Copy Markdown
Member

Hey @laxmikankanala, it looks like the values are truncated way too early. That's why I rejected the screener test. Can you check that out?

@shre-verse
Copy link
Copy Markdown
Member

shre-verse commented Jun 20, 2018 via email

@betrue-final-final
Copy link
Copy Markdown
Member

I did understand that, but it looks like it's still truncating way too early.
image

Copy link
Copy Markdown
Contributor

@aditima aditima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signing off. Please have @yiminwu / @ThomasMichon and @betrue-final-final take a look and approve as well.

}
}

.GripperBarVerticalStyle {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we change to start with lowcase to match others?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

text-overflow: clip;
}

&:hover .GripperBarVerticalStyle {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GripperBarVerticalStyle [](start = 11, length = 23)

same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@laxmikankanala
Copy link
Copy Markdown
Contributor Author

@betrue-final-final, we have fixed the right padding issue. Can you please review now.

@betrue-final-final
Copy link
Copy Markdown
Member

I wasn't quite up then, but I just checked it. It was 5:30AM PST ✌️

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants