From 28420a749a0e06ee105a2d8f1cc3c273469b83d7 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Thu, 18 Jul 2019 17:55:19 -0400
Subject: shema rows can be moved by dragging

---
 .../CollectionSchemaMovableTableHOC.tsx            | 261 +++++++++++++++++++++
 1 file changed, 261 insertions(+)
 create mode 100644 src/client/views/collections/CollectionSchemaMovableTableHOC.tsx

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
new file mode 100644
index 000000000..44a134d31
--- /dev/null
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -0,0 +1,261 @@
+import React = require("react");
+import { TableProps, ReactTableDefaults, Column, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table";
+import { ComponentType, ComponentClass } from 'react';
+import { action } from "mobx";
+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;
+    columnValue: string;
+    allColumns: string[];
+    reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void;
+    ScreenToLocalTransform: () => Transform;
+}
+export class MovableColumn extends React.Component<MovableColumnProps> {
+    // private _ref: React.RefObject<HTMLDivElement> = React.createRef();
+
+    onDragStart = (e: React.DragEvent<HTMLDivElement>, ref: React.RefObject<HTMLDivElement>): void => {
+        console.log("drag start");
+        e.dataTransfer.setData("column", this.props.columnValue);
+    }
+
+    onDragOver = (e: React.DragEvent<HTMLDivElement>,ref: React.RefObject<HTMLDivElement>): void => {
+        console.log("drag over");
+        let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+        let rect = ref.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();
+    }
+
+    onDragLeave = (e: React.DragEvent<HTMLDivElement>, ref: React.RefObject<HTMLDivElement>): void => {
+        console.log("drag leave");
+        ref.current!.className = "collectionSchema-column-header";
+        e.stopPropagation();
+    }
+
+    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();
+        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+        let before = x[0] < bounds[0];
+
+        this.props.reorderColumns(e.dataTransfer.getData("column"), this.props.columnValue, before, this.props.allColumns);
+        ref.current!.className = "collectionSchema-column-header";
+    }
+
+    render() {
+        let ref: React.RefObject<HTMLDivElement> =  React.createRef();
+        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>
+        );
+    }
+}
+
+// export function MovableColumn(columnRenderer: TableCellRenderer, columnValue: string, allColumns: string[],
+//     reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void,
+//     ScreenToLocalTransform: () => Transform) {
+//     return ;
+// }
+
+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;
+
+        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];
+            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) } });
+            }
+        }
+
+        treeDrop = (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;
+
+            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;
+        }
+
+        render() {
+            const { children = null, rowInfo } = this.props;
+            if (!rowInfo) {
+                console.log("no rowinfo");
+                return <ReactTableDefaults.TrComponent>{children}</ReactTableDefaults.TrComponent>;
+            }
+
+            const { original } = rowInfo;
+            const doc = FieldValue(Cast(original, Doc));
+            if (!doc) return <></>;
+
+            let reference = React.createRef<HTMLDivElement>();
+            let onItemDown = SetupDrag(reference, () => doc, 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>
+                    </div>
+                </div>
+            );
+        }
+    };
+}
+
-- 
cgit v1.2.3-70-g09d2


From 8a1be635352177ba05845851289d1a67b4060708 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Thu, 18 Jul 2019 19:24:58 -0400
Subject: schema cols can be moved by dragging

---
 src/client/util/DragManager.ts                     |  13 +
 .../CollectionSchemaMovableTableHOC.tsx            | 346 +++++++++------------
 .../views/collections/CollectionSchemaView.scss    |  15 +-
 .../views/collections/CollectionSchemaView.tsx     |  63 +---
 4 files changed, 175 insertions(+), 262 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 323908302..f9f6b05c0 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -288,6 +288,15 @@ export namespace DragManager {
         [id: string]: any;
     }
 
+    // for column dragging in schema view
+    export class ColumnDragData {
+        constructor(colKey: string) {
+            this.colKey = colKey;
+        }
+        colKey: string;
+        [id: string]: any;
+    }
+
     export function StartLinkDrag(ele: HTMLElement, dragData: LinkDragData, downX: number, downY: number, options?: DragOptions) {
         StartDrag([ele], dragData, downX, downY, options);
     }
@@ -296,6 +305,10 @@ export namespace DragManager {
         StartDrag([ele], dragData, downX, downY, options);
     }
 
+    export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?:DragOptions) {
+        StartDrag([ele], dragData, downX, downY, options);
+    }
+
     export let AbortDrag: () => void = emptyFunction;
 
     function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
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
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index fce1c8833..15dec4e44 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -161,18 +161,21 @@
     background: $light-color;
 }
 
-.collectionSchema-column-header {
+.collectionSchema-col{
     height: 100%;
     background-color: green;
 
-    &.col-before {
-        border-left: 2px solid red;
-    }
-    &.col-after {
-        border-right: 2px solid red;
+    .collectionSchema-col-wrapper {
+        &.col-before {
+            border-left: 2px solid red;
+        }
+        &.col-after {
+            border-right: 2px solid red;
+        }
     }
 }  
 
+
 .collectionSchemaView-header {
     height: 100%;
 
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 4746e637b..b9b299e13 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -62,7 +62,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     private _startPreviewWidth = 0;
     private DIVIDER_WIDTH = 4;
 
-    @observable _columns: Array<string> = ["title", "data", "author"];
+    // @observable _columns: Array<string> = ["title", "data", "author"];
     @observable _selectedIndex = 0;
     @observable _columnsPercentage = 0;
     @observable _keys: string[] = [];
@@ -76,7 +76,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
     @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); }
     @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); }
-    set columns(columns: string[]) { this.props.Document.schemaColumns = new List<string>(columns); }
+    set columns(columns: string[]) {this.props.Document.schemaColumns = new List<string>(columns); }
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
         let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1);
@@ -98,18 +98,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             />;
 
             return {
-                Header: <CollectionSchemaHeader 
-                    keyValue={col}
-                    possibleKeys={possibleKeys}
-                    existingKeys={this.columns}
-                    keyType={this.getColumnType(col)}
-                    typeConst={columnTypes.get(col) !== undefined}
-                    onSelect={this.changeColumns}
-                    setIsEditing={this.setHeaderIsEditing}
-                    deleteColumn={this.deleteColumn}
-                    setColumnType={this.setColumnType}
-                />,
-                // Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.columns} reorderColumns={this.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
+                Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.columns} reorderColumns={this.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
                 accessor: (doc: Doc) => doc ? doc[col] : 0,
                 id: col,
                 Cell: (rowProps: CellInfo) => {
@@ -159,7 +148,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         return cols;
     }
 
-    reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) {
+    @action
+    setColumns = (columns: string[]) => {
+        this.columns = columns;
+    }
+
+    reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => {
         let columns = [...columnsValues];
         let oldIndex = columns.indexOf(toMove);
         let relIndex = columns.indexOf(relativeTo);
@@ -168,7 +162,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         if (oldIndex === newIndex) return;
 
         columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
-        this.columns = columns;
+        this.setColumns(columns);
     }
 
 
@@ -200,6 +194,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             return {};
         }
         return {
+            ScreenToLocalTransform: this.props.ScreenToLocalTransform,
+            addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before),
+            moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc),
             rowInfo, 
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
                 that.props.select(e.ctrlKey);
@@ -209,10 +206,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     handleOriginal();
                 }
             }),
-            style: {
-                background: rowInfo.index === this._selectedIndex ? "lightGray" : "white",
-                //color: rowInfo.index === this._selectedIndex ? "white" : "black"
-            }
         };
     }
 
@@ -401,7 +394,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             let newTypesDoc = new Doc();
             newTypesDoc[key] = type;
             this.props.Document.schemaColumnTypes  = newTypesDoc;
-            console.log("no typesDoc");
             return;
         } else {
             typesDoc[key] = type;
@@ -478,31 +470,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
     @computed
     get reactTable() {
-        let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
-        let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
         let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
-
-        // return <MovableTable
-        //     style={{ position: "relative", float: "left", width: `calc(100% - ${previewWidth}px` }}
-        //     data={this.childDocs}
-        //     page={0}
-        //     pageSize={this.childDocs.length}
-        //     showPagination={false}
-        //     columns={this.tableColumns}
-        //     sortable={false}
-        //     getTrProps={this.getTrProps}
-
-        //     ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-        //     addDoc={addDoc}
-        //     moveDoc={moveDoc}
-        //     columnsValues={this.columns}
-        //     columnsList={this.tableColumns}
-        //     setColumnsOrder={(columns: string[]) => this.columns = columns}
-        //     numImmovableColumns={1}
-        // />;
-
-
-        // // let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
         return <ReactTable 
             style={{ position: "relative", float: "left", width: `calc(100% - ${previewWidth}px` }} 
             data={this.childDocs} 
@@ -510,11 +478,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             pageSize={this.childDocs.length} 
             showPagination={false}
             columns={this.tableColumns}
-            // column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }}
             getTrProps={this.getTrProps}
             sortable={false}
-
-            TrComponent={MovableRow(this.props.ScreenToLocalTransform, addDoc, moveDoc)}
+            TrComponent={MovableRow}
         />;
     }
 
@@ -566,7 +532,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} onWheel={this.onWheel}
                 onDrop={(e: React.DragEvent) => this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}>
-                    <div draggable={true} style={{backgroundColor: "green"}}>TESTER</div>
                 {this.reactTable}
                 {this.dividerDragger}
                 {!this.previewWidth() ? (null) : this.previewPanel}
-- 
cgit v1.2.3-70-g09d2


From 8515b6957f075f8ae7e88243ab5a4c7cb8fff3b6 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Mon, 22 Jul 2019 14:49:57 -0400
Subject: removed fixed row height

---
 .../views/collections/CollectionSchemaCells.tsx    | 103 +++++++++++----------
 .../CollectionSchemaMovableTableHOC.tsx            |   5 +-
 .../views/collections/CollectionSchemaView.scss    |  67 +++++++++-----
 .../views/collections/CollectionSchemaView.tsx     |  45 +++++----
 4 files changed, 126 insertions(+), 94 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 55185e30e..2dd3eeff4 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -20,6 +20,7 @@ import { CollectionView } from "./CollectionView";
 import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types";
 import { Docs } from "../../documents/Documents";
 import { DocumentContentsView } from "../nodes/DocumentContentsView";
+import { SelectionManager } from "../../util/SelectionManager";
 
 
 export interface CellProps {
@@ -118,6 +119,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     }
 
     renderCellWithType(type: string | undefined) {
+        let dragRef: React.RefObject<HTMLDivElement> = React.createRef();
+
         let props: FieldViewProps = {
             Document: this.props.rowProps.original,
             DataDoc: this.props.rowProps.original,
@@ -136,10 +139,19 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             PanelWidth: returnZero,
             addDocTab: this.props.addDocTab,
         };
+
         let onItemDown = (e: React.PointerEvent) => {
             SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
                 this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
         };
+        let onPointerEnter = (e: React.PointerEvent): void => {
+            if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) {
+                dragRef!.current!.className = "doc-drag-over";
+            }
+        };
+        let onPointerLeave = (e: React.PointerEvent): void => {
+            dragRef!.current!.className = "";
+        };
 
         let field = props.Document[props.fieldKey];
         let contents: any = "incorrect type";
@@ -153,40 +165,42 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         }
 
         return (
-            <div className="collectionSchemaView-cellWrapper" ref={this._focusRef} tabIndex={-1} onPointerDown={this.onPointerDown}>
-                <div className="collectionSchemaView-cellContents" ref={this.dropRef} onPointerDown={onItemDown} key={props.Document[Id]}>
-                    <EditableView
-                        editing={this._isEditing}
-                        isEditingCallback={this.isEditingCallback}
-                        display={"inline"}
-                        contents={contents}
-                        height={Number(MAX_ROW_HEIGHT)}
-                        GetValue={() => {
-                            let field = props.Document[props.fieldKey];
-                            if (Field.IsField(field)) {
-                                return Field.toScriptString(field);
+            <div className="" ref={dragRef} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
+                <div className="collectionSchemaView-cellWrapper" ref={this._focusRef} tabIndex={-1} onPointerDown={this.onPointerDown}>
+                    <div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef: null} onPointerDown={onItemDown} key={props.Document[Id]}>
+                        <EditableView
+                            editing={this._isEditing}
+                            isEditingCallback={this.isEditingCallback}
+                            display={"inline"}
+                            contents={contents}
+                            height={Number(MAX_ROW_HEIGHT)}
+                            GetValue={() => {
+                                let field = props.Document[props.fieldKey];
+                                if (Field.IsField(field)) {
+                                    return Field.toScriptString(field);
+                                }
+                                return "";
                             }
-                            return "";
-                        }
-                        }
-                        SetValue={(value: string) => {
-                            let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
-                            if (!script.compiled) {
-                                return false;
                             }
-                            return this.applyToDoc(props.Document, script.run);
-                        }}
-                        OnFillDown={async (value: string) => {
-                            let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
-                            if (!script.compiled) {
-                                return;
-                            }
-                            const run = script.run;
-                            //TODO This should be able to be refactored to compile the script once
-                            const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
-                            val && val.forEach(doc => this.applyToDoc(doc, run));
-                        }} />
-                </div >
+                            SetValue={(value: string) => {
+                                let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
+                                if (!script.compiled) {
+                                    return false;
+                                }
+                                return this.applyToDoc(props.Document, script.run);
+                            }}
+                            OnFillDown={async (value: string) => {
+                                let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
+                                if (!script.compiled) {
+                                    return;
+                                }
+                                const run = script.run;
+                                //TODO This should be able to be refactored to compile the script once
+                                const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
+                                val && val.forEach(doc => this.applyToDoc(doc, run));
+                            }} />
+                    </div >
+                </div>
             </div>
         );
     }
@@ -217,6 +231,13 @@ export class CollectionSchemaStringCell extends CollectionSchemaCell {
     }
 }
 
+@observer
+export class CollectionSchemaDocCell extends CollectionSchemaCell {
+    render() {
+        return this.renderCellWithType("document");
+    }
+}
+
 @observer
 export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
     @observable private _isChecked: boolean = typeof this.props.rowProps.original[this.props.rowProps.column.id as string] === "boolean" ? BoolCast(this.props.rowProps.original[this.props.rowProps.column.id as string]) : false;
@@ -245,21 +266,3 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
         );
     }
 }
-
-@observer
-export class CollectionSchemaDocCell extends CollectionSchemaCell {
-    render() {
-        return this.renderCellWithType("document");
-        // let reference = React.createRef<HTMLDivElement>();
-        // let onItemDown = (e: React.PointerEvent) => {
-        //     // (!this.props.CollectionView.props.isSelected() ? undefined :
-        //     //     SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e));
-        // };
-        // return (
-        //     <div className="collectionSchemaView-cellWrapper" ref={this._focusRef} tabIndex={-1} onPointerDown={this.onPointerDown}>
-        //         <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} key={this._document[Id]} ref={reference}>
-        //         </div >
-        //     </div>
-        // );
-    }
-}
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 3a61881a7..8ed71d70f 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -105,6 +105,7 @@ export interface MovableRowProps {
     ScreenToLocalTransform: () => Transform;
     addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
     moveDoc: DragManager.MoveFunction;
+    rowFocused: boolean;
 }
 
 export class MovableRow extends React.Component<MovableRowProps> {
@@ -178,8 +179,10 @@ export class MovableRow extends React.Component<MovableRowProps> {
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc);
 
+        console.log("row focused", this.props.rowFocused);
+
         return (
-            <div className="collectionSchema-row" ref={this.createRowDropTarget}>
+            <div className={this.props.rowFocused ? "collectionSchema-row row-focused" : "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>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index e511bc1bd..ef93e381b 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -11,6 +11,7 @@
     height: calc(100% - 25px);
     // overflow: hidden;
     overflow-x: scroll;
+    border: none;
 
     .collectionSchemaView-previewRegion {
         position: relative;
@@ -70,10 +71,11 @@
 
     .rt-thead {
         &.-header {
-            background: $intermediate-color;
-            color: $light-color;
+            // background: $intermediate-color;
+            // color: $light-color;
             font-size: 12px;
             height: 30px;
+            border: 1px solid $intermediate-color;
         }
 
         .rt-resizable-header {
@@ -89,11 +91,14 @@
             height: 100%;
             overflow: visible;
         }
+
+        .rt-th {
+            padding: 0;
+        }
     }
 
     .rt-th {
-        max-height: $MAX_ROW_HEIGHT;
-        padding: 3px 7px;
+        // max-height: $MAX_ROW_HEIGHT;
         font-size: 13px;
         text-align: center;
         
@@ -108,16 +113,17 @@
 
     .rt-tr-group {
         direction: ltr;
-        max-height: $MAX_ROW_HEIGHT;
+        flex: 0 1 auto;
+        // max-height: $MAX_ROW_HEIGHT;
         // for sub comp
 
-        &:nth-child(even) {
-            background-color: $light-color;
-        }
+        // &:nth-child(even) {
+        //     background-color: $light-color;
+        // }
     
-        &:nth-child(odd) {
-            background-color: $light-color-secondary;
-        }
+        // &:nth-child(odd) {
+        //     background-color: $light-color-secondary;
+        // }
 
         &:last-child {
             border-bottom: $intermediate-color;
@@ -128,13 +134,13 @@
 
     .rt-tr {
         width: 100%;
-        height: $MAX_ROW_HEIGHT;
+        // height: $MAX_ROW_HEIGHT;
     }
 
     .rt-td {
         border-width: 1px;
         border-right-color: $intermediate-color;
-        max-height: $MAX_ROW_HEIGHT;
+        // max-height: $MAX_ROW_HEIGHT;
         padding: 0;
         font-size: 13px;
         text-align: center;
@@ -184,6 +190,7 @@
 
 .collectionSchemaView-header {
     height: 100%;
+    color: $intermediate-color;
 
     .collectionSchema-header-menu {
         height: 100%;
@@ -223,10 +230,6 @@
         position: relative;
         max-width: 175px;
 
-        // .keys-search {
-
-        // }
-
         .keys-options-wrapper {
             width: 100%;
             max-height: 150px;
@@ -261,17 +264,18 @@
 }
 
 .collectionSchema-row {
-    height: $MAX_ROW_HEIGHT;
-    // display: flex;
+    // height: $MAX_ROW_HEIGHT;
+
+    &.row-focused {
+        background-color: $light-color-secondary;
+    }
 
     .row-dragger {
-        height: $MAX_ROW_HEIGHT;
+        // height: $MAX_ROW_HEIGHT;
     }
 
     .collectionSchema-row-wrapper {
-        max-height: $MAX_ROW_HEIGHT;
-        // width: 100%;
-        // border: 1px solid lightgray;
+        // max-height: $MAX_ROW_HEIGHT;
 
         &.row-above {
             border-top: 1px solid red;
@@ -287,8 +291,6 @@
 
 
 .collectionSchemaView-cellWrapper {
-    // height: $MAX_ROW_HEIGHT;
-    // background-color: red;
     height: 100%;
     padding: 4px;
 
@@ -311,6 +313,21 @@
             border: none;
         }
     }
+
+    p {
+        width: 100%;
+        height: 100%;
+        word-wrap: break-word;
+    }
+}
+
+.doc-drag-over {
+    background-color: red;
+}
+
+.collectionSchemaView-toolbar {
+    display: flex;
+    justify-content: flex-end;
 }
 
 #preview-schema-checkbox-div {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index ea09926d4..a1251b028 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -81,6 +81,21 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
         let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1);
+        let columns: Column<Doc>[] = [
+            {
+            expander: true,
+            Header: "",
+            width: 45,
+            Expander: (rowInfo) => {
+                if (rowInfo.original.type === "collection") {
+                    return <div>+</div>;
+                } else {
+                    return null;
+                }
+            }
+        }
+        ];
+        
         let cols = this.columns.map(col => {
             let focusedRow = this._focusedCell.row;
             let focusedCol = this._focusedCell.col;
@@ -139,22 +154,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 },
                 minWidth: 200,
             };
-        }) as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult<Field>, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[];
-
-        // cols.push({
-        //     expander: true,
-        //     Header: "",
-        //     width: 45,
-        //     Expander: (rowInfo) => {
-        //         if (rowInfo.original.type === "collection") {
-        //             return <div>+</div>;
-        //         } else {
-        //             return null;
-        //         }
-        //     }
-        // });
-
-        cols.push({
+        });// as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult<Field>, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[];
+        columns.push(...cols);
+
+        columns.push({
             Header: <CollectionSchemaAddColumnHeader
                 createColumn={this.createColumn}
                 // possibleKeys={possibleKeys}
@@ -171,7 +174,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
         // SubComponent={row => row.original.type === "collection" && <div>SUB</div>}
 
-        return cols;
+        return columns;
     }
 
     // onHeaderDrag = (columnName: string) => {
@@ -201,11 +204,17 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         if (!rowInfo) {
             return {};
         }
+        let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false;
         return {
             ScreenToLocalTransform: this.props.ScreenToLocalTransform,
             addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before),
             moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc),
             rowInfo, 
+            rowFocused: !this._headerIsEditing && isSelected && rowInfo.index === this._focusedCell.row,
+            // style: {
+            //     background: rowInfo.index === this._focusedCell.row ? "lightGray" : "white",
+            //     //color: rowInfo.index === this._selectedIndex ? "white" : "black"
+            // }
             // onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
             //     that.props.select(e.ctrlKey);
             //     that._selectedIndex = rowInfo.index;
@@ -486,7 +495,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             sortable={false}
             TrComponent={MovableRow}
             sorted={Array.from(this._sortedColumns.values())}
-            // SubComponent={row => row.original.type === "collection" && <div>this is the sub component</div>}
+            SubComponent={row => row.original.type === "collection" && <div>this is the sub component</div>}
         />;
 
 
-- 
cgit v1.2.3-70-g09d2


From d3edc59402efb5d8ada602305a95a7a3a7f0ba95 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Mon, 22 Jul 2019 17:08:46 -0400
Subject: can have expanded collection in schema

---
 .../CollectionSchemaMovableTableHOC.tsx            |  2 -
 .../views/collections/CollectionSchemaView.scss    |  9 ++-
 .../views/collections/CollectionSchemaView.tsx     | 93 ++++++++++------------
 3 files changed, 51 insertions(+), 53 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 8ed71d70f..db60e657a 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -179,8 +179,6 @@ export class MovableRow extends React.Component<MovableRowProps> {
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc);
 
-        console.log("row focused", this.props.rowFocused);
-
         return (
             <div className={this.props.rowFocused ? "collectionSchema-row row-focused" : "collectionSchema-row"} ref={this.createRowDropTarget}>
                 <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index ef93e381b..4b20e8241 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -6,9 +6,9 @@
     border-style: solid;
     border-radius: $border-radius;
     box-sizing: border-box;
-    position: absolute;
+    // position: absolute;
     width: 100%;
-    height: calc(100% - 25px);
+    // height: calc(100% - 25px);
     // overflow: hidden;
     overflow-x: scroll;
     border: none;
@@ -333,4 +333,9 @@
 #preview-schema-checkbox-div {
     margin-left: 20px;
     font-size: 12px;
+}
+
+.sub {
+    padding: 20px;
+    background-color: red;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a1251b028..25e90a25e 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -61,7 +61,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     private _startPreviewWidth = 0;
     private DIVIDER_WIDTH = 4;
 
-    // @observable _selectedIndex = 0;
     @observable _columnsPercentage = 0;
     @observable _keys: string[] = [];
     @observable _newKeyName: string = "";
@@ -70,8 +69,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @observable _cellIsEditing: boolean = false;
     @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0};
     @observable _sortedColumns: Map<string, {id: string, desc: boolean}> = new Map();
+    @observable _openCollections: Array<Doc> = [];
     @observable private _node : HTMLDivElement | null = null;
-    // @observable _schemaIsFocused: boolean = 
 
     @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); }
     @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
@@ -81,27 +80,30 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
         let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1);
-        let columns: Column<Doc>[] = [
-            {
-            expander: true,
-            Header: "",
-            width: 45,
-            Expander: (rowInfo) => {
-                if (rowInfo.original.type === "collection") {
-                    return <div>+</div>;
-                } else {
-                    return null;
+        let columns: Column<Doc>[] = [];
+
+        if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) {
+            columns.push(
+                {
+                    expander: true,
+                    Header: "",
+                    width: 45,
+                    Expander: (rowInfo) => {
+                        if (rowInfo.original.type === "collection") {
+                            if (rowInfo.isExpanded) return <div onClick={() => this.onCloseCollection(rowInfo.original)}>-</div>;
+                            if (!rowInfo.isExpanded) return <div onClick={() => this.onExpandCollection(rowInfo.original)}>+</div>;
+                        } else {
+                            return null;
+                        }
+                    }
                 }
-            }
+            );
         }
-        ];
         
         let cols = this.columns.map(col => {
             let focusedRow = this._focusedCell.row;
             let focusedCol = this._focusedCell.col;
-            let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false;
-            let isEditable = !this._headerIsEditing && (isSelected);// || BoolCast(this.props.Document.libraryBrush));
-            console.log(BoolCast(this.props.Document.libraryBrush), isSelected);
+            let isEditable = !this._headerIsEditing && this.props.isSelected();// || BoolCast(this.props.Document.libraryBrush));
 
             let header = <CollectionSchemaHeader 
                 keyValue={col}
@@ -146,34 +148,23 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     let colType = this.getColumnType(col);
                     if (colType === ColumnType.Number) return <CollectionSchemaNumberCell {...props}/>;
                     if (colType === ColumnType.String) return <CollectionSchemaStringCell {...props}/>;
-                    // if (colType === ColumnType.Boolean) return <CollectionSchemaBooleanCell {...props} />;
-                    // if (colType === ColumnType.Checkbox) return <CollectionSchemaCheckboxCell {...props} />;
                     if (colType === ColumnType.Boolean) return <CollectionSchemaCheckboxCell {...props} />;
                     if (colType === ColumnType.Doc) return <CollectionSchemaDocCell {...props} />;
                     return <CollectionSchemaCell {...props}/>;
                 },
                 minWidth: 200,
             };
-        });// as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult<Field>, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[];
+        });
         columns.push(...cols);
 
         columns.push({
-            Header: <CollectionSchemaAddColumnHeader
-                createColumn={this.createColumn}
-                // possibleKeys={possibleKeys}
-                // existingKeys={this.columns}
-                // onSelect={this.changeColumns}
-                // setIsEditing={this.setHeaderIsEditing}
-            />,
+            Header: <CollectionSchemaAddColumnHeader createColumn={this.createColumn} />,
             accessor: (doc: Doc) => 0,
             id: "add",
             Cell: (rowProps: CellInfo) => <></>,
             width: 45,
             resizable: false
         });
-
-        // SubComponent={row => row.original.type === "collection" && <div>SUB</div>}
-
         return columns;
     }
 
@@ -204,25 +195,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         if (!rowInfo) {
             return {};
         }
-        let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false;
         return {
             ScreenToLocalTransform: this.props.ScreenToLocalTransform,
             addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before),
             moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc),
             rowInfo, 
-            rowFocused: !this._headerIsEditing && isSelected && rowInfo.index === this._focusedCell.row,
-            // style: {
-            //     background: rowInfo.index === this._focusedCell.row ? "lightGray" : "white",
-            //     //color: rowInfo.index === this._selectedIndex ? "white" : "black"
-            // }
-            // onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
-            //     that.props.select(e.ctrlKey);
-            //     that._selectedIndex = rowInfo.index;
-
-            //     if (handleOriginal) {
-            //         handleOriginal();
-            //     }
-            // }),
+            rowFocused: !this._headerIsEditing && this.props.isSelected() && rowInfo.index === this._focusedCell.row,
         };
     }
 
@@ -239,6 +217,17 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     //     }
     // }
 
+    @action
+    onExpandCollection = (collection: Doc): void => {
+        this._openCollections.push(collection);
+    }
+
+    @action
+    onCloseCollection = (collection: Doc): void => {
+        let index = this._openCollections.findIndex(col => col === collection);
+        if (index > -1) this._openCollections.splice(index, 1);
+    }
+
     @action
     setCellIsEditing = (isEditing: boolean): void => {
         this._cellIsEditing = isEditing;
@@ -296,8 +285,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     }
 
     onKeyDown = (e: KeyboardEvent): void => {
-        let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false;
-        if (!this._cellIsEditing && !this._headerIsEditing && isSelected) {
+        if (!this._cellIsEditing && !this._headerIsEditing && this.props.isSelected()) {
             let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this.changeFocusedCellByDirection(direction);
         }
@@ -457,7 +445,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed
     get previewDocument(): Doc | undefined {
         let selectedIndex = this._focusedCell.row;
-        console.log("preview", selectedIndex);
         const selected = this.childDocs.length > selectedIndex ? this.childDocs[selectedIndex] : undefined;
         let pdc = selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined;
         return pdc;
@@ -484,6 +471,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed
     get reactTable() {
         let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
+        let hasCollectionChild = this.childDocs.reduce((found, doc) => found || doc.type === "collection", false);
+        let expandedRowsList = this._openCollections.map(col => this.childDocs.findIndex(doc => doc === col).toString());
+        let expanded = {};
+        expandedRowsList.forEach(row => expanded[row] = true);
+
         return <ReactTable 
             style={{ position: "relative", float: "left", width: `calc(100% - ${previewWidth}px` }} 
             data={this.childDocs} 
@@ -494,8 +486,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             getTrProps={this.getTrProps}
             sortable={false}
             TrComponent={MovableRow}
-            sorted={Array.from(this._sortedColumns.values())}
-            SubComponent={row => row.original.type === "collection" && <div>this is the sub component</div>}
+            sorted={Array.from(this._sortedColumns.values())}    
+            expanded={expanded}       
+            SubComponent={hasCollectionChild ? row => row.original.type === "collection" && 
+            <div className="sub"><CollectionSchemaView {...this.props} Document={row.original} /></div> : undefined}
+            
         />;
 
 
-- 
cgit v1.2.3-70-g09d2


From 7d9958f23b2b69f59bb108b33ec014b52ad41c99 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Tue, 23 Jul 2019 19:11:17 -0400
Subject: merge

---
 .../collections/CollectionSchemaMovableTableHOC.tsx | 10 ++++++----
 .../views/collections/CollectionSchemaView.tsx      | 21 +++++++++++++++++----
 2 files changed, 23 insertions(+), 8 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index db60e657a..6fc04849c 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -5,7 +5,7 @@ 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";
+import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
 
 
 export interface MovableColumnProps {
@@ -152,15 +152,17 @@ export class MovableRow extends React.Component<MovableRowProps> {
         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) ?
+            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)
+                    movedDocs.reduce((added: boolean, d) =>  de.data.moveDocument(d, rowDoc, addDocument) || added, false)
+                    // movedDocs.reduce((added: boolean, d) => this.props.moveDoc(d, rowDoc, addDocument) || added, false)
                     : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
         }
         return false;
@@ -177,7 +179,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
         if (!doc) return <></>;
 
         let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc);
+        let onItemDown = SetupDrag(reference, () => doc);
 
         return (
             <div className={this.props.rowFocused ? "collectionSchema-row row-focused" : "collectionSchema-row"} ref={this.createRowDropTarget}>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 5546feb95..6d71823c2 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -95,6 +95,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         this._focusedTable = doc;
     }
 
+    @action
+    setPreviewDoc = (doc: Doc): void => {
+        this.previewDoc = doc;
+    }
 
     //toggles preview side-panel of schema
     @action
@@ -384,6 +388,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         document.removeEventListener("keydown", this.onKeyDown);
     }
 
+    tableAddDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
+        console.log("table add doc");
+        return Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
+    }
+
+    tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
+        console.log("SCHEMA MOVE"); 
+        this.props.moveDocument(d, target, addDoc);
+    }
+
     private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
         const that = this;
         if (!rowInfo) {
@@ -391,8 +405,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         }
         return {
             ScreenToLocalTransform: this.props.ScreenToLocalTransform,
-            addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before),
-            moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc),
+            addDoc: this.tableAddDoc,
+            moveDoc: this.tableMoveDoc,
             rowInfo, 
             rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document)
         };
@@ -654,7 +668,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     render() {
-        if (this.props.isFocused(this.props.Document)) console.log(StrCast(this.props.Document.title), "IS FOCUSED");
         // if (SelectionManager.SelectedDocuments().length > 0) console.log(StrCast(SelectionManager.SelectedDocuments()[0].Document.title));
         // if (DocumentManager.Instance.getDocumentView(this.props.Document)) console.log(StrCast(this.props.Document.title), SelectionManager.IsSelected(DocumentManager.Instance.getDocumentView(this.props.Document)!))
         return (
@@ -669,7 +682,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
 interface CollectionSchemaPreviewProps {
     Document?: Doc;
-    DataDocument?: Doc;
+    DataDocument?: Doc; 
     childDocs?: Doc[];
     renderDepth: number;
     fitToBox?: boolean;
-- 
cgit v1.2.3-70-g09d2


From 07e4ad670134213afc019bf84f765cdfc00a510a Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Wed, 24 Jul 2019 12:28:17 -0400
Subject: can text wrap row via context menu

---
 .../CollectionSchemaMovableTableHOC.tsx            | 34 +++++++++++++++-------
 .../views/collections/CollectionSchemaView.scss    |  8 ++++-
 .../views/collections/CollectionSchemaView.tsx     | 28 ++++++++++++++----
 3 files changed, 53 insertions(+), 17 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 6fc04849c..beae739ec 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -1,11 +1,12 @@
 import React = require("react");
-import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table";
+import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0, RowInfo } from "react-table";
 import "./CollectionSchemaView.scss";
 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, StrCast } from "../../../new_fields/Types";
+import { ContextMenu } from "../ContextMenu";
 
 
 export interface MovableColumnProps {
@@ -60,7 +61,7 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         return false;
     }
 
-    setupDrag (ref: React.RefObject<HTMLElement>) {
+    setupDrag(ref: React.RefObject<HTMLElement>) {
         let onRowMove = (e: PointerEvent) => {
             e.stopPropagation();
             e.preventDefault();
@@ -102,10 +103,13 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
 }
 
 export interface MovableRowProps {
+    rowInfo: RowInfo;
     ScreenToLocalTransform: () => Transform;
     addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
     moveDoc: DragManager.MoveFunction;
     rowFocused: boolean;
+    textWrapRow: (doc: Doc) => void;
+    rowWrapped: boolean;
 }
 
 export class MovableRow extends React.Component<MovableRowProps> {
@@ -141,11 +145,10 @@ export class MovableRow extends React.Component<MovableRowProps> {
     }
 
     rowDrop = (e: Event, de: DragManager.DropEvent) => {
-        const { children = null, rowInfo } = this.props;
-        if (!rowInfo) return false;
+        // const { children = null, rowInfo } = this.props;
+        // if (!rowInfo) return false;
 
-        const { original } = rowInfo;
-        const rowDoc = FieldValue(Cast(original, Doc));
+        const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc));
         if (!rowDoc) return false;
 
         let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
@@ -158,16 +161,23 @@ export class MovableRow extends React.Component<MovableRowProps> {
             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) ? 
+            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)
+                    movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false)
                     // movedDocs.reduce((added: boolean, d) => this.props.moveDoc(d, rowDoc, addDocument) || added, false)
                     : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
         }
         return false;
     }
 
+    onRowContextMenu = (e: React.MouseEvent): void => {
+        // const { rowInfo } = this.props;
+        // const { textWrapRow, original } = rowInfo;
+        let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
+        ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original) });
+    }
+
     render() {
         const { children = null, rowInfo } = this.props;
         if (!rowInfo) {
@@ -179,10 +189,14 @@ export class MovableRow extends React.Component<MovableRowProps> {
         if (!doc) return <></>;
 
         let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = SetupDrag(reference, () => doc);
+        let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc);
+
+        let className = "collectionSchema-row";
+        if (this.props.rowFocused) className += " row-focused";
+        if (this.props.rowWrapped) className += " row-wrapped";
 
         return (
-            <div className={this.props.rowFocused ? "collectionSchema-row row-focused" : "collectionSchema-row"} ref={this.createRowDropTarget}>
+            <div className={className} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
                 <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
                     <div className="row-dragger" ref={reference} onPointerDown={onItemDown}>
                         <ReactTableDefaults.TrComponent>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 38d14c2de..410790197 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -148,7 +148,7 @@
         padding: 0;
         font-size: 13px;
         text-align: center;
-        white-space: normal;
+        // white-space: normal;
 
         .imageBox-cont {
             position: relative;
@@ -287,6 +287,12 @@ button.add-column {
         background-color: $light-color-secondary;
     }
 
+    &.row-wrapped {
+        .rt-td {
+            white-space: normal;
+        }
+    }
+
     .row-dragger {
         // height: $MAX_ROW_HEIGHT;
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 0e2d37a9e..62e4ceb54 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -53,6 +53,7 @@ export enum ColumnType {
 }
 // this map should be used for keys that should have a const type of value
 const columnTypes: Map<string, ColumnType> = new Map([
+    ["title", ColumnType.String],
     ["x", ColumnType.Number], ["y", ColumnType.Number], ["width", ColumnType.Number], ["height", ColumnType.Number],
     ["nativeWidth", ColumnType.Number], ["nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean],
     ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["libraryBrush", ColumnType.Boolean], ["zIndex", ColumnType.Number]
@@ -268,7 +269,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @observable _cellIsEditing: boolean = false;
     @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 };
     @observable _sortedColumns: Map<string, { id: string, desc: boolean }> = new Map();
-    @observable _openCollections: Array<Doc> = [];
+    @observable _openCollections: Array<string> = [];
+    @observable _textWrappedRows: Array<string> = [];
     @observable private _node: HTMLDivElement | null = null;
 
     @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); }
@@ -396,7 +398,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
-        console.log("SCHEMA MOVE");
+        console.log("SCHEMA MOVE", StrCast(d.title), StrCast(target.title));
         this.props.moveDocument(d, target, addDoc);
     }
 
@@ -410,7 +412,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             addDoc: this.tableAddDoc,
             moveDoc: this.tableMoveDoc,
             rowInfo,
-            rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document)
+            rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
+            textWrapRow: this.textWrapRow,
+            rowWrapped: this._textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1
         };
     }
 
@@ -429,12 +433,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     onExpandCollection = (collection: Doc): void => {
-        this._openCollections.push(collection);
+        this._openCollections.push(collection[Id]);
     }
 
     @action
     onCloseCollection = (collection: Doc): void => {
-        let index = this._openCollections.findIndex(col => col === collection);
+        let index = this._openCollections.findIndex(col => col === collection[Id]);
         if (index > -1) this._openCollections.splice(index, 1);
     }
 
@@ -610,13 +614,25 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return Array.from(Object.keys(keys));
     }
 
+    @action
+    textWrapRow = (doc: Doc): void => {
+        let index = this._textWrappedRows.findIndex(id => doc[Id] === id);
+        if (index > -1) {
+            this._textWrappedRows.splice(index, 1);
+        } else {
+            this._textWrappedRows.push(doc[Id]);
+        }
+
+    }
+
     @computed
     get reactTable() {
         let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
         let hasCollectionChild = this.props.childDocs.reduce((found, doc) => found || doc.type === "collection", false);
-        let expandedRowsList = this._openCollections.map(col => this.props.childDocs.findIndex(doc => doc === col).toString());
+        let expandedRowsList = this._openCollections.map(col => this.props.childDocs.findIndex(doc => doc[Id] === col).toString());
         let expanded = {};
         expandedRowsList.forEach(row => expanded[row] = true);
+        console.log(...[...this._textWrappedRows]); // TODO: get component to rerender on text wrap change without needign to console.log :((((
 
         return <ReactTable
             style={{ position: "relative", float: "left", width: `calc(100% - ${previewWidth}px` }}
-- 
cgit v1.2.3-70-g09d2


From 75070c4c2188823ed9a09816861d4f873574c9db Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Wed, 24 Jul 2019 17:48:11 -0400
Subject: can move rows within expanded collection

---
 src/client/util/DragManager.ts                     |  4 +--
 .../views/collections/CollectionSchemaCells.tsx    | 42 ++++++++++++----------
 .../CollectionSchemaMovableTableHOC.tsx            | 18 +++++-----
 .../views/collections/CollectionSchemaView.scss    | 24 ++++++-------
 .../views/collections/CollectionSchemaView.tsx     | 17 +++++----
 src/new_fields/Doc.ts                              |  9 ++++-
 6 files changed, 64 insertions(+), 50 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index f9f6b05c0..0299b1d90 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,6 +1,6 @@
 import { action, runInAction } from "mobx";
 import { Doc } from "../../new_fields/Doc";
-import { Cast } from "../../new_fields/Types";
+import { Cast, StrCast } from "../../new_fields/Types";
 import { URLField } from "../../new_fields/URLField";
 import { emptyFunction } from "../../Utils";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
@@ -305,7 +305,7 @@ export namespace DragManager {
         StartDrag([ele], dragData, downX, downY, options);
     }
 
-    export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?:DragOptions) {
+    export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?: DragOptions) {
         StartDrag([ele], dragData, downX, downY, options);
     }
 
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index abb2203a0..bc84da140 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -34,7 +34,7 @@ export interface CellProps {
     renderDepth: number;
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
     moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
-    isFocused: boolean; 
+    isFocused: boolean;
     changeFocusedCellByIndex: (row: number, col: number) => void;
     setIsEditing: (isEditing: boolean) => void;
     isEditable: boolean;
@@ -42,22 +42,22 @@ export interface CellProps {
 
 @observer
 export class CollectionSchemaCell extends React.Component<CellProps> {
-    @observable protected _isEditing: boolean = false;
+    @observable protected _isEditing: boolean = this.props.isEditing ? true : false;
     protected _focusRef = React.createRef<HTMLDivElement>();
     protected _document = this.props.rowProps.original;
     private _dropDisposer?: DragManager.DragDropDisposer;
 
     componentDidMount() {
-        if (this._focusRef.current) {
-            if (this.props.isFocused) {
-                this._focusRef.current.className += " focused";
-                if (!this.props.isEditable) {
-                    this._focusRef.current.className += " inactive";
-                }
-            } else {
-                this._focusRef.current.className = "collectionSchemaView-cellWrapper";
-            }
-        }
+        // if (this._focusRef.current) {
+        //     if (this.props.isFocused) {
+        //         this._focusRef.current.className += " focused";
+        //         if (!this.props.isEditable) {
+        //             this._focusRef.current.className += " inactive";
+        //         }
+        //     } else {
+        //         this._focusRef.current.className = "collectionSchemaView-cellWrapper";
+        //     }
+        // }
 
         document.addEventListener("keydown", this.onKeyDown);
 
@@ -69,6 +69,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
 
     @action
     onKeyDown = (e: KeyboardEvent): void => {
+        console.log("CELL keydown");
         if (this.props.isFocused && this.props.isEditable) {
             document.removeEventListener("keydown", this.onKeyDown);
             this._isEditing = true;
@@ -139,10 +140,10 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             addDocTab: this.props.addDocTab,
         };
 
-        let onItemDown = (e: React.PointerEvent) => {
-            SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
-                this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
-        };
+        // let onItemDown = (e: React.PointerEvent) => {
+        //     SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
+        //         this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
+        // };
         let onPointerEnter = (e: React.PointerEvent): void => {
             if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) {
                 dragRef!.current!.className = "doc-drag-over";
@@ -163,10 +164,15 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             contents = typeof field === "object" ? doc ? StrCast(doc.title) === "" ? "--" : StrCast(doc.title) : `--${typeof field}--` : `--${typeof field}--`;
         }
 
+        let className = "collectionSchemaView-cellWrapper";
+        if (this._isEditing) className += " editing";
+        if (this.props.isFocused && this.props.isEditable) className += " focused";
+        if (this.props.isFocused && !this.props.isEditable) className += " inactive";
+
         return (
             <div className="" ref={dragRef} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
-                <div className="collectionSchemaView-cellWrapper" ref={this._focusRef} tabIndex={-1} onPointerDown={this.onPointerDown}>
-                    <div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef: null} onPointerDown={onItemDown} key={props.Document[Id]}>
+                <div className={className} ref={this._focusRef} tabIndex={-1} onPointerDown={this.onPointerDown}>
+                    <div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
                         <EditableView
                             editing={this._isEditing}
                             isEditingCallback={this.isEditingCallback}
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index beae739ec..6d388bb40 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -7,6 +7,7 @@ import { DragManager, SetupDrag } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
 import { ContextMenu } from "../ContextMenu";
+import { action } from "mobx";
 
 
 export interface MovableColumnProps {
@@ -106,7 +107,7 @@ export interface MovableRowProps {
     rowInfo: RowInfo;
     ScreenToLocalTransform: () => Transform;
     addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
-    moveDoc: DragManager.MoveFunction;
+    removeDoc: (doc: Doc) => boolean;
     rowFocused: boolean;
     textWrapRow: (doc: Doc) => void;
     rowWrapped: boolean;
@@ -145,9 +146,6 @@ export class MovableRow extends React.Component<MovableRowProps> {
     }
 
     rowDrop = (e: Event, de: DragManager.DropEvent) => {
-        // const { children = null, rowInfo } = this.props;
-        // if (!rowInfo) return false;
-
         const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc));
         if (!rowDoc) return false;
 
@@ -160,24 +158,26 @@ export class MovableRow extends React.Component<MovableRowProps> {
             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);
+            let movedDocs = de.data.draggedDocuments;
             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)
-                    // movedDocs.reduce((added: boolean, d) => this.props.moveDoc(d, rowDoc, addDocument) || added, false)
                     : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
         }
         return false;
     }
 
     onRowContextMenu = (e: React.MouseEvent): void => {
-        // const { rowInfo } = this.props;
-        // const { textWrapRow, original } = rowInfo;
         let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
         ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original) });
     }
 
+    @action
+    move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
+        return doc !== target && this.props.removeDoc(doc) && addDoc(doc);
+    }
+
     render() {
         const { children = null, rowInfo } = this.props;
         if (!rowInfo) {
@@ -189,7 +189,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
         if (!doc) return <></>;
 
         let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc);
+        let onItemDown = SetupDrag(reference, () => doc, this.move);
 
         let className = "collectionSchema-row";
         if (this.props.rowFocused) className += " row-focused";
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 410790197..c2b0d8f42 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -148,7 +148,7 @@
         padding: 0;
         font-size: 13px;
         text-align: center;
-        // white-space: normal;
+        white-space: normal;
 
         .imageBox-cont {
             position: relative;
@@ -196,8 +196,6 @@
 .collectionSchemaView-header {
     height: 100%;
     color: gray;
-    letter-spacing: 2px;
-    text-transform: uppercase;
 
     .collectionSchema-header-menu {
         height: 100%;
@@ -206,16 +204,18 @@
             width: 100%;
             height: 100%;
             padding: 4px;
+            letter-spacing: 2px;
+            text-transform: uppercase;
 
             svg {
                 margin-right: 4px;
             }
         }
 
-        div[class*="css"] {
-            width: 100%;
-            height: 100%;
-        }
+        // div[class*="css"] {
+        //     width: 100%;
+        //     height: 100%;
+        // }
     }
 }
 
@@ -287,12 +287,6 @@ button.add-column {
         background-color: $light-color-secondary;
     }
 
-    &.row-wrapped {
-        .rt-td {
-            white-space: normal;
-        }
-    }
-
     .row-dragger {
         // height: $MAX_ROW_HEIGHT;
     }
@@ -309,6 +303,10 @@ button.add-column {
         &.row-inside {
             border: 1px solid red;
         }
+
+        .row-dragging {
+            background-color: blue;
+        }
     }
 }
 
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 62e4ceb54..a7e435ac6 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -344,7 +344,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         addDocTab: this.props.addDocTab,
                         moveDocument: this.props.moveDocument,
                         setIsEditing: this.setCellIsEditing,
-                        isEditable: isEditable
+                        isEditable: isEditable,
                     };
 
                     let colType = this.getColumnType(col);
@@ -393,13 +393,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     tableAddDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
-        console.log("table add doc");
         return Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
     }
 
-    tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
-        console.log("SCHEMA MOVE", StrCast(d.title), StrCast(target.title));
-        this.props.moveDocument(d, target, addDoc);
+    tableRemoveDoc = (document: Doc): boolean => {
+        let index = this.props.childDocs.findIndex(d => d === document);
+        if (index !== -1) {
+            this.props.childDocs.splice(index, 1);
+            return true;
+        }
+        return false;
     }
 
     private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
@@ -410,7 +413,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return {
             ScreenToLocalTransform: this.props.ScreenToLocalTransform,
             addDoc: this.tableAddDoc,
-            moveDoc: this.tableMoveDoc,
+            removeDoc: this.tableRemoveDoc,
             rowInfo,
             rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
             textWrapRow: this.textWrapRow,
@@ -467,6 +470,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     onKeyDown = (e: KeyboardEvent): void => {
+        console.log("schema keydown", !this._cellIsEditing, !this._headerIsEditing, this.props.isFocused(this.props.Document));
         if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) {
             let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this.changeFocusedCellByDirection(direction);
@@ -504,7 +508,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     changeFocusedCellByIndex = (row: number, col: number): void => {
         this._focusedCell = { row: row, col: col };
         this.props.setFocused(this.props.Document);
-        // console.log("changed cell by index", StrCast(this.props.Document.title));
     }
 
     @action
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5ae0753d8..eba1d4f04 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -267,21 +267,28 @@ export namespace Doc {
 
     export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean) {
         if (target[key] === undefined) {
+            console.log("target key undefined");
             Doc.GetProto(target)[key] = new List<Doc>();
         }
         let list = Cast(target[key], listSpec(Doc));
         if (list) {
+            console.log("has list");
             if (allowDuplicates !== true) {
                 let pind = list.reduce((l, d, i) => d instanceof Doc && Doc.AreProtosEqual(d, doc) ? i : l, -1);
                 if (pind !== -1) {
                     list.splice(pind, 1);
                 }
             }
-            if (first) list.splice(0, 0, doc);
+            if (first) {
+                console.log("is first");
+                list.splice(0, 0, doc);
+            }
             else {
+                console.log("not first");
                 let ind = relativeTo ? list.indexOf(relativeTo) : -1;
                 if (ind === -1) list.push(doc);
                 else list.splice(before ? ind : ind + 1, 0, doc);
+                console.log("index", ind);
             }
         }
         return true;
-- 
cgit v1.2.3-70-g09d2


From f8f3ee8df596758ca6f5f7e735fb1296a676f5b6 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Wed, 24 Jul 2019 22:31:45 -0400
Subject: merge

---
 .../views/collections/CollectionSchemaMovableTableHOC.tsx | 15 ++++++++++-----
 src/client/views/collections/CollectionSchemaView.scss    |  9 +++++++++
 src/client/views/collections/CollectionViewChromes.tsx    |  6 +++---
 3 files changed, 22 insertions(+), 8 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 6d388bb40..290958cd0 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -8,7 +8,11 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { action } from "mobx";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faGripVertical } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
+library.add(faGripVertical);
 
 export interface MovableColumnProps {
     columnRenderer: TableCellRenderer;
@@ -198,11 +202,12 @@ export class MovableRow extends React.Component<MovableRowProps> {
         return (
             <div className={className} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
                 <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>
+                    <ReactTableDefaults.TrComponent>
+                        <div className="row-dragger" ref={reference} onPointerDown={onItemDown}>
+                            <FontAwesomeIcon icon={"grip-vertical"} size="sm" />
+                        </div>
+                        {children}
+                    </ReactTableDefaults.TrComponent>
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 3bc1bc060..22d8a5cb6 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -70,6 +70,9 @@
     }
 
     .rt-thead {
+        width: calc(100% - 30px);
+        margin-left: 30px;
+
         &.-header {
             // background: $intermediate-color;
             // color: $light-color;
@@ -77,6 +80,8 @@
             height: 30px;
             // border: 1px solid $intermediate-color;
             box-shadow: none;
+            // width: calc(100% - 30px);
+            // margin-right: -30px;
         }
 
         .rt-resizable-header {
@@ -298,6 +303,10 @@ button.add-column {
 
     .row-dragger {
         // height: $MAX_ROW_HEIGHT;
+        width: 30px;
+        height: 100%;
+        padding: 10px;
+        color: gray;
     }
 
     .collectionSchema-row-wrapper {
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 52fee26bf..03676fe86 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -53,7 +53,7 @@ class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps
                     <option value="masonry" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Masonry}>Masonry View</option>
                 </select>
             </div>
-        )
+        );
     }
 }
 
@@ -147,6 +147,6 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
                     </div>
                 </div>
             </div>
-        )
+        );
     }
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2


From 2d62ca0060c9ef7d3932e8681deb09cc3acf6d48 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Thu, 25 Jul 2019 11:47:23 -0400
Subject: schema stylign

---
 .../CollectionSchemaMovableTableHOC.tsx            | 10 +--
 .../views/collections/CollectionSchemaView.scss    | 82 +++++++++++++++++-----
 .../views/collections/CollectionSchemaView.tsx     |  2 +-
 src/client/views/collections/CollectionView.tsx    |  2 +-
 4 files changed, 73 insertions(+), 23 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 290958cd0..70d6fbc7b 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -9,10 +9,10 @@ import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { action } from "mobx";
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faGripVertical } from '@fortawesome/free-solid-svg-icons';
+import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
-library.add(faGripVertical);
+library.add(faGripVertical, faTrash);
 
 export interface MovableColumnProps {
     columnRenderer: TableCellRenderer;
@@ -198,13 +198,15 @@ export class MovableRow extends React.Component<MovableRowProps> {
         let className = "collectionSchema-row";
         if (this.props.rowFocused) className += " row-focused";
         if (this.props.rowWrapped) className += " row-wrapped";
+        // if (!this.props.rowWrapped) className += " row-unwrapped";
 
         return (
             <div className={className} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
                 <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
                     <ReactTableDefaults.TrComponent>
-                        <div className="row-dragger" ref={reference} onPointerDown={onItemDown}>
-                            <FontAwesomeIcon icon={"grip-vertical"} size="sm" />
+                        <div className="row-dragger">
+                            <div className="row-option" onClick={() => 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>
                         {children}
                     </ReactTableDefaults.TrComponent>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 22d8a5cb6..9ad52db4c 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -8,7 +8,7 @@
     box-sizing: border-box;
     // position: absolute;
     width: 100%;
-    // height: calc(100% - 25px);
+    height: calc(100% - 50px);
     // overflow: hidden;
     overflow-x: scroll;
     border: none;
@@ -55,7 +55,7 @@
 }
 
 .ReactTable {
-    width: 100%;
+    width: 100% !important;
     height: 100%;
     background: white;
     box-sizing: border-box;
@@ -70,8 +70,8 @@
     }
 
     .rt-thead {
-        width: calc(100% - 30px);
-        margin-left: 30px;
+        width: calc(100% - 50px);
+        margin-left: 50px;
 
         &.-header {
             // background: $intermediate-color;
@@ -118,6 +118,7 @@
 
     .rt-tbody {
         direction: rtl;
+        overflow: visible;
     }
 
     .rt-tr-group {
@@ -139,12 +140,12 @@
         //     background-color: $light-color-secondary;
         // }
 
-        &:first-child {
-            border-top: 1px solid $light-color-secondary !important;
-        }
-        &:last-child {
-            border-bottom: 1px solid $light-color-secondary !important;
-        }
+        // &:first-child {
+        //     border-top: 1px solid $light-color-secondary !important;
+        // }
+        // &:last-child {
+        //     border-bottom: 1px solid $light-color-secondary !important;
+        // }
     }
 
     .rt-tr {
@@ -162,7 +163,8 @@
         padding: 0;
         font-size: 13px;
         text-align: center;
-        white-space: normal;
+        
+        // white-space: normal;
 
         .imageBox-cont {
             position: relative;
@@ -296,17 +298,46 @@ button.add-column {
 .collectionSchema-row {
     // height: $MAX_ROW_HEIGHT;
     height: 100%;
+    background-color: white;
 
     &.row-focused {
-        background-color: rgb(253, 191, 191);//$light-color-secondary;
+        background-color: rgb(255, 246, 246);//$light-color-secondary;
+    }
+
+    &.row-wrapped {
+        white-space: normal;
     }
 
     .row-dragger {
+        display: flex;
+        justify-content: space-evenly;
         // height: $MAX_ROW_HEIGHT;
-        width: 30px;
+        flex: 50 0 auto;
+        width: 50px;
+        max-width: 50px;
         height: 100%;
-        padding: 10px;
-        color: gray;
+        min-height: 30px;
+        // padding: 5px 5px 5px 0;
+        color: lightgray;
+        background-color: white;
+        transition: color 0.1s ease;
+
+        // &:hover {
+        //     color: lightgray;
+        // }
+
+        .row-option {
+            // padding: 5px;
+            cursor: pointer;
+            transition: color 0.1s ease;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+
+            &:hover {
+                color: gray;
+            }
+        }
     }
 
     .collectionSchema-row-wrapper {
@@ -369,6 +400,7 @@ button.add-column {
 }
 
 .collectionSchemaView-toolbar {
+    height: 50px;
     display: flex;
     justify-content: flex-end;
 }
@@ -379,8 +411,24 @@ button.add-column {
 }
 
 .sub {
-    padding: 20px;
-    background-color: $intermediate-color;
+    padding: 10px 30px;
+    // padding-left: 80px;
+    background-color: rgb(252, 252, 252);
+    width: calc(100% - 50px);
+    margin-left: 50px;
+
+    .rt-table {
+        overflow-x: hidden; // todo; this shouldnt be like this :((
+        overflow-y: visible;
+    } // TODO fix
+
+    .row-dragger {
+        background-color: rgb(252, 252, 252);
+    }
+
+    .rt-table {
+        background-color: rgb(252, 252, 252);
+    }
 }
 
 .collectionSchemaView-expander {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 87a4a0c6a..a8692ee95 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -435,7 +435,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
         return {
             style: {
-                border: !this._headerIsEditing && isFocused ? "2px solid black" : "1px solid #f1efeb"
+                border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
             }
         };
     }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 62d721868..df8a1ebc1 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -62,7 +62,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
         }
         else {
             return [
-                (<CollectionViewBaseChrome CollectionView={this} type={type} collapse={this.collapse} />),
+                // (<CollectionViewBaseChrome CollectionView={this} type={type} collapse={this.collapse} />),
                 this.SubViewHelper(type, renderProps)
             ];
         }
-- 
cgit v1.2.3-70-g09d2


From bf5911a4de0b6f7e3d73b91b747bfeec89ff4b94 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Thu, 25 Jul 2019 12:58:26 -0400
Subject: minor updates

---
 src/client/views/collections/CollectionSchemaMovableTableHOC.tsx | 6 +++++-
 src/client/views/collections/CollectionSchemaView.tsx            | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 70d6fbc7b..f45575143 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -90,6 +90,10 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         return onItemDown;
     }
 
+    // onColDrag = (e: React.DragEvent, ref: React.RefObject<HTMLDivElement>) => {
+    //     this.setupDrag(reference);
+    // }
+
 
     render() {
         let reference = React.createRef<HTMLDivElement>();
@@ -98,7 +102,7 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         return (
             <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}>
+                    <div className="col-dragger" ref={reference} onPointerDown={onItemDown} >
                         {this.props.columnRenderer}
                     </div>
                 </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index ed2c88f19..ab1c85416 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -212,6 +212,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 isFocused={this.isFocused}
                 setFocused={this.setFocused}
                 setPreviewDoc={this.setPreviewDoc}
+                deleteDocument={this.props.removeDocument}
             />
         );
     }
@@ -254,6 +255,7 @@ export interface SchemaTableProps {
     ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>;
     fieldKey: string;
     renderDepth: number;
+    deleteDocument: (document: Doc) => boolean;
     moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     // CreateDropTarget: (ele: HTMLDivElement)=> void; // super createdriotarget
-- 
cgit v1.2.3-70-g09d2


From 4c8d0e0cf2422bffe26fcddd91eca9e8f3145e1a Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Fri, 26 Jul 2019 18:08:26 -0400
Subject: collection cannot be moved to inside itself in schema

---
 src/client/views/collections/CollectionSchemaMovableTableHOC.tsx | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index f45575143..0ddd56180 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -11,6 +11,7 @@ import { action } from "mobx";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { DocumentManager } from "../../util/DocumentManager";
 
 library.add(faGripVertical, faTrash);
 
@@ -183,6 +184,14 @@ export class MovableRow extends React.Component<MovableRowProps> {
 
     @action
     move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
+        let targetView = DocumentManager.Instance.getDocumentView(target);
+        if (targetView) {
+            let targetContainingColl = targetView.props.ContainingCollectionView; //.props.ContainingCollectionView.props.Document;
+            if (targetContainingColl) {
+                let targetContCollDoc = targetContainingColl.props.Document;
+                return doc !== target && doc !== targetContCollDoc && this.props.removeDoc(doc) && addDoc(doc);
+            }
+        }
         return doc !== target && this.props.removeDoc(doc) && addDoc(doc);
     }
 
-- 
cgit v1.2.3-70-g09d2


From 905d77804bf9a810822e5e43f0cd06019aef7620 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Sat, 27 Jul 2019 17:03:20 -0400
Subject: schema headers changed to schemaheaderfields, a bug with udpating the
 headers (in CollectionSchemaView>ChangeColumn)

---
 src/client/documents/Documents.ts                  |  13 +--
 src/client/util/DragManager.ts                     |   5 +-
 src/client/views/MainView.tsx                      |   3 +-
 .../views/collections/CollectionSchemaCells.tsx    |  30 +++++-
 .../views/collections/CollectionSchemaHeaders.tsx  |   9 +-
 .../CollectionSchemaMovableTableHOC.tsx            |   7 +-
 .../views/collections/CollectionSchemaView.scss    |  15 +++
 .../views/collections/CollectionSchemaView.tsx     | 103 +++++++++++++--------
 .../views/collections/CollectionStackingView.tsx   |   2 +-
 .../collections/collectionFreeForm/MarqueeView.tsx |   3 +-
 src/client/views/nodes/LinkEditor.tsx              |   3 +-
 src/client/views/nodes/LinkMenuGroup.tsx           |   3 +-
 src/new_fields/SchemaHeaderField.ts                |  55 +++++++++--
 13 files changed, 186 insertions(+), 65 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 76ac34d85..e6fe1b8b3 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -39,6 +39,7 @@ import { DocumentManager } from "../util/DocumentManager";
 import DirectoryImportBox from "../util/Import & Export/DirectoryImportBox";
 import { Scripting } from "../util/Scripting";
 import { ButtonBox } from "../views/nodes/ButtonBox";
+import { SchemaHeaderField, RandomPastel } from "../../new_fields/SchemaHeaderField";
 var requestImageSize = require('../util/request-image-size');
 var path = require('path');
 
@@ -84,7 +85,7 @@ export interface DocumentOptions {
     curPage?: number;
     documentText?: string;
     borderRounding?: string;
-    schemaColumns?: List<string>;
+    schemaColumns?: List<SchemaHeaderField>;
     dockingConfig?: string;
     dbDoc?: Doc;
     // [key: string]: Opt<Field>;
@@ -403,23 +404,23 @@ export namespace Docs {
         }
 
         export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Freeform });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Freeform });
         }
 
-        export function SchemaDocument(schemaColumns: string[], documents: Array<Doc>, options: DocumentOptions) {
+        export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array<Doc>, options: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(schemaColumns), ...options, viewType: CollectionViewType.Schema });
         }
 
         export function TreeDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Tree });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Tree });
         }
 
         export function StackingDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Stacking });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Stacking });
         }
 
         export function MasonryDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Masonry });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Masonry });
         }
 
         export function ButtonDocument(options?: DocumentOptions) {
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 0299b1d90..47d3c313d 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -8,6 +8,7 @@ import * as globalCssVariables from "../views/globalCssVariables.scss";
 import { DocumentManager } from "./DocumentManager";
 import { LinkManager } from "./LinkManager";
 import { SelectionManager } from "./SelectionManager";
+import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
 
 export type dropActionType = "alias" | "copy" | undefined;
 export function SetupDrag(
@@ -290,10 +291,10 @@ export namespace DragManager {
 
     // for column dragging in schema view
     export class ColumnDragData {
-        constructor(colKey: string) {
+        constructor(colKey: SchemaHeaderField) {
             this.colKey = colKey;
         }
-        colKey: string;
+        colKey: SchemaHeaderField;
         [id: string]: any;
     }
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 0e04b5e7e..282db244e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -39,6 +39,7 @@ import { PreviewCursor } from './PreviewCursor';
 import { FilterBox } from './search/FilterBox';
 import { CollectionTreeView } from './collections/CollectionTreeView';
 import { ClientUtils } from '../util/ClientUtils';
+import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
 
 @observer
 export class MainView extends React.Component {
@@ -375,7 +376,7 @@ export class MainView extends React.Component {
         let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
 
         // let addDockingNode = action(() => Docs.Create.StandardCollectionDockingDocument([{ doc: addColNode(), initialWidth: 200 }], { width: 200, height: 200, title: "a nested docking freeform collection" }));
-        let addSchemaNode = action(() => Docs.Create.SchemaDocument(["title"], [], { width: 200, height: 200, title: "a schema collection" }));
+        let addSchemaNode = action(() => Docs.Create.SchemaDocument([new SchemaHeaderField("title")], [], { width: 200, height: 200, title: "a schema collection" }));
         //let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" }));
         // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy"  }));
         let addColNode = action(() => Docs.Create.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 4a618a436..c91f1017b 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -21,7 +21,12 @@ import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_field
 import { Docs } from "../../documents/Documents";
 import { DocumentContentsView } from "../nodes/DocumentContentsView";
 import { SelectionManager } from "../../util/SelectionManager";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faExpand } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
 
+library.add(faExpand);
 
 export interface CellProps {
     row: number;
@@ -38,6 +43,7 @@ export interface CellProps {
     changeFocusedCellByIndex: (row: number, col: number) => void;
     setIsEditing: (isEditing: boolean) => void;
     isEditable: boolean;
+    setPreviewDoc: (doc: Doc) => void;
 }
 
 @observer
@@ -92,7 +98,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                 this._document[fieldKey] = de.data.draggedDocuments[0];
             }
             else {
-                let coll = Docs.Create.SchemaDocument(["title"], de.data.draggedDocuments, {});
+                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title")], de.data.draggedDocuments, {});
                 this._document[fieldKey] = coll;
             }
             e.stopPropagation();
@@ -106,6 +112,18 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         }
     }
 
+    expandDoc = (e: React.PointerEvent) => {
+        let field = this.props.rowProps.original[this.props.rowProps.column.id as string];
+        let doc = FieldValue(Cast(field, Doc));
+
+        console.log("Expanding doc", StrCast(doc!.title));
+        this.props.setPreviewDoc(doc!);
+
+        // this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
+
+        e.stopPropagation();
+    }
+
     renderCellWithType(type: string | undefined) {
         let dragRef: React.RefObject<HTMLDivElement> = React.createRef();
 
@@ -157,6 +175,15 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         if (this.props.isFocused && this.props.isEditable) className += " focused";
         if (this.props.isFocused && !this.props.isEditable) className += " inactive";
 
+        let doc = FieldValue(Cast(field, Doc));
+        if (type === "document") console.log("doc", typeof field);
+        let fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
+        let docExpander = (
+            <div className="collectionSchemaView-cellContents-docExpander" onPointerDown={this.expandDoc} >
+                <FontAwesomeIcon icon="expand" size="sm" />
+            </div>
+        );
+
         return (
             <div className="collectionSchemaView-cellContainer" ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
                 <div className={className} ref={this._focusRef} tabIndex={-1}>
@@ -193,6 +220,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                 val && val.forEach(doc => this.applyToDoc(doc, run));
                             }} />
                     </div >
+                    {fieldIsDoc ? docExpander : null}
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index d1d0674c4..9fc28eafa 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -10,11 +10,12 @@ import { ColumnType } from "./CollectionSchemaView";
 import { emptyFunction } from "../../../Utils";
 import { contains } from "typescript-collections/dist/lib/arrays";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
+import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 
 library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile);
 
 export interface HeaderProps {
-    keyValue: string;
+    keyValue: SchemaHeaderField;
     possibleKeys: string[];
     existingKeys: string[];
     keyType: ColumnType;
@@ -33,14 +34,14 @@ export class CollectionSchemaHeader extends React.Component<HeaderProps> {
             this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify";
 
         return (
-            <div className="collectionSchemaView-header" >
+            <div className="collectionSchemaView-header" style={{ background: this.props.keyValue.color }}>
                 <CollectionSchemaColumnMenu
-                    keyValue={this.props.keyValue}
+                    keyValue={this.props.keyValue.heading}
                     possibleKeys={this.props.possibleKeys}
                     existingKeys={this.props.existingKeys}
                     keyType={this.props.keyType}
                     typeConst={this.props.typeConst}
-                    menuButtonContent={<div><FontAwesomeIcon icon={icon} size="sm" />{this.props.keyValue}</div>}
+                    menuButtonContent={<div><FontAwesomeIcon icon={icon} size="sm" />{this.props.keyValue.heading}</div>}
                     addNew={false}
                     onSelect={this.props.onSelect}
                     setIsEditing={this.props.setIsEditing}
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 0ddd56180..2349e42ca 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -12,14 +12,15 @@ import { library } from '@fortawesome/fontawesome-svg-core';
 import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { DocumentManager } from "../../util/DocumentManager";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 
 library.add(faGripVertical, faTrash);
 
 export interface MovableColumnProps {
     columnRenderer: TableCellRenderer;
-    columnValue: string;
-    allColumns: string[];
-    reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void;
+    columnValue: SchemaHeaderField;
+    allColumns: SchemaHeaderField[];
+    reorderColumns: (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columns: SchemaHeaderField[]) => void;
     ScreenToLocalTransform: () => Transform;
 }
 export class MovableColumn extends React.Component<MovableColumnProps> {
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 91c6e8b3c..e0de76247 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -379,6 +379,7 @@ button.add-column {
 .collectionSchemaView-cellWrapper {
     height: 100%;
     padding: 4px;
+    position: relative;
 
     &:focus {
         outline: none;
@@ -405,6 +406,20 @@ button.add-column {
         height: 100%;
         // word-wrap: break-word;
     }
+
+    &:hover .collectionSchemaView-cellContents-docExpander {
+        display: block;
+    }
+}
+
+.collectionSchemaView-cellContents-docExpander {
+    height: 30px;
+    width: 30px;
+    display: none;
+    position: absolute;
+    top: 0;
+    right: 0;
+    background-color: lightgray;
 }
 
 .doc-drag-over {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index c6550560a..176872503 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -38,6 +38,7 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { DocumentManager } from "../../util/DocumentManager";
 import { ImageBox } from "../nodes/ImageBox";
 import { ComputedField } from "../../../new_fields/ScriptField";
+import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
 
 
 library.add(faCog, faPlus, faSortUp, faSortDown);
@@ -284,11 +285,13 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); }
     @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
     @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); }
-    @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); }
-    set columns(columns: string[]) { this.props.Document.schemaColumns = new List<string>(columns); }
+    @computed get columns() {
+        return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []);
+    }
+    set columns(columns: SchemaHeaderField[]) { this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns); }
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
-        let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1);
+        let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
         let columns: Column<Doc>[] = [];
         let tableIsFocused = this.props.isFocused(this.props.Document);
         let focusedRow = this._focusedCell.row;
@@ -321,9 +324,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             let header = <CollectionSchemaHeader
                 keyValue={col}
                 possibleKeys={possibleKeys}
-                existingKeys={this.columns}
+                existingKeys={this.columns.map(c => c.heading)}
                 keyType={this.getColumnType(col)}
-                typeConst={columnTypes.get(col) !== undefined}
+                typeConst={col.type !== undefined || columnTypes.get(col.heading) !== undefined}
                 onSelect={this.changeColumns}
                 setIsEditing={this.setHeaderIsEditing}
                 deleteColumn={this.deleteColumn}
@@ -334,16 +337,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
             return {
                 Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.columns} reorderColumns={this.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
-                accessor: (doc: Doc) => doc ? doc[col] : 0,
-                id: col,
+                accessor: (doc: Doc) => doc ? doc[col.heading] : 0,
+                id: col.heading,
                 Cell: (rowProps: CellInfo) => {
-                    let row = rowProps.index;
-                    let column = this.columns.indexOf(rowProps.column.id!);
-                    let isFocused = focusedRow === row && focusedCol === column && tableIsFocused;
+                    let rowIndex = rowProps.index;
+                    let columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!);
+                    let isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused;
 
                     let props: CellProps = {
-                        row: row,
-                        col: column,
+                        row: rowIndex,
+                        col: columnIndex,
                         rowProps: rowProps,
                         isFocused: isFocused,
                         changeFocusedCellByIndex: this.changeFocusedCellByIndex,
@@ -356,6 +359,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         moveDocument: this.props.moveDocument,
                         setIsEditing: this.setCellIsEditing,
                         isEditable: isEditable,
+                        setPreviewDoc: this.props.setPreviewDoc
                     };
 
                     let colType = this.getColumnType(col);
@@ -394,6 +398,15 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     //     }
     //     return this.props.Document;  
     // }
+    constructor(props: SchemaTableProps) {
+        super(props);
+        // convert old schema columns (list of strings) into new schema columns (list of schema header fields)
+        let oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []);
+        if (oldSchemaColumns && oldSchemaColumns.length) {
+            let newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i) : i);
+            this.props.Document.schemaColumns = new List<SchemaHeaderField>(newSchemaColumns);
+        }
+    }
 
     componentDidMount() {
         document.addEventListener("keydown", this.onKeyDown);
@@ -440,7 +453,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
         let row = rowInfo.index;
         //@ts-ignore
-        let col = this.columns.indexOf(column!.id);
+        let col = this.columns.map(c => c.heading).indexOf(column!.id);
         // let col = column ? this.columns.indexOf(column!) : -1;
         let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
         // let column = this.columns.indexOf(column.id!);
@@ -502,6 +515,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) {
             let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this.changeFocusedCellByDirection(direction);
+
+            let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
+            let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
+            const pdoc = FieldValue(children[this._focusedCell.row]);
+            pdoc && this.props.setPreviewDoc(pdoc);
         }
     }
 
@@ -532,8 +550,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 this._focusedCell = { row: this._focusedCell.row + 1 === children.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col };
                 break;
         }
-        const pdoc = FieldValue(children[this._focusedCell.row]);
-        pdoc && this.props.setPreviewDoc(pdoc);
+        // const pdoc = FieldValue(children[this._focusedCell.row]);
+        // pdoc && this.props.setPreviewDoc(pdoc);
     }
 
     @action
@@ -544,8 +562,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this._focusedCell = { row: row, col: col };
         this.props.setFocused(this.props.Document);
 
-        const fdoc = FieldValue(children[this._focusedCell.row]);
-        fdoc && this.props.setPreviewDoc(fdoc);
+        // const fdoc = FieldValue(children[this._focusedCell.row]);
+        // fdoc && this.props.setPreviewDoc(fdoc);
     }
 
     createRow = () => {
@@ -561,25 +579,25 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @action
     createColumn = () => {
         let index = 0;
-        let found = this.columns.findIndex(col => col.toUpperCase() === "New field".toUpperCase()) > -1;
+        let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
         if (!found) {
-            this.columns.push("New field");
+            this.columns.push(new SchemaHeaderField("New field"));
             return;
         }
         while (found) {
             index++;
-            found = this.columns.findIndex(col => col.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
+            found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
         }
-        this.columns.push("New field (" + index + ")");
+        this.columns.push(new SchemaHeaderField("New field (" + index + ")"));
     }
 
     @action
     deleteColumn = (key: string) => {
-        let list = Cast(this.props.Document.schemaColumns, listSpec("string"));
+        let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
         if (list === undefined) {
-            this.props.Document.schemaColumns = list = new List<string>([]);
+            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([]);
         } else {
-            const index = list.indexOf(key);
+            const index = list.map(c => c.heading).indexOf(key);
             if (index > -1) {
                 list.splice(index, 1);
             }
@@ -588,26 +606,37 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
-        let list = Cast(this.props.Document.schemaColumns, listSpec("string"));
+        let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
         if (list === undefined) {
-            this.props.Document.schemaColumns = list = new List<string>([newKey]);
+            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([new SchemaHeaderField(newKey)]);
         } else {
             if (addNew) {
-                this.columns.push(newKey);
+                this.columns.push(new SchemaHeaderField(newKey));
             } else {
-                const index = list.indexOf(oldKey);
+                const index = list.map(c => c.heading).indexOf(oldKey);
                 if (index > -1) {
-                    list[index] = newKey;
+                    list[index] = new SchemaHeaderField(newKey);
                 }
             }
         }
     }
 
-    getColumnType = (key: string): ColumnType => {
-        if (columnTypes.get(key)) return columnTypes.get(key)!;
+    getColumnType = (column: SchemaHeaderField): ColumnType => {
+        // added functionality to convert old column type stuff to new column type stuff -syip
+        if (column.type && column.type !== 0) {
+            return column.type;
+        }
+        if (columnTypes.get(column.heading)) {
+            column.type = columnTypes.get(column.heading)!;
+            return columnTypes.get(column.heading)!;
+        }
         const typesDoc = FieldValue(Cast(this.props.Document.schemaColumnTypes, Doc));
-        if (!typesDoc) return ColumnType.Any;
-        return NumCast(typesDoc[key]);
+        if (!typesDoc) {
+            column.type = ColumnType.Any;
+            return ColumnType.Any;
+        }
+        column.type = NumCast(typesDoc[column.heading]);
+        return NumCast(typesDoc[column.heading]);
     }
 
     setColumnType = (key: string, type: ColumnType): void => {
@@ -624,11 +653,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     @action
-    setColumns = (columns: string[]) => {
+    setColumns = (columns: SchemaHeaderField[]) => {
         this.columns = columns;
     }
 
-    reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => {
+    reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
         let columns = [...columnsValues];
         let oldIndex = columns.indexOf(toMove);
         let relIndex = columns.indexOf(relativeTo);
@@ -661,7 +690,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         //TODO Types
         untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false))));
 
-        this.columns.forEach(key => keys[key] = true);
+        this.columns.forEach(key => keys[key.heading] = true);
         return Array.from(Object.keys(keys));
     }
 
@@ -727,7 +756,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         csv = csv.substr(0, csv.length - 1) + "\n";
         let self = this;
         DocListCast(this.props.Document.data).map(doc => {
-            csv += self.columns.reduce((val, col) => val + (doc[col] ? doc[col]!.toString() : "0") + ",", "");
+            csv += self.columns.reduce((val, col) => val + (doc[col.heading] ? doc[col.heading]!.toString() : "0") + ",", "");
             csv = csv.substr(0, csv.length - 1) + "\n";
         });
         csv.substring(0, csv.length - 1);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7677f53c1..e897c5676 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -16,7 +16,7 @@ import { Transform } from "../../util/Transform";
 import { CursorProperty } from "csstype";
 import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
 import { listSpec } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
 import { List } from "../../../new_fields/List";
 import { EditableView } from "../EditableView";
 import { CollectionViewProps } from "./CollectionBaseView";
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b765517a2..2e54a9736 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -19,6 +19,7 @@ import { CollectionViewType } from "../CollectionBaseView";
 import { CollectionFreeFormView } from "./CollectionFreeFormView";
 import "./MarqueeView.scss";
 import React = require("react");
+import { SchemaHeaderField, RandomPastel } from "../../../../new_fields/SchemaHeaderField";
 
 interface MarqueeViewProps {
     getContainerTransform: () => Transform;
@@ -134,7 +135,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 doc.width = 200;
                 docList.push(doc);
             }
-            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? ["_group"] : []), ...columns.filter(c => c)], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
+            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
 
             this.props.addDocument(newCol, false);
         }
diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx
index afde85b69..0ea948c81 100644
--- a/src/client/views/nodes/LinkEditor.tsx
+++ b/src/client/views/nodes/LinkEditor.tsx
@@ -11,6 +11,7 @@ import { faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTim
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { SetupDrag } from "../../util/DragManager";
+import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
 
 library.add(faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTimes, faPlus);
 
@@ -289,7 +290,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
         let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
         let index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]];
+        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c));
         let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
         let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
         let ref = React.createRef<HTMLDivElement>();
diff --git a/src/client/views/nodes/LinkMenuGroup.tsx b/src/client/views/nodes/LinkMenuGroup.tsx
index ae97bed2f..3637807ad 100644
--- a/src/client/views/nodes/LinkMenuGroup.tsx
+++ b/src/client/views/nodes/LinkMenuGroup.tsx
@@ -14,6 +14,7 @@ import { Docs } from "../../documents/Documents";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { UndoManager } from "../../util/UndoManager";
 import { StrCast } from "../../../new_fields/Types";
+import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
 
 interface LinkMenuGroupProps {
     sourceDoc: Doc;
@@ -70,7 +71,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
         let index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]];
+        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c));
         let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
         let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
         let ref = React.createRef<HTMLDivElement>();
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
index 284de3023..a6df31e81 100644
--- a/src/new_fields/SchemaHeaderField.ts
+++ b/src/new_fields/SchemaHeaderField.ts
@@ -3,13 +3,42 @@ import { serializable, createSimpleSchema, primitive } from "serializr";
 import { ObjectField } from "./ObjectField";
 import { Copy, ToScriptString, OnUpdate } from "./FieldSymbols";
 import { scriptingGlobal, Scripting } from "../client/util/Scripting";
+import { ColumnType } from "../client/views/collections/CollectionSchemaView";
 
 export const PastelSchemaPalette = new Map<string, string>([
-    ["purple", "#f5b5fc"],
-    ["green", "#96F7D2"],
-    ["yellow", "#F0F696"],
-    ["red", "#FCB1B1"]
-])
+    ["pink1", "#FFB4E8"],
+    ["pink2", "#ff9cee"],
+    ["pink3", "#ffccf9"],
+    ["pink4", "#fcc2ff"],
+    ["pink5", "#f6a6ff"],
+    ["purple1", "#b28dff"],
+    ["purple2", "#c5a3ff"],
+    ["purple3", "#d5aaff"],
+    ["purple4", "#ecd4ff"],
+    ["purple5", "#fb34ff"],
+    ["purple6", "#dcd3ff"],
+    ["purple7", "#a79aff"],
+    ["purple8", "#b5b9ff"],
+    ["purple9", "#97a2ff"],
+    ["bluegreen1", "#afcbff"],
+    ["bluegreen2", "#aff8db"],
+    ["bluegreen3", "#c4faf8"],
+    ["bluegreen4", "#85e3ff"],
+    ["bluegreen5", "#ace7ff"],
+    ["bluegreen6", "#6eb5ff"],
+    ["bluegreen7", "#bffcc6"],
+    ["bluegreen8", "#dbffd6"],
+    ["yellow1", "#f3ffe3"],
+    ["yellow2", "#e7ffac"],
+    ["yellow3", "#ffffd1"],
+    ["yellow4", "#fff5ba"],
+    ["red1", "#ffc9de"],
+    ["red2", "#ffabab"],
+    ["red3", "#ffbebc"],
+    ["red4", "#ffcbc1"],
+]);
+
+export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * PastelSchemaPalette.size)];
 
 @scriptingGlobal
 @Deserializable("schemaheader")
@@ -17,12 +46,19 @@ export class SchemaHeaderField extends ObjectField {
     @serializable(primitive())
     heading: string;
     color: string;
+    type: number;
 
-    constructor(heading: string = "", color: string = Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * 4)]) {
+    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType) {
         super();
 
         this.heading = heading;
         this.color = color;
+        if (type) {
+            this.type = type;
+        }
+        else {
+            this.type = 0;
+        }
     }
 
     setHeading(heading: string) {
@@ -35,8 +71,13 @@ export class SchemaHeaderField extends ObjectField {
         this[OnUpdate]();
     }
 
+    setType(type: ColumnType) {
+        this.type = type;
+        this[OnUpdate]();
+    }
+
     [Copy]() {
-        return new SchemaHeaderField(this.heading, this.color);
+        return new SchemaHeaderField(this.heading, this.color, this.type);
     }
 
     [ToScriptString]() {
-- 
cgit v1.2.3-70-g09d2


From 2065186202404a2bb70f45da7ae842297da3c14c Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sat, 27 Jul 2019 18:45:28 -0400
Subject: fixes

---
 src/client/views/collections/CollectionPDFView.tsx               | 2 +-
 src/client/views/collections/CollectionSchemaMovableTableHOC.tsx | 2 +-
 src/client/views/collections/CollectionVideoView.tsx             | 2 +-
 src/server/authentication/models/current_user_utils.ts           | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'src/client/views/collections/CollectionSchemaMovableTableHOC.tsx')

diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 9074854d6..70010819a 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -78,7 +78,7 @@ export class CollectionPDFView extends React.Component<FieldViewProps> {
         let props = { ...this.props, ...renderProps };
         return (
             <>
-                <CollectionFreeFormView {...props} setPdfBox={this.setPdfBox} CollectionView={this} />
+                <CollectionFreeFormView {...props} setPdfBox={this.setPdfBox} CollectionView={this} chromeCollapsed={true} />
                 {renderProps.active() ? this.uIButtons : (null)}
             </>
         );
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 2349e42ca..7342ede7a 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -180,7 +180,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
 
     onRowContextMenu = (e: React.MouseEvent): void => {
         let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
-        ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original) });
+        ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
     }
 
     @action
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 31a8a93e0..a264cc402 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -89,7 +89,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
     private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
         return (<>
-            <CollectionFreeFormView {...props} setVideoBox={this.setVideoBox} CollectionView={this} />
+            <CollectionFreeFormView {...props} setVideoBox={this.setVideoBox} CollectionView={this} chromeCollapsed={true} />
             {this.props.isSelected() ? this.uIButtons : (null)}
         </>);
     }
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 41eb1aa0c..1693d2f48 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -50,7 +50,6 @@ export class CurrentUserUtils {
         if (doc.workspaces === undefined) {
             const workspaces = Docs.Create.TreeDocument([], { title: "Workspaces", height: 100 });
             workspaces.excludeFromLibrary = true;
-            workspaces.chromeStatus = "disabled";
             workspaces.workspaceLibrary = true;
             workspaces.boxShadow = "0 0";
             doc.workspaces = workspaces;
@@ -58,7 +57,6 @@ export class CurrentUserUtils {
         if (doc.recentlyClosed === undefined) {
             const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 });
             recentlyClosed.excludeFromLibrary = true;
-            recentlyClosed.chromeStatus = "disabled";
             recentlyClosed.boxShadow = "0 0";
             doc.recentlyClosed = recentlyClosed;
         }
@@ -67,12 +65,14 @@ export class CurrentUserUtils {
             sidebar.excludeFromLibrary = true;
             sidebar.gridGap = 5;
             sidebar.xMargin = 5;
-            sidebar.chromeStatus = "disabled";
             sidebar.yMargin = 5;
             Doc.GetProto(sidebar).backgroundColor = "#aca3a6";
             sidebar.boxShadow = "1 1 3";
             doc.sidebar = sidebar;
         }
+        (Cast(doc.workspaces, Doc) as Doc).chromeStatus = "disabled";
+        (Cast(doc.recentlyClosed, Doc) as Doc).chromeStatus = "disabled";
+        (Cast(doc.sidebar, Doc) as Doc).chromeStatus = "disabled";
         doc.chromeStatus = "disabled";
         StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library");
 
-- 
cgit v1.2.3-70-g09d2

