From 67170e521366f8178645cc85aaf377e53b1a6f21 Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Mon, 18 Mar 2019 18:07:46 -0400
Subject: ui in place, needs refinement and more backend

---
 .../views/collections/CollectionSchemaView.tsx     | 68 +++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 04f017378..7c87ef744 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,4 +1,4 @@
-import React = require("react")
+import React = require("react");
 import { action, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
@@ -17,6 +17,16 @@ import "./CollectionSchemaView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
+import '../DocumentDecorations.scss';
+import { Flyout, anchorPoints } from "../DocumentDecorations";
+import { DropdownButton, Dropdown } from 'react-bootstrap';
+import { ListField } from "../../../fields/ListField";
+import { Key } from "../../../fields/Key";
+//import { Server } from "http";
+//import { Server } from "http";
+import { Server } from "../../Server";
+
+//import { MenuItem } from 'react-bootstrap';
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
@@ -178,6 +188,19 @@ export class CollectionSchemaView extends CollectionViewBase {
 
     focusDocument = (doc: Document) => { }
 
+    keyDropDownOnSelect = (keyId: string) => {
+        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author]);
+        const listOfFields = this.props.Document.GetList<Document>(this.props.fieldKey, [])[1].fields;
+        if (listOfFields.has(keyId)) {
+            let index = columns.push(listOfFields!.get(keyId)!.key);
+            this.props.Document.SetData(KeyStore.ColumnsKey, columns, ListField);
+        }
+    }
+
+    dropdownItemOnPointerDown = (e: React.PointerEvent): void => {
+        //(e.currentTarget.children[0] as Dropdown.Item ).onSelect();
+    }
+
     render() {
         const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
@@ -205,6 +228,47 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
         let dividerDragger = this._splitPercentage == 100 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
+
+        //get the union of all childrens' keys
+        let addFields: { id: string, name: string }[] = [];
+        let removeFields: { id: string, name: string }[] = [];
+        //children.forEach((child) => {
+        //   for (var keyId in fields.keys) {
+        //       if (!allFields.includes(keyId)) {
+        //           allFields.push(keyId);
+        //      }
+        //   }
+        // });
+        let optionsMenu = null;
+        if (this.props.active()) {
+            let protos = this.props.Document.GetAllPrototypes();
+            for (const proto of protos) {
+                proto._proxies.forEach((val, key) => {
+                    if (!(key in addFields.keys)) {
+                        let this_name: string = proto.fields!.get(key)!.key.Name;
+                        addFields.push({ id: key, name: this_name });
+                    }
+                })
+            }
+            optionsMenu = !this.props.active() ? (null) : (<Flyout
+                anchorPoint={anchorPoints.LEFT_TOP}
+                content={<div id="options-flyout-div"> <h5>Options</h5>
+                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
+                        {addFields.map(({ id, name }) => (
+                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
+                    </DropdownButton>
+                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
+                        {addFields.map(({ id, name }) => (
+                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
+                    </DropdownButton>
+                </div>
+                }>
+                <div id="schemaOptionsMenuBtn" />
+            </Flyout>);
+        }
+
+
+
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
@@ -239,6 +303,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
+                    {optionsMenu}
+
                 </div>
             </div >
         )
-- 
cgit v1.2.3-70-g09d2


From 670cf766c99a8a5de806fd7d6f1d9e357a55071a Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Mon, 18 Mar 2019 18:29:10 -0400
Subject: not sure

---
 deploy/index.html                                  |   3 -
 package-lock.json                                  | 419 ++++++++++++++++++---
 package.json                                       |   6 -
 .../views/collections/CollectionSchemaView.tsx     |  80 ++--
 4 files changed, 402 insertions(+), 106 deletions(-)

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

diff --git a/deploy/index.html b/deploy/index.html
index dbfc6dee0..ca5c13e98 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -2,12 +2,9 @@
 
 <head>
   <title>Dash Web</title>
-<<<<<<< HEAD
   <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
     integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-=======
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
   <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
 </head>
 
diff --git a/package-lock.json b/package-lock.json
index 3d66773f2..18365bf9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -152,11 +152,10 @@
       }
     },
     "@hig/theme-context": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.2.tgz",
-      "integrity": "sha512-JTdYJgJpbPX0KPrjBkeKUFq8fLq7PFmMaBQaT71z6vs/ARqdeYC1ZNpksH2HCzDNU7mjGgFineA9He3eR3sgpg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.3.tgz",
+      "integrity": "sha512-c0Ju+Z8C532ZZtjwOLzN+XeO+pL3kqUawu6ZG3J084MH5RM9W8JCKyMf4D9Qr38jFWoiX6u8yiSxxjV/mz9Sqw==",
       "requires": {
-        "@hig/theme-data": "^2.3.2",
         "create-react-context": "^0.2.3",
         "prop-types": "^15.6.1"
       }
@@ -225,6 +224,11 @@
       "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
       "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
     },
+    "@types/async": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@types/async/-/async-2.4.1.tgz",
+      "integrity": "sha512-C09BK/wXzbW+/JK9zckhe+FeSbg7NmvVjUWwApnw7ksRpUq3ecGLiq2Aw1LlY4Z/VmtdhSaIs7jO5/MWRYMcOA=="
+    },
     "@types/babel-types": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.6.tgz",
@@ -292,6 +296,22 @@
         "@types/express": "*"
       }
     },
+    "@types/cookie-parser": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.1.tgz",
+      "integrity": "sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA==",
+      "requires": {
+        "@types/express": "*"
+      }
+    },
+    "@types/cookie-session": {
+      "version": "2.0.36",
+      "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.36.tgz",
+      "integrity": "sha512-vnKXnz9vGdOF6Gi9mvaMEtSn2PlDotvde1u9xVzzBRAVsPcufEmDfmas7023T7PpK9Awv1JqQDwN1ThjPSAoTA==",
+      "requires": {
+        "@types/express": "*"
+      }
+    },
     "@types/events": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -400,6 +420,14 @@
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
       "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
     },
+    "@types/mobile-detect": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/@types/mobile-detect/-/mobile-detect-1.3.4.tgz",
+      "integrity": "sha512-MGBTvT5c7aH8eX6szFYP3dWPryNLt5iGlo31XNaJtt8o6jsg6tjn99eEMq9l8T6cPZymsr+J4Jth8+/G/04ZDw==",
+      "requires": {
+        "mobile-detect": "*"
+      }
+    },
     "@types/mocha": {
       "version": "5.2.6",
       "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz",
@@ -429,6 +457,14 @@
       "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz",
       "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q=="
     },
+    "@types/nodemailer": {
+      "version": "4.6.6",
+      "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.6.tgz",
+      "integrity": "sha512-N2czhXs7fbQhvoquEGzmHAWttnxLfrM3+cWMRFX4hTQq4GE3VyaSE3MOOse4VoNgvtti/H5ow/Hq9KXu/UMWqA==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/orderedmap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
@@ -485,6 +521,15 @@
         "@types/prosemirror-state": "*"
       }
     },
+    "@types/prosemirror-inputrules": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
+      "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
+      "requires": {
+        "@types/prosemirror-model": "*",
+        "@types/prosemirror-state": "*"
+      }
+    },
     "@types/prosemirror-keymap": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
@@ -1160,7 +1205,6 @@
       "version": "4.10.1",
       "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
       "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.0.0",
         "inherits": "^2.0.1",
@@ -1215,11 +1259,11 @@
       "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk="
     },
     "async": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
-      "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
       "requires": {
-        "lodash": "^4.17.10"
+        "lodash": "^4.17.11"
       }
     },
     "async-each": {
@@ -1525,8 +1569,7 @@
     "bn.js": {
       "version": "4.11.8",
       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
     },
     "body-parser": {
       "version": "1.18.3",
@@ -1695,8 +1738,7 @@
     "brorand": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
     },
     "browser-stdout": {
       "version": "1.3.1",
@@ -1708,7 +1750,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
       "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
-      "dev": true,
       "requires": {
         "buffer-xor": "^1.0.3",
         "cipher-base": "^1.0.0",
@@ -1722,7 +1763,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
       "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
-      "dev": true,
       "requires": {
         "browserify-aes": "^1.0.4",
         "browserify-des": "^1.0.0",
@@ -1733,7 +1773,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
       "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
-      "dev": true,
       "requires": {
         "cipher-base": "^1.0.1",
         "des.js": "^1.0.0",
@@ -1745,7 +1784,6 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
       "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
-      "dev": true,
       "requires": {
         "bn.js": "^4.1.0",
         "randombytes": "^2.0.1"
@@ -1755,7 +1793,6 @@
       "version": "4.0.4",
       "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
       "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
-      "dev": true,
       "requires": {
         "bn.js": "^4.1.1",
         "browserify-rsa": "^4.0.0",
@@ -1816,8 +1853,7 @@
     "buffer-xor": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
     },
     "builtin-status-codes": {
       "version": "3.0.0",
@@ -2021,7 +2057,6 @@
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
       "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "safe-buffer": "^5.0.1"
@@ -2359,11 +2394,60 @@
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
       "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
     },
+    "cookie-parser": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz",
+      "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==",
+      "requires": {
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6"
+      }
+    },
+    "cookie-session": {
+      "version": "2.0.0-beta.3",
+      "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-beta.3.tgz",
+      "integrity": "sha512-zyqm5tA0z9yMEB/xyP7lnRnqp8eLR2e0dap+9+rBwVigla9yPKn8XTL1jJymog8xjfrowqW2o5LUjixQChkqrw==",
+      "requires": {
+        "cookies": "0.7.1",
+        "debug": "3.1.0",
+        "on-headers": "~1.0.1",
+        "safe-buffer": "5.1.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+        }
+      }
+    },
     "cookie-signature": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
       "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
     },
+    "cookies": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
+      "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=",
+      "requires": {
+        "depd": "~1.1.1",
+        "keygrip": "~1.0.2"
+      }
+    },
     "copy-concurrently": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -2430,7 +2514,6 @@
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
       "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.1.0",
         "elliptic": "^6.0.0"
@@ -2459,7 +2542,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
       "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
-      "dev": true,
       "requires": {
         "cipher-base": "^1.0.1",
         "inherits": "^2.0.1",
@@ -2472,7 +2554,6 @@
       "version": "1.1.7",
       "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
       "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
-      "dev": true,
       "requires": {
         "cipher-base": "^1.0.3",
         "create-hash": "^1.1.0",
@@ -2516,7 +2597,6 @@
       "version": "3.12.0",
       "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
       "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
-      "dev": true,
       "requires": {
         "browserify-cipher": "^1.0.0",
         "browserify-sign": "^4.0.0",
@@ -2779,7 +2859,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
       "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "minimalistic-assert": "^1.0.0"
@@ -2821,7 +2900,6 @@
       "version": "5.0.3",
       "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
       "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.1.0",
         "miller-rabin": "^4.0.0",
@@ -2954,7 +3032,6 @@
       "version": "6.4.1",
       "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
       "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.4.0",
         "brorand": "^1.0.1",
@@ -3222,7 +3299,6 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
       "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
-      "dev": true,
       "requires": {
         "md5.js": "^1.3.4",
         "safe-buffer": "^5.1.1"
@@ -4559,6 +4635,21 @@
         "ansi-regex": "^2.0.0"
       }
     },
+    "has-binary": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
+      "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
+      "requires": {
+        "isarray": "0.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        }
+      }
+    },
     "has-binary2": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
@@ -4628,7 +4719,6 @@
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
       "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "safe-buffer": "^5.0.1"
@@ -4638,7 +4728,6 @@
       "version": "1.1.7",
       "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
       "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.3",
         "minimalistic-assert": "^1.0.1"
@@ -4654,7 +4743,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
       "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
-      "dev": true,
       "requires": {
         "hash.js": "^1.0.3",
         "minimalistic-assert": "^1.0.0",
@@ -5365,8 +5453,7 @@
     "json3": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
-      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
-      "dev": true
+      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE="
     },
     "json5": {
       "version": "1.0.1",
@@ -5519,6 +5606,11 @@
       "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
       "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
     },
+    "keygrip": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz",
+      "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g=="
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -5845,7 +5937,6 @@
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
       "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
-      "dev": true,
       "requires": {
         "hash-base": "^3.0.0",
         "inherits": "^2.0.1",
@@ -5940,7 +6031,6 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
       "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.0.0",
         "brorand": "^1.0.1"
@@ -5973,14 +6063,12 @@
     "minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
-      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
-      "dev": true
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
     },
     "minimalistic-crypto-utils": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
-      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
-      "dev": true
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
     },
     "minimatch": {
       "version": "3.0.4",
@@ -6065,6 +6153,11 @@
         }
       }
     },
+    "mobile-detect": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.3.tgz",
+      "integrity": "sha512-UaahPNLllQsstHOEHAmVnTHCMQrAS9eL5Qgdi50QrYz6UgGk+Xziz2udz2GN6NYcyODcPLnasC7a7s6R2DjiaQ=="
+    },
     "mobx": {
       "version": "5.9.0",
       "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.9.0.tgz",
@@ -6189,6 +6282,14 @@
         "sliced": "1.0.1"
       },
       "dependencies": {
+        "async": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+          "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+          "requires": {
+            "lodash": "^4.17.10"
+          }
+        },
         "bson": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
@@ -6494,6 +6595,11 @@
         }
       }
     },
+    "nodemailer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-5.1.1.tgz",
+      "integrity": "sha512-hKGCoeNdFL2W7S76J/Oucbw0/qRlfG815tENdhzcqTpSjKgAN91mFOqU2lQUflRRxFM7iZvCyaFcAR9noc/CqQ=="
+    },
     "nodemon": {
       "version": "1.18.10",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.10.tgz",
@@ -9750,6 +9856,11 @@
         "is-wsl": "^1.1.0"
       }
     },
+    "options": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+      "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
+    },
     "orderedmap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.0.0.tgz",
@@ -9868,7 +9979,6 @@
       "version": "5.1.4",
       "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
       "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
-      "dev": true,
       "requires": {
         "asn1.js": "^4.0.0",
         "browserify-aes": "^1.0.0",
@@ -9893,6 +10003,14 @@
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
       "dev": true
     },
+    "parsejson": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
+      "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
+      "requires": {
+        "better-assert": "~1.0.0"
+      }
+    },
     "parseqs": {
       "version": "0.0.5",
       "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
@@ -10000,7 +10118,6 @@
       "version": "3.0.17",
       "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
       "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
-      "dev": true,
       "requires": {
         "create-hash": "^1.1.2",
         "create-hmac": "^1.1.4",
@@ -10433,7 +10550,6 @@
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
       "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.1.0",
         "browserify-rsa": "^4.0.0",
@@ -10621,7 +10737,6 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "dev": true,
       "requires": {
         "safe-buffer": "^5.1.0"
       }
@@ -10630,7 +10745,6 @@
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
       "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
-      "dev": true,
       "requires": {
         "randombytes": "^2.0.5",
         "safe-buffer": "^5.1.0"
@@ -11344,7 +11458,6 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
       "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
-      "dev": true,
       "requires": {
         "hash-base": "^3.0.0",
         "inherits": "^2.0.1"
@@ -11595,7 +11708,6 @@
       "version": "2.4.11",
       "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
       "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "safe-buffer": "^5.0.1"
@@ -11845,6 +11957,204 @@
         }
       }
     },
+    "socketio": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/socketio/-/socketio-1.0.0.tgz",
+      "integrity": "sha1-aOoVmP0kBWFgFxLldJl2ftjrqMo=",
+      "requires": {
+        "express": "^4.13.3",
+        "socket.io": "^1.3.7"
+      },
+      "dependencies": {
+        "accepts": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+          "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+          "requires": {
+            "mime-types": "~2.1.11",
+            "negotiator": "0.6.1"
+          }
+        },
+        "arraybuffer.slice": {
+          "version": "0.0.6",
+          "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
+          "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco="
+        },
+        "blob": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+          "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
+        },
+        "component-emitter": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
+          "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM="
+        },
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "engine.io": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.5.tgz",
+          "integrity": "sha512-j1DWIcktw4hRwrv6nWx++5nFH2X64x16MAG2P0Lmi5Dvdfi3I+Jhc7JKJIdAmDJa+5aZ/imHV7dWRPy2Cqjh3A==",
+          "requires": {
+            "accepts": "1.3.3",
+            "base64id": "1.0.0",
+            "cookie": "0.3.1",
+            "debug": "2.3.3",
+            "engine.io-parser": "1.3.2",
+            "ws": "~1.1.5"
+          }
+        },
+        "engine.io-client": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz",
+          "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==",
+          "requires": {
+            "component-emitter": "1.2.1",
+            "component-inherit": "0.0.3",
+            "debug": "2.3.3",
+            "engine.io-parser": "1.3.2",
+            "has-cors": "1.1.0",
+            "indexof": "0.0.1",
+            "parsejson": "0.0.3",
+            "parseqs": "0.0.5",
+            "parseuri": "0.0.5",
+            "ws": "~1.1.5",
+            "xmlhttprequest-ssl": "1.5.3",
+            "yeast": "0.1.2"
+          },
+          "dependencies": {
+            "component-emitter": {
+              "version": "1.2.1",
+              "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+              "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+            }
+          }
+        },
+        "engine.io-parser": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
+          "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
+          "requires": {
+            "after": "0.8.2",
+            "arraybuffer.slice": "0.0.6",
+            "base64-arraybuffer": "0.1.5",
+            "blob": "0.0.4",
+            "has-binary": "0.1.7",
+            "wtf-8": "1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+        },
+        "object-assign": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+          "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A="
+        },
+        "socket.io": {
+          "version": "1.7.4",
+          "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.4.tgz",
+          "integrity": "sha1-L37O3DORvy1cc+KR/iM+bjTU3QA=",
+          "requires": {
+            "debug": "2.3.3",
+            "engine.io": "~1.8.4",
+            "has-binary": "0.1.7",
+            "object-assign": "4.1.0",
+            "socket.io-adapter": "0.5.0",
+            "socket.io-client": "1.7.4",
+            "socket.io-parser": "2.3.1"
+          }
+        },
+        "socket.io-adapter": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
+          "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
+          "requires": {
+            "debug": "2.3.3",
+            "socket.io-parser": "2.3.1"
+          }
+        },
+        "socket.io-client": {
+          "version": "1.7.4",
+          "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz",
+          "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=",
+          "requires": {
+            "backo2": "1.0.2",
+            "component-bind": "1.0.0",
+            "component-emitter": "1.2.1",
+            "debug": "2.3.3",
+            "engine.io-client": "~1.8.4",
+            "has-binary": "0.1.7",
+            "indexof": "0.0.1",
+            "object-component": "0.0.3",
+            "parseuri": "0.0.5",
+            "socket.io-parser": "2.3.1",
+            "to-array": "0.1.4"
+          },
+          "dependencies": {
+            "component-emitter": {
+              "version": "1.2.1",
+              "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+              "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+            }
+          }
+        },
+        "socket.io-parser": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
+          "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
+          "requires": {
+            "component-emitter": "1.1.2",
+            "debug": "2.2.0",
+            "isarray": "0.0.1",
+            "json3": "3.3.2"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.2.0",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+              "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+              "requires": {
+                "ms": "0.7.1"
+              }
+            },
+            "ms": {
+              "version": "0.7.1",
+              "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+              "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
+            }
+          }
+        },
+        "ws": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
+          "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
+          "requires": {
+            "options": ">=0.0.5",
+            "ultron": "1.0.x"
+          }
+        },
+        "xmlhttprequest-ssl": {
+          "version": "1.5.3",
+          "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
+          "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0="
+        }
+      }
+    },
     "sockjs": {
       "version": "0.3.19",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
@@ -12745,6 +13055,11 @@
         "random-bytes": "~1.0.0"
       }
     },
+    "ultron": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+      "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
+    },
     "uncontrollable": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.1.0.tgz",
@@ -13884,6 +14199,11 @@
         "async-limiter": "~1.0.0"
       }
     },
+    "wtf-8": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
+      "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo="
+    },
     "xdg-basedir": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
@@ -13894,6 +14214,11 @@
       "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
       "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
     },
+    "xoauth2": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-1.2.0.tgz",
+      "integrity": "sha1-8u76wRRyyXHqO8RuVU60sSMhRuU="
+    },
     "xregexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz",
diff --git a/package.json b/package.json
index 640f16437..a4a328859 100644
--- a/package.json
+++ b/package.json
@@ -38,13 +38,10 @@
     "@fortawesome/free-solid-svg-icons": "^5.7.2",
     "@fortawesome/react-fontawesome": "^0.1.4",
     "@hig/flyout": "^1.0.3",
-<<<<<<< HEAD
     "@trendmicro/react-dropdown": "^1.3.0",
-=======
     "@types/async": "^2.4.1",
     "@hig/theme-context": "^2.1.3",
     "@hig/theme-data": "^2.3.3",
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
     "@types/bcrypt-nodejs": "0.0.30",
     "@types/bluebird": "^3.5.25",
     "@types/body-parser": "^1.17.0",
@@ -92,11 +89,8 @@
     "bcrypt-nodejs": "0.0.3",
     "bluebird": "^3.5.3",
     "body-parser": "^1.18.3",
-<<<<<<< HEAD
     "bootstrap": "^4.3.1",
-=======
     "connect-flash": "^0.1.1",
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
     "connect-mongo": "^2.0.3",
     "cookie-parser": "^1.4.4",
     "cookie-session": "^2.0.0-beta.3",
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 2598dd3a9..da38d54c4 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,10 +1,5 @@
-<<<<<<< HEAD
-import React = require("react");
-import { action, observable } from "mobx";
-=======
 import React = require("react")
 import { action, observable, ObservableMap, computed } from "mobx";
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -22,23 +17,13 @@ import "./CollectionSchemaView.scss";
 import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
-<<<<<<< HEAD
 import '../DocumentDecorations.scss';
 import { Flyout, anchorPoints } from "../DocumentDecorations";
 import { DropdownButton, Dropdown } from 'react-bootstrap';
 import { ListField } from "../../../fields/ListField";
 import { Key } from "../../../fields/Key";
-//import { Server } from "http";
-//import { Server } from "http";
 import { Server } from "../../Server";
 
-//import { MenuItem } from 'react-bootstrap';
-=======
-import { Key } from "./../../../fields/Key";
-import { Server } from "../../Server";
-import { ListField } from "../../../fields/ListField";
-
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
@@ -349,18 +334,10 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />);
         let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
-<<<<<<< HEAD
 
         //get the union of all childrens' keys
         let addFields: { id: string, name: string }[] = [];
         let removeFields: { id: string, name: string }[] = [];
-        //children.forEach((child) => {
-        //   for (var keyId in fields.keys) {
-        //       if (!allFields.includes(keyId)) {
-        //           allFields.push(keyId);
-        //      }
-        //   }
-        // });
         let optionsMenu = null;
         if (this.props.active()) {
             let protos = this.props.Document.GetAllPrototypes();
@@ -372,28 +349,32 @@ export class CollectionSchemaView extends CollectionViewBase {
                     }
                 })
             }
-            optionsMenu = !this.props.active() ? (null) : (<Flyout
-                anchorPoint={anchorPoints.LEFT_TOP}
-                content={<div id="options-flyout-div"> <h5>Options</h5>
-                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
+            /*<DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
                         {addFields.map(({ id, name }) => (
                             <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
                     </DropdownButton>
                     <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
                         {addFields.map(({ id, name }) => (
                             <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>
+                    </DropdownButton>*/
+            optionsMenu = !this.props.active() ? (null) : (<Flyout
+                anchorPoint={anchorPoints.LEFT_TOP}
+                content={<div id="options-flyout-div"> <h5>Options</h5>
+                    <div className="addColumn-options">
+                        <ul style={{ overflow: "scroll" }}>
+                            {Array.from(Object.keys(allKeys)).map(item => {
+                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                            })}
+                        </ul>
+                    </div>
                 </div>
                 }>
                 <div id="schemaOptionsMenuBtn" />
             </Flyout>);
         }
 
-
-=======
         let colDividerDragger = this._columnsPercentage == 0 ? (null) :
             <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} />
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -424,19 +405,6 @@ export class CollectionSchemaView extends CollectionViewBase {
                                         getTrProps={this.getTrProps}
                                     />
                                 </div>
-                                {colDividerDragger}
-                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
-                                    {/* <input type="checkbox" id="addColumn-toggle" />
-                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> */}
-
-                                    <div className="addColumn-options">
-                                        <ul style={{ overflow: "scroll" }}>
-                                            {Array.from(Object.keys(allKeys)).map(item => {
-                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                                            })}
-                                        </ul>
-                                    </div>
-                                </div>
                             </div>
                         }
                     </Measure>
@@ -445,14 +413,26 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
-<<<<<<< HEAD
-                    {optionsMenu}
-=======
-                    {columnsHandle}
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
+                    {columnsHandle}
+                    {optionsMenu}
                 </div>
             </div >
         )
     }
-}
\ No newline at end of file
+}
+/*
+{colDividerDragger}
+                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
+                                    {/* <input type="checkbox" id="addColumn-toggle" />
+                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> }
+
+                                    <div className="addColumn-options">
+                                        <ul style={{ overflow: "scroll" }}>
+                                            {Array.from(Object.keys(allKeys)).map(item => {
+                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                                            })}
+                                        </ul>
+                                    </div>
+                                </div>
+                                */
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From f2fa6d6d28f2011a13f9034f5685b08301c291e4 Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Tue, 19 Mar 2019 16:48:10 -0400
Subject: ui much better

---
 src/client/views/Main.tsx                          |   1 +
 .../views/collections/CollectionSchemaView.scss    |  87 ++++++-------
 .../views/collections/CollectionSchemaView.tsx     | 143 ++++++---------------
 3 files changed, 77 insertions(+), 154 deletions(-)

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

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 26a07fdfe..a6b893eca 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -78,6 +78,7 @@ export class Main extends React.Component {
         library.add(faFilm);
         library.add(faMusic);
 
+
         this.initEventListeners();
         Documents.initProtos(() => {
             this.initAuthenticationRouters();
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d16f0edf9..8c2f62d43 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,66 +1,57 @@
+@import "../global_variables";
+
 //options menu styling
 #schemaOptionsMenuBtn {
     position: absolute;
-    height: 15px;
-    width: 15px;
+    height: 20px;
+    width: 20px;
     border-radius: 50%;
     z-index: 21; 
-    right: 3px;
-    top: 3px; 
+    right: 4px;
+    top: 4px; 
     pointer-events: auto;
-    background-color:red;
-}
-
-.dd-item-containter:hover {
-  background-color: rgb(204, 204, 204);
+    background-color:black;
+    display:inline-block;
+    padding: 0px;
+    font-size: 100%;
 }
-
-.dd-item {
-    color: black;
-    padding-left: 6px;
-    padding-bottom: 0px;
-    padding-top: 4px;
-    font-size: 12px;
+#schema-options-header {
+    text-align: center;
+    padding: 0px;
     margin: 0px;
-    display: block;
-    width: 100%;
-    height: 25px;
-    z-index: 100;
 }
-.dd-item:hover {
-    color: black;
-    font-weight: 500;
+.schema-options-subHeader {
+    color: $intermediate-color;
+    margin-bottom: 5px;
+}
+#schemaOptionsMenuBtn:hover {
+    transform: scale(1.15);
 }
 
-.dropdown-menu {
-    height: 100px;
-    overflow-y: scroll;
-  }
-
-#dropdown-basic-button {
-    background-color: #fff;
-    border: .75px solid #bbbbbb;
-    border-radius: 0;
-    -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
-    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-    margin:10px;
-    margin-top: 8px;
-    color: black;
-    display: inline-block;
-    width: 160px;
-    height: 25px;
-    font-size: 15px;
-    padding: 0px;
-    border-radius: 3px;
-    font-size: 12px;
-  }
+#preview-schema-checkbox-div {
+    margin-left: 20px;
+    font-size: 11px;
+}
 
   #options-flyout-div {
-    text-align: center;
+    text-align: left;
     padding:0px;
+    z-index: 100;
+    font-family: $sans-serif;
+    padding-left: 5px;
+  }
+
+  #schema-col-checklist {
+    overflow: scroll;
+    text-align: left;
+    //background-color: $light-color-secondary;
+    line-height: 25px;
+    max-height: 175px;
+    font-family: $sans-serif;
+    font-size: 12px;
   }
   
-@import "../global_variables";
+
 .collectionSchemaView-container {
     border: 1px solid $intermediate-color;
     border-radius: $border-radius;
@@ -68,7 +59,7 @@
     position: absolute;
     width: 100%;
     height: 100%;
-    overflow: hidden;
+    
     .collectionSchemaView-content {
         position: absolute;
         height: 100%;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index da38d54c4..07b4d150a 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -19,10 +19,12 @@ import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
 import '../DocumentDecorations.scss';
 import { Flyout, anchorPoints } from "../DocumentDecorations";
-import { DropdownButton, Dropdown } from 'react-bootstrap';
 import { ListField } from "../../../fields/ListField";
 import { Key } from "../../../fields/Key";
 import { Server } from "../../Server";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCog } from '@fortawesome/free-solid-svg-icons';
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -44,7 +46,7 @@ class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggl
     render() {
         if (this.key) {
             return (<div key={this.key.Id}>
-                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />{this.key.Name}
+                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />  {this.key.Name}
             </div>)
         } else {
             return <div></div>
@@ -66,6 +68,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _columnsPercentage = 0;
     @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
+
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
             doc: rowProps.value[0],
@@ -156,6 +159,15 @@ export class CollectionSchemaView extends CollectionViewBase {
             })
     }
 
+    //toggles preview side-panel of schema
+    @action
+    toggleExpander = (event: React.ChangeEvent<HTMLInputElement>) => {
+        this._startSplitPercent = this.splitPercentage;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
+        }
+    }
+
     @observable keys: Key[] = [];
 
     findAllDocumentKeys = (): { [id: string]: boolean } => {
@@ -220,37 +232,6 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.stopPropagation();
         e.preventDefault();
     }
-    @action
-    onExpanderUp = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.removeEventListener("pointermove", this.onExpanderMove);
-        document.removeEventListener('pointerup', this.onExpanderUp);
-        if (this._startSplitPercent == this.splitPercentage) {
-            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
-        }
-    }
-    onExpanderDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this.splitPercentage;
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onExpanderMove);
-        document.addEventListener('pointerup', this.onExpanderUp);
-    }
-
-    onPointerDown = (e: React.PointerEvent) => {
-        // if (e.button === 2 && this.active) {
-        //     e.stopPropagation();
-        //     e.preventDefault();
-        // } else 
-        {
-            // if (e.buttons === 1) {
-            //     if (this.props.isSelected()) {
-            //         e.stopPropagation();
-            //     }
-            // }
-        }
-    }
 
     @action
     onColumnsMove = (e: PointerEvent): void => {
@@ -291,23 +272,16 @@ export class CollectionSchemaView extends CollectionViewBase {
 
     focusDocument = (doc: Document) => { }
 
-    keyDropDownOnSelect = (keyId: string) => {
-        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author]);
-        const listOfFields = this.props.Document.GetList<Document>(this.props.fieldKey, [])[1].fields;
-        if (listOfFields.has(keyId)) {
-            let index = columns.push(listOfFields!.get(keyId)!.key);
-            this.props.Document.SetData(KeyStore.ColumnsKey, columns, ListField);
-        }
-    }
-
-    dropdownItemOnPointerDown = (e: React.PointerEvent): void => {
-        //(e.currentTarget.children[0] as Dropdown.Item ).onSelect();
+    onPointerDown = (e: React.PointerEvent): void => {
+        //
     }
 
     render() {
+        library.add(faCog);
         const columns = this.columns;
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
+        //all the keys/columns that will be displayed in the schema
         const allKeys = this.findAllDocumentKeys();
         let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
@@ -328,53 +302,28 @@ export class CollectionSchemaView extends CollectionViewBase {
                 }
             </Measure>
         )
-        let previewHandle = !this.props.active() ? (null) : (
-            <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
-        let columnsHandle = !this.props.active() ? (null) : (
-            <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />);
         let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
 
-        //get the union of all childrens' keys
-        let addFields: { id: string, name: string }[] = [];
-        let removeFields: { id: string, name: string }[] = [];
-        let optionsMenu = null;
-        if (this.props.active()) {
-            let protos = this.props.Document.GetAllPrototypes();
-            for (const proto of protos) {
-                proto._proxies.forEach((val, key) => {
-                    if (!(key in addFields.keys)) {
-                        let this_name: string = proto.fields!.get(key)!.key.Name;
-                        addFields.push({ id: key, name: this_name });
-                    }
-                })
-            }
-            /*<DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
-                        {addFields.map(({ id, name }) => (
-                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>
-                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
-                        {addFields.map(({ id, name }) => (
-                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>*/
-            optionsMenu = !this.props.active() ? (null) : (<Flyout
-                anchorPoint={anchorPoints.LEFT_TOP}
-                content={<div id="options-flyout-div"> <h5>Options</h5>
-                    <div className="addColumn-options">
-                        <ul style={{ overflow: "scroll" }}>
-                            {Array.from(Object.keys(allKeys)).map(item => {
-                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                            })}
-                        </ul>
-                    </div>
+        //options button and menu
+        let optionsMenu = !this.props.active() ? (null) : (<Flyout
+            anchorPoint={anchorPoints.LEFT_TOP}
+            content={<div>
+                <div id="schema-options-header"><h5><b>Options</b></h5></div>
+                <div id="options-flyout-div">
+                    <h6 className="schema-options-subHeader">Preview Window</h6>
+                    <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={this.splitPercentage != 0} onChange={this.toggleExpander} />  Show Preview </div>
+                    <h6 className="schema-options-subHeader" >Displayed Columns</h6>
+                    <ul id="schema-col-checklist" >
+                        {Array.from(Object.keys(allKeys)).map(item => {
+                            return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                        })}
+                    </ul>
                 </div>
-                }>
-                <div id="schemaOptionsMenuBtn" />
-            </Flyout>);
-        }
-
-        let colDividerDragger = this._columnsPercentage == 0 ? (null) :
-            <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} />
+            </div>
+            }>
+            <button id="schemaOptionsMenuBtn"><FontAwesomeIcon style={{ color: "white" }} icon="cog" size="sm" /></button>
+        </Flyout>);
 
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -412,27 +361,9 @@ export class CollectionSchemaView extends CollectionViewBase {
                     <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
                         {content}
                     </div>
-                    {previewHandle}
-
-                    {columnsHandle}
                     {optionsMenu}
                 </div>
             </div >
         )
     }
-}
-/*
-{colDividerDragger}
-                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
-                                    {/* <input type="checkbox" id="addColumn-toggle" />
-                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> }
-
-                                    <div className="addColumn-options">
-                                        <ul style={{ overflow: "scroll" }}>
-                                            {Array.from(Object.keys(allKeys)).map(item => {
-                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                                            })}
-                                        </ul>
-                                    </div>
-                                </div>
-                                */
\ No newline at end of file
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 79846f5e85c04435082106724d49b03eea31657f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 21 Mar 2019 00:57:02 -0400
Subject: minor fix to schema dragger and treeview

---
 src/client/views/collections/CollectionSchemaView.tsx | 2 +-
 src/client/views/collections/CollectionTreeView.tsx   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index c2645ea73..d3ade7ebb 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -189,7 +189,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100));
+        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, Math.max(0, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100)));
     }
     @action
     onDividerUp = (e: PointerEvent): void => {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6edd90215..ec1bf5d0e 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 { Document } from "../../../fields/Document";
 import { FieldWaiting } from "../../../fields/Field";
@@ -90,14 +90,14 @@ class TreeView extends React.Component<TreeViewProps> {
         if (children && children !== FieldWaiting) { // add children for a collection
             if (!this._collapsed) {
                 bulletType = BulletType.Collapsible;
-                childElements = <ul key={this.props.document.Id}>
+                childElements = <ul>
                     {children.Data.map(value => <TreeView key={value.Id} document={value} deleteDoc={this.remove} />)}
                 </ul>
             }
             else bulletType = BulletType.Collapsed;
         }
         return <div className="treeViewItem-container" >
-            <li className="collection-child" key={this.props.document.Id}>
+            <li className="collection-child">
                 {this.renderBullet(bulletType)}
                 {this.renderTitle()}
                 {childElements ? childElements : (null)}
-- 
cgit v1.2.3-70-g09d2


From 18ef731f66340c759f6818c923e1032bd5b84c7a Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 21 Mar 2019 01:50:48 -0400
Subject: fixed selections within schema.  fixed image double-tap.  fixed Open
 Full Screen

---
 .../views/collections/CollectionDockingView.tsx    |   2 +
 .../views/collections/CollectionSchemaView.tsx     | 151 +++++++--------------
 src/client/views/nodes/ImageBox.tsx                |   4 +-
 3 files changed, 53 insertions(+), 104 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 0f0276929..fd0810242 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -61,6 +61,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         docconfig.callDownwards('_$init');
         this._goldenLayout._$maximiseItem(docconfig);
         this._fullScreen = docconfig;
+        this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
         this.stateChanged();
     }
     @action
@@ -69,6 +70,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             this._goldenLayout._$minimiseItem(this._fullScreen);
             this._goldenLayout.root.contentItems[0].removeChild(this._fullScreen);
             this._fullScreen = null;
+            this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
             this.stateChanged();
         }
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index d3ade7ebb..b986f394c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,29 +1,29 @@
 import React = require("react")
-import { action, observable, ObservableMap, computed } from "mobx";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faCog } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
 import "react-table/react-table.css";
 import { Document } from "../../../fields/Document";
 import { Field, Opt } from "../../../fields/Field";
+import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
+import { ListField } from "../../../fields/ListField";
+import { Server } from "../../Server";
+import { setupDrag } from "../../util/DragManager";
 import { CompileScript, ToField } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
+import { anchorPoints, Flyout } from "../DocumentDecorations";
+import '../DocumentDecorations.scss';
 import { EditableView } from "../EditableView";
 import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
-import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
+import { CollectionView, COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
-import { setupDrag } from "../../util/DragManager";
-import '../DocumentDecorations.scss';
-import { Flyout, anchorPoints } from "../DocumentDecorations";
-import { ListField } from "../../../fields/ListField";
-import { Key } from "../../../fields/Key";
-import { Server } from "../../Server";
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -44,17 +44,18 @@ class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggl
     render() {
         if (this.key) {
             return (<div key={this.key.Id}>
-                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />  {this.key.Name}
+                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />
+                {this.key.Name}
             </div>)
-        } else {
-            return <div></div>
         }
+        return (null);
     }
 }
 
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
+    private _startSplitPercent = 0;
     private DIVIDER_WIDTH = 4;
 
     @observable _columns: Array<Key> = [KeyStore.Title, KeyStore.Data, KeyStore.Author];
@@ -64,6 +65,8 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _panelHeight = 0;
     @observable _selectedIndex = 0;
     @observable _columnsPercentage = 0;
+    @observable _keys: Key[] = [];
+
     @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
 
@@ -124,9 +127,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
+                that.props.select(e.ctrlKey);
                 that._selectedIndex = rowInfo.index;
-                // bcz - ugh - needed to force Measure to do its thing and call onResize
-                this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage - 0.05)
 
                 if (handleOriginal) {
                     handleOriginal()
@@ -165,27 +167,14 @@ export class CollectionSchemaView extends CollectionViewBase {
             this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
-
-    @observable keys: Key[] = [];
-
     findAllDocumentKeys = (): { [id: string]: boolean } => {
         const docs = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         let keys: { [id: string]: boolean } = {}
-        docs.forEach(doc => {
-            let protos = doc.GetAllPrototypes();
-            for (const proto of protos) {
-                proto._proxies.forEach((val: any, key: string) => {
-                    keys[key] = false
-                })
-            }
-        })
-        this.columns.forEach(key => {
-            keys[key.Id] = true;
-        })
+        docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false)));
+        this.columns.forEach(key => keys[key.Id] = true)
         return keys;
     }
 
-    _startSplitPercent = 0;
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
@@ -207,51 +196,11 @@ export class CollectionSchemaView extends CollectionViewBase {
         document.addEventListener('pointerup', this.onDividerUp);
     }
 
-
+    @observable _tableWidth = 0;
     @action
-    onColDividerMove = (e: PointerEvent): void => {
-        let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this._columnsPercentage = 100 - (e.clientY - nativeWidth.top) / nativeWidth.height * 100;
+    setTableDimensions = (r: any) => {
+        this._tableWidth = r.entry.width;
     }
-    @action
-    onColDividerUp = (e: PointerEvent): void => {
-        document.removeEventListener("pointermove", this.onColDividerMove);
-        document.removeEventListener('pointerup', this.onColDividerUp);
-    }
-    onColDividerDown = (e: React.PointerEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onColDividerMove);
-        document.addEventListener('pointerup', this.onColDividerUp);
-    }
-
-    @action
-    onExpanderMove = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    @action
-    onColumnsMove = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-    @action
-    onColumnsUp = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.removeEventListener("pointermove", this.onColumnsMove);
-        document.removeEventListener('pointerup', this.onColumnsUp);
-        this._columnsPercentage = this._columnsPercentage ? 0 : 50;
-    }
-    onColumnsDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this.splitPercentage;
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onColumnsMove);
-        document.addEventListener('pointerup', this.onColumnsUp);
-    }
-
     @action
     setScaling = (r: any) => {
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
@@ -267,11 +216,16 @@ export class CollectionSchemaView extends CollectionViewBase {
     getTransform = (): Transform => {
         return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._contentScaling);
     }
+    getPreviewTransform = (): Transform => {
+        return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth, - COLLECTION_BORDER_WIDTH).scale(1 / this._contentScaling);
+    }
 
     focusDocument = (doc: Document) => { }
 
     onPointerDown = (e: React.PointerEvent): void => {
-        //
+        if (this.props.isSelected()) {
+            e.stopPropagation();
+        }
     }
 
     render() {
@@ -289,7 +243,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                             AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
                             isTopMost={false}
                             SelectOnLoad={false}
-                            ScreenToLocalTransform={this.getTransform}
+                            ScreenToLocalTransform={this.getPreviewTransform}
                             ContentScaling={this.getContentScaling}
                             PanelWidth={this.getPanelWidth}
                             PanelHeight={this.getPanelHeight}
@@ -326,34 +280,27 @@ export class CollectionSchemaView extends CollectionViewBase {
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
-                    <Measure onResize={action((r: any) => {
-                        this._dividerX = r.entry.width;
-                        this._panelHeight = r.entry.height;
-                    })}>
+                    <Measure onResize={this.setTableDimensions}>
                         {({ measureRef }) =>
-                            <div ref={measureRef} className="collectionSchemaView-tableContainer"
-                                style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
-                                <div className="collectionSchemaView-reactContainer" style={{ height: `calc(100% - ${this._columnsPercentage}%)` }}>
-                                    <ReactTable
-                                        data={children}
-                                        pageSize={children.length}
-                                        page={0}
-                                        showPagination={false}
-                                        columns={columns.map(col => ({
-                                            Header: col.Name,
-                                            accessor: (doc: Document) => [doc, col],
-                                            id: col.Id
-                                        }))}
-                                        column={{
-                                            ...ReactTableDefaults.column,
-                                            Cell: this.renderCell,
+                            <div className="collectionSchemaView-tableContainer" ref={measureRef} style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
+                                <ReactTable
+                                    data={children}
+                                    pageSize={children.length}
+                                    page={0}
+                                    showPagination={false}
+                                    columns={columns.map(col => ({
+                                        Header: col.Name,
+                                        accessor: (doc: Document) => [doc, col],
+                                        id: col.Id
+                                    }))}
+                                    column={{
+                                        ...ReactTableDefaults.column,
+                                        Cell: this.renderCell,
 
-                                        }}
-                                        getTrProps={this.getTrProps}
-                                    />
-                                </div>
-                            </div>
-                        }
+                                    }}
+                                    getTrProps={this.getTrProps}
+                                />
+                            </div>}
                     </Measure>
                     {dividerDragger}
                     <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2db0cc4e2..60d1f7214 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -50,7 +50,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     onPointerDown = (e: React.PointerEvent): void => {
         if (Date.now() - this._lastTap < 300) {
-            if (e.buttons === 1 && this.props.isSelected()) {
+            if (e.buttons === 1) {
                 e.stopPropagation();
                 this._downX = e.clientX;
                 this._downY = e.clientY;
@@ -72,7 +72,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     lightbox = (path: string) => {
         const images = [path];
-        if (this._isOpen && this.props.isSelected()) {
+        if (this._isOpen) {
             return (<Lightbox
                 mainSrc={images[this._photoIndex]}
                 nextSrc={images[(this._photoIndex + 1) % images.length]}
-- 
cgit v1.2.3-70-g09d2

