aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
diff options
context:
space:
mode:
authorSam Wilkins <abdullah_ahmed@brown.edu>2019-07-18 19:24:58 -0400
committerSam Wilkins <abdullah_ahmed@brown.edu>2019-07-18 19:24:58 -0400
commit8a1be635352177ba05845851289d1a67b4060708 (patch)
tree787eb46da1d63036db5c2d6d4cdae37fbfc9eccd /src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
parent28420a749a0e06ee105a2d8f1cc3c273469b83d7 (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.tsx346
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