From a4555fb8d5cd64482dd8431aad03878cb173f688 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 1 Sep 2020 03:58:41 -0400
Subject: fixed following link to a doc that is in a hidden tab to show that
 tab.  fixed linear view to hit content bounds accurately.  fixed editing of
 text in tabs somewhat.  fixed place ment of link anchor boxes for topMost
 views.

---
 src/client/views/search/SearchBox.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 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 d08cc7f5b..c04b1da10 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -102,7 +102,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             this._curRequest = undefined;
             this._maxSearchIndex = 0;
         }
-    })
+    });
 
     enter = action((e: React.KeyboardEvent | undefined) => {
         if (!e || e.key === "Enter") {
@@ -378,7 +378,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             Doc.ClearSearchMatches();
         });
         close && (this.open = this._searchbarOpen = false);
-    })
+    });
 
     @action.bound
     closeResults() {
@@ -483,7 +483,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             collectionView.props.Document._searchFilterDocs = docsForFilter?.length ? new List<Doc>(docsForFilter) : undefined;
             collectionView.props.Document._docFilters = docsForFilter?.length && docFilters?.length ? new List<string>(docFilters) : undefined;
         }
-    })
+    });
 
     render() {
         const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
-- 
cgit v1.2.3-70-g09d2


From 25d8d43425785038a74acbc9be618b70f48bbba0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 1 Sep 2020 17:43:59 -0400
Subject: fixed search bar getting stuck open. fixed search for fields in full
 db.

---
 src/client/util/SearchUtil.ts                            | 3 ++-
 src/client/views/collections/CollectionSchemaHeaders.tsx | 2 --
 src/client/views/nodes/LabelBox.scss                     | 1 +
 src/client/views/search/SearchBox.tsx                    | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

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

diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index afa8ff575..b34acce27 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -41,7 +41,8 @@ export namespace SearchUtil {
         const rpquery = Utils.prepend("/dashsearch");
         let replacedQuery = query.replace(/type_t:([^ )])/g, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
         if (options.onlyAliases) {
-            replacedQuery = `{!join from=id to=proto_i}DEFAULT:${replacedQuery}`;
+            const header = query.match(/_[atnb]?:/) ? replacedQuery : "DEFAULT:" + replacedQuery;
+            replacedQuery = `{!join from=id to=proto_i}${header}`;
         }
         const gotten = await rp.get(rpquery, { qs: { ...options, q: replacedQuery } });
         const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index cecee1de3..94f9d4f92 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -352,7 +352,6 @@ 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
 
         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",
@@ -458,7 +457,6 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     updateFilter() {
         const filters = Cast(this.props.Document._docFilters, listSpec("string"));
         if (filters === undefined || filters.length === 0 || filters.includes(this._key) === false) {
-            console.log("PLEASE");
             this.props.col.setColor("rgb(241, 239, 235)");
             this.closeResultsVisibility = "none";
         }
diff --git a/src/client/views/nodes/LabelBox.scss b/src/client/views/nodes/LabelBox.scss
index b605df262..109a02df4 100644
--- a/src/client/views/nodes/LabelBox.scss
+++ b/src/client/views/nodes/LabelBox.scss
@@ -8,6 +8,7 @@
 }
 
 .labelBox-mainButton {
+    max-width: 100%;
     width: fit-content;
     height: max-content;
     border-radius: inherit;
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c04b1da10..e6fd64a3c 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -250,7 +250,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             this._numTotalResults = -1;
             this._searchFullDB ? await this.searchDatabase(query) : this.searchCollection(query);
             runInAction(() => {
-                this._searchbarOpen = true;
+                this.open = this._searchbarOpen = true;
                 this.resultsScrolled();
             });
         }
-- 
cgit v1.2.3-70-g09d2


From 4ab5484797ccc39a4e7924135f92259c2b15d88f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 1 Sep 2020 23:15:55 -0400
Subject: trying new solr schema that splits words on whitespace.  fixed
 context menu clicking in schema/search view.

---
 solr-8.3.1/server/solr/dash/conf/characters.txt    |  3 +++
 solr-8.3.1/server/solr/dash/conf/schema.xml        | 24 +++++++++++++---------
 src/client/util/SearchUtil.ts                      |  4 ++--
 src/client/views/MainView.tsx                      |  4 +++-
 src/client/views/PropertiesView.tsx                | 15 +++++++++++---
 .../CollectionSchemaMovableTableHOC.tsx            |  1 +
 src/client/views/search/SearchBox.tsx              |  2 +-
 src/server/ApiManagers/SearchManager.ts            |  2 +-
 src/server/Search.ts                               |  5 ++---
 9 files changed, 39 insertions(+), 21 deletions(-)
 create mode 100644 solr-8.3.1/server/solr/dash/conf/characters.txt

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

diff --git a/solr-8.3.1/server/solr/dash/conf/characters.txt b/solr-8.3.1/server/solr/dash/conf/characters.txt
new file mode 100644
index 000000000..3a4c81bc8
--- /dev/null
+++ b/solr-8.3.1/server/solr/dash/conf/characters.txt
@@ -0,0 +1,3 @@
+\# => ALPHA
+@ => ALPHA
+\u0023 => ALPHA
\ No newline at end of file
diff --git a/solr-8.3.1/server/solr/dash/conf/schema.xml b/solr-8.3.1/server/solr/dash/conf/schema.xml
index 74c4b494c..11078caeb 100644
--- a/solr-8.3.1/server/solr/dash/conf/schema.xml
+++ b/solr-8.3.1/server/solr/dash/conf/schema.xml
@@ -5,19 +5,23 @@
   <fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true">
         <tokenizer class="solr.KeywordTokenizerFactory"/>
   </fieldType>
-  <fieldType name="text" class="solr.TextField">
+  <fieldType name="text" class="solr.TextField" positionIncrementGap="100" multiValued="true">
     <analyzer type="index">
-      <tokenizer class="solr.StandardTokenizerFactory"/>
-      <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
-      <filter class="solr.LowerCaseFilterFactory"/>
-      <filter class="solr.PorterStemFilterFactory"/>
-      <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="12"/>
+        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+      <!-- <tokenizer class="solr.StandardTokenizerFactory"/> -->
+        <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
+        <filter class="solr.LowerCaseFilterFactory"/>
+        <filter class="solr.PorterStemFilterFactory"/>
+        <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="12"/>
+        <!-- <filter catenateAll="0" catenateNumbers="0" catenateWords="0" class="solr.WordDelimiterFilterFactory" generateNumberParts="1" generateWordParts="1" splitOnCaseChange="1" types="characters.txt"/> -->
     </analyzer>
     <analyzer type="query">
-      <tokenizer class="solr.StandardTokenizerFactory"/>
-      <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
-      <filter class="solr.LowerCaseFilterFactory"/>
-      <filter class="solr.PorterStemFilterFactory"/>
+        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+      <!-- <tokenizer class="solr.StandardTokenizerFactory"/> -->
+        <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
+        <filter class="solr.LowerCaseFilterFactory"/>
+        <filter class="solr.PorterStemFilterFactory"/>
+        <!-- <filter catenateAll="0" catenateNumbers="0" catenateWords="0" class="solr.WordDelimiterFilterFactory" generateNumberParts="1" generateWordParts="1" splitOnCaseChange="1" types="characters.txt"/> -->
     </analyzer>
   </fieldType>
   <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index b34acce27..b09eff849 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -23,7 +23,7 @@ export namespace SearchUtil {
     }
 
     export interface SearchParams {
-        hl?: boolean;
+        hl?: string;
         "hl.fl"?: string;
         start?: number;
         rows?: number;
@@ -39,7 +39,7 @@ 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");
-        let replacedQuery = query.replace(/type_t:([^ )])/g, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
+        let replacedQuery = query.replace(/type_t:([^ )])/g, (substring, arg) => `{!join from=id to=proto_i}*:* AND ${arg}`);
         if (options.onlyAliases) {
             const header = query.match(/_[atnb]?:/) ? replacedQuery : "DEFAULT:" + replacedQuery;
             replacedQuery = `{!join from=id to=proto_i}${header}`;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 7dddd1669..6db518f1e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -55,6 +55,7 @@ import { PDFMenu } from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
 import { PropertiesView } from './PropertiesView';
 import { SearchBox } from './search/SearchBox';
+import { TraceMobx } from '../../fields/util';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -152,7 +153,7 @@ export class MainView extends React.Component {
         const targets = document.elementsFromPoint(e.x, e.y);
         if (targets.length) {
             const targClass = targets[0].className.toString();
-            if (SearchBox.Instance._searchbarOpen) {
+            if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
                     (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
                         thing.className === "collectionSchema-header-menuOptions"));
@@ -520,6 +521,7 @@ export class MainView extends React.Component {
     }
 
     @computed get search() {
+        TraceMobx();
         return <div className="mainView-searchPanel">
             <DocumentView Document={CurrentUserUtils.MySearchPanelDoc}
                 DataDoc={undefined}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index b9d7bd18d..ddc76d373 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -178,7 +178,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => dv.dataDoc);
             docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
             const rows: JSX.Element[] = [];
-            const noviceReqFields = ["author", "creationDate"];
+            const noviceReqFields = ["author", "creationDate", "tags"];
             const noviceLayoutFields = ["_curPage"];
             const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL"))),
             ...noviceReqFields, ...noviceLayoutFields];
@@ -234,11 +234,20 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         docs.forEach(doc => {
             if (value.indexOf(":") !== -1) {
                 const newVal = value[0].toUpperCase() + value.substring(1, value.length);
-                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                const splits = newVal.split(":");
+                KeyValueBox.SetField(doc, splits[0], splits[1], true);
+                const tags = StrCast(doc.tags, ":");
+                if (tags.includes(`${splits[0]}:`) && splits[1] === "undefined") {
+                    KeyValueBox.SetField(doc, "tags", `"${tags.replace(splits[0] + ":", "")}"`, true);
+                }
                 return true;
             } else if (value[0] === "#") {
                 const newVal = value + `:'${value}'`;
-                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                KeyValueBox.SetField(doc, value, `'${value}'`, true);
+                const tags = StrCast(doc.tags, ":");
+                if (!tags.includes(`#${value}:`)) {
+                    KeyValueBox.SetField(doc, "tags", `"${tags + value + ':'}"`, true);
+                }
                 return true;
             }
         });
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 383a9312f..881246bd4 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -201,6 +201,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
     }
 
     onRowContextMenu = (e: React.MouseEvent): void => {
+        e.preventDefault();
         const description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
         ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
     }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index e6fd64a3c..3d564f073 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -286,7 +286,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         this._lockPromise && (await this._lockPromise);
         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, { onlyAliases: true, allowAliases: true, /*sort: this.primarySort,*/ fq: this.filterQuery, start: 0, rows: this._numResultsPerPage, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
+                this._curRequest = SearchUtil.Search(query, true, { onlyAliases: true, allowAliases: true, /*sort: this.primarySort,*/ fq: this.filterQuery, start: 0, rows: this._numResultsPerPage, hl: "on", "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
                     // happens at the beginning
                     this.realTotalResults = res.numFound <= 0 ? 0 : res.numFound;
                     if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index a5aaab63e..a52430ee8 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -62,7 +62,7 @@ export class SearchManager extends ApiManager {
             subscription: "/dashsearch",
             secureHandler: async ({ req, res }) => {
                 const solrQuery: any = {};
-                ["q", "fq", "start", "rows", "sort", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
+                ["q", "fq", "start", "rows", "sort", "hl.maxAnalyzedChars", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
                 if (solrQuery.q === undefined) {
                     res.send([]);
                     return;
diff --git a/src/server/Search.ts b/src/server/Search.ts
index 3869867cd..68f61deb2 100644
--- a/src/server/Search.ts
+++ b/src/server/Search.ts
@@ -29,9 +29,8 @@ export namespace Search {
 
     export async function search(query: any) {
         try {
-            const searchResults = JSON.parse(await rp.get(pathTo("select"), {
-                qs: query
-            }));
+            const output = await rp.get(pathTo("select"), { qs: query });
+            const searchResults = JSON.parse(output);
             const { docs, numFound } = searchResults.response;
             const ids = docs.map((field: any) => field.id);
             return { ids, numFound, highlighting: searchResults.highlighting };
-- 
cgit v1.2.3-70-g09d2

