aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx')
-rw-r--r--src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx b/src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx
new file mode 100644
index 000000000..f872637e5
--- /dev/null
+++ b/src/client/views/collections/old_collectionSchema/OldCollectionSchemaMovableRow.tsx
@@ -0,0 +1,151 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action } from 'mobx';
+import * as React from 'react';
+import { ReactTableDefaults, RowInfo } from 'react-table';
+import { Doc } from '../../../../fields/Doc';
+import { Cast, FieldValue, StrCast } from '../../../../fields/Types';
+import { DocumentManager } from '../../../util/DocumentManager';
+import { DragManager, dropActionType, SetupDrag } from '../../../util/DragManager';
+import { SnappingManager } from '../../../util/SnappingManager';
+import { Transform } from '../../../util/Transform';
+import { undoBatch } from '../../../util/UndoManager';
+import { ContextMenu } from '../../ContextMenu';
+import './CollectionSchemaView.scss';
+
+export interface MovableRowProps {
+ rowInfo: RowInfo;
+ ScreenToLocalTransform: () => Transform;
+ addDoc: (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => boolean;
+ removeDoc: (doc: Doc | Doc[]) => boolean;
+ rowFocused: boolean;
+ textWrapRow: (doc: Doc) => void;
+ rowWrapped: boolean;
+ dropAction: string;
+ addDocTab: any;
+}
+
+export class MovableRow extends React.Component<React.PropsWithChildren<MovableRowProps>> {
+ private _header?: React.RefObject<HTMLDivElement> = React.createRef();
+ private _rowDropDisposer?: DragManager.DragDropDisposer;
+
+ // Event listeners are only necessary when the user is hovering over the table
+ // Create one when the mouse starts hovering...
+ onPointerEnter = (e: React.PointerEvent): void => {
+ if (e.buttons === 1 && SnappingManager.GetIsDragging()) {
+ this._header!.current!.className = 'collectionSchema-row-wrapper';
+ document.addEventListener('pointermove', this.onDragMove, true);
+ }
+ };
+ // ... and delete it when the mouse leaves
+ onPointerLeave = (e: React.PointerEvent): void => {
+ this._header!.current!.className = 'collectionSchema-row-wrapper';
+ document.removeEventListener('pointermove', this.onDragMove, true);
+ };
+ // The method for the event listener, reorders columns when dragged to their new locations.
+ onDragMove = (e: PointerEvent): void => {
+ const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+ const rect = this._header!.current!.getBoundingClientRect();
+ const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
+ const 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();
+ };
+ componentWillUnmount() {
+ this._rowDropDisposer?.();
+ }
+ //
+ createRowDropTarget = (ele: HTMLDivElement) => {
+ this._rowDropDisposer?.();
+ if (ele) {
+ this._rowDropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this));
+ }
+ };
+ // Controls what hppens when a row is dragged and dropped
+ rowDrop = (e: Event, de: DragManager.DropEvent) => {
+ this.onPointerLeave(e as any);
+ const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc));
+ if (!rowDoc) return false;
+
+ const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+ const rect = this._header!.current!.getBoundingClientRect();
+ const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
+ const before = x[1] < bounds[1];
+
+ const docDragData = de.complete.docDragData;
+ if (docDragData) {
+ e.stopPropagation();
+ if (docDragData.draggedDocuments[0] === rowDoc) return true;
+ const addDocument = (doc: Doc | Doc[]) => this.props.addDoc(doc, rowDoc, before);
+ const movedDocs = docDragData.draggedDocuments;
+ return docDragData.dropAction || docDragData.userDropAction
+ ? docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false)
+ : docDragData.moveDocument
+ ? movedDocs.reduce((added: boolean, d) => docDragData.moveDocument?.(d, rowDoc, addDocument) || added, false)
+ : docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
+ }
+ return false;
+ };
+
+ onRowContextMenu = (e: React.MouseEvent): void => {
+ const description = this.props.rowWrapped ? 'Unwrap text on row' : 'Text wrap row';
+ ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: 'file-pdf' });
+ };
+
+ @undoBatch
+ @action
+ move: DragManager.MoveFunction = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc) => {
+ const targetView = targetCollection && DocumentManager.Instance.getDocumentView(targetCollection);
+ return doc !== targetCollection && doc !== targetView?.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc);
+ };
+
+ @action
+ onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ console.log('yes');
+ if (e.key === 'Backspace' || e.key === 'Delete') {
+ undoBatch(() => this.props.removeDoc(this.props.rowInfo.original));
+ }
+ };
+
+ 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 null;
+
+ const reference = React.createRef<HTMLDivElement>();
+ const onItemDown = SetupDrag(reference, () => doc, this.move, StrCast(this.props.dropAction) as dropActionType);
+
+ let className = 'collectionSchema-row';
+ if (this.props.rowFocused) className += ' row-focused';
+ if (this.props.rowWrapped) className += ' row-wrapped';
+
+ return (
+ <div className={className} onKeyPress={this.onKeyDown} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
+ <div className="collectionSchema-row-wrapper" onKeyPress={this.onKeyDown} ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
+ <ReactTableDefaults.TrComponent onKeyPress={this.onKeyDown}>
+ <div className="row-dragger">
+ <div className="row-option" onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}>
+ <FontAwesomeIcon icon="trash" size="sm" />
+ </div>
+ <div className="row-option" style={{ cursor: 'grab' }} ref={reference} onPointerDown={onItemDown}>
+ <FontAwesomeIcon icon="grip-vertical" size="sm" />
+ </div>
+ <div className="row-option" onClick={() => this.props.addDocTab(this.props.rowInfo.original, 'add:right')}>
+ <FontAwesomeIcon icon="external-link-alt" size="sm" />
+ </div>
+ </div>
+ {children}
+ </ReactTableDefaults.TrComponent>
+ </div>
+ </div>
+ );
+ }
+}