From 1eb965a5d9c8aaebf1970bc645edecfb7017b601 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 20 Apr 2019 03:29:35 -0400
Subject: Made the switch in a couple more classes

---
 src/client/views/nodes/DocumentContentsView.tsx | 26 +++----------------------
 1 file changed, 3 insertions(+), 23 deletions(-)

(limited to 'src/client/views/nodes/DocumentContentsView.tsx')

diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 07599c345..273401111 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,9 +1,5 @@
 import { computed } from "mobx";
 import { observer } from "mobx-react";
-import { FieldWaiting, Field } from "../../../fields/Field";
-import { Key } from "../../../fields/Key";
-import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
 import { CollectionPDFView } from "../collections/CollectionPDFView";
@@ -22,46 +18,30 @@ import { VideoBox } from "./VideoBox";
 import { WebBox } from "./WebBox";
 import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
 import React = require("react");
-import { Document } from "../../../fields/Document";
 import { FieldViewProps } from "./FieldView";
 import { Without, OmitKeys } from "../../../Utils";
+import { Cast } from "../../../new_fields/Types";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
 export interface JsxBindings {
     props: BindingProps;
-    [keyName: string]: BindingProps | Field;
 }
 
 @observer
 export class DocumentContentsView extends React.Component<DocumentViewProps & {
     isSelected: () => boolean,
     select: (ctrl: boolean) => void,
-    layoutKey: Key
+    layoutKey: string
 }> {
-    @computed get layout(): string { return this.props.Document.GetText(this.props.layoutKey, "<p>Error loading layout data</p>"); }
-    @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); }
-    @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); }
-
+    @computed get layout(): string { return Cast(this.props.Document[this.props.layoutKey], "string", "<p>Error loading layout data</p>"); }
 
     CreateBindings(): JsxBindings {
         let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) };
-
-        for (const key of this.layoutKeys) {
-            bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname  e.g,   "DataKey" => KeyStore.Data
-        }
-        for (const key of this.layoutFields) {
-            let field = this.props.Document.Get(key);
-            bindings[key.Name] = field && field !== FieldWaiting ? field.GetValue() : field;
-        }
         return bindings;
     }
 
     render() {
-        let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField);
-        if (!lkeys || lkeys === FieldWaiting) {
-            return <p>Error loading layout keys</p>;
-        }
         return <JsxParser
             components={{ FormattedTextBox, ImageBox, IconBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
             bindings={this.CreateBindings()}
-- 
cgit v1.2.3-70-g09d2


From 5ffb2f404a6a3da851c0fe7318b73f5c7723c3d7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Tue, 23 Apr 2019 01:05:12 -0400
Subject: Did most of Documents and some other stuff

---
 src/Utils.ts                                       |  19 +-
 src/client/documents/Documents.ts                  | 202 +++++++++------------
 src/client/northstar/dash-fields/HistogramField.ts |   2 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |   2 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   2 +-
 src/new_fields/Doc.ts                              |  31 +++-
 src/new_fields/List.ts                             |   2 +-
 src/new_fields/Types.ts                            |   2 +-
 src/new_fields/util.ts                             |  12 +-
 9 files changed, 139 insertions(+), 135 deletions(-)

(limited to 'src/client/views/nodes/DocumentContentsView.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 066d653f5..59ff45dc9 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -86,13 +86,20 @@ export class Utils {
     }
 }
 
-export function OmitKeys(obj: any, keys: any, addKeyFunc?: (dup: any) => void) {
+export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void): { omit: any, extract: any } {
+    const omit: any = { ...obj };
+    const extract: any = {};
+    keys.forEach(key => {
+        extract[key] = omit[key];
+        delete omit[key];
+    });
+    addKeyFunc && addKeyFunc(omit);
+    return { omit, extract };
+}
+
+export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
     var dup: any = {};
-    for (var key in obj) {
-        if (keys.indexOf(key) === -1) {
-            dup[key] = obj[key];
-        }
-    }
+    keys.forEach(key => dup[key] = obj[key]);
     addKeyFunc && addKeyFunc(dup);
     return dup;
 }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b0bb74d89..a145a76c9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,20 +1,6 @@
-import { AudioField } from "../../fields/AudioField";
-import { Document } from "../../fields/Document";
-import { Field, Opt } from "../../fields/Field";
-import { HtmlField } from "../../fields/HtmlField";
-import { ImageField } from "../../fields/ImageField";
-import { InkField, StrokeData } from "../../fields/InkField";
-import { Key } from "../../fields/Key";
-import { KeyStore } from "../../fields/KeyStore";
-import { ListField } from "../../fields/ListField";
-import { PDFField } from "../../fields/PDFField";
-import { TextField } from "../../fields/TextField";
-import { VideoField } from "../../fields/VideoField";
-import { WebField } from "../../fields/WebField";
 import { HistogramField } from "../northstar/dash-fields/HistogramField";
 import { HistogramBox } from "../northstar/dash-nodes/HistogramBox";
 import { HistogramOperation } from "../northstar/operations/HistogramOperation";
-import { Server } from "../Server";
 import { CollectionPDFView } from "../views/collections/CollectionPDFView";
 import { CollectionVideoView } from "../views/collections/CollectionVideoView";
 import { CollectionView } from "../views/collections/CollectionView";
@@ -34,39 +20,47 @@ import { AttributeTransformationModel } from "../northstar/core/attribute/Attrib
 import { AggregateFunction } from "../northstar/model/idea/idea";
 import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss";
 import { IconBox } from "../views/nodes/IconBox";
-import { IconField } from "../../fields/IconFIeld";
+import { Field, Doc, Opt } from "../../new_fields/Doc";
+import { OmitKeys } from "../../Utils";
+import { ImageField, VideoField, AudioField, PdfField, WebField } from "../../new_fields/URLField";
+import { HtmlField } from "../../new_fields/HtmlField";
+import { List } from "../../new_fields/List";
+import { Cast } from "../../new_fields/Types";
 
 export interface DocumentOptions {
     x?: number;
     y?: number;
-    ink?: Map<string, StrokeData>;
+    // ink?: Map<string, StrokeData>;
     width?: number;
     height?: number;
     nativeWidth?: number;
     nativeHeight?: number;
     title?: string;
-    panx?: number;
-    pany?: number;
+    panX?: number;
+    panY?: number;
     page?: number;
     scale?: number;
     layout?: string;
-    layoutKeys?: Key[];
     viewType?: number;
     backgroundColor?: string;
     copyDraggedItems?: boolean;
+    backgroundLayout?: string;
+    curPage?: number;
+    // [key: string]: Opt<Field>;
 }
+const delegateKeys = ["x", "y", "width", "height", "panX", "panY"];
 
-export namespace Documents {
-    let textProto: Document;
-    let histoProto: Document;
-    let imageProto: Document;
-    let webProto: Document;
-    let collProto: Document;
-    let kvpProto: Document;
-    let videoProto: Document;
-    let audioProto: Document;
-    let pdfProto: Document;
-    let iconProto: Document;
+export namespace Docs {
+    let textProto: Doc;
+    let histoProto: Doc;
+    let imageProto: Doc;
+    let webProto: Doc;
+    let collProto: Doc;
+    let kvpProto: Doc;
+    let videoProto: Doc;
+    let audioProto: Doc;
+    let pdfProto: Doc;
+    let iconProto: Doc;
     const textProtoId = "textProto";
     const histoProtoId = "histoProto";
     const pdfProtoId = "pdfProto";
@@ -92,110 +86,80 @@ export namespace Documents {
             iconProto = fields[iconProtoId] as Document || CreateIconPrototype();
         });
     }
-    function assignOptions(doc: Document, options: DocumentOptions): Document {
-        if (options.nativeWidth !== undefined) { doc.SetNumber(KeyStore.NativeWidth, options.nativeWidth); }
-        if (options.nativeHeight !== undefined) { doc.SetNumber(KeyStore.NativeHeight, options.nativeHeight); }
-        if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); }
-        if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
-        if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
-        if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
-        if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
-        if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
-        if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
-        if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
-        if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
-        if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
-        if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); }
-        return doc;
-    }
 
-    function assignToDelegate(doc: Document, options: DocumentOptions): Document {
-        if (options.x !== undefined) { doc.SetNumber(KeyStore.X, options.x); }
-        if (options.y !== undefined) { doc.SetNumber(KeyStore.Y, options.y); }
-        if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
-        if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
-        if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); }
-        if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); }
-        return doc;
+    function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Doc {
+        return Doc.assign(new Doc(protoId, true), { ...options, title: title, layout: layout });
     }
-
-    function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document {
-        return assignOptions(new Document(protoId), { ...options, title: title, layout: layout });
+    function SetInstanceOptions<U extends Field>(doc: Doc, options: DocumentOptions, value: U) {
+        const deleg = Doc.MakeDelegate(doc);
+        deleg.data = value;
+        return Doc.assign(deleg, options);
     }
-    function SetInstanceOptions<T, U extends Field & { Data: T }>(doc: Document, options: DocumentOptions, value: [T, { new(): U }] | Document, id?: string) {
-        var deleg = doc.MakeDelegate(id);
-        if (value instanceof Document) {
-            deleg.Set(KeyStore.Data, value);
-        }
-        else {
-            deleg.SetData(KeyStore.Data, value[0], value[1]);
-        }
-        return assignOptions(deleg, options);
+    function SetDelegateOptions<U extends Field>(doc: Doc, options: DocumentOptions) {
+        const deleg = Doc.MakeDelegate(doc);
+        return Doc.assign(deleg, options);
     }
 
-    function CreateImagePrototype(): Document {
+    function CreateImagePrototype(): Doc {
         let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"),
-            { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
-        imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString());
-        imageProto.SetNumber(KeyStore.CurPage, 0);
+            { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0 });
         return imageProto;
     }
 
-    function CreateHistogramPrototype(): Document {
+    function CreateHistogramPrototype(): Doc {
         let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"),
-            { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
-        histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString());
+            { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString() });
         return histoProto;
     }
-    function CreateIconPrototype(): Document {
+    function CreateIconPrototype(): Doc {
         let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(),
-            { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data] });
+            { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE) });
         return iconProto;
     }
-    function CreateTextPrototype(): Document {
+    function CreateTextPrototype(): Doc {
         let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(),
-            { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+            { x: 0, y: 0, width: 300, height: 150 });
         return textProto;
     }
-    function CreatePdfPrototype(): Document {
+    function CreatePdfPrototype(): Doc {
         let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"),
-            { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
-        pdfProto.SetNumber(KeyStore.CurPage, 1);
-        pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString());
+            { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 });
         return pdfProto;
     }
-    function CreateWebPrototype(): Document {
+    function CreateWebPrototype(): Doc {
         let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(),
-            { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] });
+            { x: 0, y: 0, width: 300, height: 300 });
         return webProto;
     }
-    function CreateCollectionPrototype(): Document {
+    function CreateCollectionPrototype(): Doc {
         let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
-            { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
+            { panX: 0, panY: 0, scale: 1, width: 500, height: 500 });
         return collProto;
     }
 
-    function CreateKVPPrototype(): Document {
+    function CreateKVPPrototype(): Doc {
         let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(),
-            { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+            { x: 0, y: 0, width: 300, height: 150 });
         return kvpProto;
     }
-    function CreateVideoPrototype(): Document {
+    function CreateVideoPrototype(): Doc {
         let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
-            { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
-        videoProto.SetNumber(KeyStore.CurPage, 0);
-        videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
+            { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0 });
         return videoProto;
     }
-    function CreateAudioPrototype(): Document {
+    function CreateAudioPrototype(): Doc {
         let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(),
-            { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+            { x: 0, y: 0, width: 300, height: 150 });
         return audioProto;
     }
 
+    function CreateInstance(proto: Doc, data: Field, options: DocumentOptions) {
+        const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys);
+        return SetDelegateOptions(SetInstanceOptions(proto, protoProps, data), delegateProps);
+    }
 
     export function ImageDocument(url: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(imageProto, options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
+        return CreateInstance(imageProto, new ImageField(new URL(url)), options);
         // let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
         //     [new URL(url), ImageField]);
         // doc.SetText(KeyStore.Caption, "my caption...");
@@ -204,23 +168,23 @@ export namespace Documents {
         // return doc;
     }
     export function VideoDocument(url: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(videoProto, options, [new URL(url), VideoField]), options);
+        return CreateInstance(videoProto, new VideoField(new URL(url)), options);
     }
     export function AudioDocument(url: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(audioProto, options, [new URL(url), AudioField]), options);
+        return CreateInstance(audioProto, new AudioField(new URL(url)), options);
     }
 
-    export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}, id?: string, delegId?: string) {
-        return assignToDelegate(SetInstanceOptions(histoProto, options, [histoOp, HistogramField], id).MakeDelegate(delegId), options);
+    export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}) {
+        return CreateInstance(histoProto, new HistogramField(histoOp), options);
     }
     export function TextDocument(options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(textProto, options, ["", TextField]).MakeDelegate(), options);
+        return CreateInstance(textProto, "", options);
     }
     export function IconDocument(icon: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(iconProto, { width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data], layout: IconBox.LayoutString(), ...options }, [icon, IconField]), options);
+        return CreateInstance(iconProto, new IconField(icon), options);
     }
     export function PdfDocument(url: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(pdfProto, options, [new URL(url), PDFField]).MakeDelegate(), options);
+        return CreateInstance(pdfProto, new PdfField(new URL(url)), options);
     }
     export async function DBDocument(url: string, options: DocumentOptions = {}) {
         let schemaName = options.title ? options.title : "-no schema-";
@@ -248,35 +212,35 @@ export namespace Documents {
         return Documents.TreeDocument([], { width: 50, height: 100, title: schemaName });
     }
     export function WebDocument(url: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(webProto, options, [new URL(url), WebField]).MakeDelegate(), options);
+        return CreateInstance(webProto, new WebField(new URL(url)), options);
     }
     export function HtmlDocument(html: string, options: DocumentOptions = {}) {
-        return assignToDelegate(SetInstanceOptions(webProto, options, [html, HtmlField]).MakeDelegate(), options);
+        return CreateInstance(webProto, new HtmlField(html), options);
     }
-    export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) {
-        return assignToDelegate(SetInstanceOptions(kvpProto, options, document, id), options);
+    export function KVPDocument(document: Doc, options: DocumentOptions = {}) {
+        return CreateInstance(kvpProto, document, options);
     }
-    export function FreeformDocument(documents: Array<Document>, options: DocumentOptions, id?: string, makePrototype: boolean = true) {
+    export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions, makePrototype: boolean = true) {
         if (!makePrototype) {
-            return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id);
+            return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, new List(documents));
         }
-        return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options);
+        return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Freeform });
     }
-    export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
-        return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options);
+    export function SchemaDocument(documents: Array<Doc>, options: DocumentOptions) {
+        return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Schema });
     }
-    export function TreeDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
-        return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options);
+    export function TreeDocument(documents: Array<Doc>, options: DocumentOptions) {
+        return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Tree });
     }
-    export function DockDocument(config: string, options: DocumentOptions, id?: string) {
-        return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options);
+    export function DockDocument(config: string, options: DocumentOptions) {
+        return CreateInstance(collProto, config, { ...options, viewType: CollectionViewType.Docking });
     }
 
-    export function CaptionDocument(doc: Document) {
-        const captionDoc = doc.CreateAlias();
-        captionDoc.SetText(KeyStore.OverlayLayout, FixedCaption());
-        captionDoc.SetNumber(KeyStore.Width, doc.GetNumber(KeyStore.Width, 0));
-        captionDoc.SetNumber(KeyStore.Height, doc.GetNumber(KeyStore.Height, 0));
+    export function CaptionDocument(doc: Doc) {
+        const captionDoc = Doc.MakeAlias(doc);
+        captionDoc.overlayLayout = FixedCaption();
+        captionDoc.width = Cast(doc.width, "number", 0);
+        captionDoc.height = Cast(doc.height, "number", 0);
         return captionDoc;
     }
 
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index c699691a4..932166b21 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -15,7 +15,7 @@ export class HistogramField extends BasicField<HistogramOperation> {
     }
 
     toString(): string {
-        return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']));
+        return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit);
     }
 
     Copy(): Field {
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c6eea5623..7b7b7e65e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -71,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     @computed
     get docView() {
-        return <DocumentView {...OmitKeys(this.props, ['zoomFade'])}
+        return <DocumentView {...OmitKeys(this.props, ['zoomFade']).omit}
             ContentScaling={this.contentScaling}
             ScreenToLocalTransform={this.getTransform}
             PanelWidth={this.panelWidth}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 273401111..c90ca6d17 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -37,7 +37,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     @computed get layout(): string { return Cast(this.props.Document[this.props.layoutKey], "string", "<p>Error loading layout data</p>"); }
 
     CreateBindings(): JsxBindings {
-        let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) };
+        let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit };
         return bindings;
     }
 
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5ae095e68..987cb2cc4 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -4,7 +4,7 @@ import { autoObject, SerializationHelper, Deserializable } from "../client/util/
 import { Utils } from "../Utils";
 import { DocServer } from "../client/DocServer";
 import { setter, getter, getField } from "./util";
-import { Cast, ToConstructor } from "./Types";
+import { Cast, ToConstructor, PromiseValue } from "./Types";
 
 export type FieldId = string;
 export const HandleUpdate = Symbol("HandleUpdate");
@@ -54,7 +54,8 @@ export class Doc extends RefField {
         return doc;
     }
 
-    [key: string]: Field | FieldWaiting | undefined;
+    proto: FieldResult<Doc>;
+    [key: string]: FieldResult;
 
     @serializable(alias("fields", map(autoObject())))
     @observable
@@ -92,6 +93,32 @@ export namespace Doc {
             proto[key] = value;
         }
     }
+    export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>) {
+        for (const key in fields) {
+            if (fields.hasOwnProperty(key)) {
+                const value = fields[key];
+                if (value !== undefined) {
+                    doc[key] = value;
+                }
+            }
+        }
+        return doc;
+    }
+
+    export function MakeAlias(doc: Doc) {
+        const alias = new Doc;
+
+        PromiseValue(Cast(doc.proto, Doc)).then(proto => {
+            if (proto) {
+                alias.proto = proto;
+            }
+        });
+
+        return alias;
+    }
+
+    export function MakeDelegate(doc: Doc): Doc;
+    export function MakeDelegate(doc: Opt<Doc>): Opt<Doc>;
     export function MakeDelegate(doc: Opt<Doc>): Opt<Doc> {
         if (!doc) {
             return undefined;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index f3ec9e2c5..f01ac210a 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -33,4 +33,4 @@ class ListImpl<T extends Field> extends ObjectField {
     private [Self] = this;
 }
 export type List<T extends Field> = ListImpl<T> & T[];
-export const List: { new <T extends Field>(): List<T> } = ListImpl as any;
\ No newline at end of file
+export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any;
\ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 246b0624e..55083765a 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -68,7 +68,7 @@ export function FieldValue<T extends Field>(field: Opt<T> | Promise<Opt<T>>, def
 }
 
 export interface PromiseLike<T> {
-    then(callback: (field: Opt<T> | PromiseLike<T>) => void): void;
+    then(callback: (field: Opt<T>) => void): void;
 }
 export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> {
     return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } };
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 3806044bd..2d9721b2e 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -2,6 +2,7 @@ import { UndoManager } from "../client/util/UndoManager";
 import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
 import { SerializationHelper } from "../client/util/SerializationHelper";
 import { ProxyField } from "./Proxy";
+import { FieldValue } from "./Types";
 
 export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
     if (SerializationHelper.IsSerializing()) {
@@ -61,11 +62,16 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
         return field.value(callback);
     }
     if (field === undefined && !ignoreProto) {
-        const proto = getField(target, "prototype", true);
+        const proto = getField(target, "proto", true);
         if (proto instanceof Doc) {
             let field = proto[prop];
-            callback && callback(field === null ? undefined : field);
-            return field;
+            if (field instanceof Promise) {
+                callback && field.then(callback);
+                return undefined;
+            } else {
+                callback && callback(field);
+                return field;
+            }
         }
     }
     callback && callback(field);
-- 
cgit v1.2.3-70-g09d2


From 407c104f0ad0957d71f73c14f5b835fab387ecd2 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 2 May 2019 00:50:08 -0400
Subject: fixed up templates a bit. starting on summarization

---
 src/client/views/Templates.tsx                     |  3 ++
 .../collections/collectionFreeForm/MarqueeView.tsx |  5 +++-
 src/client/views/nodes/DocumentContentsView.tsx    | 25 +++++++++++++++--
 src/client/views/nodes/DocumentView.tsx            | 32 ++++------------------
 4 files changed, 36 insertions(+), 29 deletions(-)

(limited to 'src/client/views/nodes/DocumentContentsView.tsx')

diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 25d89772e..e17dd2354 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -53,6 +53,9 @@ export namespace Templates {
     export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div><div style="height:100%; width:100%;position:absolute;">{layout}</div><div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; padding:2px 10px">{props.Document.title}</div></div>`
     );
+    export const Summary = new Template("Title", TemplatePosition.InnerTop,
+        `<div><div style="height:100%; width:100%;position:absolute;">{layout}</div><div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; padding:2px 10px">{props.Document.doc1.title}</div></div>`
+    );
 
     export const TemplateList: Template[] = [Title, OuterCaption, InnerCaption, SideCaption];
 
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 85a12defa..c58e7780c 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -13,6 +13,8 @@ import { Utils } from "../../../../Utils";
 import { Doc } from "../../../../new_fields/Doc";
 import { NumCast, Cast } from "../../../../new_fields/Types";
 import { InkField, StrokeData } from "../../../../new_fields/InkField";
+import { Templates } from "../../Templates";
+import { List } from "../../../../new_fields/List";
 
 interface MarqueeViewProps {
     getContainerTransform: () => Transform;
@@ -178,7 +180,8 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
             // SelectionManager.DeselectAll();
             if (e.key === "r") {
                 let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" });
-                Doc.MakeLink(summary.proto!, newCollection.proto!);
+                summary.doc1 = newCollection.proto!;
+                summary.templates = new List<string>([Templates.Summary.Layout]);
                 this.props.addLiveTextDocument(summary);
                 e.preventDefault();
             }
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 794442469..24e8a36ae 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -20,7 +20,8 @@ import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
 import React = require("react");
 import { FieldViewProps } from "./FieldView";
 import { Without, OmitKeys } from "../../../Utils";
-import { Cast } from "../../../new_fields/Types";
+import { Cast, StrCast } from "../../../new_fields/Types";
+import { List } from "../../../new_fields/List";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
@@ -40,11 +41,31 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         return { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit };
     }
 
+    @computed get templates(): List<string> {
+        let field = this.props.Document.templates;
+        if (field && field instanceof List) {
+            return field;
+        }
+        return new List<string>();
+    }
+    set templates(templates: List<string>) { this.props.Document.templates = templates; }
+    get finalLayout() {
+        const baseLayout = this.layout;
+        let base = baseLayout;
+        let layout = baseLayout;
+
+        this.templates.forEach(template => {
+            layout = template.replace("{layout}", base);
+            base = layout;
+        });
+        return layout;
+    }
+
     render() {
         return <JsxParser
             components={{ FormattedTextBox, ImageBox, IconBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
             bindings={this.CreateBindings()}
-            jsx={this.layout}
+            jsx={this.finalLayout}
             showWarnings={true}
             onError={(test: any) => { console.log(test); }}
         />;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ae2d3af13..e83f3fcba 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -243,42 +243,22 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
-    updateLayout = async () => {
-        const baseLayout = await StrCast(this.props.Document.baseLayout);
-        if (baseLayout) {
-            let base = baseLayout;
-            let layout = baseLayout;
-
-            this.templates.forEach(template => {
-                layout = template.replace("{layout}", base);
-                base = layout;
-            });
-
-            this.props.Document.layout = layout;
-        }
-    }
 
     @action
     addTemplate = (template: Template) => {
-        let templates = this.templates;
-        templates.push(template.Layout);
-        this.templates = new List<string>(templates.map(t => t));
-        this.updateLayout();
+        this.templates.push(template.Layout);
+        this.templates = this.templates;
     }
 
     @action
     removeTemplate = (template: Template) => {
-        let templates = this.templates;
-        for (let i = 0; i < templates.length; i++) {
-            let temp = templates[i];
-            if (temp === template.Layout) {
-                templates.splice(i, 1);
+        for (let i = 0; i < this.templates.length; i++) {
+            if (this.templates[i] === template.Layout) {
+                this.templates.splice(i, 1);
                 break;
             }
         }
-        templates = new List<string>(templates.splice(0, templates.length));
-        this.templates = templates;
-        this.updateLayout();
+        this.templates = this.templates;
     }
 
     @action
-- 
cgit v1.2.3-70-g09d2


From a78282cdf7fbb99386484640e1fb89d4b9b0cbee Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 2 May 2019 16:19:07 -0400
Subject: fixed some things with trees and summaries.

---
 src/client/views/Main.tsx                                    |  3 +--
 src/client/views/Templates.tsx                               | 12 +++++++++++-
 src/client/views/collections/CollectionTreeView.tsx          | 10 +++++++---
 .../views/collections/collectionFreeForm/MarqueeView.tsx     |  4 +++-
 src/client/views/nodes/DocumentContentsView.tsx              |  3 ++-
 src/client/views/nodes/FieldView.tsx                         | 11 ++++-------
 src/client/views/nodes/ImageBox.scss                         |  2 ++
 src/new_fields/List.ts                                       |  6 +++---
 src/server/authentication/models/current_user_utils.ts       |  2 ++
 9 files changed, 35 insertions(+), 18 deletions(-)

(limited to 'src/client/views/nodes/DocumentContentsView.tsx')

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index a07a2d5b1..97eb73d7f 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -144,8 +144,7 @@ export class Main extends React.Component {
     createNewWorkspace = async (id?: string) => {
         const list = Cast(CurrentUserUtils.UserDocument.data, listSpec(Doc));
         if (list) {
-            let libraryDoc = Docs.TreeDocument([CurrentUserUtils.UserDocument], { x: 0, y: 400, title: `Library: ${CurrentUserUtils.email} ${list.length + 1}` });
-            libraryDoc.excludeFromLibrary = true;
+            let libraryDoc = await (CurrentUserUtils.UserDocument.library as Doc);
             let freeformDoc = Docs.FreeformDocument([], { x: 0, y: 400, title: `WS collection ${list.length + 1}` });
             var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(libraryDoc, 150), CollectionDockingView.makeDocumentConfig(freeformDoc, 600)] }] };
             let mainDoc = Docs.DockDocument([libraryDoc, freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${list.length + 1}` });
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index e17dd2354..668ae5312 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -54,7 +54,17 @@ export namespace Templates {
         `<div><div style="height:100%; width:100%;position:absolute;">{layout}</div><div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; padding:2px 10px">{props.Document.title}</div></div>`
     );
     export const Summary = new Template("Title", TemplatePosition.InnerTop,
-        `<div><div style="height:100%; width:100%;position:absolute;">{layout}</div><div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; padding:2px 10px">{props.Document.doc1.title}</div></div>`
+        `<div style="height:100%; width:100%;position:absolute; margin:0; padding: 0">
+            <div style="height:60%; width:100%;position:absolute;background:yellow; padding:0; margin:0">
+                {layout}
+            </div>
+            <div style="bottom:0px; height:40%; width:50%; position:absolute; background-color: rgba(0, 0, 0, .4); color: white;">
+                <FieldView {...props} fieldKey={"doc1"} />
+            </div>
+            <div style="bottom:0; left: 50%; height:40%; width:50%; position:absolute; background-color: rgba(0, 0, 0, .4); color: white;">
+                <FieldView {...props} fieldKey={"doc2"} />
+            </div>
+        </div>`
     );
 
     export const TemplateList: Template[] = [Title, OuterCaption, InnerCaption, SideCaption];
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 48b226615..2cef1462b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
 import { faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from "mobx";
+import { action, observable, trace } from "mobx";
 import { observer } from "mobx-react";
 import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager";
 import { EditableView } from "../EditableView";
@@ -145,8 +145,11 @@ class TreeView extends React.Component<TreeViewProps> {
         </div>;
     }
     public static GetChildElements(docs: Doc[], remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType) {
-        return docs.filter(child => !child.excludeFromLibrary).map(child =>
-            <TreeView document={child} key={child[Id]} deleteDoc={remove} moveDocument={move} dropAction={dropAction} />);
+        return docs.filter(child => !child.excludeFromLibrary).filter(doc => FieldValue(doc)).map(child => {
+            console.log("child = " + child[Id]);
+            return <TreeView document={child} key={child[Id]} deleteDoc={remove} moveDocument={move} dropAction={dropAction} />
+        }
+        );
     }
 }
 
@@ -168,6 +171,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
         }
     }
     render() {
+        trace();
         const children = this.children;
         let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType;
         if (!children) {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index c58e7780c..82027a6f2 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -180,7 +180,9 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
             // SelectionManager.DeselectAll();
             if (e.key === "r") {
                 let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" });
-                summary.doc1 = newCollection.proto!;
+                summary.doc1 = selected[0];
+                if (selected.length > 1)
+                    summary.doc2 = selected[1];
                 summary.templates = new List<string>([Templates.Summary.Layout]);
                 this.props.addLiveTextDocument(summary);
                 e.preventDefault();
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 24e8a36ae..ddfe79a5c 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -15,6 +15,7 @@ import { IconBox } from "./IconBox";
 import { KeyValueBox } from "./KeyValueBox";
 import { PDFBox } from "./PDFBox";
 import { VideoBox } from "./VideoBox";
+import { FieldView } from "./FieldView";
 import { WebBox } from "./WebBox";
 import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
 import React = require("react");
@@ -63,7 +64,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
 
     render() {
         return <JsxParser
-            components={{ FormattedTextBox, ImageBox, IconBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
+            components={{ FormattedTextBox, ImageBox, IconBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
             bindings={this.CreateBindings()}
             jsx={this.finalLayout}
             showWarnings={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 63009f2db..a1e083b36 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -57,12 +57,12 @@ export class FieldView extends React.Component<FieldViewProps> {
     }
     render() {
         const field = this.field;
-        if (!field) {
+        if (field === undefined) {
             return <p>{'<null>'}</p>;
         }
-        if (typeof field === "string") {
-            return <p>{field}</p>;
-        }
+        // if (typeof field === "string") {
+        //     return <p>{field}</p>;
+        // }
         else if (field instanceof RichTextField) {
             return <FormattedTextBox {...this.props} />;
         }
@@ -108,9 +108,6 @@ export class FieldView extends React.Component<FieldViewProps> {
         // else if (field instanceof HtmlField) {
         //     return <WebBox {...this.props} />
         // }
-        else if (typeof field === "number") {
-            return <p>{field}</p>;
-        }
         else if (!(field instanceof Promise)) {
             return <p>{JSON.stringify(field)}</p>;
         }
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 9fe211df0..2316a050e 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -10,6 +10,8 @@
 }
 .imageBox-cont-interactive {
   pointer-events: all;
+  width:100%;
+  height:auto;
 }
 
 .imageBox-dot {
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 1c4b96c81..db7932cec 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,7 +2,7 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
 import { Field, Update, Self, FieldResult } from "./Doc";
 import { setter, getter, deleteProperty } from "./util";
 import { serializable, alias, list } from "serializr";
-import { observable } from "mobx";
+import { observable, action } from "mobx";
 import { ObjectField, OnUpdate, Copy } from "./ObjectField";
 import { RefField } from "./RefField";
 import { ProxyField } from "./Proxy";
@@ -25,12 +25,12 @@ const listHandlers: any = {
         this[Update]();
         return field;
     },
-    push(...items: any[]) {
+    push: action(function (this: any, ...items: any[]) {
         items = items.map(toObjectField);
         const res = this[Self].__fields.push(...items);
         this[Update]();
         return res;
-    },
+    }),
     reverse() {
         const res = this[Self].__fields.reverse();
         this[Update]();
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 9db470ca0..93c2afb1d 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -26,6 +26,8 @@ export class CurrentUserUtils {
         doc.title = this.email;
         doc.data = new List<Doc>();
         doc.optionalRightCollection = Docs.SchemaDocument([], { title: "Pending documents" });
+        doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` });
+        (doc.library as Doc).excludeFromLibrary = true;
         return doc;
     }
 
-- 
cgit v1.2.3-70-g09d2


From 14232f5951af02d5a10ce0435a8b38a4e0502cbb Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Thu, 2 May 2019 23:13:07 -0400
Subject: Made DocumentContents JsxParser an observer

---
 src/client/views/nodes/DocumentContentsView.tsx | 11 ++++++++++-
 src/new_fields/Doc.ts                           |  1 -
 2 files changed, 10 insertions(+), 2 deletions(-)

(limited to 'src/client/views/nodes/DocumentContentsView.tsx')

diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index ddfe79a5c..bbc927b5a 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -30,6 +30,15 @@ export interface JsxBindings {
     props: BindingProps;
 }
 
+class ObserverJsxParser1 extends JsxParser {
+    constructor(props: any) {
+        super(props);
+        observer(this as any);
+    }
+}
+
+const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
+
 @observer
 export class DocumentContentsView extends React.Component<DocumentViewProps & {
     isSelected: () => boolean,
@@ -63,7 +72,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     }
 
     render() {
-        return <JsxParser
+        return <ObserverJsxParser
             components={{ FormattedTextBox, ImageBox, IconBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
             bindings={this.CreateBindings()}
             jsx={this.finalLayout}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 978aacaac..3eea6d2b2 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -10,7 +10,6 @@ import { List } from "./List";
 import { ObjectField, Parent, OnUpdate } from "./ObjectField";
 import { RefField, FieldId, Id, HandleUpdate } from "./RefField";
 import { Docs } from "../client/documents/Documents";
-// import { Docs } from "../client/documents/Documents";
 
 export function IsField(field: any): field is Field {
     return (typeof field === "string")
-- 
cgit v1.2.3-70-g09d2

