diff options
| author | Sam Wilkins <abdullah_ahmed@brown.edu> | 2019-07-18 19:24:58 -0400 |
|---|---|---|
| committer | Sam Wilkins <abdullah_ahmed@brown.edu> | 2019-07-18 19:24:58 -0400 |
| commit | 8a1be635352177ba05845851289d1a67b4060708 (patch) | |
| tree | 787eb46da1d63036db5c2d6d4cdae37fbfc9eccd /src/client/views/collections/CollectionSchemaMovableTableHOC.tsx | |
| parent | 28420a749a0e06ee105a2d8f1cc3c273469b83d7 (diff) | |
schema cols can be moved by dragging
Diffstat (limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionSchemaMovableTableHOC.tsx | 346 |
1 files changed, 139 insertions, 207 deletions
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 44a134d31..3a61881a7 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -1,111 +1,12 @@ import React = require("react"); -import { TableProps, ReactTableDefaults, Column, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; -import { ComponentType, ComponentClass } from 'react'; -import { action } from "mobx"; +import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; import "./CollectionSchemaView.scss"; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faBars } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Transform } from "../../util/Transform"; import { Doc } from "../../../new_fields/Doc"; import { DragManager, SetupDrag } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Cast, FieldValue } from "../../../new_fields/Types"; -library.add(faBars); - -// export interface MovableSchemaProps { -// ScreenToLocalTransform: () => Transform; -// addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; -// moveDoc: DragManager.MoveFunction; -// columnsValues: string[]; -// columnsList: Column<any>[]; -// setColumnsOrder: (columns: string[]) => void; -// numImmovableColumns?: number; -// } - -// export default function CollectionSchemaMovableHOC<Props extends Partial<TableProps>>(WrappedComponent: ComponentType<Props>): ComponentClass<Props & MovableSchemaProps> { -// return class CollectionSchemaMovableSchemaHOC extends React.Component<Props & MovableSchemaProps> { -// constructor(props: any) { -// super(props); -// } - -// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { -// let columns = [...columnsValues]; -// let oldIndex = columns.indexOf(toMove); -// let relIndex = columns.indexOf(relativeTo); -// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - -// if (oldIndex === newIndex) return; - -// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); -// setColumnsOrder(columns); -// } - -// createColumns(columnsValues: string[], columnsList: Column<any>[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column<any>[] { -// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; -// return columnsList.map((col, index) => { -// if (index >= immovableIndex) { -// return col; -// } else { -// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); -// } -// }); -// } - -// render() { -// console.log("THIS IS THE RIGHT HOC"); -// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; -// return ( -// <WrappedComponent {...props as Props} ></WrappedComponent> -// ); -// } - -// }; -// } -// //TrComponent={MovableRow(ScreenToLocalTransform, addDoc, moveDoc)} -// //columns={this.createColumns(columnsValues, columnsList, setColumnsOrder, ScreenToLocalTransform)} - -// export function MovableSchemaHOC<Props extends Partial<TableProps>>(WrappedComponent: ComponentType<Props>): ComponentClass<Props & MovableSchemaProps> { -// return class MovableSchemaHOC extends React.Component<Props & MovableSchemaProps> { -// constructor(props: any) { -// super(props); -// } - -// createColumns(columnsValues: string[], columnsList: Column<any>[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column<any>[] { -// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; -// return columnsList.map((col, index) => { -// if (index >= immovableIndex) { -// return col; -// } else { -// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); -// } -// }); -// } - -// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { -// let columns = [...columnsValues]; -// let oldIndex = columns.indexOf(toMove); -// let relIndex = columns.indexOf(relativeTo); -// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - -// if (oldIndex === newIndex) return; - -// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); -// setColumnsOrder(columns); -// } - -// render() { -// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; -// return ( -// <WrappedComponent {...props as Props} columns={this.createColumns(columnsValues, columnsList, setColumnsOrder, ScreenToLocalTransform)} TrComponent={MovableRow(ScreenToLocalTransform, addDoc, moveDoc)} ></WrappedComponent> -// ); -// } -// }; -// } - - - export interface MovableColumnProps { columnRenderer: TableCellRenderer; @@ -115,147 +16,178 @@ export interface MovableColumnProps { ScreenToLocalTransform: () => Transform; } export class MovableColumn extends React.Component<MovableColumnProps> { - // private _ref: React.RefObject<HTMLDivElement> = React.createRef(); + private _header?: React.RefObject<HTMLDivElement> = React.createRef(); + private _colDropDisposer?: DragManager.DragDropDisposer; - onDragStart = (e: React.DragEvent<HTMLDivElement>, ref: React.RefObject<HTMLDivElement>): void => { - console.log("drag start"); - e.dataTransfer.setData("column", this.props.columnValue); + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.addEventListener("pointermove", this.onDragMove, true); + } } - - onDragOver = (e: React.DragEvent<HTMLDivElement>,ref: React.RefObject<HTMLDivElement>): void => { - console.log("drag over"); + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + } + onDragMove = (e: PointerEvent): void => { let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = ref.current!.getBoundingClientRect(); + let rect = this._header!.current!.getBoundingClientRect(); let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); let before = x[0] < bounds[0]; - - ref.current!.className = "collectionSchema-column-header"; - if (before) ref.current!.className += " col-before"; - if (!before) ref.current!.className += " col-after"; - // e.stopPropagation(); + this._header!.current!.className = "collectionSchema-col-wrapper"; + if (before) this._header!.current!.className += " col-before"; + if (!before) this._header!.current!.className += " col-after"; + e.stopPropagation(); } - onDragLeave = (e: React.DragEvent<HTMLDivElement>, ref: React.RefObject<HTMLDivElement>): void => { - console.log("drag leave"); - ref.current!.className = "collectionSchema-column-header"; - e.stopPropagation(); + createColDropTarget = (ele: HTMLDivElement) => { + this._colDropDisposer && this._colDropDisposer(); + if (ele) { + this._colDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.colDrop.bind(this) } }); + } } - onDrop = (e: React.DragEvent<HTMLDivElement>,ref: React.RefObject<HTMLDivElement>): void => { - console.log("on drop"); - // TODO: get column being dropped and before/after - let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = ref.current!.getBoundingClientRect(); + colDrop = (e: Event, de: DragManager.DropEvent) => { + document.removeEventListener("pointermove", this.onDragMove, true); + let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + let rect = this._header!.current!.getBoundingClientRect(); let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); let before = x[0] < bounds[0]; + if (de.data instanceof DragManager.ColumnDragData) { + this.props.reorderColumns(de.data.colKey, this.props.columnValue, before, this.props.allColumns); + return true; + } + return false; + } - this.props.reorderColumns(e.dataTransfer.getData("column"), this.props.columnValue, before, this.props.allColumns); - ref.current!.className = "collectionSchema-column-header"; + setupDrag (ref: React.RefObject<HTMLElement>) { + let onRowMove = (e: PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + let dragData = new DragManager.ColumnDragData(this.props.columnValue); + DragManager.StartColumnDrag(ref.current!, dragData, e.x, e.y); + }; + let onRowUp = (): void => { + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + }; + let onItemDown = (e: React.PointerEvent) => { + if (e.button === 0) { + e.stopPropagation(); + document.addEventListener("pointermove", onRowMove); + document.addEventListener("pointerup", onRowUp); + } + }; + return onItemDown; } + render() { - let ref: React.RefObject<HTMLDivElement> = React.createRef(); + let reference = React.createRef<HTMLDivElement>(); + let onItemDown = this.setupDrag(reference); + return ( - <div className="collectionSchema-column-header" ref={ref} draggable={true} - onPointerDown={() => console.log("pointer down")} onPointerEnter={() => console.log("pointer enter")} onPointerOut={() => console.log("pointer exit")} - onDragStart={e => this.onDragStart(e, ref)} onDragOver={e => this.onDragOver(e, ref)} onDragLeave={e => this.onDragLeave(e, ref)} onDrop={e => this.onDrop(e, ref)}> - {this.props.columnRenderer} + <div className="collectionSchema-col" ref={this.createColDropTarget}> + <div className="collectionSchema-col-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> + <div className="col-dragger" ref={reference} onPointerDown={onItemDown}> + {this.props.columnRenderer} + </div> + </div> </div> ); } } -// export function MovableColumn(columnRenderer: TableCellRenderer, columnValue: string, allColumns: string[], -// reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void, -// ScreenToLocalTransform: () => Transform) { -// return ; -// } +export interface MovableRowProps { + ScreenToLocalTransform: () => Transform; + addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; + moveDoc: DragManager.MoveFunction; +} -export function MovableRow(ScreenToLocalTransform: () => Transform, addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean, moveDoc: DragManager.MoveFunction) { - return class MovableRow extends React.Component { - private _header?: React.RefObject<HTMLDivElement> = React.createRef(); - private _treedropDisposer?: DragManager.DragDropDisposer; +export class MovableRow extends React.Component<MovableRowProps> { + private _header?: React.RefObject<HTMLDivElement> = React.createRef(); + private _rowDropDisposer?: DragManager.DragDropDisposer; - onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SelectionManager.GetIsDragging()) { - this._header!.current!.className = "collectionSchema-row-wrapper"; - document.addEventListener("pointermove", this.onDragMove, true); - } - } - onPointerLeave = (e: React.PointerEvent): void => { - this._header!.current!.className = "collectionSchema-row-wrapper"; - document.removeEventListener("pointermove", this.onDragMove, true); - } - onDragMove = (e: PointerEvent): void => { - let x = ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = this._header!.current!.getBoundingClientRect(); - let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging()) { this._header!.current!.className = "collectionSchema-row-wrapper"; - if (before) this._header!.current!.className += " row-above"; - if (!before) this._header!.current!.className += " row-below"; - e.stopPropagation(); + document.addEventListener("pointermove", this.onDragMove, true); } + } + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-row-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + } + onDragMove = (e: PointerEvent): void => { + let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + this._header!.current!.className = "collectionSchema-row-wrapper"; + if (before) this._header!.current!.className += " row-above"; + if (!before) this._header!.current!.className += " row-below"; + e.stopPropagation(); + } - createTreeDropTarget = (ele: HTMLDivElement) => { - this._treedropDisposer && this._treedropDisposer(); - if (ele) { - this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } }); - } + createRowDropTarget = (ele: HTMLDivElement) => { + this._rowDropDisposer && this._rowDropDisposer(); + if (ele) { + this._rowDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } }); } + } - treeDrop = (e: Event, de: DragManager.DropEvent) => { - const { children = null, rowInfo } = this.props; - if (!rowInfo) return false; + rowDrop = (e: Event, de: DragManager.DropEvent) => { + const { children = null, rowInfo } = this.props; + if (!rowInfo) return false; - const { original } = rowInfo; - const rowDoc = FieldValue(Cast(original, Doc)); - if (!rowDoc) return false; + const { original } = rowInfo; + const rowDoc = FieldValue(Cast(original, Doc)); + if (!rowDoc) return false; - let x = ScreenToLocalTransform().transformPoint(de.x, de.y); - let rect = this._header!.current!.getBoundingClientRect(); - let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; - if (de.data instanceof DragManager.DocumentDragData) { - e.stopPropagation(); - if (de.data.draggedDocuments[0] === rowDoc) return true; - let addDocument = (doc: Doc) => addDoc(doc, rowDoc, before); - let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); - return (de.data.dropAction || de.data.userDropAction) ? - de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before) || added, false) - : (de.data.moveDocument) ? - movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) - : de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before), false); - } - return false; + let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + if (de.data instanceof DragManager.DocumentDragData) { + e.stopPropagation(); + if (de.data.draggedDocuments[0] === rowDoc) return true; + let addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before); + let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); + return (de.data.dropAction || de.data.userDropAction) ? + de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false) + : (de.data.moveDocument) ? + movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) + : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false); } + return false; + } - render() { - const { children = null, rowInfo } = this.props; - if (!rowInfo) { - console.log("no rowinfo"); - return <ReactTableDefaults.TrComponent>{children}</ReactTableDefaults.TrComponent>; - } + render() { + const { children = null, rowInfo } = this.props; + if (!rowInfo) { + return <ReactTableDefaults.TrComponent>{children}</ReactTableDefaults.TrComponent>; + } - const { original } = rowInfo; - const doc = FieldValue(Cast(original, Doc)); - if (!doc) return <></>; + const { original } = rowInfo; + const doc = FieldValue(Cast(original, Doc)); + if (!doc) return <></>; - let reference = React.createRef<HTMLDivElement>(); - let onItemDown = SetupDrag(reference, () => doc, moveDoc); + let reference = React.createRef<HTMLDivElement>(); + let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); - return ( - <div className="collectionSchema-row" ref={this.createTreeDropTarget}> - <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> - <div className="row-dragger" ref={reference} onPointerDown={onItemDown}> - <ReactTableDefaults.TrComponent> - {children} - </ReactTableDefaults.TrComponent> - </div> + return ( + <div className="collectionSchema-row" ref={this.createRowDropTarget}> + <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> + <div className="row-dragger" ref={reference} onPointerDown={onItemDown}> + <ReactTableDefaults.TrComponent> + {children} + </ReactTableDefaults.TrComponent> </div> </div> - ); - } - }; -} - + </div> + ); + } +}
\ No newline at end of file |
