From ed85a99f138c1c4609f4465f242185ecd3886eb7 Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Tue, 30 Jul 2019 12:26:43 -0400
Subject: schema column dragging has slight delay

---
 .../CollectionSchemaMovableTableHOC.tsx            | 37 +++++++++++++++-------
 1 file changed, 26 insertions(+), 11 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 7342ede7a..2e4f276bf 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -26,6 +26,9 @@ export interface MovableColumnProps {
 export class MovableColumn extends React.Component<MovableColumnProps> {
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _colDropDisposer?: DragManager.DragDropDisposer;
+    private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+    private _sensitivity: number = 16;
+    private _dragRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     onPointerEnter = (e: React.PointerEvent): void => {
         if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
@@ -36,6 +39,7 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
     onPointerLeave = (e: React.PointerEvent): void => {
         this._header!.current!.className = "collectionSchema-col-wrapper";
         document.removeEventListener("pointermove", this.onDragMove, true);
+        document.removeEventListener("pointermove", this.onPointerMove);
     }
     onDragMove = (e: PointerEvent): void => {
         let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
@@ -68,7 +72,7 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         return false;
     }
 
-    setupDrag(ref: React.RefObject<HTMLElement>) {
+    onPointerMove = (e: PointerEvent) => {
         let onRowMove = (e: PointerEvent) => {
             e.stopPropagation();
             e.preventDefault();
@@ -76,35 +80,46 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
             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);
+            DragManager.StartColumnDrag(this._dragRef.current!, dragData, e.x, e.y);
+            console.log("SETUP DRAG");
         };
         let onRowUp = (): void => {
             document.removeEventListener("pointermove", onRowMove);
             document.removeEventListener('pointerup', onRowUp);
         };
-        let onItemDown = (e: React.PointerEvent) => {
-            if (e.button === 0) {
+        if (e.buttons === 1) {
+            let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+            console.log("moving this much", Math.abs(dx), Math.abs(dy));
+            if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
+                document.removeEventListener("pointermove", this.onPointerMove);
                 e.stopPropagation();
+
                 document.addEventListener("pointermove", onRowMove);
                 document.addEventListener("pointerup", onRowUp);
             }
-        };
-        return onItemDown;
+        }
     }
 
-    // onColDrag = (e: React.DragEvent, ref: React.RefObject<HTMLDivElement>) => {
-    //     this.setupDrag(reference);
-    // }
+    onPointerUp = (e: React.PointerEvent) => {
+        document.removeEventListener("pointermove", this.onPointerMove);
+    }
+
+    @action
+    onPointerDown = (e: React.PointerEvent, ref: React.RefObject<HTMLDivElement>) => {
+        this._dragRef = ref;
+        let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY);
+        this._startDragPosition = { x: dx, y: dy };
+        document.addEventListener("pointermove", this.onPointerMove);
+    }
 
 
     render() {
         let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = this.setupDrag(reference);
 
         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={e => this.onPointerDown(e, reference)} onPointerUp={this.onPointerUp}>
                         {this.props.columnRenderer}
                     </div>
                 </div>
-- 
cgit v1.2.3-70-g09d2


From 49355364b418ceb8f04ee79132dedc5885a9bbe5 Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Tue, 30 Jul 2019 13:15:19 -0400
Subject: schema column widths get saved

---
 .../CollectionSchemaMovableTableHOC.tsx            |  2 -
 .../views/collections/CollectionSchemaView.tsx     | 44 ++++++++++++++--------
 .../CollectionStackingViewFieldColumn.tsx          |  1 -
 src/new_fields/SchemaHeaderField.ts                |  5 ++-
 4 files changed, 32 insertions(+), 20 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 2e4f276bf..483463c2b 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -81,7 +81,6 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
             document.removeEventListener('pointerup', onRowUp);
             let dragData = new DragManager.ColumnDragData(this.props.columnValue);
             DragManager.StartColumnDrag(this._dragRef.current!, dragData, e.x, e.y);
-            console.log("SETUP DRAG");
         };
         let onRowUp = (): void => {
             document.removeEventListener("pointermove", onRowMove);
@@ -89,7 +88,6 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         };
         if (e.buttons === 1) {
             let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
-            console.log("moving this much", Math.abs(dx), Math.abs(dy));
             if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
                 document.removeEventListener("pointermove", this.onPointerMove);
                 e.stopPropagation();
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 26b19474a..722d8b1f9 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -4,10 +4,10 @@ import { faCog, faPlus, faTable, faSortUp, faSortDown } from '@fortawesome/free-
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, trace, untracked } from "mobx";
 import { observer } from "mobx-react";
-import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, TableCellRenderer, Column, RowInfo } from "react-table";
+import ReactTable, { CellInfo, ComponentPropsGetterR, Column, RowInfo, ResizedChangeFunction, Resize } from "react-table";
 import "react-table/react-table.css";
-import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils";
-import { Doc, DocListCast, DocListCastAsync, Field, FieldResult, Opt } from "../../../new_fields/Doc";
+import { emptyFunction, returnOne } from "../../../Utils";
+import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { List } from "../../../new_fields/List";
 import { listSpec } from "../../../new_fields/Schema";
@@ -17,28 +17,21 @@ import { Gateway } from "../../northstar/manager/Gateway";
 import { SetupDrag, DragManager } from "../../util/DragManager";
 import { CompileScript, ts, Transformer } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
-import { COLLECTION_BORDER_WIDTH, MAX_ROW_HEIGHT } from '../../views/globalCssVariables.scss';
+import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss';
 import { ContextMenu } from "../ContextMenu";
-import { anchorPoints, Flyout } from "../DocumentDecorations";
 import '../DocumentDecorations.scss';
-import { EditableView } from "../EditableView";
 import { DocumentView } from "../nodes/DocumentView";
-import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import { CollectionPDFView } from "./CollectionPDFView";
 import "./CollectionSchemaView.scss";
 import { CollectionSubView } from "./CollectionSubView";
 import { CollectionVideoView } from "./CollectionVideoView";
 import { CollectionView } from "./CollectionView";
 import { undoBatch } from "../../util/UndoManager";
-import { timesSeries } from "async";
 import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders";
 import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell } from "./CollectionSchemaCells";
 import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC";
-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";
+import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 
 
 library.add(faCog, faPlus, faSortUp, faSortDown);
@@ -314,6 +307,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.props.Document.textwrappedSchemaRows = new List<string>(textWrappedRows);
     }
 
+    @computed get resized(): { "id": string, "value": number }[] {
+        let columns = this.columns;
+        return columns.reduce((resized, shf) => {
+            if (shf.width > -1) {
+                resized.push({ "id": shf.heading, "value": shf.width });
+            }
+            return resized;
+        }, [] as { "id": string, "value": number }[]);
+    }
+
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
         let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
@@ -658,15 +661,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
-        // console.log("setting color", key);
         let columns = this.columns;
         let index = columns.indexOf(columnField);
         if (index > -1) {
-            // let column = columns[index];
             columnField.color = color;
             columns[index] = columnField;
             this.columns = columns;
-            console.log(columnField, this.columns[index]);
         }
     }
 
@@ -730,7 +730,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     get reactTable() {
         let children = this.childDocs;
 
-        let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
+        // let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
         let hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false);
         let expandedRowsList = this._openCollections.map(col => children.findIndex(doc => doc[Id] === col).toString());
         let expanded = {};
@@ -751,6 +751,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             TrComponent={MovableRow}
             sorted={Array.from(this._sortedColumns.values())}
             expanded={expanded}
+            resized={this.resized}
+            onResizedChange={this.onResizedChange}
             SubComponent={hasCollectionChild ?
                 row => {
                     if (row.original.type === "collection") {
@@ -762,6 +764,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         />;
     }
 
+    onResizedChange = (newResized: Resize[], event: any) => {
+        let columns = this.columns;
+        newResized.forEach(resized => {
+            let index = columns.findIndex(c => c.heading === resized.id);
+            let column = columns[index];
+            column.width = resized.value;
+        });
+        this.columns = columns;
+    }
+
     onContextMenu = (e: React.MouseEvent): void => {
         if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB, icon: "table" });
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 6edfe55e5..01938a3b4 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -187,7 +187,6 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     startDrag = (e: PointerEvent) => {
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
-            console.log("start stack drag");
             let alias = Doc.MakeAlias(this.props.parent.props.Document);
             let key = StrCast(this.props.parent.props.Document.sectionFilter);
             let value = this.getValue(this._heading);
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
index 9f716bf9f..15b497759 100644
--- a/src/new_fields/SchemaHeaderField.ts
+++ b/src/new_fields/SchemaHeaderField.ts
@@ -49,8 +49,10 @@ export class SchemaHeaderField extends ObjectField {
     color: string;
     @serializable(primitive())
     type: number;
+    @serializable(primitive())
+    width: number;
 
-    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType) {
+    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType, width?: number) {
         super();
 
         this.heading = heading;
@@ -61,6 +63,7 @@ export class SchemaHeaderField extends ObjectField {
         else {
             this.type = 0;
         }
+        this.width = width ? width : -1;
     }
 
     setHeading(heading: string) {
-- 
cgit v1.2.3-70-g09d2


From f73d1eabb7ce1fb49b35c8b2ce7be585d93b22ea Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Tue, 30 Jul 2019 18:43:19 -0400
Subject: minor schema styling

---
 .../views/collections/CollectionSchemaCells.tsx    | 20 ++++++----
 .../CollectionSchemaMovableTableHOC.tsx            |  1 -
 .../views/collections/CollectionSchemaView.scss    | 44 ++++++++++------------
 .../views/collections/CollectionSchemaView.tsx     |  3 ++
 4 files changed, 34 insertions(+), 34 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 4b3dd3cc1..61f21006e 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -71,6 +71,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             document.removeEventListener("keydown", this.onKeyDown);
             this._isEditing = true;
             this.props.setIsEditing(true);
+
         }
     }
 
@@ -87,6 +88,9 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
         this.props.setPreviewDoc(this.props.rowProps.original);
 
+        // this._isEditing = true;
+        // this.props.setIsEditing(true);
+
         let field = this.props.rowProps.original[this.props.rowProps.column.id!];
         let doc = FieldValue(Cast(field, Doc));
         if (typeof field === "object" && doc) this.props.setPreviewDoc(doc);
@@ -122,17 +126,17 @@ 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));
+    // 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!);
+    //     console.log("Expanding doc", StrCast(doc!.title));
+    //     this.props.setPreviewDoc(doc!);
 
-        // this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
+    //     // this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
 
-        e.stopPropagation();
-    }
+    //     e.stopPropagation();
+    // }
 
     renderCellWithType(type: string | undefined) {
         let dragRef: React.RefObject<HTMLDivElement> = React.createRef();
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 483463c2b..5741c4191 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -225,7 +225,6 @@ 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}>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 564e4f4a5..2946fc4f7 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -120,6 +120,7 @@
             padding: 0;
             border: solid lightgray;
             border-width: 0 1px;
+            border-bottom: 2px solid lightgray;
         }
     }
 
@@ -127,7 +128,7 @@
         // max-height: $MAX_ROW_HEIGHT;
         font-size: 13px;
         text-align: center;
-        background-color: $light-color-secondary;
+        // background-color: $light-color-secondary;
 
         &:last-child {
             overflow: visible;
@@ -145,25 +146,11 @@
         flex: 0 1 auto;
         min-height: 30px;
         border: 0 !important;
-        // border: solid lightgray;
-        // border-width: 1px 0;
-        // border-left: 1px solid lightgray;
-        // max-height: $MAX_ROW_HEIGHT;
-        // for sub comp
-
-        // &:nth-child(even) {
-        //     background-color: $light-color;
-        // }
-
-        // &:nth-child(odd) {
-        //     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;
+        //     .rt-td {
+        //         border-top: 1px solid lightgray !important;
+        //     }
         // }
     }
 
@@ -215,7 +202,6 @@
 
     .rt-resizable-header:last-child {
         overflow: visible;
-        border: 3px solid red !important;
 
         .rt-resizer {
             width: 5px !important;
@@ -396,8 +382,9 @@ button.add-column {
     background-color: white;
     // white-space: nowrap;
 
-    &.row-focused .rt-tr {
+    &.row-focused .rt-td {
         background-color: rgb(255, 246, 246); //$light-color-secondary;
+        // background-color: $light-color;
     }
 
     &.row-wrapped {
@@ -473,15 +460,22 @@ button.add-column {
         outline: none;
     }
 
-    &.focused {
-        // background-color: yellowgreen;
-        // border: 2px solid yellowgreen;
-
+    &.editing {
+        padding: 0;
         input {
             outline: 0;
             border: none;
-            background-color: yellow;
+            background-color: rgb(255, 217, 217);
+            width: 100%;
+            height: 100%;
+            padding: 2px 3px;
+            min-height: 26px;
         }
+    }
+
+    &.focused {
+        // background-color: yellowgreen;
+        // border: 2px solid yellowgreen;
 
         &.inactive {
             // border: 2px solid rgba(255, 255, 0, 0.4);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 508d1f99d..a666a428b 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -477,6 +477,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         //@ts-ignore
         let col = this.columns.map(c => c.heading).indexOf(column!.id);
         let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
+        let isEditing = this.props.isFocused(this.props.Document) && this._cellIsEditing;
+        // TODO: editing border doesn't work :(
         return {
             style: {
                 border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
@@ -497,6 +499,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     setCellIsEditing = (isEditing: boolean): void => {
+        console.log("SET CELL IS EDITING", isEditing);
         this._cellIsEditing = isEditing;
     }
 
-- 
cgit v1.2.3-70-g09d2


From a28a3b79f81e82e4b3368c0e87d3a56c694cc3b4 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Tue, 30 Jul 2019 21:24:45 -0400
Subject: added undo to schema

---
 src/client/views/collections/CollectionSchemaCells.tsx         |  2 ++
 src/client/views/collections/CollectionSchemaHeaders.tsx       |  2 ++
 .../views/collections/CollectionSchemaMovableTableHOC.tsx      |  2 ++
 src/client/views/collections/CollectionSchemaView.tsx          | 10 ++++++++++
 src/client/views/collections/CollectionViewChromes.tsx         |  2 ++
 5 files changed, 18 insertions(+)

(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 61f21006e..4ff65b277 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -26,6 +26,7 @@ import { faExpand } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { KeyCodes } from "../../northstar/utils/KeyCodes";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faExpand);
 
@@ -96,6 +97,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         if (typeof field === "object" && doc) this.props.setPreviewDoc(doc);
     }
 
+    @undoBatch
     applyToDoc = (doc: Doc, row: number, col: number, run: (args?: { [name: string]: any }) => any) => {
         const res = run({ this: doc, $r: row, $c: col, $: (r: number = 0, c: number = 0) => this.props.getField(r + row, c + col) });
         if (!res.success) return false;
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 4f0681f6c..dfd65770e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -11,6 +11,7 @@ import { emptyFunction } from "../../../Utils";
 import { contains } from "typescript-collections/dist/lib/arrays";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
 import { SchemaHeaderField, RandomPastel, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile, faSortAmountDown, faSortAmountUp, faTimes);
 
@@ -286,6 +287,7 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
         this.props.setIsEditing(false);
     }
 
+    @undoBatch
     @action
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 5741c4191..ec40043cc 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -13,6 +13,7 @@ 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";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faGripVertical, faTrash);
 
@@ -196,6 +197,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
         ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
     }
 
+    @undoBatch
     @action
     move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
         let targetView = DocumentManager.Instance.getDocumentView(target);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 26b9de3e7..4d6bf437f 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -176,6 +176,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             />
         </div>;
     }
+
+    @undoBatch
     @action
     setPreviewScript = (script: string) => {
         this.previewScript = script;
@@ -552,6 +554,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.props.setFocused(this.props.Document);
     }
 
+    @undoBatch
     createRow = () => {
         let children = this.childDocs;
 
@@ -563,6 +566,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.childDocs = children;
     }
 
+    @undoBatch
     @action
     createColumn = () => {
         let index = 0;
@@ -581,6 +585,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     @action
     deleteColumn = (key: string) => {
         let columns = this.columns;
@@ -595,6 +600,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         }
     }
 
+    @undoBatch
     @action
     changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
         let columns = this.columns;
@@ -634,6 +640,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return NumCast(typesDoc[column.heading]);
     }
 
+    @undoBatch
     setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
         if (columnTypes.get(columnField.heading)) return;
 
@@ -656,6 +663,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         // }
     }
 
+    @undoBatch
     setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
         let columns = this.columns;
         let index = columns.indexOf(columnField);
@@ -671,6 +679,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
         let columns = [...columnsValues];
         let oldIndex = columns.indexOf(toMove);
@@ -683,6 +692,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     @action
     setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
         let columns = this.columns;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index bf1f35a92..ecf78b8c1 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -377,6 +377,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewChromeProps> {
     // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
 
+    @undoBatch
     togglePreview = () => {
         let dividerWidth = 4;
         let borderWidth = Number(COLLECTION_BORDER_WIDTH);
@@ -386,6 +387,7 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
         this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
     }
 
+    @undoBatch
     @action
     toggleTextwrap = async () => {
         let textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
-- 
cgit v1.2.3-70-g09d2

