From a16e6592caafb601b59c3d9f7609e8c1af231eba Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 20 Mar 2019 18:00:39 -0400
Subject: initial

---
 src/client/views/Main.tsx | 47 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 8 deletions(-)

(limited to 'src/client/views/Main.tsx')

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index ac51a7d87..b27f63e52 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,4 +1,4 @@
-import { action, configure, observable, runInAction, trace, computed } from 'mobx';
+import { action, configure, observable, runInAction, trace, computed, reaction } from 'mobx';
 import "normalize.css";
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
@@ -22,7 +22,6 @@ import "./Main.scss";
 import { observer } from 'mobx-react';
 import { InkingControl } from './InkingControl';
 import { RouteStore } from '../../server/RouteStore';
-import { json } from 'body-parser';
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faFont } from '@fortawesome/free-solid-svg-icons';
@@ -42,9 +41,10 @@ import { ServerUtils } from '../../server/ServerUtil';
 import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
 import { Field, Opt } from '../../fields/Field';
 import { ListField } from '../../fields/ListField';
-import { map } from 'bluebird';
 import { Gateway, Settings } from '../northstar/manager/Gateway';
-import { Catalog } from '../northstar/model/idea/idea';
+import { Catalog, Schema, Attribute, AttributeGroup } from '../northstar/model/idea/idea';
+import { ArrayUtil } from '../northstar/utils/ArrayUtil';
+import '../northstar/model/ModelExtensions'
 
 @observer
 export class Main extends React.Component {
@@ -88,16 +88,45 @@ export class Main extends React.Component {
 
         this.initEventListeners();
         Documents.initProtos(() => this.initAuthenticationRouters());
+
+        reaction(() => [this.mainContainer, this.ActiveSchema],
+            () => {
+                if (this.mainContainer && this.ActiveSchema) {
+                    if (!this.mainContainer!.GetTAsync(KeyStore.ActiveDB, ListField, field => this.NorthstarCatalog = field!.Data as Document[])) {
+                        this.NorthstarCatalog = this.GetAllAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
+                        this.mainContainer!.SetData(KeyStore.ActiveDB, this.NorthstarCatalog, ListField);
+                    }
+                }
+            })
     }
 
+    NorthstarCatalog: Document[] = [];
+    @observable ActiveSchema: Schema | undefined;
     @action SetNorthstarCatalog(ctlog: Catalog) {
         this._northstarCatalog = ctlog;
-        if (this._northstarCatalog) {
+        if (this._northstarCatalog && this._northstarCatalog.schemas) {
             console.log("CATALOG " + this._northstarCatalog.schemas);
+            this.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(this._northstarCatalog.schemas!, (s: Schema) => s.displayName === "mimic");
         }
     }
+    public GetAllAttributes() {
+        if (!this.ActiveSchema || !this.ActiveSchema.rootAttributeGroup) {
+            return [];
+        }
+        const recurs = (attrs: Attribute[], g: AttributeGroup) => {
+            if (g.attributes) {
+                attrs.push.apply(attrs, g.attributes);
+                if (g.attributeGroups) {
+                    g.attributeGroups.forEach(ng => recurs(attrs, ng));
+                }
+            }
+        };
+        const allAttributes: Attribute[] = new Array<Attribute>();
+        recurs(allAttributes, this.ActiveSchema.rootAttributeGroup);
+        return allAttributes;
+    }
     async initializeNorthstar(): Promise<void> {
-        let envPath = "assets/env.json";
+        let envPath = "/assets/env.json";
         const response = await fetch(envPath, {
             redirect: "follow",
             method: "GET",
@@ -251,7 +280,7 @@ export class Main extends React.Component {
 
         let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
         let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
-        let addSchemaNode = action(() => Documents.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" }));
+        let addSchemaNode = action(() => Documents.SchemaDocument(this.NorthstarCatalog, { width: 200, height: 200, title: "a schema collection" }));
         let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" }));
         let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
         let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
@@ -269,7 +298,9 @@ export class Main extends React.Component {
             [React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
         ]
 
-        let addClick = (creator: () => Document) => action(() => this.mainfreeform!.GetList<Document>(KeyStore.Data, []).push(creator()));
+        let addClick = (creator: () => Document) => action(() => {
+            this.mainfreeform!.GetList<Document>(KeyStore.Data, []).push(creator())
+        });
 
         return < div id="add-nodes-menu" >
             <input type="checkbox" id="add-menu-toggle" />
-- 
cgit v1.2.3-70-g09d2


From d888a56abfee2934e0426258c7b24cfff3ad1a77 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 20 Mar 2019 18:29:32 -0400
Subject: switched to a tree view for performance and added dragging tree view
 items.

---
 src/client/documents/Documents.ts                   |  3 +++
 src/client/views/Main.tsx                           | 10 ++++++----
 src/client/views/collections/CollectionTreeView.tsx | 13 +++++++++----
 3 files changed, 18 insertions(+), 8 deletions(-)

(limited to 'src/client/views/Main.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b1e1f8c7b..cf6d7d503 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -212,6 +212,9 @@ export namespace Documents {
     export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
         return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options)
     }
+    export function TreeDocument(documents: Array<Document>, options: DocumentOptions, id?: string) {
+        return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options)
+    }
     export function DockDocument(config: string, options: DocumentOptions, id?: string) {
         return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options)
     }
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index b27f63e52..113132ae6 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -35,6 +35,7 @@ import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
 import { faPenNib } from '@fortawesome/free-solid-svg-icons';
 import { faFilm } from '@fortawesome/free-solid-svg-icons';
 import { faMusic } from '@fortawesome/free-solid-svg-icons';
+import { faTree } from '@fortawesome/free-solid-svg-icons';
 import Measure from 'react-measure';
 import { DashUserModel } from '../../server/authentication/models/user_model';
 import { ServerUtils } from '../../server/ServerUtil';
@@ -85,6 +86,7 @@ export class Main extends React.Component {
         library.add(faPenNib);
         library.add(faFilm);
         library.add(faMusic);
+        library.add(faTree);
 
         this.initEventListeners();
         Documents.initProtos(() => this.initAuthenticationRouters());
@@ -280,7 +282,8 @@ export class Main extends React.Component {
 
         let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
         let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
-        let addSchemaNode = action(() => Documents.SchemaDocument(this.NorthstarCatalog, { width: 200, height: 200, title: "a schema collection" }));
+        let addSchemaNode = action(() => Documents.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" }));
+        let addTreeNode = action(() => Documents.TreeDocument(this.NorthstarCatalog, { width: 200, height: 200, title: "a tree collection" }));
         let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" }));
         let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
         let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
@@ -295,12 +298,11 @@ export class Main extends React.Component {
             [React.createRef<HTMLDivElement>(), "music", "Add Audio", addAudioNode],
             [React.createRef<HTMLDivElement>(), "globe-asia", "Add Web Clipping", addWebNode],
             [React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
+            [React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode],
             [React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
         ]
 
-        let addClick = (creator: () => Document) => action(() => {
-            this.mainfreeform!.GetList<Document>(KeyStore.Data, []).push(creator())
-        });
+        let addClick = (creator: () => Document) => action(() => this.mainfreeform!.GetList<Document>(KeyStore.Data, []).push(creator()));
 
         return < div id="add-nodes-menu" >
             <input type="checkbox" id="add-menu-toggle" />
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index f9da759fd..d6998cd48 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -10,11 +10,12 @@ import "./CollectionTreeView.scss";
 import { EditableView } from "../EditableView";
 import { setupDrag } from "../../util/DragManager";
 import { FieldWaiting } from "../../../fields/Field";
-import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
 
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faTrashAlt, faCaretRight, faCaretDown } from '@fortawesome/free-solid-svg-icons';
+import { CollectionDockingView } from "./CollectionDockingView";
 
 export interface TreeViewProps {
     document: Document;
@@ -41,7 +42,8 @@ class TreeView extends React.Component<TreeViewProps> {
     collapsed: boolean = false;
 
     delete = () => {
-        this.props.deleteDoc(this.props.document);
+        CollectionDockingView.Instance.AddRightSplit(this.props.document)
+        //this.props.deleteDoc(this.props.document);
     }
 
 
@@ -55,10 +57,11 @@ class TreeView extends React.Component<TreeViewProps> {
 
     renderBullet(type: BulletType) {
         let onClicked = action(() => this.collapsed = !this.collapsed);
+        let onDoubleClick = action(() => CollectionDockingView.Instance.AddRightSplit(this.props.document));
 
         switch (type) {
             case BulletType.Collapsed:
-                return <div className="bullet" onClick={onClicked}><FontAwesomeIcon icon="caret-right" /></div>
+                return <div className="bullet" onDoubleClick={onDoubleClick} onClick={onClicked}><FontAwesomeIcon icon="caret-right" /></div>
             case BulletType.Collapsible:
                 return <div className="bullet" onClick={onClicked}><FontAwesomeIcon icon="caret-down" /></div>
             case BulletType.List:
@@ -70,6 +73,8 @@ class TreeView extends React.Component<TreeViewProps> {
      * Renders the EditableView title element for placement into the tree.
      */
     renderTitle() {
+        let reference = React.createRef<HTMLDivElement>();
+        let onItemDown = setupDrag(reference, () => this.props.document, (containingCollection: CollectionView) => this.props.deleteDoc(this.props.document));
         let title = this.props.document.GetT<TextField>(KeyStore.Title, TextField);
 
         // if the title hasn't loaded, immediately return the div
@@ -77,7 +82,7 @@ class TreeView extends React.Component<TreeViewProps> {
             return <div key={this.props.document.Id}></div>;
         }
 
-        return <div className="docContainer"> <EditableView
+        return <div className="docContainer" ref={reference} onPointerDown={onItemDown}> <EditableView
             display={"inline"}
             contents={title.Data}
             height={36} GetValue={() => {
-- 
cgit v1.2.3-70-g09d2


From 2e7d87e6deac8e69d839c852570849924b59fb1b Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 21 Mar 2019 16:00:28 -0400
Subject: tweaked main

---
 src/client/views/Main.tsx               | 95 +++++++++++++++------------------
 src/client/views/nodes/HistogramBox.tsx |  2 +-
 2 files changed, 45 insertions(+), 52 deletions(-)

(limited to 'src/client/views/Main.tsx')

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index d79907518..53a5aba6e 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -46,6 +46,7 @@ import { Gateway, Settings } from '../northstar/manager/Gateway';
 import { Catalog, Schema, Attribute, AttributeGroup } from '../northstar/model/idea/idea';
 import { ArrayUtil } from '../northstar/utils/ArrayUtil';
 import '../northstar/model/ModelExtensions'
+import '../northstar/utils/Extensions'
 
 @observer
 export class Main extends React.Component {
@@ -55,7 +56,8 @@ export class Main extends React.Component {
     @observable private userWorkspaces: Document[] = [];
     @observable public pwidth: number = 0;
     @observable public pheight: number = 0;
-    @observable private _northstarCatalog: Catalog | undefined = undefined;
+    @observable ActiveSchema: Schema | undefined;
+    private _northstarColumns: Document[] = [];
 
     public mainDocId: string | undefined;
     private currentUser?: DashUserModel;
@@ -71,7 +73,8 @@ export class Main extends React.Component {
             this.mainDocId = pathname[pathname.length - 1];
         };
 
-        this.initializeNorthstar();
+        let y = "";
+        y.ReplaceAll("a", "B");
 
         CurrentUserUtils.loadCurrentUser();
 
@@ -88,57 +91,10 @@ export class Main extends React.Component {
         library.add(faMusic);
         library.add(faTree);
 
-
         this.initEventListeners();
         Documents.initProtos(() => this.initAuthenticationRouters());
 
-        reaction(() => [this.mainContainer, this.ActiveSchema],
-            () => {
-                if (this.mainContainer && this.ActiveSchema) {
-                    if (!this.mainContainer!.GetTAsync(KeyStore.ActiveDB, ListField, field => this.NorthstarCatalog = field!.Data as Document[])) {
-                        this.NorthstarCatalog = this.GetAllAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
-                        this.mainContainer!.SetData(KeyStore.ActiveDB, this.NorthstarCatalog, ListField);
-                    }
-                }
-            })
-    }
-
-    NorthstarCatalog: Document[] = [];
-    @observable ActiveSchema: Schema | undefined;
-    @action SetNorthstarCatalog(ctlog: Catalog) {
-        this._northstarCatalog = ctlog;
-        if (this._northstarCatalog && this._northstarCatalog.schemas) {
-            console.log("CATALOG " + this._northstarCatalog.schemas);
-            this.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(this._northstarCatalog.schemas!, (s: Schema) => s.displayName === "mimic");
-        }
-    }
-    public GetAllAttributes() {
-        if (!this.ActiveSchema || !this.ActiveSchema.rootAttributeGroup) {
-            return [];
-        }
-        const recurs = (attrs: Attribute[], g: AttributeGroup) => {
-            if (g.attributes) {
-                attrs.push.apply(attrs, g.attributes);
-                if (g.attributeGroups) {
-                    g.attributeGroups.forEach(ng => recurs(attrs, ng));
-                }
-            }
-        };
-        const allAttributes: Attribute[] = new Array<Attribute>();
-        recurs(allAttributes, this.ActiveSchema.rootAttributeGroup);
-        return allAttributes;
-    }
-    async initializeNorthstar(): Promise<void> {
-        let envPath = "/assets/env.json";
-        const response = await fetch(envPath, {
-            redirect: "follow",
-            method: "GET",
-            credentials: "include"
-        });
-        const env = await response.json();
-        Settings.Instance.Update(env);
-        let cat = Gateway.Instance.ClearCatalog();
-        cat.then(async () => this.SetNorthstarCatalog(await Gateway.Instance.GetCatalog()));
+        this.initializeNorthstar();
     }
 
     onHistory = () => {
@@ -284,7 +240,7 @@ export class Main extends React.Component {
         let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
         let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
         let addSchemaNode = action(() => Documents.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" }));
-        let addTreeNode = action(() => Documents.TreeDocument(this.NorthstarCatalog, { width: 200, height: 200, title: "a tree collection" }));
+        let addTreeNode = action(() => Documents.TreeDocument(this._northstarColumns, { width: 200, height: 200, title: "a tree collection" }));
         let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" }));
         let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
         let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
@@ -365,6 +321,43 @@ export class Main extends React.Component {
             </div>
         );
     }
+
+    // --------------- Northstar hooks ------------- /
+
+    @action SetNorthstarCatalog(ctlog: Catalog) {
+        if (ctlog && ctlog.schemas) {
+            this.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(ctlog.schemas!, (s: Schema) => s.displayName === "mimic");
+            this._northstarColumns = this.GetAllNorthstarColumnAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
+        }
+    }
+    async initializeNorthstar(): Promise<void> {
+        let envPath = "/assets/env.json";
+        const response = await fetch(envPath, {
+            redirect: "follow",
+            method: "GET",
+            credentials: "include"
+        });
+        const env = await response.json();
+        Settings.Instance.Update(env);
+        let cat = Gateway.Instance.ClearCatalog();
+        cat.then(async () => this.SetNorthstarCatalog(await Gateway.Instance.GetCatalog()));
+    }
+    public GetAllNorthstarColumnAttributes() {
+        if (!this.ActiveSchema || !this.ActiveSchema.rootAttributeGroup) {
+            return [];
+        }
+        const recurs = (attrs: Attribute[], g: AttributeGroup) => {
+            if (g.attributes) {
+                attrs.push.apply(attrs, g.attributes);
+                if (g.attributeGroups) {
+                    g.attributeGroups.forEach(ng => recurs(attrs, ng));
+                }
+            }
+        };
+        const allAttributes: Attribute[] = new Array<Attribute>();
+        recurs(allAttributes, this.ActiveSchema.rootAttributeGroup);
+        return allAttributes;
+    }
 }
 
 ReactDOM.render(<Main />, document.getElementById('root'));
diff --git a/src/client/views/nodes/HistogramBox.tsx b/src/client/views/nodes/HistogramBox.tsx
index 0fcc25e66..223fdf0d8 100644
--- a/src/client/views/nodes/HistogramBox.tsx
+++ b/src/client/views/nodes/HistogramBox.tsx
@@ -23,7 +23,7 @@ export class HistogramBox extends React.Component<FieldViewProps> {
     _histoOp?: HistogramOperation;
 
     componentDidMount() {
-        Main.Instance.GetAllAttributes().map(a => {
+        Main.Instance.GetAllNorthstarColumnAttributes().map(a => {
             if (a.displayName == this.props.doc.Title) {
                 var atmod = new ColumnAttributeModel(a);
                 this._histoOp = new HistogramOperation(new AttributeTransformationModel(atmod, AggregateFunction.None),
-- 
cgit v1.2.3-70-g09d2

