From f0781beeadf54bfc7cd4709ace9f49b1bb7e7a0d Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Wed, 5 Aug 2020 20:03:37 -0400
Subject: ff

---
 src/client/views/search/SearchBox.tsx | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 1e44a379b..68afcf60c 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -129,6 +129,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             this._results.forEach(result => {
                 Doc.UnBrushDoc(result[0]);
                 result[0].searchMatch = undefined;
+                result[0].resetSearch = undefined;
+
             });
 
             this.props.Document._schemaHeaders = new List<SchemaHeaderField>([]);
@@ -429,6 +431,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._results.forEach(result => {
             Doc.UnBrushDoc(result[0]);
             result[0].searchMatch = undefined;
+            result[0].resetSearch = undefined;
+
         });
         this._results = [];
         this._resultsSet.clear();
@@ -677,6 +681,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             this._isSearch[i] = "search";
                             Doc.BrushDoc(result[0]);
                             result[0].searchMatch = true;
+                            result[0].resetSearch = true;
                             Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
                             this.children++;
                         }
@@ -690,6 +695,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             result[0].lines = lines;
                             result[0].highlighting = highlights.join(", ");
                             result[0].searchMatch = true;
+                            result[0].resetSearch = true;
                             if (i < this._visibleDocuments.length) {
                                 this._visibleDocuments[i] = result[0];
                                 this._isSearch[i] = "search";
-- 
cgit v1.2.3-70-g09d2


From 9526353b2eca02cb472291e28f16e578dcbb826e Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Thu, 6 Aug 2020 12:37:51 -0400
Subject: reverting:

---
 src/client/views/MainView.tsx                             | 2 +-
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 1 -
 src/client/views/search/SearchBox.tsx                     | 3 ++-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 1b2dd1c44..20d4ecf2c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -195,7 +195,7 @@ export class MainView extends React.Component {
             let check = false;
             const icon = "icon";
             targets.forEach((thing) => {
-                if (thing.className.toString() === "collectionSchemaView-table" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "beta" || thing.className.toString() === "collectionSchemaView-menuOptions-wrapper") {
+                if (thing.className.toString() === "collectionSchemaView-table" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "beta" || thing.className.toString() === "collectionSchemaView-menuOptions-wrapper" || thing.className.toString() === "collectionSchemaView-container") {
                     check = true;
                 }
             });
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 2711a08c0..6865efa5b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -307,7 +307,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             if (BoolCast(Doc.GetProto(this.dataDoc).resetSearch) === true) {
                 this._searchIndex = 0;
                 Doc.GetProto(this.dataDoc).resetSearch = undefined;
-                this.dumbthing = true;
             }
             else {
                 this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex;
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 68afcf60c..c4923947e 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -590,7 +590,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 y += 300;
             }
         }
-        return Docs.Create.SearchDocument({ _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString), searchQuery: StrCast(this.layoutDoc._searchString) });
+
+        return Docs.Create.SchemaDocument(Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []), DocListCast(this.dataDoc[this.fieldKey]), { _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString) });
     }
 
     @action.bound
-- 
cgit v1.2.3-70-g09d2


From e0d002211d50558eb250ad13a57480f31a8b9ebe Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Thu, 6 Aug 2020 15:46:11 -0400
Subject: restoring viewspec algorithm and fixing kvp menu

---
 .../views/collections/CollectionSchemaHeaders.tsx  | 56 +++++++++++++++++-----
 .../views/collections/CollectionSchemaView.scss    |  1 -
 src/client/views/collections/CollectionSubView.tsx | 29 ++++-------
 src/client/views/search/SearchBox.tsx              | 56 +++++++++++++---------
 4 files changed, 86 insertions(+), 56 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index a05b12292..523fb74bb 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -11,6 +11,7 @@ import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHe
 import { undoBatch } from "../../util/UndoManager";
 import { Doc } from "../../../fields/Doc";
 import { StrCast } from "../../../fields/Types";
+import { optionFocusAriaMessage } from "react-select/src/accessibility";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -286,6 +287,7 @@ export interface KeysDropdownProps {
     setIsEditing: (isEditing: boolean) => void;
     width?: string;
     docs?: Doc[];
+
 }
 @observer
 export class KeysDropdown extends React.Component<KeysDropdownProps> {
@@ -365,10 +367,12 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     onPointerOut = (e: React.PointerEvent): void => {
         this._canClose = true;
     }
-
+    @action
     renderOptions = (): JSX.Element[] | JSX.Element => {
-        if (!this._isOpen) return <></>;
-
+        // if (!this._isOpen) {
+        //     this.defaultMenuHeight = 0;
+        //     return <></>;
+        // }
         const searchTerm = this._searchTerm.trim() === "New field" ? "" : this._searchTerm;
 
         const keyOptions = searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
@@ -378,7 +382,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         const options = keyOptions.map(key => {
             return <div key={key} className="key-option" style={{
                 border: "1px solid lightgray",
-                width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
+                width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white",
             }}
                 onPointerDown={e => e.stopPropagation()} onClick={() => { this.onSelect(key); this.setSearchTerm(""); }}>{key}</div>;
         });
@@ -387,21 +391,35 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         if (this._key !== this._searchTerm.slice(0, this._key.length)) {
             if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
                 options.push(<div key={""} className="key-option" style={{
-                    border: "1px solid lightgray",
-                    width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
+                    border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white",
                 }}
                     onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>
                     Create "{this._searchTerm}" key</div>);
             }
         }
 
+        if (options.length === 0) {
+            this.defaultMenuHeight = 0;
+        }
+        else {
+            if (this.props.docs) {
+                let panesize = this.props.docs.length * 30;
+                options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
+            }
+            else {
+                options.length > 5 ? this.defaultMenuHeight = 108 : this.defaultMenuHeight = options.length * 20 + 8;
+            }
+        }
         return options;
     }
-
+    @action
     renderFilterOptions = (): JSX.Element[] | JSX.Element => {
-        if (!this._isOpen) return <></>;
+        // if (!this._isOpen) {
+        //     this.defaultMenuHeight = 0;
+        //     return <></>;
+        // }
         const keyOptions: string[] = [];
-        const colpos = this._searchTerm.indexOf(":")
+        const colpos = this._searchTerm.indexOf(":");
         const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
         this.props.docs?.forEach((doc) => {
             const key = StrCast(doc[this._key]);
@@ -413,15 +431,28 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
 
         const options = keyOptions.map(key => {
             return <div key={key} className="key-option" style={{
-                border: "1px solid lightgray",
-                width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
+                border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
             }}
                 onPointerDown={e => e.stopPropagation()} onClick={() => { this.onSelectValue(key); }}>{key}</div>;
         });
+        if (options.length === 0) {
+            this.defaultMenuHeight = 0;
+        }
+        else {
+            if (this.props.docs) {
+                let panesize = this.props.docs.length * 30;
+                options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
+            }
+            else {
+                options.length > 5 ? this.defaultMenuHeight = 108 : this.defaultMenuHeight = options.length * 20 + 8;
+            }
+
+        }
 
         return options;
     }
 
+    @observable defaultMenuHeight = 0;
 
     render() {
         return (
@@ -434,8 +465,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                         e.stopPropagation();
                     }} onFocus={this.onFocus} onBlur={this.onBlur}></input>
                 <div className="keys-options-wrapper" style={{
-                    backgroundColor: "white",
-                    width: this.props.width, maxWidth: this.props.width,
+                    width: this.props.width, maxWidth: this.props.width, overflow: "scroll", height: this.defaultMenuHeight,
                 }}
                     onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
                     {this._searchTerm.includes(":") ?
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index ba0a259c5..0d09f2031 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -280,7 +280,6 @@ button.add-column {
             background-color: white;
 
             .key-option {
-                //background-color: $light-color;
                 background-color: white;
                 border: 1px solid lightgray;
                 padding: 2px 3px;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 4025e25f9..9a64298fb 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -112,10 +112,9 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                 [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])];
         }
         @computed get childDocs() {
-            let rawdocs: (Doc | Promise<Doc>)[] = DocListCast(this.props.Document._searchDocs);
-
-            if (rawdocs.length !== 0) {
-            } else if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
+            //DO NOT CHANGE the new algorithm in this class without emailing andy r. first!!
+            let rawdocs: (Doc | Promise<Doc>)[] = [];
+            if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
                 rawdocs = [this.dataField];
             } else if (Cast(this.dataField, listSpec(Doc), null)) { // otherwise, if the collection data is a list, then use it.  
                 rawdocs = Cast(this.dataField, listSpec(Doc), null);
@@ -131,24 +130,15 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
             let childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
 
             const searchDocs = DocListCast(this.props.Document._searchDocs);
-            // if (searchDocs !== undefined && searchDocs.length > 0) {
-            //     let newdocs: Doc[] = [];
-            //     childDocs.forEach((el) => {
-            //         searchDocs.includes(el) ? newdocs.push(el) : undefined;
-            //     });
-            //     childDocs = newdocs;
-            // }
+
+            //DO NOT CHANGE the new algorithm in this class without emailing andy r. first!!
 
             let docsforFilter: Doc[] = childDocs;
             if (searchDocs !== undefined && searchDocs.length > 0) {
                 docsforFilter = [];
-                // let newdocs: Doc[] = [];
-                // let newarray: Doc[] = [];
-                //while (childDocs.length > 0) {
-                //newarray = [];
+
                 childDocs.forEach((d) => {
                     if (d.data !== undefined) {
-                        console.log(d);
                         let newdocs = DocListCast(d.data);
                         if (newdocs.length > 0) {
                             let vibecheck: boolean | undefined = undefined;
@@ -177,8 +167,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                         docsforFilter.push(d);
                     }
                 });
-                //childDocs = newarray;
-                //}
+
             }
             childDocs = docsforFilter;
 
@@ -186,7 +175,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
             const docFilters = this.docFilters();
             const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
 
-            return this.props.Document.dontRegisterView ? docs : DocUtils.FilterDocs(docs, this.docFilters(), docRangeFilters, viewSpecScript);
+            return this.props.Document.dontRegisterView ? childDocs : DocUtils.FilterDocs(childDocs, this.docFilters(), docRangeFilters, viewSpecScript);
         }
 
         @action
@@ -491,4 +480,4 @@ import { FormattedTextBox, GoogleRef } from "../nodes/formattedText/FormattedTex
 import { CollectionView, CollectionViewType } from "./CollectionView";
 import { SelectionManager } from "../../util/SelectionManager";
 import { OverlayView } from "../OverlayView";
-import { setTimeout } from "timers";
+import { setTimeout } from "timers";
\ No newline at end of file
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c4923947e..5a2c5400f 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -129,8 +129,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             this._results.forEach(result => {
                 Doc.UnBrushDoc(result[0]);
                 result[0].searchMatch = undefined;
-                result[0].resetSearch = undefined;
-
             });
 
             this.props.Document._schemaHeaders = new List<SchemaHeaderField>([]);
@@ -301,6 +299,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     searchCollection(query: string) {
         const selectedCollection: DocumentView = SelectionManager.SelectedDocuments()[0];
         query = query.toLowerCase();
+
         if (selectedCollection !== undefined) {
             this.currentSelectedCollection = selectedCollection;
             if (this.filter === true) {
@@ -431,8 +430,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._results.forEach(result => {
             Doc.UnBrushDoc(result[0]);
             result[0].searchMatch = undefined;
-            result[0].resetSearch = undefined;
-
         });
         this._results = [];
         this._resultsSet.clear();
@@ -590,7 +587,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 y += 300;
             }
         }
-
         return Docs.Create.SchemaDocument(Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []), DocListCast(this.dataDoc[this.fieldKey]), { _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString) });
     }
 
@@ -682,7 +678,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             this._isSearch[i] = "search";
                             Doc.BrushDoc(result[0]);
                             result[0].searchMatch = true;
-                            result[0].resetSearch = true;
                             Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
                             this.children++;
                         }
@@ -696,7 +691,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             result[0].lines = lines;
                             result[0].highlighting = highlights.join(", ");
                             result[0].searchMatch = true;
-                            result[0].resetSearch = true;
                             if (i < this._visibleDocuments.length) {
                                 this._visibleDocuments[i] = result[0];
                                 this._isSearch[i] = "search";
@@ -780,29 +774,47 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                     style={{ padding: 1, backgroundColor: this.filter ? "white" : "lightgray", color: this.filter ? "black" : "white" }}
                                     onPointerDown={e => { e.stopPropagation(); SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined); }}
                                     onClick={action(() => {
-                                        const dofilter = (currentSelectedCollection: DocumentView) => {
-                                            let docs = DocListCast(currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(currentSelectedCollection.dataDoc)]);
+                                        ///DONT Change without emailing andy r first.
+                                        this.filter = !this.filter && !this.searchFullDB;
+                                        if (this.filter === true && this.currentSelectedCollection !== undefined) {
+                                            this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>(this.docsforfilter);
+                                            let newarray: Doc[] = [];
+                                            let docs: Doc[] = [];
+                                            docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]);
                                             while (docs.length > 0) {
-                                                const newarray: Doc[] = [];
-                                                docs.filter(d => d.data !== undefined).forEach((d) => {
-                                                    d._searchDocs = new List<Doc>(this.docsforfilter);
-                                                    newarray.push(...DocListCast(d.data));
+                                                newarray = [];
+                                                docs.forEach((d) => {
+                                                    if (d.data !== undefined) {
+                                                        d._searchDocs = new List<Doc>(this.docsforfilter);
+                                                        const newdocs = DocListCast(d.data);
+                                                        newdocs.forEach((newdoc) => {
+                                                            newarray.push(newdoc);
+                                                        });
+                                                    }
                                                 });
                                                 docs = newarray;
                                             }
-                                        };
-                                        this.filter = !this.filter && !this.searchFullDB;
-                                        if (this.filter === true && this.currentSelectedCollection !== undefined) {
-                                            this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>(this.docsforfilter);
-
-                                            dofilter(this.currentSelectedCollection);
 
                                             this.currentSelectedCollection.props.Document._docFilters = new List<string>(Cast(this.props.Document._docFilters, listSpec("string"), []));
                                             this.props.Document.selectedDoc = this.currentSelectedCollection.props.Document;
                                         }
                                         else if (this.filter === false && this.currentSelectedCollection !== undefined) {
-
-                                            dofilter(this.currentSelectedCollection);
+                                            let newarray: Doc[] = [];
+                                            let docs: Doc[] = [];
+                                            docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]);
+                                            while (docs.length > 0) {
+                                                newarray = [];
+                                                docs.forEach((d) => {
+                                                    if (d.data !== undefined) {
+                                                        d._searchDocs = new List<Doc>();
+                                                        const newdocs = DocListCast(d.data);
+                                                        newdocs.forEach((newdoc) => {
+                                                            newarray.push(newdoc);
+                                                        });
+                                                    }
+                                                });
+                                                docs = newarray;
+                                            }
 
                                             this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]);
                                             this.currentSelectedCollection.props.Document._docFilters = undefined;
@@ -927,4 +939,4 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             </div >
         );
     }
-}
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 3bd97210a1112d9d0af802255677caf1de95616c Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Sat, 8 Aug 2020 21:24:47 -0400
Subject: tidying up assorted features, disabling editing doc keys in search,
 etc

---
 src/client/views/DocComponent.tsx                  |   2 +
 src/client/views/GlobalKeyHandler.ts               |   2 +
 src/client/views/MainView.tsx                      |   2 +-
 .../views/collections/CollectionSchemaCells.tsx    | 173 +++++++++++++--------
 .../views/collections/CollectionSchemaHeaders.tsx  |  11 +-
 .../views/collections/CollectionSchemaView.scss    |  45 +++++-
 .../views/collections/CollectionSchemaView.tsx     |  26 +++-
 src/client/views/collections/CollectionView.tsx    |   3 +
 src/client/views/collections/SchemaTable.tsx       |   8 +-
 src/client/views/search/SearchBox.tsx              |  12 +-
 10 files changed, 199 insertions(+), 85 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 831c246d1..75ac9141d 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -170,6 +170,8 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
                         added.map(doc => doc.context = this.props.Document);
                         (targetDataDoc[this.annotationKey] as List<Doc>).push(...added);
                         targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
+                        const lastModified = "lastModified";
+                        targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
                     }
                 }
             }
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 3a61e89ce..3b8828ecc 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -331,6 +331,8 @@ export default class KeyManager {
                             undoBatch(() => {
                                 targetDataDoc[fieldKey] = new List<Doc>([...docList, ...added]);
                                 targetDataDoc[fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+                                const lastModified = "lastModified";
+                                targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
                             })();
                         }
                     }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index eb9f77641..744e5c68b 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -195,7 +195,7 @@ export class MainView extends React.Component {
             let check = false;
             const icon = "icon";
             targets.forEach((thing) => {
-                if (thing.className.toString() === "collectionSchemaView-table" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "beta" || thing.className.toString() === "collectionSchemaView-menuOptions-wrapper") {
+                if (thing.className.toString() === "collectionSchemaView-searchContainer" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "collectionSchema-header-menuOptions") {
                     check = true;
                 }
             });
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 0bc2afd47..3725b0dd9 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -159,6 +159,29 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     //     e.stopPropagation();
     // }
 
+    returnHighlights(bing: (() => string), positions?: number[]) {
+        const results = [];
+        const contents = bing();
+
+        if (positions !== undefined) {
+            StrCast(this.props.Document._searchString)
+            const length = StrCast(this.props.Document._searchString).length;
+
+            results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(0, positions[0]) : "enter value"}</span>);
+            positions.forEach((num, cur) => {
+                results.push(<span style={{ backgroundColor: "#FFFF00", color: contents ? "black" : "grey" }}>{contents ? contents.slice(num, num + length) : "enter value"}</span>);
+                let end = 0;
+                cur === positions.length - 1 ? end = contents.length : end = positions[cur + 1];
+                results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(num + length, end) : "enter value"}</span>);
+            }
+            );
+            return results;
+        }
+        else {
+            return <span style={{ color: contents ? "black" : "grey" }}>{contents ? contents?.valueOf() : "enter value"}</span>;
+        }
+    }
+
     renderCellWithType(type: string | undefined) {
         const dragRef: React.RefObject<HTMLDivElement> = React.createRef();
 
@@ -274,24 +297,95 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                 positions.pop();
             }
         }
+        let search = false;
+        if (this.props.Document._searchDoc !== undefined) {
+            search = true;
+        }
+
+
         return (
             <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }}
                 ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
                 <div className={className} ref={this._focusRef} onPointerDown={onItemDown} tabIndex={-1}>
                     <div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
-                        <EditableView
-                            positions={positions.length > 0 ? positions : undefined}
-                            search={StrCast(this.props.Document._searchString) ? StrCast(this.props.Document._searchString) : undefined}
-                            editing={this._isEditing}
-                            isEditingCallback={this.isEditingCallback}
-                            display={"inline"}
-                            contents={contents ? contents : type === "number" ? "0" : "undefined"}
-                            highlight={positions.length > 0 ? true : undefined}
-                            //contents={StrCast(contents)}
-                            height={"auto"}
-                            maxHeight={Number(MAX_ROW_HEIGHT)}
-                            placeholder={"enter value"}
-                            bing={() => {
+                        {!search ?
+                            <EditableView
+                                positions={positions.length > 0 ? positions : undefined}
+                                search={StrCast(this.props.Document._searchString) ? StrCast(this.props.Document._searchString) : undefined}
+                                editing={this._isEditing}
+                                isEditingCallback={this.isEditingCallback}
+                                display={"inline"}
+                                contents={contents ? contents : type === "number" ? "0" : "undefined"}
+                                highlight={positions.length > 0 ? true : undefined}
+                                //contents={StrCast(contents)}
+                                height={"auto"}
+                                maxHeight={Number(MAX_ROW_HEIGHT)}
+                                placeholder={"enter value"}
+                                bing={() => {
+                                    const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+                                    if (cfield !== undefined) {
+                                        // if (typeof(cfield)===RichTextField)
+                                        const a = cfield as RichTextField;
+                                        if (a.Text !== undefined) {
+                                            return (a.Text);
+                                        }
+                                        else if (StrCast(cfield)) {
+                                            return StrCast(cfield);
+                                        }
+                                        else {
+                                            return String(NumCast(cfield));
+                                        }
+                                    }
+                                }}
+                                GetValue={() => {
+                                    if (type === "number" && (contents === 0 || contents === "0")) {
+                                        return "0";
+                                    } else {
+                                        const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+                                        if (type === "number") {
+                                            return StrCast(cfield);
+                                        }
+                                        const cscript = cfield instanceof ComputedField ? cfield.script.originalScript : undefined;
+                                        const cfinalScript = cscript?.split("return")[cscript.split("return").length - 1];
+                                        const val = cscript !== undefined ? (cfinalScript?.endsWith(";") ? `:=${cfinalScript?.substring(0, cfinalScript.length - 2)}` : cfinalScript) :
+                                            Field.IsField(cfield) ? Field.toScriptString(cfield) : "";
+                                        return val;
+
+                                    }
+
+                                }}
+                                SetValue={action((value: string) => {
+                                    let retVal = false;
+
+                                    if (value.startsWith(":=")) {
+                                        retVal = this.props.setComputed(value.substring(2), props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
+                                    } else {
+                                        const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+                                        if (script.compiled) {
+                                            retVal = this.applyToDoc(props.Document, this.props.row, this.props.col, script.run);
+                                        }
+
+                                    }
+                                    if (retVal) {
+                                        this._isEditing = false; // need to set this here. otherwise, the assignment of the field will invalidate & cause render() to be called with the wrong value for 'editing'
+                                        this.props.setIsEditing(false);
+                                    }
+                                    return retVal;
+
+                                    //return true;
+                                })}
+                                OnFillDown={async (value: string) => {
+                                    const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+                                    if (script.compiled) {
+                                        DocListCast(this.props.Document[this.props.fieldKey]).
+                                            forEach((doc, i) => value.startsWith(":=") ?
+                                                this.props.setComputed(value.substring(2), doc, this.props.rowProps.column.id!, i, this.props.col) :
+                                                this.applyToDoc(doc, i, this.props.col, script.run));
+                                    }
+                                }}
+                            />
+                            :
+                            this.returnHighlights(() => {
                                 const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
                                 if (cfield !== undefined) {
                                     // if (typeof(cfield)===RichTextField)
@@ -306,56 +400,11 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                         return String(NumCast(cfield));
                                     }
                                 }
-                            }}
-                            GetValue={() => {
-                                if (type === "number" && (contents === 0 || contents === "0")) {
-                                    return "0";
-                                } else {
-                                    const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
-                                    if (type === "number") {
-                                        return StrCast(cfield);
-                                    }
-                                    const cscript = cfield instanceof ComputedField ? cfield.script.originalScript : undefined;
-                                    const cfinalScript = cscript?.split("return")[cscript.split("return").length - 1];
-                                    const val = cscript !== undefined ? (cfinalScript?.endsWith(";") ? `:=${cfinalScript?.substring(0, cfinalScript.length - 2)}` : cfinalScript) :
-                                        Field.IsField(cfield) ? Field.toScriptString(cfield) : "";
-                                    return val;
-
+                                else {
+                                    return "";
                                 }
-
-                            }}
-                            SetValue={action((value: string) => {
-                                let retVal = false;
-
-                                if (value.startsWith(":=")) {
-                                    retVal = this.props.setComputed(value.substring(2), props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
-                                } else {
-                                    const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
-                                    if (script.compiled) {
-                                        retVal = this.applyToDoc(props.Document, this.props.row, this.props.col, script.run);
-                                    }
-
-                                }
-                                if (retVal) {
-                                    this._isEditing = false; // need to set this here. otherwise, the assignment of the field will invalidate & cause render() to be called with the wrong value for 'editing'
-                                    this.props.setIsEditing(false);
-                                }
-                                return retVal;
-
-                                //return true;
-                            })}
-                            OnFillDown={async (value: string) => {
-                                const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
-                                if (script.compiled) {
-                                    DocListCast(this.props.Document[this.props.fieldKey]).
-                                        forEach((doc, i) => value.startsWith(":=") ?
-                                            this.props.setComputed(value.substring(2), doc, this.props.rowProps.column.id!, i, this.props.col) :
-                                            this.applyToDoc(doc, i, this.props.col, script.run));
-                                }
-                            }}
-                        />
-
-
+                            }, positions)
+                        }
                     </div >
                     {/* {fieldIsDoc ? docExpander : null} */}
                 </div>
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 892b93f80..bde7d054e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -330,7 +330,9 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     @undoBatch
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
-            const keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+            let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+            let blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+            keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
             if (keyOptions.length) {
                 this.onSelect(keyOptions[0]);
             } else if (this._searchTerm !== "" && this.props.canAddNew) {
@@ -375,10 +377,13 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         }
         const searchTerm = this._searchTerm.trim() === "New field" ? "" : this._searchTerm;
 
-        const keyOptions = searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+        let keyOptions = searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
         const exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
             this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
 
+        let blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+        keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
+
         const options = keyOptions.map(key => {
             return <div key={key} className="key-option" style={{
                 border: "1px solid lightgray",
@@ -418,7 +423,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             this.defaultMenuHeight = 0;
             return <></>;
         }
-        const keyOptions: string[] = [];
+        let keyOptions: string[] = [];
         const colpos = this._searchTerm.indexOf(":");
         const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
         this.props.docs?.forEach((doc) => {
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 0d09f2031..86bf9d0e0 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -43,6 +43,49 @@
     // }
 }
 
+.collectionSchemaView-searchContainer {
+    border-width: $COLLECTION_BORDER_WIDTH;
+    border-color: $intermediate-color;
+    border-style: solid;
+    border-radius: $border-radius;
+    box-sizing: border-box;
+    position: relative;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    margin-top: 0;
+    transition: top 0.5s;
+    display: flex;
+    justify-content: space-between;
+    flex-wrap: nowrap;
+    touch-action: none;
+
+    div {
+        touch-action: none;
+    }
+
+
+    .collectionSchemaView-tableContainer {
+        width: 100%;
+        height: 100%;
+    }
+
+    .collectionSchemaView-dividerDragger {
+        position: relative;
+        height: 100%;
+        width: 20px;
+        z-index: 20;
+        right: 0;
+        top: 0;
+        background: gray;
+        cursor: col-resize;
+    }
+
+    // .documentView-node:first-child {
+    //     background: $light-color;
+    // }
+}
+
 .ReactTable {
     width: 100%;
     background: white;
@@ -165,7 +208,7 @@
 
 
 .collectionSchema-header-menu {
-    height: 100%;
+    height: auto;
     z-index: 100;
     position: absolute;
     background:white;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a003de0d3..7409640eb 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -11,7 +11,7 @@ import { Doc } from "../../../fields/Doc";
 import { List } from "../../../fields/List";
 import { listSpec } from "../../../fields/Schema";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { Cast, NumCast } from "../../../fields/Types";
+import { Cast, NumCast, BoolCast } from "../../../fields/Types";
 import { TraceMobx } from "../../../fields/util";
 import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents } from "../../../Utils";
 import { SnappingManager } from "../../util/SnappingManager";
@@ -71,8 +71,18 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @observable _pointerY = 0;
     @observable _openTypes: boolean = false;
     @computed get menuCoordinates() {
-        const x = Math.max(0, Math.min(document.body.clientWidth - this._menuWidth, this._pointerX));
-        const y = Math.max(0, Math.min(document.body.clientHeight - this._menuHeight, this._pointerY));
+        let searchx = 0;
+        let searchy = 0;
+        if (this.props.Document._searchDoc !== undefined) {
+            let el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0];
+            if (el !== undefined) {
+                let rect = el.getBoundingClientRect();
+                searchx = rect.x;
+                searchy = rect.y
+            }
+        }
+        const x = Math.max(0, Math.min(document.body.clientWidth - this._menuWidth, this._pointerX)) - searchx;
+        const y = Math.max(0, Math.min(document.body.clientHeight - this._menuHeight, this._pointerY)) - searchy;
         return this.props.ScreenToLocalTransform().transformPoint(x, y);
     }
 
@@ -611,14 +621,18 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
     }
     render() {
+        let name = "collectionSchemaView-container";
+        if (this.props.Document._searchDoc !== undefined) {
+            name = "collectionSchemaView-searchContainer";
+        }
         TraceMobx();
         const menuContent = this.renderMenuContent;
         const menu = <div className="collectionSchema-header-menu" ref={this.setNode}
             onWheel={e => this.onZoomMenu(e)}
             onPointerDown={e => this.onHeaderClick(e)}
             style={{
-                position: "fixed", background: "white",
-                transform: `translate(${this.menuCoordinates[0] / this.scale}px, ${this.menuCoordinates[1] / this.scale}px)`
+                position: "fixed", background: "white", border: "black 1px solid",
+                transform: `translate(${(this.menuCoordinates[0] / this.scale)}px, ${(this.menuCoordinates[1] / this.scale)}px)`
             }}>
             <Measure offset onResize={action((r: any) => {
                 const dim = this.props.ScreenToLocalTransform().inverse().transformDirection(r.offset.width, r.offset.height);
@@ -627,7 +641,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 {({ measureRef }) => <div ref={measureRef}> {menuContent} </div>}
             </Measure>
         </div>;
-        return <div className="collectionSchemaView-container"
+        return <div className={name}
             style={{
                 overflow: this.props.overflow === true ? "auto" : undefined,
                 pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined,
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4d1cb670c..30747ff4f 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -46,6 +46,7 @@ import { CollectionTimeView } from './CollectionTimeView';
 import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import { ContextMenuProps } from '../ContextMenuItem';
+import { table } from 'console';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -182,6 +183,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     // targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
                     (targetDataDoc[this.props.fieldKey] as List<Doc>).push(...added);
                     targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+                    const lastModified = "lastModified";
+                    targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
                 }
             }
         }
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 530004b54..972f4c066 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -218,19 +218,15 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         background: col.color, padding: "2px",
                         display: "flex", cursor: "default", height: "100%",
                     }}>
-                    <FontAwesomeIcon icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px" }} />
+                    <FontAwesomeIcon onClick={e => this.props.openHeader(col, e.clientX, e.clientY)} icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
                     {/* <div className="keys-dropdown"
                         style={{ display: "inline", zIndex: 1000 }}> */}
                     {keysDropdown}
                     {/* </div> */}
                     <div onClick={e => this.changeSorting(col)}
-                        style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit" }}>
+                        style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
                         <FontAwesomeIcon icon={sortIcon} size="lg" />
                     </div>
-                    {/* <div onClick={e => this.props.openHeader(col, e.clientX, e.clientY)}
-                        style={{ float: "right", paddingRight: "6px", zIndex: 1, background: "inherit" }}>
-                        <FontAwesomeIcon icon={"compass"} size="sm" />
-                    </div> */}
                 </div>;
 
             return {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 5a2c5400f..fb28ddae0 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -750,7 +750,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @observable filter = false;
 
-    //Make id layour document
     render() {
         this.props.Document._chromeStatus === "disabled";
         this.props.Document._searchDoc = true;
@@ -759,19 +758,20 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         cols > 5 ? length = 1076 : length = cols * 205 + 51;
         let height = 0;
         const rows = this.children;
-        rows > 8 ? height = 31 + 31 * 8 : height = 31 * rows + 31;
+        rows > 6 ? height = 31 + 31 * 6 : height = 31 * rows + 31;
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
                 <div className="searchBox-bar">
                     <div style={{ position: "absolute", left: 15 }}>{Doc.CurrentUserEmail}</div>
                     <div style={{ display: "flex", alignItems: "center" }}>
-                        <FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
-                            style={{ color: "black", padding: 1, left: 35, position: "relative" }} />
-
+                        <Tooltip title={<div className="dash-tooltip" >drag search results as collection</div>} ><div>
+                            <FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
+                                style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} />
+                        </div></Tooltip>
                         <div style={{ cursor: "default", left: 250, position: "relative", }}>
                             <Tooltip title={<div className="dash-tooltip" >only display documents matching search</div>} ><div>
                                 <FontAwesomeIcon icon={"filter"} size="lg"
-                                    style={{ padding: 1, backgroundColor: this.filter ? "white" : "lightgray", color: this.filter ? "black" : "white" }}
+                                    style={{ cursor: "hand", padding: 1, backgroundColor: this.filter ? "white" : "lightgray", color: this.filter ? "black" : "white" }}
                                     onPointerDown={e => { e.stopPropagation(); SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined); }}
                                     onClick={action(() => {
                                         ///DONT Change without emailing andy r first.
-- 
cgit v1.2.3-70-g09d2


From 6b00ff204acbe9d98bb9b6a39c09164afcc18c9e Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Sun, 9 Aug 2020 15:39:16 -0400
Subject: clicking document opens it" "

---
 src/client/util/DocumentManager.ts                 |  1 +
 .../views/collections/CollectionSchemaCells.tsx    | 24 +++++++++++++++-------
 src/client/views/search/SearchBox.tsx              |  1 +
 3 files changed, 19 insertions(+), 7 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 523dbfca0..61892daa3 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -231,6 +231,7 @@ export class DocumentManager {
                     containerDoc.currentTimecode = targetTimecode;
                     const targetContext = await target?.context as Doc;
                     const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
+                    console.log(targetNavContext);
                     DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc, undefined, doc, finished);
                 } else {
                     finished?.();
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 3725b0dd9..64c925af2 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -33,6 +33,7 @@ import DatePicker from "react-datepicker";
 import "react-datepicker/dist/react-datepicker.css";
 import { DateField } from "../../../fields/DateField";
 import { RichTextField } from "../../../fields/RichTextField";
+import { DocumentManager } from "../../util/DocumentManager";
 const path = require('path');
 
 library.add(faExpand);
@@ -216,12 +217,20 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         const doc = FieldValue(Cast(field, Doc));
         const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
 
-        const onItemDown = (e: React.PointerEvent) => {
-            //fieldIsDoc && 
-            SetupDrag(this._focusRef,
-                () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
-                this._document[props.fieldKey] instanceof Doc ? (doc: Doc | Doc[], target: Doc | undefined, addDoc: (newDoc: Doc | Doc[]) => any) => addDoc(doc) : this.props.moveDocument,
-                this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
+        const onItemDown = async (e: React.PointerEvent) => {
+            //DocumentManager.Instance.FollowLink(undefined, this.props.rowProps.original, doc => this.props.addDocTab(doc, "onRight"), false);
+            let doc = Doc.GetProto(this.props.rowProps.original);
+            const targetContext = doc.links;
+            //const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
+            console.log(targetContext);
+            DocumentManager.Instance.jumpToDocument(this.props.rowProps.original, false, undefined, undefined);
+
+            //target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc, undefined, doc, finished);
+            //fieldIsDoc &&     
+            // SetupDrag(this._focusRef,
+            //     () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
+            //     this._document[props.fieldKey] instanceof Doc ? (doc: Doc | Doc[], target: Doc | undefined, addDoc: (newDoc: Doc | Doc[]) => any) => addDoc(doc) : this.props.moveDocument,
+            //     this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
         };
         const onPointerEnter = (e: React.PointerEvent): void => {
             if (e.buttons === 1 && SnappingManager.GetIsDragging() && (type === "document" || type === undefined)) {
@@ -307,7 +316,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }}
                 ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
                 <div className={className} ref={this._focusRef} onPointerDown={onItemDown} tabIndex={-1}>
-                    <div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
+                    <div className="collectionSchemaView-cellContents"
+                        ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
                         {!search ?
                             <EditableView
                                 positions={positions.length > 0 ? positions : undefined}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index fb28ddae0..310e3f235 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -313,6 +313,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             while (docs.length > 0) {
                 newarray = [];
                 docs.forEach((d) => {
+                    d ? console.log(Cast(d.context, Doc)) : null;
                     if (d.data !== undefined) {
                         newarray.push(...DocListCast(d.data));
                     }
-- 
cgit v1.2.3-70-g09d2


From 4f1e459051b069dd1500df4c850deb3e67c01e16 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 10 Aug 2020 19:23:08 -0400
Subject: fixes for search to do filter system and non-searchable documents on
 the server.

---
 src/client/documents/DocumentTypes.ts   |   4 +-
 src/client/documents/Documents.ts       |   5 +-
 src/client/util/CurrentUserUtils.ts     | 179 ++++++++++++++++----------------
 src/client/views/search/SearchBox.tsx   |  14 +--
 src/server/ApiManagers/SearchManager.ts |   3 +-
 5 files changed, 106 insertions(+), 99 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 71d6c2ccc..1bef6fa08 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -10,7 +10,7 @@ export enum DocumentType {
     VID = "video",      // video
     AUDIO = "audio",    // audio
     PDF = "pdf",        // pdf
-    INK = "ink",        // ink stroke
+    INK = "inks",        // ink stroke
     SCREENSHOT = "screenshot",  // view of a desktop application
     FONTICON = "fonticonbox",   // font icon
     SEARCH = "search",            // search query
@@ -31,7 +31,7 @@ export enum DocumentType {
     COLOR = "color",            // color picker (view of a color picker for a color string)
     YOUTUBE = "youtube",        // youtube directory (view of you tube search results)
     DOCHOLDER = "docholder",    // nested document (view of a document)
-    SEARCHITEM= "searchitem",
+    SEARCHITEM = "searchitem",
     COMPARISON = "comparison",   // before/after view with slider (view of 2 images)
     GROUP = "group",            // group of users
 
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index a6a697574..e54c89d9f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -53,6 +53,7 @@ import { Upload } from "../../server/SharedMediaTypes";
 const path = require('path');
 
 export interface DocumentOptions {
+    system?: boolean;
     _autoHeight?: boolean;
     _panX?: number;
     _panY?: number;
@@ -530,7 +531,7 @@ export namespace Docs {
 
         Scripting.addGlobal(Buxton);
 
-        const delegateKeys = ["x", "y", "layoutKey", "dropAction", "lockedPosiiton", "childDropAction", "isLinkButton", "isBackground", "removeDropProperties", "treeViewOpen"];
+        const delegateKeys = ["x", "y", "system", "layoutKey", "dropAction", "lockedPosiiton", "childDropAction", "isLinkButton", "isBackground", "removeDropProperties", "treeViewOpen"];
 
         /**
          * This function receives the relevant document prototype and uses
@@ -553,6 +554,8 @@ export namespace Docs {
         export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data") {
             const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys, "^_");
 
+            protoProps.system = delegateProps.system;
+
             if (!("author" in protoProps)) {
                 protoProps.author = Doc.CurrentUserEmail;
             }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b2fb1e33a..7eed4d2b1 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -45,10 +45,10 @@ export class CurrentUserUtils {
         if (doc["template-button-query"] === undefined) {
             const queryTemplate = Docs.Create.MulticolumnDocument(
                 [
-                    Docs.Create.SearchDocument({ _viewType: CollectionViewType.Schema, ignoreClick: true, forceActive: true, lockedPosition: true, title: "query", _height: 200 }),
-                    Docs.Create.FreeformDocument([], { title: "data", _height: 100 })
+                    Docs.Create.SearchDocument({ _viewType: CollectionViewType.Schema, ignoreClick: true, forceActive: true, lockedPosition: true, title: "query", _height: 200, system: true }),
+                    Docs.Create.FreeformDocument([], { title: "data", _height: 100, system: true })
                 ],
-                { _width: 400, _height: 300, title: "queryView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true }
+                { _width: 400, _height: 300, title: "queryView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true, system: true }
             );
             queryTemplate.isTemplateDoc = makeTemplate(queryTemplate);
             doc["template-button-query"] = CurrentUserUtils.ficon({
@@ -80,10 +80,10 @@ export class CurrentUserUtils {
         if (doc["template-button-slides"] === undefined) {
             const slideTemplate = Docs.Create.MultirowDocument(
                 [
-                    Docs.Create.MulticolumnDocument([], { title: "data", _height: 200 }),
-                    Docs.Create.TextDocument("", { title: "text", _height: 100 })
+                    Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
+                    Docs.Create.TextDocument("", { title: "text", _height: 100, system: true })
                 ],
-                { _width: 400, _height: 300, title: "slideView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true }
+                { _width: 400, _height: 300, title: "slideView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true, system: true }
             );
             slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
             doc["template-button-slides"] = CurrentUserUtils.ficon({
@@ -94,7 +94,7 @@ export class CurrentUserUtils {
         }
 
         if (doc["template-button-description"] === undefined) {
-            const descriptionTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100 }, "header")); // text needs to be a space to allow templateText to be created
+            const descriptionTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created
             descriptionTemplate[DataSym].layout =
                 "<div>" +
                 "    <FormattedTextBox {...props} height='{this._headerHeight||75}px' background='{this._headerColor||`orange`}' fieldKey={'header'}/>" +
@@ -110,7 +110,7 @@ export class CurrentUserUtils {
         }
 
         if (doc["template-button-link"] === undefined) {  // set _backgroundColor to transparent to prevent link dot from obscuring document it's attached to.
-            const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100 }, "header")); // text needs to be a space to allow templateText to be created
+            const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created
             Doc.GetProto(linkTemplate).layout =
                 "<div>" +
                 "    <FormattedTextBox {...props} height='{this._headerHeight||75}px' background='{this._headerColor||`lightGray`}' fieldKey={'header'}/>" +
@@ -158,9 +158,9 @@ export class CurrentUserUtils {
         if (doc["template-button-switch"] === undefined) {
             const { FreeformDocument, MulticolumnDocument, TextDocument } = Docs.Create;
 
-            const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40 });
-            const name = TextDocument("name", { title: "name", _height: 35, _width: 70, _dimMagnitude: 1 });
-            const no = FreeformDocument([], { title: "no", _height: 100, _width: 100 });
+            const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40, system: true });
+            const name = TextDocument("name", { title: "name", _height: 35, _width: 70, _dimMagnitude: 1, system: true });
+            const no = FreeformDocument([], { title: "no", _height: 100, _width: 100, system: true });
             const labelTemplate = {
                 doc: {
                     type: "doc", content: [{
@@ -177,13 +177,13 @@ export class CurrentUserUtils {
             // Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = true");
             Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = !self[this.PARAMS]");
             // Doc.GetProto(no).onClick = ScriptField.MakeScript("self[this.PARAMS] = false");
-            const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, });
+            const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, system: true });
             box.isTemplateDoc = makeTemplate(box, true, "switch");
 
             doc["template-button-switch"] = CurrentUserUtils.ficon({
                 onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
                 dragFactory: new PrefetchProxy(box) as any as Doc,
-                removeDropProperties: new List<string>(["dropAction"]), title: "data switch", icon: "toggle-on"
+                removeDropProperties: new List<string>(["dropAction"]), title: "data switch", icon: "toggle-on", system: true
             });
         }
 
@@ -193,12 +193,12 @@ export class CurrentUserUtils {
             const openInTarget = ScriptField.MakeScript("openOnRight(self.doubleClickView)");
             const carousel = CarouselDocument([], {
                 title: "data", _height: 350, _itemIndex: 0, "_carousel-caption-xMargin": 10, "_carousel-caption-yMargin": 10,
-                onChildDoubleClick: openInTarget, backgroundColor: "#9b9b9b3F"
+                onChildDoubleClick: openInTarget, backgroundColor: "#9b9b9b3F", system: true
             });
 
-            const details = TextDocument("", { title: "details", _height: 350, _autoHeight: true });
-            const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 100, _autoHeight: true });
-            const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 350, _autoHeight: true });
+            const details = TextDocument("", { title: "details", _height: 350, _autoHeight: true, system: true });
+            const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 100, _autoHeight: true, system: true });
+            const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 350, _autoHeight: true, system: true });
 
             const buxtonFieldKeys = ["year", "originalPrice", "degreesOfFreedom", "company", "attribute", "primaryKey", "secondaryKey", "dimensions"];
             const detailedTemplate = {
@@ -223,7 +223,7 @@ export class CurrentUserUtils {
                 new SchemaHeaderField("[Long Description]", "dimGray", undefined, undefined, undefined, true),
                 new SchemaHeaderField("[Details]", "dimGray", undefined, undefined, undefined, true),
             ]);
-            const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts });
+            const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, system: true });
             detailView.isTemplateDoc = makeTemplate(detailView);
 
             details.title = "Details";
@@ -233,7 +233,7 @@ export class CurrentUserUtils {
             doc["template-button-detail"] = CurrentUserUtils.ficon({
                 onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
                 dragFactory: new PrefetchProxy(detailView) as any as Doc,
-                removeDropProperties: new List<string>(["dropAction"]), title: "detail view", icon: "window-maximize"
+                removeDropProperties: new List<string>(["dropAction"]), title: "detail view", icon: "window-maximize", system: true
             });
         }
 
@@ -251,7 +251,7 @@ export class CurrentUserUtils {
                 hidden: ComputedField.MakeFunction("self.userDoc.noviceMode") as any,
                 userDoc: doc,
                 _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
-                dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
+                dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
             }));
         } else {
             const curButnTypes = Cast(doc["template-buttons"], Doc, null);
@@ -266,42 +266,42 @@ export class CurrentUserUtils {
     // setup the different note type skins
     static setupNoteTemplates(doc: Doc) {
         if (doc["template-note-Note"] === undefined) {
-            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Note", isTemplateDoc: true, backgroundColor: "yellow" });
+            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Note", isTemplateDoc: true, backgroundColor: "yellow", system: true });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Note");
             doc["template-note-Note"] = new PrefetchProxy(noteView);
         }
         if (doc["template-note-Idea"] === undefined) {
-            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Idea", backgroundColor: "pink" });
+            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Idea", backgroundColor: "pink", system: true });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea");
             doc["template-note-Idea"] = new PrefetchProxy(noteView);
         }
         if (doc["template-note-Topic"] === undefined) {
-            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Topic", backgroundColor: "lightBlue" });
+            const noteView = Docs.Create.TextDocument("", { title: "text", style: "Topic", backgroundColor: "lightBlue", system: true });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic");
             doc["template-note-Topic"] = new PrefetchProxy(noteView);
         }
         if (doc["template-note-Todo"] === undefined) {
             const noteView = Docs.Create.TextDocument("", {
                 title: "text", style: "Todo", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption",
-                layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus")
+                layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus"), system: true
             });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Todo");
             doc["template-note-Todo"] = new PrefetchProxy(noteView);
         }
         const taskStatusValues = [
-            { title: "todo", _backgroundColor: "blue", color: "white" },
-            { title: "in progress", _backgroundColor: "yellow", color: "black" },
-            { title: "completed", _backgroundColor: "green", color: "white" }
+            { title: "todo", _backgroundColor: "blue", color: "white", system: true },
+            { title: "in progress", _backgroundColor: "yellow", color: "black", system: true },
+            { title: "completed", _backgroundColor: "green", color: "white", system: true }
         ];
         if (doc.fieldTypes === undefined) {
-            doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" });
+            doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations", system: true });
             DocUtils.addFieldEnumerations(Doc.GetProto(doc["template-note-Todo"] as any as Doc), "taskStatus", taskStatusValues);
         }
 
         if (doc["template-notes"] === undefined) {
             doc["template-notes"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-note-Note"] as any as Doc,
             doc["template-note-Idea"] as any as Doc, doc["template-note-Topic"] as any as Doc, doc["template-note-Todo"] as any as Doc],
-                { title: "Note Layouts", _height: 75 }));
+                { title: "Note Layouts", _height: 75, system: true }));
         } else {
             const curNoteTypes = Cast(doc["template-notes"], Doc, null);
             const requiredTypes = [doc["template-note-Note"] as any as Doc, doc["template-note-Idea"] as any as Doc,
@@ -322,7 +322,7 @@ export class CurrentUserUtils {
         const clickTemplates = CurrentUserUtils.setupClickEditorTemplates(doc);
         if (doc.templateDocs === undefined) {
             doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([noteTemplates, userTemplateBtns, clickTemplates], {
-                title: "template layouts", _xPadding: 0,
+                title: "template layouts", _xPadding: 0, system: true,
                 dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name })
             }));
         }
@@ -333,7 +333,7 @@ export class CurrentUserUtils {
         if (doc["template-icon-view"] === undefined) {
             const iconView = Docs.Create.LabelDocument({
                 title: "icon", textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("title"), _backgroundColor: "dimGray",
-                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
+                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true
             });
             //  Docs.Create.TextDocument("", {
             //     title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
@@ -345,7 +345,7 @@ export class CurrentUserUtils {
         if (doc["template-icon-view-rtf"] === undefined) {
             const iconRtfView = Docs.Create.LabelDocument({
                 title: "icon_" + DocumentType.RTF, textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("text"),
-                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
+                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true
             });
             iconRtfView.isTemplateDoc = makeTemplate(iconRtfView, true, "icon_" + DocumentType.RTF);
             doc["template-icon-view-rtf"] = new PrefetchProxy(iconRtfView);
@@ -353,26 +353,26 @@ export class CurrentUserUtils {
         if (doc["template-icon-view-button"] === undefined) {
             const iconBtnView = Docs.Create.FontIconDocument({
                 title: "icon_" + DocumentType.BUTTON, _nativeHeight: 30, _nativeWidth: 30,
-                _width: 30, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
+                _width: 30, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true
             });
             iconBtnView.isTemplateDoc = makeTemplate(iconBtnView, true, "icon_" + DocumentType.BUTTON);
             doc["template-icon-view-button"] = new PrefetchProxy(iconBtnView);
         }
         if (doc["template-icon-view-img"] === undefined) {
             const iconImageView = Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", {
-                title: "data", _width: 50, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
+                title: "data", _width: 50, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true
             });
             iconImageView.isTemplateDoc = makeTemplate(iconImageView, true, "icon_" + DocumentType.IMG);
             doc["template-icon-view-img"] = new PrefetchProxy(iconImageView);
         }
         if (doc["template-icon-view-col"] === undefined) {
-            const iconColView = Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") });
+            const iconColView = Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true });
             iconColView.isTemplateDoc = makeTemplate(iconColView, true, "icon_" + DocumentType.COL);
             doc["template-icon-view-col"] = new PrefetchProxy(iconColView);
         }
         if (doc["template-icons"] === undefined) {
             doc["template-icons"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc,
-            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-pdf"] as Doc], { title: "icon templates", _height: 75 }));
+            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-pdf"] as Doc], { title: "icon templates", _height: 75, system: true }));
         } else {
             const templateIconsDoc = Cast(doc["template-icons"], Doc, null);
             const requiredTypes = [doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc,
@@ -391,37 +391,37 @@ export class CurrentUserUtils {
     }[] {
         if (doc.emptyPresentation === undefined) {
             doc.emptyPresentation = Docs.Create.PresDocument(new List<Doc>(),
-                { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" });
+                { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0", system: true });
         }
         if (doc.emptyCollection === undefined) {
             doc.emptyCollection = Docs.Create.FreeformDocument([],
-                { _nativeWidth: undefined, _nativeHeight: undefined, _width: 150, _height: 100, title: "freeform" });
+                { _nativeWidth: undefined, _nativeHeight: undefined, _width: 150, _height: 100, title: "freeform", system: true });
         }
         if (doc.emptyComparison === undefined) {
-            doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300 });
+            doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300, system: true });
         }
         if (doc.emptyScript === undefined) {
-            doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250, title: "script" });
+            doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250, title: "script", system: true });
         }
         if (doc.emptyScreenshot === undefined) {
-            doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" });
+            doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot", system: true });
         }
         if (doc.emptyAudio === undefined) {
-            doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "ready to record audio" });
+            doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "ready to record audio", system: true });
         }
         if (doc.emptyImage === undefined) {
-            doc.emptyImage = Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth: 250, title: "an image of a cat" });
+            doc.emptyImage = Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth: 250, title: "an image of a cat", system: true });
         }
         if (doc.emptyButton === undefined) {
-            doc.emptyButton = Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, title: "Button" });
+            doc.emptyButton = Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, title: "Button", system: true });
         }
         if (doc.emptyDocHolder === undefined) {
             doc.emptyDocHolder = Docs.Create.DocumentDocument(
                 ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]") as any,
-                { _width: 250, _height: 250, title: "container" });
+                { _width: 250, _height: 250, title: "container", system: true });
         }
         if (doc.emptyWebpage === undefined) {
-            doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 400, UseCors: true });
+            doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 400, UseCors: true, system: true });
         }
         if (doc.activeMobileMenu === undefined) {
             this.setupActiveMobileMenu(doc);
@@ -481,14 +481,14 @@ export class CurrentUserUtils {
             removeDropProperties: new List<string>(["dropAction"]),
             dragFactory,
             userDoc: noviceMode ? undefined as any : doc,
-            hidden: noviceMode ? undefined as any : ComputedField.MakeFunction("self.userDoc.noviceMode")
+            hidden: noviceMode ? undefined as any : ComputedField.MakeFunction("self.userDoc.noviceMode"), system: true
         }));
 
         if (dragCreatorSet === undefined) {
             doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, {
                 title: "Basic Item Creators", _showTitle: "title", _xMargin: 0,
                 _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
-                dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
+                dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
             }));
         } else {
             creatorBtns.forEach(nb => Doc.AddDocToList(doc.myItemCreators as Doc, "data", nb));
@@ -516,7 +516,7 @@ export class CurrentUserUtils {
         if (doc["search-panel"] === undefined) {
             doc["search-panel"] = new PrefetchProxy(Docs.Create.SearchDocument({
                 _width: 500, _height: 400, backgroundColor: "dimGray", ignoreClick: true,
-                childDropAction: "alias", lockedPosition: true, _viewType: CollectionViewType.Schema, _chromeStatus: "disabled", title: "sidebar search stack",
+                childDropAction: "alias", lockedPosition: true, _viewType: CollectionViewType.Schema, _chromeStatus: "disabled", title: "sidebar search stack", system: true
             })) as any as Doc;
         }
     }
@@ -532,7 +532,7 @@ export class CurrentUserUtils {
                     childDropAction: "same",
                     _width: 60,
                     _height: 60,
-                    onClick: ScriptField.MakeScript(click, { scriptContext: "any" }),
+                    onClick: ScriptField.MakeScript(click, { scriptContext: "any" }), system: true
                 }));
             const userDoc = menuBtns[menuBtns.length - 1];
             userDoc.userDoc = doc;
@@ -544,7 +544,7 @@ export class CurrentUserUtils {
                 _backgroundColor: "black",
                 _gridGap: 0,
                 _yMargin: 0,
-                _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled",
+                _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled", system: true
             }));
         }
         // this resets all sidebar buttons to being deactivated
@@ -571,7 +571,7 @@ export class CurrentUserUtils {
     // Sets up mobileMenu stacking document
     static setupMobileMenu() {
         const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), {
-            _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100
+            _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100, system: true
         }));
         return menu;
     }
@@ -592,9 +592,9 @@ export class CurrentUserUtils {
                 title: data.title,
                 lockedPosition: true,
                 onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
-                _backgroundColor: data.backgroundColor
+                _backgroundColor: data.backgroundColor, system: true
             },
-                [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)" }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
+                [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
         );
     }
 
@@ -602,26 +602,26 @@ export class CurrentUserUtils {
     static mobileButton = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MulticolumnDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
-        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled"
+        borderRounding: "5px", boxShadow: "0 0", _chromeStatus: "disabled", system: true
     }) as any as Doc
 
     // sets up the text container for the information contained within the mobile button
     static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MultirowDocument(docs, {
         ...opts,
         dropAction: undefined, removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
-        backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled", ignoreClick: true
+        backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", _chromeStatus: "disabled", ignoreClick: true, system: true
     }) as any as Doc
 
     // Sets up the title of the button
     static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, {
         ...opts,
-        dropAction: undefined, title: buttonTitle, _fontSize: "37pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)"
+        dropAction: undefined, title: buttonTitle, _fontSize: "37pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", system: true
     }) as any as Doc
 
     // Sets up the description of the button
     static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, {
         ...opts,
-        dropAction: undefined, title: "info", _fontSize: "25pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2,
+        dropAction: undefined, title: "info", _fontSize: "25pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2, system: true
     }) as any as Doc
 
 
@@ -640,7 +640,7 @@ export class CurrentUserUtils {
             clipboard: data.clipboard,
             onPointerUp: data.pointerUp ? ScriptField.MakeScript(data.pointerUp) : undefined, onPointerDown: data.pointerDown ? ScriptField.MakeScript(data.pointerDown) : undefined,
             ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activeInkPen: data.activeInkPen, pointerHack: true,
-            backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
+            backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory, system: true
         }));
     }
 
@@ -648,10 +648,10 @@ export class CurrentUserUtils {
         if (!userDoc.thumbDoc) {
             const thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), {
                 _width: 100, _height: 50, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons",
-                _autoHeight: true, _yMargin: 5, linearViewIsExpanded: true, backgroundColor: "white"
+                _autoHeight: true, _yMargin: 5, linearViewIsExpanded: true, backgroundColor: "white", system: true
             });
             thumbDoc.inkToTextDoc = Docs.Create.LinearDocument([], {
-                _width: 300, _height: 25, _autoHeight: true, _chromeStatus: "disabled", linearViewIsExpanded: true, flexDirection: "column"
+                _width: 300, _height: 25, _autoHeight: true, _chromeStatus: "disabled", linearViewIsExpanded: true, flexDirection: "column", system: true
             });
             userDoc.thumbDoc = thumbDoc;
         }
@@ -670,20 +670,20 @@ export class CurrentUserUtils {
         if (doc.myCreators === undefined) {
             doc.myCreators = new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], {
                 title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0,
-                _width: 500, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
+                _width: 500, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", system: true
             }));
         }
         // setup a color picker
         if (doc.myColorPicker === undefined) {
             const color = Docs.Create.ColorDocument({
-                title: "color picker", _width: 300, dropAction: "alias", forceActive: true, removeDropProperties: new List<string>(["dropAction", "forceActive"])
+                title: "color picker", _width: 300, dropAction: "alias", forceActive: true, removeDropProperties: new List<string>(["dropAction", "forceActive"]), system: true
             });
             doc.myColorPicker = new PrefetchProxy(color);
         }
 
         if (doc["sidebar-tools"] === undefined) {
             const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], {
-                title: "sidebar-tools", _width: 500, _yMargin: 20, lockedPosition: true, _chromeStatus: "disabled", hideFilterView: true, forceActive: true
+                title: "sidebar-tools", _width: 500, _yMargin: 20, lockedPosition: true, _chromeStatus: "disabled", hideFilterView: true, forceActive: true, system: true
             })) as any as Doc;
 
             doc["sidebar-tools"] = toolsStack;
@@ -695,7 +695,7 @@ export class CurrentUserUtils {
         doc.myWorkspaces === undefined;
         if (doc.myWorkspaces === undefined) {
             doc.myWorkspaces = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true,
+                title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true, system: true
             }));
         }
         if (doc["sidebar-workspaces"] === undefined) {
@@ -708,7 +708,7 @@ export class CurrentUserUtils {
             doc["sidebar-workspaces"] = new PrefetchProxy(Docs.Create.TreeDocument([workspaces], {
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
-                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
         }
     }
@@ -718,7 +718,7 @@ export class CurrentUserUtils {
         if (doc.myCatalog === undefined) {
             doc.myCatalog = new PrefetchProxy(Docs.Create.SchemaDocument([], [], {
                 title: "CATALOG", _height: 1000, _fitWidth: true, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false,
-                childDropAction: "alias", targetDropAction: "same", stayInCollection: true, treeViewOpen: true,
+                childDropAction: "alias", targetDropAction: "same", stayInCollection: true, treeViewOpen: true, system: true
             }));
         }
 
@@ -729,7 +729,7 @@ export class CurrentUserUtils {
                 title: "sidebar-catalog",
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
-                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
         }
     }
@@ -738,7 +738,7 @@ export class CurrentUserUtils {
         doc.myRecentlyClosed === undefined;
         if (doc.myRecentlyClosed === undefined) {
             doc.myRecentlyClosed = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, stayInCollection: true,
+                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, stayInCollection: true, system: true
             }));
         }
         // this is equivalent to using PrefetchProxies to make sure the recentlyClosed doc is ready
@@ -754,7 +754,7 @@ export class CurrentUserUtils {
                 title: "sidebar-recentlyClosed",
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
-                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
         }
     }
@@ -767,7 +767,7 @@ export class CurrentUserUtils {
             doc["sidebar-userDoc"] = new PrefetchProxy(Docs.Create.TreeDocument([doc], {
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, title: "sidebar-userDoc",
                 treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
-                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+                lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
         }
     }
@@ -778,6 +778,7 @@ export class CurrentUserUtils {
             sidebarContainer._chromeStatus = "disabled";
             sidebarContainer.onClick = ScriptField.MakeScript("freezeSidebar()");
             doc.sidebar = new PrefetchProxy(sidebarContainer);
+            doc.system = true;
         }
         return doc.sidebar as Doc;
     }
@@ -795,20 +796,20 @@ export class CurrentUserUtils {
     static blist = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, {
         ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", forceActive: true,
         dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
-        backgroundColor: "black", treeViewPreventOpen: true, lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true
+        backgroundColor: "black", treeViewPreventOpen: true, lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, system: true
     })) as any as Doc
 
     static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
-        ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40
+        ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
     })) as any as Doc
 
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
     static setupDockedButtons(doc: Doc) {
         if (doc["dockedBtn-undo"] === undefined) {
-            doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), toolTip: "click to undo", title: "undo", icon: "undo-alt" });
+            doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), toolTip: "click to undo", title: "undo", icon: "undo-alt", system: true });
         }
         if (doc["dockedBtn-redo"] === undefined) {
-            doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), toolTip: "click to redo", title: "redo", icon: "redo-alt" });
+            doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), toolTip: "click to redo", title: "redo", icon: "redo-alt", system: true });
         }
         if (doc.dockedBtns === undefined) {
             doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
@@ -817,7 +818,7 @@ export class CurrentUserUtils {
     // sets up the default set of documents to be shown in the Overlay layer
     static setupOverlays(doc: Doc) {
         if (doc.myOverlayDocuments === undefined) {
-            doc.myOverlayDocuments = new PrefetchProxy(Docs.Create.FreeformDocument([], { title: "overlay documents", backgroundColor: "#aca3a6" }));
+            doc.myOverlayDocuments = new PrefetchProxy(Docs.Create.FreeformDocument([], { title: "overlay documents", backgroundColor: "#aca3a6", system: true }));
         }
     }
 
@@ -825,13 +826,13 @@ export class CurrentUserUtils {
     static setupDefaultPresentation(doc: Doc) {
         if (doc["template-presentation"] === undefined) {
             doc["template-presentation"] = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
-                title: "pres element template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data"
+                title: "pres element template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data", system: true
             }));
         }
         if (doc.activePresentation === undefined) {
             doc.activePresentation = Docs.Create.PresDocument(new List<Doc>(), {
                 title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias",
-                _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0"
+                _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0", system: true
             });
         }
     }
@@ -839,7 +840,7 @@ export class CurrentUserUtils {
     // Right sidebar is where mobile uploads are contained
     static setupSharingSidebar(doc: Doc) {
         if (doc["sidebar-sharing"] === undefined) {
-            doc["sidebar-sharing"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Shared Documents", childDropAction: "alias" }));
+            doc["sidebar-sharing"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Shared Documents", childDropAction: "alias", system: true }));
         }
     }
 
@@ -851,14 +852,14 @@ export class CurrentUserUtils {
                 "docCast(thisContainer.target).then((target) => target && (target.proto.data = new List([self]))) ",
                 { thisContainer: Doc.name }), {
                 title: "Click to open in target", _width: 300, _height: 200,
-                targetScriptKey: "onChildClick",
+                targetScriptKey: "onChildClick", system: true
             });
 
             const openDetail = Docs.Create.ScriptingDocument(ScriptField.MakeScript(
                 "openOnRight(self.doubleClickView)",
-                {}), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick" });
+                {}), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick", system: true });
 
-            doc["clickFuncs-child"] = Docs.Create.TreeDocument([openInTarget, openDetail], { title: "on Child Click function templates" });
+            doc["clickFuncs-child"] = Docs.Create.TreeDocument([openInTarget, openDetail], { title: "on Child Click function templates", system: true });
         }
         // this is equivalent to using PrefetchProxies to make sure all the childClickFuncs have been retrieved.
         PromiseValue(Cast(doc["clickFuncs-child"], Doc)).then(func => func && PromiseValue(func.data).then(DocListCast));
@@ -866,24 +867,26 @@ export class CurrentUserUtils {
         if (doc.clickFuncs === undefined) {
             const onClick = Docs.Create.ScriptingDocument(undefined, {
                 title: "onClick", "onClick-rawScript": "console.log('click')",
-                isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200
+                isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200, system: true
             }, "onClick");
             const onChildClick = Docs.Create.ScriptingDocument(undefined, {
                 title: "onChildClick", "onChildClick-rawScript": "console.log('child click')",
-                isTemplateDoc: true, isTemplateForField: "onChildClick", _width: 300, _height: 200
+                isTemplateDoc: true, isTemplateForField: "onChildClick", _width: 300, _height: 200, system: true
             }, "onChildClick");
             const onDoubleClick = Docs.Create.ScriptingDocument(undefined, {
                 title: "onDoubleClick", "onDoubleClick-rawScript": "console.log('double click')",
-                isTemplateDoc: true, isTemplateForField: "onDoubleClick", _width: 300, _height: 200
+                isTemplateDoc: true, isTemplateForField: "onDoubleClick", _width: 300, _height: 200, system: true
             }, "onDoubleClick");
             const onChildDoubleClick = Docs.Create.ScriptingDocument(undefined, {
                 title: "onChildDoubleClick", "onChildDoubleClick-rawScript": "console.log('child double click')",
-                isTemplateDoc: true, isTemplateForField: "onChildDoubleClick", _width: 300, _height: 200
+                isTemplateDoc: true, isTemplateForField: "onChildDoubleClick", _width: 300, _height: 200, system: true
             }, "onChildDoubleClick");
             const onCheckedClick = Docs.Create.ScriptingDocument(undefined, {
-                title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)", "onCheckedClick-params": new List<string>(["heading", "checked", "containingTreeView"]), isTemplateDoc: true, isTemplateForField: "onCheckedClick", _width: 300, _height: 200
+                title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)",
+                "onCheckedClick-params": new List<string>(["heading", "checked", "containingTreeView"]), isTemplateDoc: true,
+                isTemplateForField: "onCheckedClick", _width: 300, _height: 200, system: true
             }, "onCheckedClick");
-            doc.clickFuncs = Docs.Create.TreeDocument([onClick, onChildClick, onDoubleClick, onCheckedClick], { title: "onClick funcs" });
+            doc.clickFuncs = Docs.Create.TreeDocument([onClick, onChildClick, onDoubleClick, onCheckedClick], { title: "onClick funcs", system: true });
         }
         PromiseValue(Cast(doc.clickFuncs, Doc)).then(func => func && PromiseValue(func.data).then(DocListCast));
 
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 25fc8ff0b..f7b817aa1 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -185,7 +185,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         }
     }
 
-    public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB];
+    public _allIcons: string[] = [DocumentType.INK, DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB];
     //if true, any keywords can be used. if false, all keywords are required.
     //this also serves as an indicator if the word status filter is applied
     @observable private _filterOpen: boolean = false;
@@ -473,13 +473,13 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     }
 
     private get filterQuery() {
-        const types = this.filterTypes;
-        const baseExpr = "NOT baseProto_b:true";
+        const types = ["preselement", "docholder", "collection", "search", "searchitem", "script", "fonticonbox", "button", "label"]; // this.filterTypes;
+        const baseExpr = "NOT baseProto_b:true AND NOT system_b:true";
         const includeDeleted = this.getDataStatus() ? "" : " NOT deleted_b:true";
         const includeIcons = this.getDataStatus() ? "" : " NOT type_t:fonticonbox";
-        // const typeExpr = !types ? "" : ` (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})`;
+        const typeExpr = !types ? "" : ` ${types.map(type => `NOT ({!join from=id to=proto_i}type_t:${type}) AND NOT type_t:${type}`).join(" AND ")}`;
         // fq: type_t:collection OR {!join from=id to=proto_i}type_t:collection   q:text_t:hello
-        const query = [baseExpr, includeDeleted, includeIcons].join(" AND ").replace(/AND $/, "");
+        const query = [baseExpr, includeDeleted, includeIcons, typeExpr].join(" AND ").replace(/AND $/, "");
         return query;
     }
 
@@ -513,7 +513,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             const index = this._resultsSet.get(doc);
                             const highlight = highlights[doc[Id]];
                             const line = lines.get(doc[Id]) || [];
-                            const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : [];
+                            const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)).filter(k => k) : [];
                             doc ? console.log(Cast(doc.context, Doc)) : null;
                             if (this.findCommonElements(hlights)) {
                             }
@@ -642,7 +642,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
         // only hit right at the beginning
         // visibleElements is all of the elements (even the ones you can't see)
-        else if (this._visibleElements.length !== this._numTotalResults) {
+        if (this._visibleElements.length !== this._numTotalResults) {
             // undefined until a searchitem is put in there
             this._visibleElements = Array<JSX.Element>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
             this._visibleDocuments = Array<Doc>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index 7251e07a1..99f227b28 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -176,7 +176,8 @@ export namespace SolrManager {
         "audio": ["_t", "url"],
         "web": ["_t", "url"],
         "date": ["_d", value => new Date(value.date).toISOString()],
-        // "proxy": ["_i", "fieldId"],
+        "proxy": ["_i", "fieldId"],
+        "prefetch_proxy": ["_i", "fieldId"],
         "list": ["_l", list => {
             const results = [];
             for (const value of list.fields) {
-- 
cgit v1.2.3-70-g09d2


From 769588ee0f3471e4f576dd1627ed6c11ecfbeee0 Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Mon, 10 Aug 2020 23:02:33 -0400
Subject: bugfixing

---
 .../views/collections/CollectionSchemaHeaders.tsx  | 20 +++++--
 .../views/collections/CollectionSchemaView.scss    |  6 ++-
 src/client/views/collections/CollectionSubView.tsx | 16 +++---
 src/client/views/search/SearchBox.tsx              | 61 ++++++++++++++++++++--
 4 files changed, 86 insertions(+), 17 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index b7d6f212f..8cc91b3da 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -23,6 +23,8 @@ import { listSpec } from "../../../fields/Schema";
 import { ScriptField, ComputedField } from "../../../fields/ScriptField";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { CollectionView } from "./CollectionView";
+import { SearchBox } from "../search/SearchBox";
+import { createParameter } from "typescript";
 
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
@@ -450,16 +452,26 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                 keyOptions.push(key);
             }
         });
-        //checked={() =>{Cast(this.props.Document!._docRangeFilters, listSpec("string"))!.includes(key)}}
 
         const options = keyOptions.map(key => {
             //Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
+            let bool = false;
+            let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
+            console.log(filters);
+            if (filters !== undefined) {
+                bool = filters.includes(key) && filters[filters.indexOf(key) + 1] === "check";
+                console.log(filters.includes(key));
+            }
             return <div key={key} className="key-option" style={{
-                border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
+                border: "1px solid lightgray", paddingLeft: 5, textAlign: "left",
+                width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
             }}
             >
-                <input type="checkbox" onChange={(e) => { e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined) }} ></input>
-                {key}
+                <input type="checkbox" onChange={(e) => { e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined); e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined); }}
+                    checked={bool} ></input>
+                <span style={{ paddingLeft: 4 }}>
+                    {key}
+                </span>
 
             </div>;
         });
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index ee643b86b..5c2931a8b 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -326,7 +326,6 @@ button.add-column {
                 background-color: white;
                 border: 1px solid lightgray;
                 padding: 2px 3px;
-
                 &:not(:first-child) {
                     border-top: 0;
                 }
@@ -403,7 +402,7 @@ button.add-column {
     background-color: white;
 
     &.row-focused .rt-td {
-        background-color: rgb(255, 246, 246); //$light-color-secondary;
+        background-color: #bfffc0; //$light-color-secondary;
     }
 
     &.row-wrapped {
@@ -466,6 +465,9 @@ button.add-column {
 .collectionSchemaView-cellWrapper {
     height: 100%;
     padding: 4px;
+    text-align:left;
+    padding-left:19px;
+    
     position: relative;
 
     &:focus {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 9be5a5d99..c2fe2c26c 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -128,13 +128,18 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
             const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
             let childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
 
-            const searchDocs = DocListCast(this.props.Document._searchDocs);
+            let searchDocs = DocListCast(this.props.Document._searchDocs);
 
 
             let docsforFilter: Doc[] = childDocs;
+
             if (searchDocs !== undefined && searchDocs.length > 0) {
                 docsforFilter = [];
-
+                const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
+                console.log(searchDocs);
+                searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript)
+                console.log(this.docFilters());
+                console.log(searchDocs);
                 childDocs.forEach((d) => {
                     if (d.data !== undefined) {
                         let newdocs = DocListCast(d.data);
@@ -165,12 +170,11 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                         docsforFilter.push(d);
                     }
                 });
-
+                return docsforFilter;
             }
-            childDocs = docsforFilter;
-
+            console.log("you fool");
+            console.log(childDocs);
             const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
-
             return this.props.Document.dontRegisterView ? childDocs : DocUtils.FilterDocs(childDocs, this.docFilters(), docRangeFilters, viewSpecScript);
         }
 
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 6d6f32da7..4a14b222c 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -126,6 +126,29 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
 
         if (e.target.value === "") {
+            if (this.currentSelectedCollection !== undefined) {
+                let newarray: Doc[] = [];
+                let docs: Doc[] = [];
+                docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]);
+                while (docs.length > 0) {
+                    newarray = [];
+                    docs.forEach((d) => {
+                        if (d.data !== undefined) {
+                            d._searchDocs = new List<Doc>();
+                            d._docFilters = new List();
+                            const newdocs = DocListCast(d.data);
+                            newdocs.forEach((newdoc) => {
+                                newarray.push(newdoc);
+                            });
+                        }
+                    });
+                    docs = newarray;
+                }
+
+                this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]);
+                this.currentSelectedCollection.props.Document._docFilters = new List();
+                this.props.Document.selectedDoc = undefined;
+            }
             this._results.forEach(result => {
                 Doc.UnBrushDoc(result[0]);
                 result[0].searchMatch = undefined;
@@ -414,10 +437,33 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @action
     submitSearch = async (reset?: boolean) => {
+        if (this.currentSelectedCollection !== undefined) {
+            let newarray: Doc[] = [];
+            let docs: Doc[] = [];
+            docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]);
+            while (docs.length > 0) {
+                newarray = [];
+                docs.forEach((d) => {
+                    if (d.data !== undefined) {
+                        d._searchDocs = new List<Doc>();
+                        d._docFilters = new List();
+                        const newdocs = DocListCast(d.data);
+                        newdocs.forEach((newdoc) => {
+                            newarray.push(newdoc);
+                        });
+                    }
+                });
+                docs = newarray;
+            }
+
+            this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]);
+            this.currentSelectedCollection.props.Document._docFilters = new List();
+            this.props.Document.selectedDoc = undefined;
+        }
         if (reset) {
             this.layoutDoc._searchString = "";
         }
-        this.props.Document._docFilters = undefined;
+        this.props.Document._docFilters = new List();
         this.noresults = "";
 
         this.dataDoc[this.fieldKey] = new List<Doc>([]);
@@ -735,6 +781,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); }
 
+    @computed get viewspec() { return Cast(this.props.Document._docFilters, listSpec("string"), []) }
+
     getTransform = () => {
         return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
     }
@@ -796,7 +844,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                 docs = newarray;
                                             }
 
-                                            this.currentSelectedCollection.props.Document._docFilters = new List<string>(Cast(this.props.Document._docFilters, listSpec("string"), []));
+                                            this.currentSelectedCollection.props.Document._docFilters = new List<string>(this.viewspec);
                                             this.props.Document.selectedDoc = this.currentSelectedCollection.props.Document;
                                         }
                                         else if (this.filter === false && this.currentSelectedCollection !== undefined) {
@@ -808,6 +856,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                 docs.forEach((d) => {
                                                     if (d.data !== undefined) {
                                                         d._searchDocs = new List<Doc>();
+                                                        d._docFilters = new List();
                                                         const newdocs = DocListCast(d.data);
                                                         newdocs.forEach((newdoc) => {
                                                             newarray.push(newdoc);
@@ -818,7 +867,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                             }
 
                                             this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]);
-                                            this.currentSelectedCollection.props.Document._docFilters = undefined;
+                                            this.currentSelectedCollection.props.Document._docFilters = new List();
                                             this.props.Document.selectedDoc = undefined;
                                         }
                                     }
@@ -852,6 +901,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                             docs.forEach((d) => {
                                                                 if (d.data !== undefined) {
                                                                     d._searchDocs = new List<Doc>();
+                                                                    d._docFilters = new List();
                                                                     const newdocs = DocListCast(d.data);
                                                                     newdocs.forEach((newdoc) => {
                                                                         newarray.push(newdoc);
@@ -860,7 +910,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                             });
                                                             docs = newarray;
                                                         }
-                                                        this.currentSelectedCollection.props.Document._docFilters = undefined;
+                                                        this.currentSelectedCollection.props.Document._docFilters = new List();
                                                         this.currentSelectedCollection.props.Document._searchDocs = undefined;
                                                         this.currentSelectedCollection = undefined;
                                                     }
@@ -886,6 +936,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                             docs.forEach((d) => {
                                                                 if (d.data !== undefined) {
                                                                     d._searchDocs = new List<Doc>();
+                                                                    d._docFilters = new List()
                                                                     const newdocs = DocListCast(d.data);
                                                                     newdocs.forEach((newdoc) => {
                                                                         newarray.push(newdoc);
@@ -894,7 +945,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                             });
                                                             docs = newarray;
                                                         }
-                                                        this.currentSelectedCollection.props.Document._docFilters = undefined;
+                                                        this.currentSelectedCollection.props.Document._docFilters = new List();
                                                         this.currentSelectedCollection.props.Document._searchDocs = undefined;
                                                         this.currentSelectedCollection = undefined;
                                                     }
-- 
cgit v1.2.3-70-g09d2


From ee2302223e215ba4d35cdab61517e3feb2167e1c Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Tue, 11 Aug 2020 16:51:16 -0400
Subject: adjusting when filter menu should open and close

---
 .../views/collections/CollectionSchemaHeaders.tsx  | 251 ++++-----------------
 .../views/collections/CollectionSchemaView.tsx     |  16 +-
 src/client/views/collections/SchemaTable.tsx       |  28 +--
 src/client/views/search/SearchBox.tsx              |   2 +-
 4 files changed, 51 insertions(+), 246 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 8cc91b3da..c1c4eb628 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, observable, computed } from "mobx";
+import { action, observable, computed, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import "./CollectionSchemaView.scss";
 import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes, faImage, faListUl, faCalendar } from '@fortawesome/free-solid-svg-icons';
@@ -253,18 +253,6 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
     renderContent = () => {
         return (
             <div className="collectionSchema-header-menuOptions">
-                <div className="collectionSchema-headerMenu-group">
-                    <label>Key:</label>
-                    <KeysDropdown
-                        keyValue={this.props.columnField.heading}
-                        possibleKeys={this.props.possibleKeys}
-                        existingKeys={this.props.existingKeys}
-                        canAddNew={true}
-                        addNew={this.props.addNew}
-                        onSelect={this.props.onSelect}
-                        setIsEditing={this.props.setIsEditing}
-                    />
-                </div>
                 {this.props.onlyShowOptions ? <></> :
                     <>
                         {this.renderTypes()}
@@ -301,12 +289,15 @@ export interface KeysDropdownProps {
     setIsEditing: (isEditing: boolean) => void;
     width?: string;
     docs?: Doc[];
-    Document?: Doc;
-    dataDoc?: Doc;
-    fieldKey?: string;
-    ContainingCollectionDoc?: Doc;
-    ContainingCollectionView?: CollectionView;
+    Document: Doc;
+    dataDoc: Doc;
+    fieldKey: string;
+    ContainingCollectionDoc: Doc;
+    ContainingCollectionView: CollectionView;
     active?: (outsideReaction?: boolean) => boolean;
+    openHeader: (column: any, screenx: number, screeny: number) => void;
+    col: SchemaHeaderField;
+    icon: IconProp;
 }
 @observer
 export class KeysDropdown extends React.Component<KeysDropdownProps> {
@@ -322,28 +313,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
 
     @action
     onSelect = (key: string): void => {
-        if (this._searchTerm.includes(":")) {
-            const colpos = this._searchTerm.indexOf(":");
-            const filter = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
-            //const filter = key.slice(this._key.length - key.length);
-            this.props.onSelect(this._key, this._key, this.props.addNew, filter);
-        }
-        else {
-            this.props.onSelect(this._key, key, this.props.addNew);
-            this.setKey(key);
-            this._isOpen = false;
-            this.props.setIsEditing(false);
-        }
-    }
-
-    @action
-    onSelectValue = (key: string): void => {
-        const colpos = this._searchTerm.indexOf(":");
-        this.onSelect(key);
-        this._searchTerm = this._searchTerm.slice(0, colpos + 1) + key;
+        this.props.onSelect(this._key, key, this.props.addNew);
+        this.setKey(key);
         this._isOpen = false;
-        this.props.onSelect(this._key, this._key, this.props.addNew, key);
-
+        this.props.setIsEditing(false);
     }
 
     @undoBatch
@@ -354,8 +327,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
             if (keyOptions.length) {
                 this.onSelect(keyOptions[0]);
+                console.log("case1");
             } else if (this._searchTerm !== "" && this.props.canAddNew) {
                 this.setSearchTerm(this._searchTerm || this._key);
+                console.log("case2");
                 this.onSelect(this._searchTerm);
             }
         }
@@ -412,7 +387,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         });
 
         // if search term does not already exist as a group type, give option to create new group type
+        console.log("Start here");
+        console.log(this._key, this._searchTerm.slice(0, this._key.length));
         if (this._key !== this._searchTerm.slice(0, this._key.length)) {
+            console.log("little further");
             if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
                 options.push(<div key={""} className="key-option" style={{
                     border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white",
@@ -438,17 +416,17 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     }
     @action
     renderFilterOptions = (): JSX.Element[] | JSX.Element => {
+        console.log("we here");
         if (!this._isOpen) {
             this.defaultMenuHeight = 0;
             return <></>;
         }
         let keyOptions: string[] = [];
-        const colpos = this._searchTerm.indexOf(":");
-        const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
         let docs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+
         docs.forEach((doc) => {
             const key = StrCast(doc[this._key]);
-            if (keyOptions.includes(key) === false && key.includes(temp)) {
+            if (keyOptions.includes(key) === false) {
                 keyOptions.push(key);
             }
         });
@@ -488,107 +466,12 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             }
 
         }
-
         return options;
     }
 
-
-    // @action
-    // renderFilterOptions = (): JSX.Element[] | JSX.Element => {
-    //     this.facetClick(this._key);
-    //     return <div>
-    //         {this.filterView}
-    //     </div>
-    // }
     @observable defaultMenuHeight = 0;
 
 
-    facetClick = (facetHeader: string) => {
-        facetHeader = this._key;
-        let newFacet: Opt<Doc>;
-        if (this.props.Document !== undefined) {
-            const facetCollection = this.props.Document;
-            // const found = DocListCast(facetCollection[this.props.fieldKey + "-filter"]).findIndex(doc => doc.title === facetHeader);
-            // if (found !== -1) {
-            //     console.log("found not n-1");
-            //     (facetCollection[this.props.fieldKey + "-filter"] as List<Doc>).splice(found, 1);
-            //     const docFilter = Cast(this.props.Document._docFilters, listSpec("string"));
-            //     if (docFilter) {
-            //         let index: number;
-            //         while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
-            //             docFilter.splice(index, 3);
-            //         }
-            //     }
-            //     const docRangeFilters = Cast(this.props.Document._docRangeFilters, listSpec("string"));
-            //     if (docRangeFilters) {
-            //         let index: number;
-            //         while ((index = docRangeFilters.findIndex(item => item === facetHeader)) !== -1) {
-            //             docRangeFilters.splice(index, 3);
-            //         }
-            //     }
-            // }
-
-
-
-            console.log("found is n-1");
-            const allCollectionDocs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
-            var rtfields = 0;
-            const facetValues = Array.from(allCollectionDocs.reduce((set, child) => {
-                const field = child[facetHeader] as Field;
-                const fieldStr = Field.toString(field);
-                if (field instanceof RichTextField || (typeof (field) === "string" && fieldStr.split(" ").length > 2)) rtfields++;
-                return set.add(fieldStr);
-            }, new Set<string>()));
-
-            let nonNumbers = 0;
-            let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
-            facetValues.map(val => {
-                const num = Number(val);
-                if (Number.isNaN(num)) {
-                    nonNumbers++;
-                } else {
-                    minVal = Math.min(num, minVal);
-                    maxVal = Math.max(num, maxVal);
-                }
-            });
-            if (facetHeader === "text" || rtfields / allCollectionDocs.length > 0.1) {
-                console.log("Case1");
-                newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
-                Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
-                newFacet.target = this.props.Document;
-                newFacet._textBoxPadding = 4;
-                const scriptText = `setDocFilter(this.target, "${facetHeader}", text, "match")`;
-                newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
-            } else if (nonNumbers / facetValues.length < .1) {
-                console.log("Case2");
-                newFacet = Docs.Create.SliderDocument({ title: facetHeader, treeViewExpandedView: "layout", treeViewOpen: true });
-                const newFacetField = Doc.LayoutFieldKey(newFacet);
-                const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader);
-                Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
-                const extendedMinVal = minVal - Math.min(1, Math.abs(maxVal - minVal) * .05);
-                const extendedMaxVal = maxVal + Math.min(1, Math.abs(maxVal - minVal) * .05);
-                newFacet[newFacetField + "-min"] = ranged === undefined ? extendedMinVal : ranged[0];
-                newFacet[newFacetField + "-max"] = ranged === undefined ? extendedMaxVal : ranged[1];
-                Doc.GetProto(newFacet)[newFacetField + "-minThumb"] = extendedMinVal;
-                Doc.GetProto(newFacet)[newFacetField + "-maxThumb"] = extendedMaxVal;
-                newFacet.target = this.props.Document;
-                const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`;
-                newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" });
-                Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
-            } else {
-                console.log("Case3");
-                newFacet = new Doc();
-                newFacet.title = facetHeader;
-                newFacet.treeViewOpen = true;
-                newFacet.type = DocumentType.COL;
-                const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.props.dataDoc! };
-                this.props.Document.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, {}, capturedVariables);
-                // this.props.Document.data
-            }
-            //newFacet && Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
-        }
-    }
-
 
     get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; }
 
@@ -600,82 +483,28 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     }
     filterBackground = () => "rgba(105, 105, 105, 0.432)";
 
-
-    // @computed get filterView() {
-    //     TraceMobx();
-    //     if (this.props.Document !== undefined) {
-    //         //const facetCollection = this.props.Document;
-    //         // const flyout = (
-    //         //     <div className="collectionTimeView-flyout" style={{ width: `${this.facetWidth()}`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}>
-    //         //         {this._allFacets.map(facet => <label className="collectionTimeView-flyout-item" key={`${facet}`} onClick={e => this.facetClick(facet)}>
-    //         //             <input type="checkbox" onChange={e => { }} checked={DocListCast(this.props.Document[this.props.fieldKey + "-filter"]).some(d => d.title === facet)} />
-    //         //             <span className="checkmark" />
-    //         //             {facet}
-    //         //         </label>)}
-    //         //     </div>
-    //         // );
-    //         return <div className="altcollectionTimeView-treeView">
-    //             <div className="altcollectionTimeView-tree" key="tree">
-    //                 <CollectionTreeView
-    //                     PanelPosition={""}
-    //                     Document={this.props.Document}
-    //                     DataDoc={this.props.Document}
-    //                     fieldKey={this.props.fieldKey!}
-    //                     CollectionView={undefined}
-    //                     docFilters={returnEmptyFilter}
-    //                     ContainingCollectionDoc={this.props.ContainingCollectionDoc!}
-    //                     ContainingCollectionView={this.props.ContainingCollectionView!}
-    //                     PanelWidth={() => 200}
-    //                     PanelHeight={() => 200}
-    //                     NativeHeight={returnZero}
-    //                     NativeWidth={returnZero}
-    //                     LibraryPath={emptyPath}
-    //                     rootSelected={returnFalse}
-    //                     renderDepth={1}
-    //                     dropAction={undefined}
-    //                     ScreenToLocalTransform={Transform.Identity}
-    //                     addDocTab={returnFalse}
-    //                     pinToPres={returnFalse}
-    //                     isSelected={returnFalse}
-    //                     select={returnFalse}
-    //                     bringToFront={emptyFunction}
-    //                     active={this.props.active!}
-    //                     whenActiveChanged={returnFalse}
-    //                     treeViewHideTitle={true}
-    //                     ContentScaling={returnOne}
-    //                     focus={returnFalse}
-    //                     treeViewHideHeaderFields={true}
-    //                     onCheckedClick={this.scriptField}
-    //                     ignoreFields={this.ignoreFields}
-    //                     annotationsKey={""}
-    //                     dontRegisterView={true}
-    //                     backgroundColor={this.filterBackground}
-    //                     moveDocument={returnFalse}
-    //                     removeDocument={returnFalse}
-    //                     addDocument={returnFalse} />
-    //             </div>
-    //         </div>;
-    //     }
-    // }
-
+    @observable filterOpen: boolean | undefined = undefined;
     render() {
+        console.log(this._isOpen, this._key, this._searchTerm);
         return (
-            <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
-                <input className="keys-search" style={{ width: "100%" }}
-                    ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
-                    onChange={e => this.onChange(e.target.value)}
-                    onClick={(e) => {
-                        //this._inputRef.current!.select();
-                        e.stopPropagation();
-                    }} onFocus={this.onFocus} onBlur={this.onBlur}></input>
-                <div className="keys-options-wrapper" style={{
-                    width: this.props.width, maxWidth: this.props.width, height: "auto",
-                }}
-                    onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
-                    {this._searchTerm.includes(":") ?
-                        this.renderFilterOptions() : this.renderOptions()}
-                </div>
-            </div >
+            <div style={{ display: "flex" }}>
+                <FontAwesomeIcon onClick={e => { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) : this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+                <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
+                    <input className="keys-search" style={{ width: "100%" }}
+                        ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
+                        onChange={e => this.onChange(e.target.value)}
+                        onClick={(e) => {
+                            //this._inputRef.current!.select();
+                            e.stopPropagation();
+                        }} onFocus={this.onFocus} onBlur={this.onBlur}></input>
+                    <div className="keys-options-wrapper" style={{
+                        width: this.props.width, maxWidth: this.props.width, height: "auto",
+                    }}
+                        onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
+                        {this._key === this._searchTerm ? this.renderFilterOptions() : this.renderOptions()}
+                    </div>
+                </div >
+            </div>
         );
     }
 }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 3f879b489..ef7b1c4f7 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -366,17 +366,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @action
     closeHeader = () => { this._headerOpen = false; }
 
-    renderKeysDropDown = (col: any) => {
-        return <KeysDropdown
-            keyValue={col.heading}
-            possibleKeys={this.possibleKeys}
-            existingKeys={this.columns.map(c => c.heading)}
-            canAddNew={true}
-            addNew={false}
-            onSelect={this.changeColumns}
-            setIsEditing={this.setHeaderIsEditing}
-        />;
-    }
+
 
     @undoBatch
     @action
@@ -415,10 +405,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @computed get renderMenuContent() {
         TraceMobx();
         return <div className="collectionSchema-header-menuOptions">
-            <div className="collectionSchema-headerMenu-group">
-                <label>Key:</label>
-                {this.renderKeysDropDown(this._col)}
-            </div>
             {this.renderTypes(this._col)}
             {this.renderSorting(this._col)}
             {this.renderColors(this._col)}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index d8756aae3..4fb05733a 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -180,6 +180,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.props.active
 
         const cols = this.props.columns.map(col => {
+            const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
+                this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
+                    this.getColumnType(col) === ColumnType.Image ? "image" : this.getColumnType(col) === ColumnType.List ? "list-ul" :
+                        this.getColumnType(col) === ColumnType.Date ? "calendar" : "align-justify";
+
             const keysDropdown = <KeysDropdown
                 keyValue={col.heading}
                 possibleKeys={possibleKeys}
@@ -195,26 +200,14 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                 ContainingCollectionView={this.props.ContainingCollectionView}
                 active={this.props.active}
-
-
+                openHeader={this.props.openHeader}
+                icon={icon}
+                col={col}
                 // try commenting this out
                 width={"100%"}
             />;
 
-            const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
-                this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
-                    this.getColumnType(col) === ColumnType.Image ? "image" : this.getColumnType(col) === ColumnType.List ? "list-ul" :
-                        this.getColumnType(col) === ColumnType.Date ? "calendar" : "align-justify";
 
-            const headerText = this._showTitleDropdown ? keysDropdown : <div
-                onClick={this.changeTitleMode}
-                style={{
-                    background: col.color, padding: "2px",
-                    letterSpacing: "2px",
-                    textTransform: "uppercase",
-                    display: "flex"
-                }}>
-                {col.heading}</div>;
 
             const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
 
@@ -226,11 +219,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         background: col.color, padding: "2px",
                         display: "flex", cursor: "default", height: "100%",
                     }}>
-                    <FontAwesomeIcon onClick={e => this.props.openHeader(col, e.clientX, e.clientY)} icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
-                    {/* <div className="keys-dropdown"
-                        style={{ display: "inline", zIndex: 1000 }}> */}
+                    {/* <FontAwesomeIcon onClick={e => this.props.openHeader(col, e.clientX, e.clientY)} icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} /> */}
                     {keysDropdown}
-                    {/* </div> */}
                     <div onClick={e => this.changeSorting(col)}
                         style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
                         <FontAwesomeIcon icon={sortIcon} size="lg" />
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 4a14b222c..da298e54c 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -533,7 +533,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     getDataStatus() { return this._deletedDocsStatus; }
 
-    private NumResults = 25;
+    private NumResults = 50;
     private lockPromise?: Promise<void>;
     getResults = async (query: string) => {
         console.log("Get");
-- 
cgit v1.2.3-70-g09d2


From 4d6da44b4eb484d79fc263e5d36c02ea50265767 Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Wed, 12 Aug 2020 03:55:26 -0400
Subject: filtering in solr and pagination

---
 .../views/collections/CollectionSchemaHeaders.tsx  |  13 +-
 src/client/views/collections/CollectionSubView.tsx |   2 -
 src/client/views/search/SearchBox.tsx              | 269 +++++++++++++--------
 src/fields/Doc.ts                                  |   1 +
 4 files changed, 177 insertions(+), 108 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index c1c4eb628..fc2463c97 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -387,8 +387,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         });
 
         // if search term does not already exist as a group type, give option to create new group type
-        console.log("Start here");
-        console.log(this._key, this._searchTerm.slice(0, this._key.length));
+
         if (this._key !== this._searchTerm.slice(0, this._key.length)) {
             console.log("little further");
             if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
@@ -414,16 +413,20 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         }
         return options;
     }
+
+    docSafe: Doc[] = []
+
     @action
     renderFilterOptions = (): JSX.Element[] | JSX.Element => {
-        console.log("we here");
         if (!this._isOpen) {
             this.defaultMenuHeight = 0;
             return <></>;
         }
         let keyOptions: string[] = [];
-        let docs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
-
+        if (this.docSafe.length === 0) {
+            this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+        }
+        let docs = this.docSafe;
         docs.forEach((doc) => {
             const key = StrCast(doc[this._key]);
             if (keyOptions.includes(key) === false) {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 806ae8ffa..a4493897c 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -172,8 +172,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                 });
                 return docsforFilter;
             }
-            console.log("you fool");
-            console.log(childDocs);
             const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
             return this.props.Document.dontRegisterView ? childDocs : DocUtils.FilterDocs(childDocs, this.docFilters(), docRangeFilters, viewSpecScript);
         }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index da298e54c..39dd8d4bf 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from '@material-ui/core';
-import { action, computed, observable, runInAction } from 'mobx';
+import { action, computed, observable, runInAction, reaction, IReactionDisposer } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as rp from 'request-promise';
@@ -24,6 +24,8 @@ import { ViewBoxBaseComponent } from "../DocComponent";
 import { DocumentView } from '../nodes/DocumentView';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import "./SearchBox.scss";
+import { stringifyUrl } from "query-string";
+import { filterSeries } from "async";
 
 export const searchSchema = createSchema({
     id: "string",
@@ -86,7 +88,19 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     }
     @observable setupButtons = false;
+    private _disposers: { [name: string]: IReactionDisposer } = {};
+
     componentDidMount = () => {
+        this._disposers.filters = reaction(() => Cast(this.props.Document._docFilters, listSpec("string")), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
+            newFilters => {
+                if (this.searchFullDB) {
+                    runInAction(() => this._pageStart = 0);
+                    this.submitSearch();
+                    // newFilters?.forEach(f => {
+                    //     console.log(f);
+                    // })
+                }
+            });
         if (this.setupButtons === false) {
 
             runInAction(() => this.setupButtons = true);
@@ -113,6 +127,10 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         }
     }
 
+    componentWillUnmount() {
+        Object.values(this._disposers).forEach(disposer => disposer?.());
+    }
+
 
     @action
     getViews = (doc: Doc) => SearchUtil.GetViewsOfDocument(doc)
@@ -123,8 +141,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     onChange(e: React.ChangeEvent<HTMLInputElement>) {
         this.layoutDoc._searchString = e.target.value;
         this.newsearchstring = e.target.value;
-
-
         if (e.target.value === "") {
             if (this.currentSelectedCollection !== undefined) {
                 let newarray: Doc[] = [];
@@ -176,6 +192,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     enter = (e: React.KeyboardEvent) => {
         if (e.key === "Enter") {
             this.layoutDoc._searchString = this.newsearchstring;
+            runInAction(() => this._pageStart = 0);
 
             if (StrCast(this.layoutDoc._searchString) !== "" || !this.searchFullDB) {
                 runInAction(() => this.open = true);
@@ -228,26 +245,102 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     getFinalQuery(query: string): string {
         //alters the query so it looks in the correct fields
-        //if this is true, then not all of the field boxes are checked
+        //if this is true, th`en not all of the field boxes are checked
         //TODO: data
-        if (this.fieldFiltersApplied) {
-            query = this.applyBasicFieldFilters(query);
-            query = query.replace(/\s+/g, ' ').trim();
+        let initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []);
+
+        let type: string[] = [];
+
+        let filters: string[] = []
+
+        for (let i = 0; i < initialfilters.length; i = i + 3) {
+            if (initialfilters[i + 2] !== undefined) {
+                filters.push(initialfilters[i]);
+                filters.push(initialfilters[i + 1]);
+                filters.push(initialfilters[i + 2]);
+            }
         }
 
-        //alters the query based on if all words or any words are required
-        //if this._wordstatus is false, all words are required and a + is added before each
-        if (!this._basicWordStatus) {
-            query = this.basicRequireWords(query);
-            query = query.replace(/\s+/g, ' ').trim();
+        let finalfilters: { [key: string]: string[] } = {};
+
+        for (let i = 0; i < filters.length; i = i + 3) {
+            if (finalfilters[filters[i]] !== undefined) {
+                finalfilters[filters[i]].push(filters[i + 1]);
+            }
+            else {
+                finalfilters[filters[i]] = [filters[i + 1]];
+            }
         }
 
-        // if should be searched in a specific collection
-        if (this._collectionStatus) {
-            query = this.addCollectionFilter(query);
-            query = query.replace(/\s+/g, ' ').trim();
+        for (var key in finalfilters) {
+            let values = finalfilters[key];
+            if (values.length === 1) {
+                let mod = "_t:"
+                const newWords: string[] = [];
+                const oldWords = values[0].split(" ");
+                oldWords.forEach((word, i) => {
+                    i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+                });
+                let v = "(" + newWords.join(" ") + ")";
+                query = query + " && " + v;
+            }
+            else {
+                for (let i = 0; i < values.length; i++) {
+                    let mod = "_t:"
+                    const newWords: string[] = [];
+                    const oldWords = values[i].split(" ");
+                    oldWords.forEach((word, i) => {
+                        i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+                    });
+                    let v = "(" + newWords.join(" ") + ")";
+                    if (i === 0) {
+                        query = query + " && (" + v;
+                        if (values.length === 1) {
+                            query = query + ")";
+                        }
+                    }
+                    else if (i === values.length - 1) {
+                        query = query + " " + v + ")";
+                    }
+                    else {
+                        query = query + " " + v;
+                    }
+                }
+            }
 
         }
+
+
+        // let limit = typepos.length
+        // typepos.forEach(i => {
+        //     if (i === 0) {
+        //         if (i + 1 === limit) {
+        // query = query + " && " + filters[i] + "_t:" + filters;
+        //         }
+        //         else if (filters[i] === filters[i + 3]) {
+        //             query = query + " && (" + filters[i] + "_t:" + filters;
+        //         }
+        //         else {
+        //             query = query + " && " + filters[i] + "_t:" + filters;
+        //         }
+
+        //     }
+        //     else if (i + 3 > filters.length) {
+
+        //     }
+        //     else {
+
+        //     }
+
+        // });
+
+        // query = this.applyBasicFieldFilters(query);
+
+
+
+        query = query.replace(/-\s+/g, '');
+        query = query.replace(/-/g, "");
+        console.log(query);
         return query;
     }
 
@@ -400,15 +493,9 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     applyBasicFieldFilters(query: string) {
         let finalQuery = "";
 
-        if (this._titleFieldStatus) {
-            finalQuery = finalQuery + this.basicFieldFilters(query, Keys.TITLE);
-        }
-        if (this._authorFieldStatus) {
-            finalQuery = finalQuery + this.basicFieldFilters(query, Keys.AUTHOR);
-        }
-        if (this._deletedDocsStatus) {
-            finalQuery = finalQuery + this.basicFieldFilters(query, Keys.DATA);
-        }
+        finalQuery = finalQuery + this.basicFieldFilters(query, Keys.TITLE);
+        finalQuery = finalQuery + this.basicFieldFilters(query, Keys.AUTHOR);
+
         if (this._deletedDocsStatus) {
             finalQuery = finalQuery + this.basicFieldFilters(query, Keys.TEXT);
         }
@@ -419,8 +506,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         let mod = "";
         switch (type) {
             case Keys.AUTHOR: mod = " author_t:"; break;
-            case Keys.DATA: break; // TODO
-            case Keys.TITLE: mod = " _title_t:"; break;
+            case Keys.TITLE: mod = " title_t:"; break;
             case Keys.TEXT: mod = " text_t:"; break;
         }
 
@@ -446,7 +532,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 docs.forEach((d) => {
                     if (d.data !== undefined) {
                         d._searchDocs = new List<Doc>();
-                        d._docFilters = new List();
+                        //d._docFilters = new List();
                         const newdocs = DocListCast(d.data);
                         newdocs.forEach((newdoc) => {
                             newarray.push(newdoc);
@@ -463,7 +549,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         if (reset) {
             this.layoutDoc._searchString = "";
         }
-        this.props.Document._docFilters = new List();
+        //this.props.Document._docFilters = new List();
         this.noresults = "";
 
         this.dataDoc[this.fieldKey] = new List<Doc>([]);
@@ -471,9 +557,9 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this.children = 0;
         this.buckets = [];
         this.new_buckets = {};
-        const query = StrCast(this.layoutDoc._searchString);
+        let query = StrCast(this.layoutDoc._searchString);
         Doc.SetSearchQuery(query);
-        this.getFinalQuery(query);
+        this.searchFullDB ? query = this.getFinalQuery(query) : console.log("local");
         this._results.forEach(result => {
             Doc.UnBrushDoc(result[0]);
             result[0].searchMatch = undefined;
@@ -542,11 +628,12 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         }
         this.lockPromise = new Promise(async res => {
             while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) {
-                this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
+                this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: 10000000, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
                     // happens at the beginning
                     if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
                         this._numTotalResults = res.numFound;
                     }
+                    console.log(res.numFound);
                     const highlighting = res.highlighting || {};
                     const highlightList = res.docs.map(doc => highlighting[doc[Id]]);
                     const lines = new Map<string, string[]>();
@@ -558,31 +645,23 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
                     runInAction(() => {
                         filteredDocs.forEach((doc, i) => {
+                            console.log(i);
                             const index = this._resultsSet.get(doc);
                             const highlight = highlights[doc[Id]];
                             const line = lines.get(doc[Id]) || [];
                             const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)).filter(k => k) : [];
                             doc ? console.log(Cast(doc.context, Doc)) : null;
-                            if (this.findCommonElements(hlights)) {
-                            }
-                            else {
-                                const layoutresult = Cast(doc.type, "string");
-                                if (layoutresult) {
-                                    if (this.new_buckets[layoutresult] === undefined) {
-                                        this.new_buckets[layoutresult] = 1;
-                                    }
-                                    else {
-                                        this.new_buckets[layoutresult] = this.new_buckets[layoutresult] + 1;
-                                    }
-                                }
-                                if (index === undefined) {
-                                    this._resultsSet.set(doc, this._results.length);
-                                    this._results.push([doc, hlights, line]);
-                                } else {
-                                    this._results[index][1].push(...hlights);
-                                    this._results[index][2].push(...line);
-                                }
+                            // if (this.findCommonElements(hlights)) {
+                            // }
+                            if (index === undefined) {
+                                this._resultsSet.set(doc, this._results.length);
+                                this._results.push([doc, hlights, line]);
+                                console.log(i);
+                            } else {
+                                this._results[index][1].push(...hlights);
+                                this._results[index][2].push(...line);
                             }
+
                         });
                     });
 
@@ -663,15 +742,16 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._curRequest = undefined;
     }
 
+    @observable _pageStart: number = 0
+    @observable _pageCount: number = 5;
+
     @observable children: number = 0;
     @action
     resultsScrolled = (e?: React.UIEvent<HTMLDivElement>) => {
         if (!this._resultsRef.current) return;
-        this.props.Document._schemaHeaders = new List<SchemaHeaderField>([]);
 
         const scrollY = e ? e.currentTarget.scrollTop : this._resultsRef.current ? this._resultsRef.current.scrollTop : 0;
         const itemHght = 53;
-        const startIndex = Math.floor(Math.max(0, scrollY / itemHght));
         //const endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this._resultsRef.current.getBoundingClientRect().height / itemHght)));
         const endIndex = 30;
         //this._endIndex = endIndex === -1 ? 12 : endIndex;
@@ -699,62 +779,42 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             this._isSorted = Array<undefined>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
 
         }
-        for (let i = 0; i < this._numTotalResults; i++) {
+        let max = this._pageStart + this._pageCount;
+        max > this._results.length ? max = this._results.length : console.log("");
+        for (let i = this._pageStart; i < max; i++) {
             //if the index is out of the window then put a placeholder in
             //should ones that have already been found get set to placeholders?
-            if (i < startIndex || i > endIndex) {
-                if (this._isSearch[i] !== "placeholder") {
-                    this._isSearch[i] = "placeholder";
-                    this._isSorted[i] = "placeholder";
-                    this._visibleElements[i] = <div className="searchBox-placeholder" key={`searchBox-placeholder-${i}`}>Loading...</div>;
-                }
-            }
-            else {
-                if (this._isSearch[i] !== "search") {
-                    let result: [Doc, string[], string[]] | undefined = undefined;
-                    if (i >= this._results.length) {
-                        this.getResults(StrCast(this.layoutDoc._searchString));
-                        if (i < this._results.length) result = this._results[i];
-                        if (result) {
-                            const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
-                            const lines = new List<string>(result[2]);
-                            result[0].lines = lines;
-                            result[0].highlighting = highlights.join(", ");
-                            highlights.forEach((item) => headers.add(item));
-                            this._visibleDocuments[i] = result[0];
-                            this._isSearch[i] = "search";
-                            Doc.BrushDoc(result[0]);
-                            result[0].searchMatch = true;
-                            Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
-                            this.children++;
-                        }
-                    }
-                    else {
-                        result = this._results[i];
-                        if (result) {
-                            const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
-                            const lines = new List<string>(result[2]);
-                            highlights.forEach((item) => headers.add(item));
-                            result[0].lines = lines;
-                            result[0].highlighting = highlights.join(", ");
-                            result[0].searchMatch = true;
-                            if (i < this._visibleDocuments.length) {
-                                this._visibleDocuments[i] = result[0];
-                                this._isSearch[i] = "search";
-                                Doc.BrushDoc(result[0]);
-                                Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
-                                this.children++;
-                            }
-                        }
+
+            if (this._isSearch[i] !== "search") {
+                let result: [Doc, string[], string[]] | undefined = undefined;
+
+                result = this._results[i];
+                if (result) {
+                    const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
+                    const lines = new List<string>(result[2]);
+                    highlights.forEach((item) => headers.add(item));
+                    result[0].lines = lines;
+                    result[0].highlighting = highlights.join(", ");
+                    result[0].searchMatch = true;
+                    if (i < this._visibleDocuments.length) {
+                        this._visibleDocuments[i] = result[0];
+                        this._isSearch[i] = "search";
+                        Doc.BrushDoc(result[0]);
+                        Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+                        this.children++;
                     }
+
                 }
+
             }
         }
         const schemaheaders: SchemaHeaderField[] = [];
         this.headerscale = headers.size;
         headers.forEach((item) => schemaheaders.push(new SchemaHeaderField(item, "#f1efeb")));
         this.headercount = schemaheaders.length;
-        this.props.Document._schemaHeaders = new List<SchemaHeaderField>(schemaheaders);
+        if (Cast(this.props.Document._docFilters, listSpec("string"), []).length === 0) {
+            this.props.Document._schemaHeaders = new List<SchemaHeaderField>(schemaheaders);
+        }
         if (this._maxSearchIndex >= this._numTotalResults) {
             this._visibleElements.length = this._results.length;
             this._visibleDocuments.length = this._results.length;
@@ -799,6 +859,11 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @observable filter = false;
 
+    @action newpage() {
+        this._pageStart += 5;
+        this.dataDoc[this.fieldKey] = new List<Doc>([]);
+        this.resultsScrolled();
+    }
     render() {
         this.props.Document._chromeStatus === "disabled";
         this.props.Document._searchDoc = true;
@@ -807,14 +872,16 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         cols > 5 ? length = 1076 : length = cols * 205 + 51;
         let height = 0;
         const rows = this.children;
-        rows > 6 ? height = 31 + 31 * 6 : height = 31 * rows + 31;
+        height = 31 + 31 * 6;
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
                 <div className="searchBox-bar">
                     <div style={{ position: "absolute", left: 15 }}>{Doc.CurrentUserEmail}</div>
                     <div style={{ display: "flex", alignItems: "center" }}>
                         <Tooltip title={<div className="dash-tooltip" >drag search results as collection</div>} ><div>
-                            <FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
+                            {/* <FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
+                                style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} /> */}
+                            <FontAwesomeIcon onPointerDown={() => { this.newpage(); }} icon={"search"} size="lg"
                                 style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} />
                         </div></Tooltip>
                         <div style={{ cursor: "default", left: 250, position: "relative", }}>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index b535fea5a..927ff4422 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1044,6 +1044,7 @@ export namespace Doc {
                 if (docFilters[i] === key && (docFilters[i + 1] === value || modifiers === "match")) {
                     if (docFilters[i + 2] === modifiers && modifiers && docFilters[i + 1] === value) return;
                     docFilters.splice(i, 3);
+                    container._docFilters = new List<string>(docFilters);
                     break;
                 }
             }
-- 
cgit v1.2.3-70-g09d2


From 4927e0d6318afc63f3476839999761decc5842ac Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 12 Aug 2020 08:04:56 -0400
Subject: switching syntax from && to AND for solr filters and added quotes
 around solr term values

---
 src/client/views/search/SearchBox.tsx | 8 ++++----
 src/fields/SchemaHeaderField.ts       | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 39dd8d4bf..36b490839 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -279,10 +279,10 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 const newWords: string[] = [];
                 const oldWords = values[0].split(" ");
                 oldWords.forEach((word, i) => {
-                    i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+                    i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
                 });
                 let v = "(" + newWords.join(" ") + ")";
-                query = query + " && " + v;
+                query = query + " AND " + v;
             }
             else {
                 for (let i = 0; i < values.length; i++) {
@@ -290,11 +290,11 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                     const newWords: string[] = [];
                     const oldWords = values[i].split(" ");
                     oldWords.forEach((word, i) => {
-                        i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+                        i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
                     });
                     let v = "(" + newWords.join(" ") + ")";
                     if (i === 0) {
-                        query = query + " && (" + v;
+                        query = query + " AND (" + v;
                         if (values.length === 1) {
                             query = query + ")";
                         }
diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts
index 07c90f5a2..22ae454f8 100644
--- a/src/fields/SchemaHeaderField.ts
+++ b/src/fields/SchemaHeaderField.ts
@@ -114,7 +114,7 @@ export class SchemaHeaderField extends ObjectField {
     }
 
     [ToScriptString]() {
-        return `invalid`;
+        return `header(${this.heading},${this.type}})`;
     }
     [ToString]() {
         return `SchemaHeaderField`;
-- 
cgit v1.2.3-70-g09d2


From 5117ba5f30afe271095ae92c511844dfe7d0cc85 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 12 Aug 2020 11:39:55 -0400
Subject: fixed searching on 'type' to join with parent document

---
 src/client/util/SearchUtil.ts         | 3 ++-
 src/client/views/search/SearchBox.tsx | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 7b2c601fe..3073da954 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -37,7 +37,8 @@ export namespace SearchUtil {
     export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) {
         query = query || "*"; //If we just have a filter query, search for * as the query
         const rpquery = Utils.prepend("/dashsearch");
-        const gotten = await rp.get(rpquery, { qs: { ...options, q: query } });
+        const replacedQuery = query.replace(/type_t:([^ )])/, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
+        const gotten = await rp.get(rpquery, { qs: { ...options, q: replacedQuery } });
         const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
         if (!returnDocs) {
             return result;
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 36b490839..25baaa0b9 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -756,7 +756,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         const endIndex = 30;
         //this._endIndex = endIndex === -1 ? 12 : endIndex;
         this._endIndex = 30;
-        const headers = new Set<string>(["title", "author", "*lastModified"]);
+        const headers = new Set<string>(["title", "author", "*lastModified", "type"]);
         if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
             if (this.noresults === "") {
                 this.noresults = "No search results :(";
-- 
cgit v1.2.3-70-g09d2


From e5e693d7699e34d20fb183bc2514557edfb7d0f7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 12 Aug 2020 13:09:36 -0400
Subject: fixed compound solr query syntax.  fixed filter options to be sticky
 so that they don't get lost with a new search

---
 .../views/collections/CollectionSchemaHeaders.tsx  | 13 +++++++++--
 src/client/views/search/SearchBox.tsx              | 25 ++++++++++------------
 2 files changed, 22 insertions(+), 16 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 7a1a6b41e..d379f1c1e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -420,10 +420,16 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             }
         });
 
+        let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
+        for (let i = 0; i < (filters?.length ?? 0) - 1; i += 3) {
+            if (filters![i] === this.props.col.heading && keyOptions.includes(filters![i + 1]) === false) {
+                keyOptions.push(filters![i + 1]);
+            }
+        }
+
         const options = keyOptions.map(key => {
             //Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
             let bool = false;
-            let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
             console.log(filters);
             if (filters !== undefined) {
                 bool = filters.includes(key) && filters[filters.indexOf(key) + 1] === "check";
@@ -434,7 +440,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                 width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
             }}
             >
-                <input type="checkbox" onChange={(e) => { e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined); e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined); }}
+                <input type="checkbox" onChange={(e) => {
+                    e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
+                    e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined);
+                }}
                     checked={bool} ></input>
                 <span style={{ paddingLeft: 4 }}>
                     {key}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 25baaa0b9..2e2e87092 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -24,8 +24,6 @@ import { ViewBoxBaseComponent } from "../DocComponent";
 import { DocumentView } from '../nodes/DocumentView';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import "./SearchBox.scss";
-import { stringifyUrl } from "query-string";
-import { filterSeries } from "async";
 
 export const searchSchema = createSchema({
     id: "string",
@@ -281,8 +279,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 oldWords.forEach((word, i) => {
                     i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
                 });
-                let v = "(" + newWords.join(" ") + ")";
-                query = query + " AND " + v;
+                query = `(${query}) AND (${newWords.join(" ")})`;
             }
             else {
                 for (let i = 0; i < values.length; i++) {
@@ -294,16 +291,16 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                     });
                     let v = "(" + newWords.join(" ") + ")";
                     if (i === 0) {
-                        query = query + " AND (" + v;
+                        query = `(${query}) AND (${v}`;
                         if (values.length === 1) {
                             query = query + ")";
                         }
                     }
                     else if (i === values.length - 1) {
-                        query = query + " " + v + ")";
+                        query = query + " OR " + v + ")";
                     }
                     else {
-                        query = query + " " + v;
+                        query = query + " OR " + v;
                     }
                 }
             }
@@ -607,7 +604,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     }
 
     private get filterQuery() {
-        const types = ["preselement", "docholder", "collection", "search", "searchitem", "script", "fonticonbox", "button", "label"]; // this.filterTypes;
+        const types = ["preselement", "docholder", "search", "searchitem", "script", "fonticonbox", "button", "label"]; // this.filterTypes;
         const baseExpr = "NOT baseProto_b:true AND NOT system_b:true";
         const includeDeleted = this.getDataStatus() ? "" : " NOT deleted_b:true";
         const includeIcons = this.getDataStatus() ? "" : " NOT type_t:fonticonbox";
@@ -757,12 +754,12 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         //this._endIndex = endIndex === -1 ? 12 : endIndex;
         this._endIndex = 30;
         const headers = new Set<string>(["title", "author", "*lastModified", "type"]);
-        if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
-            if (this.noresults === "") {
-                this.noresults = "No search results :(";
-            }
-            return;
-        }
+        // if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
+        //     if (this.noresults === "") {
+        //         this.noresults = "No search results :(";
+        //     }
+        //     return;
+        // }
 
         if (this._numTotalResults <= this._maxSearchIndex) {
             this._numTotalResults = this._results.length;
-- 
cgit v1.2.3-70-g09d2


From f7b6e64c5c60f7221d80d16460d0a85d0f17b35a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 12 Aug 2020 15:05:36 -0400
Subject: fixed warnings and fixed rendering of fields in search view.

---
 .../views/collections/CollectionSchemaCells.tsx    | 34 +++----------------
 .../views/collections/CollectionSchemaHeaders.tsx  | 32 +++++++++---------
 .../views/collections/CollectionSchemaView.tsx     |  8 ++---
 src/client/views/collections/CollectionSubView.tsx |  6 ++--
 src/client/views/collections/SchemaTable.tsx       | 14 ++++----
 src/client/views/nodes/FieldView.tsx               |  8 ++---
 src/client/views/pdf/PDFViewer.tsx                 |  4 +--
 src/client/views/search/SearchBox.tsx              | 38 ++++++++++++----------
 8 files changed, 61 insertions(+), 83 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 20ae74b44..c9dccd23b 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -166,7 +166,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         const contents = bing();
 
         if (positions !== undefined) {
-            StrCast(this.props.Document._searchString)
+            StrCast(this.props.Document._searchString);
             const length = StrCast(this.props.Document._searchString).length;
 
             results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(0, positions[0]) : "undefined"}</span>);
@@ -227,7 +227,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
 
         const onItemDown = async (e: React.PointerEvent) => {
             if (this.props.Document._searchDoc !== undefined) {
-                let doc = Doc.GetProto(this.props.rowProps.original);
+                const doc = Doc.GetProto(this.props.rowProps.original);
                 const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc);
                 let targetContext = undefined;
                 if (aliasdoc.length > 0) {
@@ -289,18 +289,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         const positions = [];
         if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
             const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
-            let term = "";
-            if (cfield !== undefined) {
-                if (cfield.Text !== undefined) {
-                    term = cfield.Text;
-                }
-                else if (StrCast(cfield)) {
-                    term = StrCast(cfield);
-                }
-                else {
-                    term = String(NumCast(cfield));
-                }
-            }
+            let term = Field.toString(cfield as Field);
             term = term.toLowerCase();
             const search = StrCast(this.props.Document._searchString).toLowerCase();
             let start = term.indexOf(search);
@@ -409,22 +398,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                             :
                             this.returnHighlights(() => {
                                 const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
-                                if (cfield !== undefined) {
-                                    // if (typeof(cfield)===RichTextField)
-                                    const a = cfield as RichTextField;
-                                    if (a.Text !== undefined) {
-                                        return (a.Text);
-                                    }
-                                    else if (StrCast(cfield)) {
-                                        return StrCast(cfield);
-                                    }
-                                    else {
-                                        return String(NumCast(cfield));
-                                    }
-                                }
-                                else {
-                                    return "";
-                                }
+                                return Field.toString(cfield as Field);
                             }, positions)
                         }
                     </div >
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index d379f1c1e..12fb5a874 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -3,7 +3,7 @@ import { IconProp, library } from "@fortawesome/fontawesome-svg-core";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
 import { listSpec } from "../../../fields/Schema";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import { ScriptField } from "../../../fields/ScriptField";
@@ -276,10 +276,10 @@ export interface KeysDropdownProps {
     width?: string;
     docs?: Doc[];
     Document: Doc;
-    dataDoc: Doc;
+    dataDoc: Doc | undefined;
     fieldKey: string;
-    ContainingCollectionDoc: Doc;
-    ContainingCollectionView: CollectionView;
+    ContainingCollectionDoc: Doc | undefined;
+    ContainingCollectionView: Opt<CollectionView>;
     active?: (outsideReaction?: boolean) => boolean;
     openHeader: (column: any, screenx: number, screeny: number) => void;
     col: SchemaHeaderField;
@@ -309,7 +309,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
             let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-            let blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+            const blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
             keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
             if (keyOptions.length) {
                 this.onSelect(keyOptions[0]);
@@ -361,7 +361,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         const exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
             this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
 
-        let blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+        const blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
         keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
 
         const options = keyOptions.map(key => {
@@ -390,7 +390,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         }
         else {
             if (this.props.docs) {
-                let panesize = this.props.docs.length * 30;
+                const panesize = this.props.docs.length * 30;
                 options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
             }
             else {
@@ -400,7 +400,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         return options;
     }
 
-    docSafe: Doc[] = []
+    docSafe: Doc[] = [];
 
     @action
     renderFilterOptions = (): JSX.Element[] | JSX.Element => {
@@ -408,11 +408,11 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             this.defaultMenuHeight = 0;
             return <></>;
         }
-        let keyOptions: string[] = [];
+        const keyOptions: string[] = [];
         if (this.docSafe.length === 0) {
-            this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+            this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey]);
         }
-        let docs = this.docSafe;
+        const docs = this.docSafe;
         docs.forEach((doc) => {
             const key = StrCast(doc[this._key]);
             if (keyOptions.includes(key) === false) {
@@ -420,7 +420,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             }
         });
 
-        let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
+        const filters = Cast(this.props.Document._docFilters, listSpec("string"));
         for (let i = 0; i < (filters?.length ?? 0) - 1; i += 3) {
             if (filters![i] === this.props.col.heading && keyOptions.includes(filters![i + 1]) === false) {
                 keyOptions.push(filters![i + 1]);
@@ -441,8 +441,8 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             }}
             >
                 <input type="checkbox" onChange={(e) => {
-                    e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
-                    e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined);
+                    e.target.checked === true ? Doc.setDocFilter(this.props.Document, this._key, key, "check") : Doc.setDocFilter(this.props.Document, this._key, key, undefined);
+                    e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs[0], this._key, key, "check") : Doc.setDocFilter(docs[0], this._key, key, undefined);
                 }}
                     checked={bool} ></input>
                 <span style={{ paddingLeft: 4 }}>
@@ -456,7 +456,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         }
         else {
             if (this.props.docs) {
-                let panesize = this.props.docs.length * 30;
+                const panesize = this.props.docs.length * 30;
                 options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
             }
             else {
@@ -486,7 +486,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         console.log(this._isOpen, this._key, this._searchTerm);
         return (
             <div style={{ display: "flex" }}>
-                <FontAwesomeIcon onClick={e => { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) : this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+                <FontAwesomeIcon onClick={e => { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen; }) : this.props.openHeader(this.props.col, e.clientX, e.clientY); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
                 <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
                     <input className="keys-search" style={{ width: "100%" }}
                         ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index ef7b1c4f7..892148cd7 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -74,11 +74,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         let searchx = 0;
         let searchy = 0;
         if (this.props.Document._searchDoc !== undefined) {
-            let el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0];
+            const el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0];
             if (el !== undefined) {
-                let rect = el.getBoundingClientRect();
+                const rect = el.getBoundingClientRect();
                 searchx = rect.x;
-                searchy = rect.y
+                searchy = rect.y;
             }
         }
         const x = Math.max(0, Math.min(document.body.clientWidth - this._menuWidth, this._pointerX)) - searchx;
@@ -420,7 +420,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         super.CreateDropTarget(ele);
     }
 
-    isFocused = (doc: Doc): boolean => this.props.isSelected() && doc === this._focusedTable;
+    isFocused = (doc: Doc, outsideReaction: boolean): boolean => this.props.isSelected(outsideReaction) && doc === this._focusedTable;
 
     @action setFocused = (doc: Doc) => this._focusedTable = doc;
 
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a43685a5e..3f2ad47a5 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -126,7 +126,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
 
             const docs = rawdocs.filter(d => !(d instanceof Promise)).map(d => d as Doc);
             const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
-            let childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
+            const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
 
             let searchDocs = DocListCast(this.props.Document._searchDocs);
 
@@ -137,7 +137,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                 docsforFilter = [];
                 const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
                 console.log(searchDocs);
-                searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript)
+                searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript);
                 console.log(this.docFilters());
                 console.log(searchDocs);
                 childDocs.forEach((d) => {
@@ -240,6 +240,8 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                             Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
                         added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.addDocument : returnFalse);
                     } else added = res;
+                    !added && alert("You don't have permission to perform this move");
+                    e.stopPropagation();
                 } else {
                     ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
                     added = this.addDocument(docDragData.droppedDocuments);
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 4fb05733a..8bf5a0475 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -63,12 +63,12 @@ export interface SchemaTableProps {
     addDocument: (document: Doc | Doc[]) => boolean;
     moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
-    active: (outsideReaction: boolean) => boolean;
+    active: (outsideReaction: boolean | undefined) => boolean;
     onDrop: (e: React.DragEvent<Element>, options: DocumentOptions, completed?: (() => void) | undefined) => void;
     addDocTab: (document: Doc, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     isSelected: (outsideReaction?: boolean) => boolean;
-    isFocused: (document: Doc) => boolean;
+    isFocused: (document: Doc, outsideReaction: boolean) => boolean;
     setFocused: (document: Doc) => void;
     setPreviewDoc: (document: Doc) => void;
     columns: SchemaHeaderField[];
@@ -155,7 +155,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
         const possibleKeys = this.props.documentKeys.filter(key => this.props.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
         const columns: Column<Doc>[] = [];
-        const tableIsFocused = this.props.isFocused(this.props.Document);
+        const tableIsFocused = this.props.isFocused(this.props.Document, false);
         const focusedRow = this._focusedCell.row;
         const focusedCol = this._focusedCell.col;
         const isEditable = !this.props.headerIsEditing;
@@ -177,7 +177,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 }
             );
         }
-        this.props.active
+        this.props.active;
 
         const cols = this.props.columns.map(col => {
             const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
@@ -342,7 +342,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             addDoc: this.tableAddDoc,
             removeDoc: this.props.deleteDocument,
             rowInfo,
-            rowFocused: !this.props.headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
+            rowFocused: !this.props.headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document, true),
             textWrapRow: this.toggleTextWrapRow,
             rowWrapped: this.textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1,
             dropAction: StrCast(this.props.Document.childDropAction),
@@ -356,7 +356,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         const row = rowInfo.index;
         //@ts-ignore
         const col = this.columns.map(c => c.heading).indexOf(column!.id);
-        const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
+        const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document, true);
         // TODO: editing border doesn't work :(
         return {
             style: {
@@ -376,7 +376,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     onKeyDown = (e: KeyboardEvent): void => {
-        if (!this._cellIsEditing && !this.props.headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
+        if (!this._cellIsEditing && !this.props.headerIsEditing && this.props.isFocused(this.props.Document, true)) {// && this.props.isSelected(true)) {
             const direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
 
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index fe0ea80d5..3f2a590ab 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -5,7 +5,7 @@ import { DateField } from "../../../fields/DateField";
 import { Doc, FieldResult, Opt, Field } from "../../../fields/Doc";
 import { List } from "../../../fields/List";
 import { ScriptField } from "../../../fields/ScriptField";
-import { AudioField, VideoField } from "../../../fields/URLField";
+import { AudioField, VideoField, WebField } from "../../../fields/URLField";
 import { Transform } from "../../util/Transform";
 import { CollectionView } from "../collections/CollectionView";
 import { AudioBox } from "./AudioBox";
@@ -135,9 +135,9 @@ export class FieldView extends React.Component<FieldViewProps> {
             return <div> {field.map(f => Field.toString(f)).join(", ")}  </div>;
         }
         // bcz: this belongs here, but it doesn't render well so taking it out for now
-        // else if (field instanceof HtmlField) {
-        //     return <WebBox {...this.props} />
-        // }
+        else if (field instanceof WebField) {
+            return <p>{Field.toString(field.url.href)}</p>;
+        }
         else if (!(field instanceof Promise)) {
             return <p>{Field.toString(field)}</p>;
         }
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index cca86adb5..f9ae78778 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -399,10 +399,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
     @action
     search = (searchString: string, fwd: boolean, clear: boolean = false) => {
         if (clear) {
-            this._pdfViewer.findController.executeCommand('reset', { query: "" });
+            this._pdfViewer?.findController.executeCommand('reset', { query: "" });
         } else if (!searchString) {
             fwd ? this.nextAnnotation() : this.prevAnnotation();
-        } else if (this._pdfViewer.pageViewsReady) {
+        } else if (this._pdfViewer?.pageViewsReady) {
             this._pdfViewer.findController.executeCommand('findagain', {
                 caseSensitive: false,
                 findPrevious: !fwd,
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 2e2e87092..b1ddeb08b 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -54,6 +54,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     @observable private _visibleElements: JSX.Element[] = [];
     @observable private _visibleDocuments: Doc[] = [];
 
+    static NUM_SEARCH_RESULTS_PER_PAGE = 25;
+
     private _resultsSet = new Map<Doc, number>();
     private _resultsRef = React.createRef<HTMLDivElement>();
     public inputRef = React.createRef<HTMLInputElement>();
@@ -245,11 +247,11 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         //alters the query so it looks in the correct fields
         //if this is true, th`en not all of the field boxes are checked
         //TODO: data
-        let initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []);
+        const initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []);
 
-        let type: string[] = [];
+        const type: string[] = [];
 
-        let filters: string[] = []
+        const filters: string[] = [];
 
         for (let i = 0; i < initialfilters.length; i = i + 3) {
             if (initialfilters[i + 2] !== undefined) {
@@ -259,7 +261,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             }
         }
 
-        let finalfilters: { [key: string]: string[] } = {};
+        const finalfilters: { [key: string]: string[] } = {};
 
         for (let i = 0; i < filters.length; i = i + 3) {
             if (finalfilters[filters[i]] !== undefined) {
@@ -270,26 +272,26 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             }
         }
 
-        for (var key in finalfilters) {
-            let values = finalfilters[key];
+        for (const key in finalfilters) {
+            const values = finalfilters[key];
             if (values.length === 1) {
-                let mod = "_t:"
+                const mod = "_t:";
                 const newWords: string[] = [];
                 const oldWords = values[0].split(" ");
                 oldWords.forEach((word, i) => {
-                    i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
+                    i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"");
                 });
                 query = `(${query}) AND (${newWords.join(" ")})`;
             }
             else {
                 for (let i = 0; i < values.length; i++) {
-                    let mod = "_t:"
+                    const mod = "_t:";
                     const newWords: string[] = [];
                     const oldWords = values[i].split(" ");
                     oldWords.forEach((word, i) => {
-                        i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
+                        i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"");
                     });
-                    let v = "(" + newWords.join(" ") + ")";
+                    const v = "(" + newWords.join(" ") + ")";
                     if (i === 0) {
                         query = `(${query}) AND (${v}`;
                         if (values.length === 1) {
@@ -348,7 +350,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     @action
     filterDocsByType(docs: Doc[]) {
         const finalDocs: Doc[] = [];
-        const blockedTypes: string[] = ["preselement", "docholder", "search", "searchitem", "script", "fonticonbox", "button", "label"];
+        const blockedTypes: string[] = [DocumentType.PRESELEMENT, DocumentType.DOCHOLDER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
         docs.forEach(doc => {
             const layoutresult = Cast(doc.type, "string");
             if (layoutresult && !blockedTypes.includes(layoutresult)) {
@@ -739,8 +741,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._curRequest = undefined;
     }
 
-    @observable _pageStart: number = 0
-    @observable _pageCount: number = 5;
+    @observable _pageStart: number = 0;
+    @observable _pageCount: number = SearchBox.NUM_SEARCH_RESULTS_PER_PAGE;
 
     @observable children: number = 0;
     @action
@@ -753,7 +755,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         const endIndex = 30;
         //this._endIndex = endIndex === -1 ? 12 : endIndex;
         this._endIndex = 30;
-        const headers = new Set<string>(["title", "author", "*lastModified", "type"]);
+        const headers = new Set<string>(["title", "author", "text", "type", "data", "*lastModified"]);
         // if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
         //     if (this.noresults === "") {
         //         this.noresults = "No search results :(";
@@ -838,7 +840,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); }
 
-    @computed get viewspec() { return Cast(this.props.Document._docFilters, listSpec("string"), []) }
+    @computed get viewspec() { return Cast(this.props.Document._docFilters, listSpec("string"), []); }
 
     getTransform = () => {
         return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
@@ -857,7 +859,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     @observable filter = false;
 
     @action newpage() {
-        this._pageStart += 5;
+        this._pageStart += SearchBox.NUM_SEARCH_RESULTS_PER_PAGE;
         this.dataDoc[this.fieldKey] = new List<Doc>([]);
         this.resultsScrolled();
     }
@@ -1000,7 +1002,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                                             docs.forEach((d) => {
                                                                 if (d.data !== undefined) {
                                                                     d._searchDocs = new List<Doc>();
-                                                                    d._docFilters = new List()
+                                                                    d._docFilters = new List();
                                                                     const newdocs = DocListCast(d.data);
                                                                     newdocs.forEach((newdoc) => {
                                                                         newarray.push(newdoc);
-- 
cgit v1.2.3-70-g09d2


From 57bbb175bfed6388f63566230eb7f1a591107855 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 12 Aug 2020 16:10:39 -0400
Subject: fixed run-time warnings & remove print statements

---
 src/client/views/collections/CollectionSchemaCells.tsx   |  8 ++++----
 src/client/views/collections/CollectionSchemaHeaders.tsx |  1 -
 src/client/views/nodes/PDFBox.tsx                        | 10 +++++-----
 src/client/views/nodes/WebBox.tsx                        |  4 ++--
 src/client/views/search/SearchBox.tsx                    |  8 +-------
 5 files changed, 12 insertions(+), 19 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index c9dccd23b..49d75e6de 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -168,13 +168,14 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         if (positions !== undefined) {
             StrCast(this.props.Document._searchString);
             const length = StrCast(this.props.Document._searchString).length;
+            const color = contents ? "black" : "grey";
 
-            results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(0, positions[0]) : "undefined"}</span>);
+            results.push(<span key="-1" style={{ color }}>{contents?.slice(0, positions[0])}</span>);
             positions.forEach((num, cur) => {
-                results.push(<span style={{ backgroundColor: "#FFFF00", color: contents ? "black" : "grey" }}>{contents ? contents.slice(num, num + length) : "undefined"}</span>);
+                results.push(<span key={"start" + cur} style={{ backgroundColor: "#FFFF00", color }}>{contents?.slice(num, num + length)}</span>);
                 let end = 0;
                 cur === positions.length - 1 ? end = contents.length : end = positions[cur + 1];
-                results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(num + length, end) : "undefined"}</span>);
+                results.push(<span key={"end" + cur} style={{ color }}>{contents?.slice(num + length, end)}</span>);
             }
             );
             return results;
@@ -233,7 +234,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                 if (aliasdoc.length > 0) {
                     targetContext = Cast(aliasdoc[0].context, Doc) as Doc;
                 }
-                console.log(targetContext);
                 DocumentManager.Instance.jumpToDocument(this.props.rowProps.original, false, undefined, targetContext);
             }
             else {
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 12fb5a874..c2bc7c77c 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -483,7 +483,6 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
 
     @observable filterOpen: boolean | undefined = undefined;
     render() {
-        console.log(this._isOpen, this._key, this._searchTerm);
         return (
             <div style={{ display: "flex" }}>
                 <FontAwesomeIcon onClick={e => { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen; }) : this.props.openHeader(this.props.col, e.clientX, e.clientY); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 2fdb87e63..255a1b2d0 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -60,19 +60,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         if (href) {
             const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g;
             const matches = pathCorrectionTest.exec(href);
-            console.log("\nHere's the { url } being fed into the outer regex:");
-            console.log(href);
-            console.log("And here's the 'properPath' build from the captured filename:\n");
+            // console.log("\nHere's the { url } being fed into the outer regex:");
+            // console.log(href);
+            // console.log("And here's the 'properPath' build from the captured filename:\n");
             if (matches !== null && href.startsWith(window.location.origin)) {
                 const properPath = Utils.prepend(`/files/pdfs/${matches[0]}`);
-                console.log(properPath);
+                //console.log(properPath);
                 if (!properPath.includes(href)) {
                     console.log(`The two (url and proper path) were not equal`);
                     const proto = Doc.GetProto(Document);
                     proto[this.props.fieldKey] = new PdfField(properPath);
                     proto[backup] = href;
                 } else {
-                    console.log(`The two (url and proper path) were equal`);
+                    //console.log(`The two (url and proper path) were equal`);
                 }
             } else {
                 console.log("Outer matches was null!");
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f37909e6e..105b0b2e2 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -454,9 +454,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             view = <span className="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
         } else if (field instanceof WebField) {
             const url = this.layoutDoc.UseCors ? Utils.CorsProxy(field.url.href) : field.url.href;
-            view = <iframe className="webBox-iframe" enable-annotation={true} ref={this._iframeRef} src={url} onLoad={this.iframeLoaded} />;
+            view = <iframe className="webBox-iframe" enable-annotation={"true"} ref={this._iframeRef} src={url} onLoad={this.iframeLoaded} />;
         } else {
-            view = <iframe className="webBox-iframe" enable-annotation={true} ref={this._iframeRef} src={"https://crossorigin.me/https://cs.brown.edu"} />;
+            view = <iframe className="webBox-iframe" enable-annotation={"true"} ref={this._iframeRef} src={"https://crossorigin.me/https://cs.brown.edu"} />;
         }
         return view;
     }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index b1ddeb08b..9cd03d518 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -339,7 +339,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
         query = query.replace(/-\s+/g, '');
         query = query.replace(/-/g, "");
-        console.log(query);
         return query;
     }
 
@@ -621,7 +620,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     private NumResults = 50;
     private lockPromise?: Promise<void>;
     getResults = async (query: string) => {
-        console.log("Get");
         if (this.lockPromise) {
             await this.lockPromise;
         }
@@ -632,7 +630,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                     if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
                         this._numTotalResults = res.numFound;
                     }
-                    console.log(res.numFound);
                     const highlighting = res.highlighting || {};
                     const highlightList = res.docs.map(doc => highlighting[doc[Id]]);
                     const lines = new Map<string, string[]>();
@@ -644,18 +641,15 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
                     runInAction(() => {
                         filteredDocs.forEach((doc, i) => {
-                            console.log(i);
                             const index = this._resultsSet.get(doc);
                             const highlight = highlights[doc[Id]];
                             const line = lines.get(doc[Id]) || [];
                             const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)).filter(k => k) : [];
-                            doc ? console.log(Cast(doc.context, Doc)) : null;
                             // if (this.findCommonElements(hlights)) {
                             // }
                             if (index === undefined) {
                                 this._resultsSet.set(doc, this._results.length);
                                 this._results.push([doc, hlights, line]);
-                                console.log(i);
                             } else {
                                 this._results[index][1].push(...hlights);
                                 this._results[index][2].push(...line);
@@ -755,7 +749,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         const endIndex = 30;
         //this._endIndex = endIndex === -1 ? 12 : endIndex;
         this._endIndex = 30;
-        const headers = new Set<string>(["title", "author", "text", "type", "data", "*lastModified"]);
+        const headers = new Set<string>(["title", "author", "text", "type", "data", "*lastModified", "context"]);
         // if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
         //     if (this.noresults === "") {
         //         this.noresults = "No search results :(";
-- 
cgit v1.2.3-70-g09d2


From a37cdb9d11271a28b0d9265fcb598747a6a0074a Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Wed, 12 Aug 2020 16:33:59 -0400
Subject: f

---
 .../views/collections/CollectionSchemaHeaders.tsx      |  8 +++++++-
 src/client/views/collections/SchemaTable.tsx           |  2 +-
 src/client/views/search/SearchBox.tsx                  | 18 +++++++++++++-----
 3 files changed, 21 insertions(+), 7 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index d379f1c1e..0ad1c5fa1 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -13,6 +13,7 @@ import { SearchBox } from "../search/SearchBox";
 import { ColumnType } from "./CollectionSchemaView";
 import "./CollectionSchemaView.scss";
 import { CollectionView } from "./CollectionView";
+import * as fa from '@fortawesome/free-solid-svg-icons';
 
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
@@ -486,7 +487,12 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         console.log(this._isOpen, this._key, this._searchTerm);
         return (
             <div style={{ display: "flex" }}>
-                <FontAwesomeIcon onClick={e => { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) : this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+                <FontAwesomeIcon onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+
+                <FontAwesomeIcon icon={fa.faSearchMinus} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} onClick={e => {
+                    runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen })
+                }} />
+
                 <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
                     <input className="keys-search" style={{ width: "100%" }}
                         ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 4fb05733a..2866bb497 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -320,7 +320,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             const newSchemaHeaders = oldSchemaHeaders.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
             this.props.Document._schemaHeaders = new List<SchemaHeaderField>(newSchemaHeaders);
         } else if (this.props.Document._schemaHeaders === undefined) {
-            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb")]);
+            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb"), new SchemaHeaderField("author", "#f1efeb"), new SchemaHeaderField("*lastModified", "#f1efeb")]);
         }
     }
 
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 2e2e87092..da3bafa95 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -168,7 +168,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 result[0].searchMatch = undefined;
             });
 
-            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([]);
             if (this.currentSelectedCollection !== undefined) {
                 this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]);
                 this.currentSelectedCollection = undefined;
@@ -805,12 +804,21 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
             }
         }
-        const schemaheaders: SchemaHeaderField[] = [];
         this.headerscale = headers.size;
-        headers.forEach((item) => schemaheaders.push(new SchemaHeaderField(item, "#f1efeb")));
-        this.headercount = schemaheaders.length;
         if (Cast(this.props.Document._docFilters, listSpec("string"), []).length === 0) {
-            this.props.Document._schemaHeaders = new List<SchemaHeaderField>(schemaheaders);
+            const oldSchemaHeaders = Cast(this.props.Document._schemaHeaders, listSpec("string"), []);
+            if (oldSchemaHeaders?.length && typeof oldSchemaHeaders[0] !== "object") {
+                const newSchemaHeaders = oldSchemaHeaders.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
+                headers.forEach(header => {
+                    if (oldSchemaHeaders.includes(header) === false) {
+                        newSchemaHeaders.push(new SchemaHeaderField(header, "#f1efeb"))
+                    }
+                });
+                this.headercount = newSchemaHeaders.length;
+                this.props.Document._schemaHeaders = new List<SchemaHeaderField>(newSchemaHeaders);
+            } else if (this.props.Document._schemaHeaders === undefined) {
+                this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb")]);
+            }
         }
         if (this._maxSearchIndex >= this._numTotalResults) {
             this._visibleElements.length = this._results.length;
-- 
cgit v1.2.3-70-g09d2


From a2a1f480a9af6cdf9863750df9314e29455cba60 Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Thu, 13 Aug 2020 16:51:01 -0400
Subject: total results, schema field fixes, filtering in headers

---
 src/client/util/SearchUtil.ts                      |  2 +-
 .../views/collections/CollectionSchemaCells.tsx    | 55 ++++++++++++++++++++--
 .../views/collections/CollectionSchemaHeaders.tsx  | 37 ++++++++++-----
 src/client/views/collections/SchemaTable.tsx       |  3 +-
 src/client/views/search/SearchBox.tsx              | 12 ++++-
 5 files changed, 89 insertions(+), 20 deletions(-)

(limited to 'src/client/views/search/SearchBox.tsx')

diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 3073da954..286544222 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -83,7 +83,7 @@ export namespace SearchUtil {
             }
         }
 
-        return { docs: theDocs, numFound: theDocs.length, highlighting, lines: theLines };
+        return { docs: theDocs, numFound: result.numFound, highlighting, lines: theLines };
     }
 
     export async function GetAliasesOfDocument(doc: Doc): Promise<Doc[]>;
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 49d75e6de..9cdd3b082 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, observable, trace, computed } from "mobx";
+import { action, observable, trace, computed, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { CellInfo } from "react-table";
 import "react-table/react-table.css";
@@ -69,10 +69,30 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     protected _document = this.props.rowProps.original;
     protected _dropDisposer?: DragManager.DragDropDisposer;
 
-    componentDidMount() {
+    async componentWillMount() {
+
+    }
+
+    async componentDidMount() {
         document.addEventListener("keydown", this.onKeyDown);
+        console.log("mounted");
+        console.log(this.type);
+        if (this.type === "context") {
+            console.log("mounted2");
+            const doc = Doc.GetProto(this.props.rowProps.original);
+            const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc);
+            let targetContext = undefined;
+            if (aliasdoc.length > 0) {
+                targetContext = Cast(aliasdoc[0].context, Doc) as Doc;
+                console.log(StrCast(targetContext.title));
+                runInAction(() => this.contents = StrCast(targetContext.title));
+            }
+        }
+
     }
 
+    @observable contents: string = "";
+
     componentWillUnmount() {
         document.removeEventListener("keydown", this.onKeyDown);
     }
@@ -184,6 +204,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             return <span style={{ color: contents ? "black" : "grey" }}>{contents ? contents?.valueOf() : "undefined"}</span>;
         }
     }
+    type: string = "";
 
     renderCellWithType(type: string | undefined) {
         const dragRef: React.RefObject<HTMLDivElement> = React.createRef();
@@ -287,8 +308,9 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         //     </div>
         // );   
         const positions = [];
+        let cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+        this.type = props.fieldKey;
         if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
-            const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
             let term = Field.toString(cfield as Field);
             term = term.toLowerCase();
             const search = StrCast(this.props.Document._searchString).toLowerCase();
@@ -312,7 +334,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             search = true;
         }
 
-
         return (
             <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }}
                 ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
@@ -337,9 +358,14 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                     if (cfield !== undefined) {
                                         // if (typeof(cfield)===RichTextField)
                                         const a = cfield as RichTextField;
+                                        const b = cfield as DateField;
+                                        console.log(b);
                                         if (a.Text !== undefined) {
                                             return (a.Text);
                                         }
+                                        else if (b.toString() !== undefined) {
+                                            return b.toString();
+                                        }
                                         else if (StrCast(cfield)) {
                                             return StrCast(cfield);
                                         }
@@ -397,7 +423,26 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                             />
                             :
                             this.returnHighlights(() => {
-                                const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+                                console.log(props.fieldKey);
+                                let dateCheck: Date | undefined = this.props.rowProps.original[this.props.rowProps.column.id as string] instanceof DateField ? DateCast(this.props.rowProps.original[this.props.rowProps.column.id as string]).date : undefined;
+                                if (dateCheck !== undefined) {
+                                    cfield = dateCheck.toLocaleString();
+                                }
+                                if (props.fieldKey === "context") {
+                                    cfield = this.contents;
+                                    console.log("this should work");
+                                }
+                                if (props.fieldKey === "*lastModified") {
+                                    if (FieldValue(props.Document["data-lastModified"]) !== undefined) {
+                                        const d = ComputedField.WithoutComputed(() => FieldValue(props.Document["data-lastModified"])) as DateField;
+                                        cfield = d.date.toLocaleString();
+                                    }
+
+                                    else if (FieldValue(props.Document["text-lastModified"]) !== undefined) {
+                                        const d = ComputedField.WithoutComputed(() => FieldValue(props.Document["text-lastModified"])) as DateField;
+                                        cfield = d.date.toLocaleString();
+                                    }
+                                }
                                 return Field.toString(cfield as Field);
                             }, positions)
                         }
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index fa260bee1..5c0e6581b 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -309,16 +309,29 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     @undoBatch
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
-            let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-            const blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
-            keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
-            if (keyOptions.length) {
-                this.onSelect(keyOptions[0]);
-                console.log("case1");
-            } else if (this._searchTerm !== "" && this.props.canAddNew) {
-                this.setSearchTerm(this._searchTerm || this._key);
-                console.log("case2");
-                this.onSelect(this._searchTerm);
+            if (this._searchTerm.includes(":")) {
+                const colpos = this._searchTerm.indexOf(":");
+                const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
+                if (temp === "") {
+                    Doc.setDocFilter(this.props.Document, this._key, temp, undefined);
+                }
+                else {
+                    Doc.setDocFilter(this.props.Document, this._key, temp, "match");
+                    this.props.col.setColor("green");
+                }
+            }
+            else {
+                let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+                const blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+                keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
+                if (keyOptions.length) {
+                    this.onSelect(keyOptions[0]);
+                    console.log("case1");
+                } else if (this._searchTerm !== "" && this.props.canAddNew) {
+                    this.setSearchTerm(this._searchTerm || this._key);
+                    console.log("case2");
+                    this.onSelect(this._searchTerm);
+                }
             }
         }
     }
@@ -410,7 +423,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             return <></>;
         }
 
-        let keyOptions: string[] = [];
+        const keyOptions: string[] = [];
         const colpos = this._searchTerm.indexOf(":");
         const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
         if (this.docSafe.length === 0) {
@@ -494,7 +507,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     render() {
         return (
             <div style={{ display: "flex" }}>
-                <FontAwesomeIcon onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+                <FontAwesomeIcon onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
 
                 {/* <FontAwesomeIcon icon={fa.faSearchMinus} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} onClick={e => {
                     runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen })
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 8d87a3ba2..a2c529a21 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -320,7 +320,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             const newSchemaHeaders = oldSchemaHeaders.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
             this.props.Document._schemaHeaders = new List<SchemaHeaderField>(newSchemaHeaders);
         } else if (this.props.Document._schemaHeaders === undefined) {
-            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb"), new SchemaHeaderField("author", "#f1efeb"), new SchemaHeaderField("*lastModified", "#f1efeb")]);
+            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb"), new SchemaHeaderField("author", "#f1efeb"), new SchemaHeaderField("*lastModified", "#f1efeb"),
+            new SchemaHeaderField("text", "#f1efeb"), new SchemaHeaderField("type", "#f1efeb"), new SchemaHeaderField("context", "#f1efeb")]);
         }
     }
 
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 35b383a27..770a03cb1 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -626,6 +626,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) {
                 this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
                     // happens at the beginning
+                    this.realTotalResults = res.numFound;
                     if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
                         this._numTotalResults = res.numFound;
                     }
@@ -716,6 +717,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._searchbarOpen = true;
     }
 
+    realTotalResults: number = 0;
+
     @action.bound
     closeSearch = () => {
         //this.closeResults();
@@ -877,6 +880,13 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             <FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
                                 style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} />
                         </div></Tooltip>
+                        <div style={{
+                            position: "relative",
+                            left: 245,
+                            zIndex: 9000,
+                            color: "grey",
+                            background: "white",
+                        }}> {`${this._results.length}` + " of " + `${this.realTotalResults}`}</div>
                         <div style={{ cursor: "default", left: 250, position: "relative", }}>
                             <Tooltip title={<div className="dash-tooltip" >only display documents matching search</div>} ><div>
                                 <FontAwesomeIcon icon={"filter"} size="lg"
@@ -1031,7 +1041,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                                     removeDocument={returnFalse}
                                     PanelHeight={this.open === true ? () => height : () => 0}
                                     PanelWidth={this.open === true ? () => length : () => 0}
-                                    overflow={length > screen.width || rows > 6 ? true : false}
+                                    overflow={length > window.innerWidth || rows > 6 ? true : false}
                                     focus={this.selectElement}
                                     ScreenToLocalTransform={Transform.Identity}
                                 />
-- 
cgit v1.2.3-70-g09d2

