aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json183
-rw-r--r--package.json2
-rw-r--r--solr-8.3.1/CHANGES.txt2
-rw-r--r--solr-8.3.1/bin/solr-8983.pid2
-rw-r--r--solr-8.3.1/server/solr/dash/conf/schema.xml3
-rw-r--r--src/client/documents/DocumentTypes.ts3
-rw-r--r--src/client/documents/Documents.ts28
-rw-r--r--src/client/util/CurrentUserUtils.ts11
-rw-r--r--src/client/util/Scripting.ts2
-rw-r--r--src/client/util/SearchUtil.ts4
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx5
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx5
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx4
-rw-r--r--src/client/views/nodes/LabelBox.tsx18
-rw-r--r--src/client/views/nodes/QueryBox.tsx71
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx45
-rw-r--r--src/client/views/pdf/PDFViewer.tsx23
-rw-r--r--src/client/views/search/SearchBox.scss60
-rw-r--r--src/client/views/search/SearchBox.tsx772
-rw-r--r--src/client/views/search/SearchItem.scss33
-rw-r--r--src/client/views/search/SearchItem.tsx330
-rw-r--r--src/fields/Doc.ts2
-rw-r--r--src/server/ApiManagers/SearchManager.ts2
-rw-r--r--src/server/ApiManagers/UploadManager.ts36
-rw-r--r--src/server/websocket.ts19
27 files changed, 1258 insertions, 411 deletions
diff --git a/package-lock.json b/package-lock.json
index 9ef83c537..062ea26f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -921,15 +921,6 @@
"@types/prosemirror-transform": "*"
}
},
- "@types/puppeteer": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-2.1.0.tgz",
- "integrity": "sha512-QIRQXl0VaSgnwOZ1LwxD321Tfb1jLOzCWuF2BrwjEkWq2IhxSicPOddUywLV7dRSO6mcU4sWKRdoGdci6gk0Aw==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
- },
"@types/qs": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz",
@@ -1239,15 +1230,6 @@
"integrity": "sha512-3gJTS9gt27pS7U9q5IVqo4YvKSlkf2ck8ish6etuDj6LIRxkL/2Y8RMUtK/QzvE1Yv2zwWV5yemI2BS0GGGFnA==",
"dev": true
},
- "@types/yauzl": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
- "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
- "optional": true,
- "requires": {
- "@types/node": "*"
- }
- },
"@types/youtube": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.39.tgz",
@@ -2893,7 +2875,8 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -2911,11 +2894,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2928,15 +2913,18 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3039,7 +3027,8 @@
},
"inherits": {
"version": "2.0.4",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -3049,6 +3038,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3061,17 +3051,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.5",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3088,6 +3081,7 @@
"mkdirp": {
"version": "0.5.3",
"bundled": true,
+ "optional": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -3143,7 +3137,8 @@
},
"npm-normalize-package-bin": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"npm-packlist": {
"version": "1.4.8",
@@ -3168,7 +3163,8 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -3178,6 +3174,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3246,7 +3243,8 @@
},
"safe-buffer": {
"version": "5.1.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3276,6 +3274,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3293,6 +3292,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3331,11 +3331,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"yallist": {
"version": "3.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
}
}
}
@@ -5715,35 +5717,6 @@
}
}
},
- "extract-zip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz",
- "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==",
- "requires": {
- "@types/yauzl": "^2.9.1",
- "debug": "^4.1.1",
- "get-stream": "^5.1.0",
- "yauzl": "^2.10.0"
- },
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "get-stream": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
- "requires": {
- "pump": "^3.0.0"
- }
- }
- }
- },
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -5793,14 +5766,6 @@
"ua-parser-js": "^0.7.18"
}
},
- "fd-slicer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
- "requires": {
- "pend": "~1.2.0"
- }
- },
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@@ -13353,11 +13318,6 @@
"worker-loader": "^2.0.0"
}
},
- "pend": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
- },
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -13638,11 +13598,6 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
- "progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
- },
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
@@ -13782,11 +13737,6 @@
"ipaddr.js": "1.9.1"
}
},
- "proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- },
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -13973,52 +13923,6 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
- "puppeteer": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.1.0.tgz",
- "integrity": "sha512-jLa9sqdVx0tPnr2FcwAq+8DSjGhSM4YpkwOf3JE22Ycyqm71SW7B5uGfTyMGFoLCmbCozbLZclCjasPb0flTRw==",
- "requires": {
- "debug": "^4.1.0",
- "extract-zip": "^2.0.0",
- "https-proxy-agent": "^4.0.0",
- "mime": "^2.0.3",
- "progress": "^2.0.1",
- "proxy-from-env": "^1.0.0",
- "rimraf": "^3.0.2",
- "tar-fs": "^2.0.0",
- "unbzip2-stream": "^1.3.3",
- "ws": "^7.2.3"
- },
- "dependencies": {
- "agent-base": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
- "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g=="
- },
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "https-proxy-agent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
- "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==",
- "requires": {
- "agent-base": "5",
- "debug": "4"
- }
- },
- "mime": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
- "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w=="
- }
- }
- },
"pure-color": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz",
@@ -16319,11 +16223,6 @@
"resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz",
"integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q=="
},
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
- },
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
@@ -16836,15 +16735,6 @@
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
"integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
},
- "unbzip2-stream": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz",
- "integrity": "sha512-pZMVAofMrrHX6Ik39hCk470kulCbmZ2SWfQLPmTWqfJV/oUm0gn1CblvHdUu4+54Je6Jq34x8kY6XjTy6dMkOg==",
- "requires": {
- "buffer": "^5.2.1",
- "through": "^2.3.8"
- }
- },
"undefsafe": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
@@ -18346,15 +18236,6 @@
"yargs": "^13.3.0"
}
},
- "yauzl": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
- "requires": {
- "buffer-crc32": "~0.2.3",
- "fd-slicer": "~1.1.0"
- }
- },
"yeast": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
diff --git a/package.json b/package.json
index 096c26cd0..90141c321 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,6 @@
"@types/prosemirror-state": "^1.2.3",
"@types/prosemirror-transform": "^1.1.1",
"@types/prosemirror-view": "^1.11.2",
- "@types/puppeteer": "^2.1.0",
"@types/rc-switch": "^1.9.0",
"@types/react": "^16.9.19",
"@types/react-autosuggest": "^9.3.13",
@@ -200,7 +199,6 @@
"prosemirror-transform": "^1.2.3",
"prosemirror-view": "^1.13.8",
"pug": "^2.0.4",
- "puppeteer": "^3.1.0",
"query-string": "^6.10.1",
"raw-loader": "^1.0.0",
"rc-switch": "^1.9.0",
diff --git a/solr-8.3.1/CHANGES.txt b/solr-8.3.1/CHANGES.txt
index 219888b49..78ee2efc1 100644
--- a/solr-8.3.1/CHANGES.txt
+++ b/solr-8.3.1/CHANGES.txt
@@ -66,7 +66,7 @@ Upgrade Notes
----------------------
* Users who have written test cases that extend SolrTestCaseJ4 may see NullPointerExceptions if
- their tests directly reference both SolrTestCaseJ4.initCoreDataDir and SolrTestCaseJ4.deleteCore().
+ their tests directly reference both SolrTestCaseJ4.initCoreDataDir and TestCaseJ4.deleteCore().
This change in behavior is due to a bug fix in deleteCore() to ensure the dataDir is properly reset
in tests that call initCore()/deleteCore() multiple times in a given test (class). initCoreDataDir
is now deprecated, and users are encouraged to use SolrTestCaseJ4.initAndGetDataDir() in it's place.
diff --git a/solr-8.3.1/bin/solr-8983.pid b/solr-8.3.1/bin/solr-8983.pid
index 779eb1af5..6a21a128a 100644
--- a/solr-8.3.1/bin/solr-8983.pid
+++ b/solr-8.3.1/bin/solr-8983.pid
@@ -1 +1 @@
-17656
+918
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 c0a4bab07..36e803d83 100644
--- a/solr-8.3.1/server/solr/dash/conf/schema.xml
+++ b/solr-8.3.1/server/solr/dash/conf/schema.xml
@@ -44,6 +44,9 @@
<field name="text" type="text" indexed="true" stored="false" uninvertible="false" multiValued="true"/>
<field name="id" type="string" indexed="true" stored="true" uninvertible="false" required="true"/>
<field name="_version_" type="plong" indexed="true" stored="true"/>
+ <field name="proto" type="string" indexed="true" stored="true" uninvertible="false" />
+ <field name="_height" type="pdouble" indexed="true" stored="true" uninvertible="false" docValues="true"/>
+
<dynamicField name="*_t" type="text" indexed="true" stored="true" uninvertible="false" docValues="false"/>
<dynamicField name="*_n" type="pdouble" indexed="true" stored="true" uninvertible="false" docValues="false"/>
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 7ba21b2f6..454fb2ad2 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -13,7 +13,7 @@ export enum DocumentType {
INK = "ink", // ink stroke
SCREENSHOT = "screenshot", // view of a desktop application
FONTICON = "fonticonbox", // font icon
- QUERY = "query", // search query
+ SEARCH = "search", // search query
LABEL = "label", // simple text label
BUTTON = "button", // onClick button
WEBCAM = "webcam", // webcam
@@ -31,6 +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",
COMPARISON = "comparison", // before/after view with slider (view of 2 images)
LINKDB = "linkdb", // database of links ??? why do we have this
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index dac3a1aaa..c32d187a0 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -19,6 +19,11 @@ import { LinkManager } from "../util/LinkManager";
import { Scripting } from "../util/Scripting";
import { UndoManager } from "../util/UndoManager";
import { DocumentType } from "./DocumentTypes";
+import { filterData} from "../views/search/SearchBox";
+//import { PresBox } from "../views/nodes/PresBox";
+//import { PresField } from "../../new_fields/PresField";
+import { SearchItem } from "../views/search/SearchItem";
+import { SearchBox } from "../views/search/SearchBox";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
import { ContextMenu } from "../views/ContextMenu";
@@ -176,10 +181,12 @@ export interface DocumentOptions {
flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse";
selectedIndex?: number;
syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text
- searchText?: string; //for searchbox
- searchQuery?: string; // for queryBox
- filterQuery?: string;
+ searchText?: string, //for searchbox
+ searchQuery?: string, // for quersyBox
+ filterQuery?: filterData,
linearViewIsExpanded?: boolean; // is linear view expanded
+ border?: string; //for searchbox
+ hovercolor?:string;
}
class EmptyBox {
@@ -209,8 +216,8 @@ export namespace Docs {
layout: { view: FormattedTextBox, dataField: "text" },
options: { _height: 150, _xMargin: 10, _yMargin: 10 }
}],
- [DocumentType.QUERY, {
- layout: { view: QueryBox, dataField: defaultDataKey },
+ [DocumentType.SEARCH, {
+ layout: { view: SearchBox, dataField: defaultDataKey },
options: { _width: 400 }
}],
[DocumentType.COLOR, {
@@ -300,6 +307,9 @@ export namespace Docs {
[DocumentType.PRESELEMENT, {
layout: { view: PresElementBox, dataField: defaultDataKey }
}],
+ [DocumentType.SEARCHITEM, {
+ layout: { view: SearchItem, dataField: defaultDataKey }
+ }],
[DocumentType.INK, {
layout: { view: InkingStroke, dataField: defaultDataKey },
options: { backgroundColor: "transparent" }
@@ -596,8 +606,8 @@ export namespace Docs {
return instance;
}
- export function QueryDocument(options: DocumentOptions = {}) {
- return InstanceFromProto(Prototypes.get(DocumentType.QUERY), "", options);
+ export function SearchDocument(options: DocumentOptions = {}) {
+ return InstanceFromProto(Prototypes.get(DocumentType.SEARCH), new List<Doc>([]), options);
}
export function ColorDocument(options: DocumentOptions = {}) {
@@ -760,6 +770,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) });
}
+ export function SearchItemBoxDocument(options?: DocumentOptions) {
+ return InstanceFromProto(Prototypes.get(DocumentType.SEARCHITEM), undefined, { ...(options || {}) });
+ }
+
export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
Doc.GetProto(inst).data = new List<Doc>(documents);
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index fc73dbf58..a7cb29815 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -42,7 +42,7 @@ export class CurrentUserUtils {
if (doc["template-button-query"] === undefined) {
const queryTemplate = Docs.Create.MulticolumnDocument(
[
- Docs.Create.QueryDocument({ title: "query", _height: 200 }),
+ Docs.Create.SearchDocument({ _viewType: CollectionViewType.Stacking, title: "query", _height: 200 }),
Docs.Create.FreeformDocument([], { title: "data", _height: 100, _LODdisable: true })
],
{ _width: 400, _height: 300, title: "queryView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true }
@@ -386,7 +386,7 @@ export class CurrentUserUtils {
{ title: "Drag a audio recorder", label: "Audio", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` },
{ title: "Drag a clickable button", label: "Btn", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding:10, _yPadding: 10, title: "Button" })' },
{ title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc },
- { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' },
+ { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.SearchDocument({ _width: 200, title: "an image of a cat" })' },
{ title: "Drag a scripting box", label: "Script", icon: "terminal", ignoreClick: true, drag: 'Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250 title: "untitled script" })' },
{ title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' },
{ title: "Drag a mobile view", label: "Phone", icon: "phone", ignoreClick: true, drag: 'Doc.UserDoc().activeMobile' },
@@ -628,7 +628,7 @@ export class CurrentUserUtils {
doc["tabs-button-search"] = new PrefetchProxy(Docs.Create.ButtonDocument({
_width: 50, _height: 25, title: "Search", _fontSize: 10,
letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
- sourcePanel: new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc,
+ sourcePanel: new PrefetchProxy(Docs.Create.SearchDocument({_viewType: CollectionViewType.Stacking, title: "sidebar search stack", })) as any as Doc,
searchFileTypes: new List<string>([DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.VID, DocumentType.WEB, DocumentType.SCRIPTING]),
targetContainer: new PrefetchProxy(sidebarContainer) as any as Doc,
lockedPosition: true,
@@ -704,6 +704,11 @@ export class CurrentUserUtils {
// the initial presentation Doc to use
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"
+ }));
+ }
if (doc.activePresentation === undefined) {
doc.activePresentation = Docs.Create.PresDocument(new List<Doc>(), {
title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias",
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index e6cf50de3..09e2aa56b 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -136,7 +136,7 @@ export function scriptingGlobal(constructor: { new(...args: any[]): any }) {
Scripting.addGlobal(constructor);
}
-const _scriptingGlobals: { [name: string]: any } = {};
+export const _scriptingGlobals: { [name: string]: any } = {};
let scriptingGlobals: { [name: string]: any } = _scriptingGlobals;
const _scriptingDescriptions: { [name: string]: any } = {};
const _scriptingParams: { [name: string]: any } = {};
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 5679c0a14..e4c4f5fb7 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -4,6 +4,7 @@ import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { Utils } from '../../Utils';
import { DocumentType } from '../documents/DocumentTypes';
+import { StringMap } from 'libxmljs';
export namespace SearchUtil {
export type HighlightingResult = { [id: string]: { [key: string]: string[] } };
@@ -29,6 +30,8 @@ export namespace SearchUtil {
rows?: number;
fq?: string;
allowAliases?: boolean;
+ "facet"?:string;
+ "facet.field"?: string;
}
export function Search(query: string, returnDocs: true, options?: SearchParams): Promise<DocSearchResult>;
export function Search(query: string, returnDocs: false, options?: SearchParams): Promise<IdSearchResult>;
@@ -128,7 +131,6 @@ export namespace SearchUtil {
});
const result: IdSearchResult = JSON.parse(response);
const { ids, numFound, highlighting } = result;
- //console.log(ids.length);
const docMap = await DocServer.GetRefFields(ids);
const docs: Doc[] = [];
for (const id of ids) {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4aab43b08..9f6643ee0 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -49,6 +49,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
@computed get xMargin() { return NumCast(this.props.Document._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
@computed get yMargin() { return Math.max(this.props.Document._showTitle && !this.props.Document._showTitleHover ? 30 : 0, NumCast(this.props.Document._yMargin, 0)); } // 2 * this.gridGap)); }
@computed get gridGap() { return NumCast(this.props.Document._gridGap, 10); }
+ @computed get searchDoc() { return BoolCast(this.props.Document._searchDoc, false); }
+
@computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
@computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@computed get showAddAGroup() { return (this.pivotField && (this.props.Document._chromeStatus !== 'view-mode' && this.props.Document._chromeStatus !== 'disabled')); }
@@ -77,7 +79,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
const dxf = () => this.getDocTransform(d, dref.current!);
this._docXfs.push({ dxf, width, height });
const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
- const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+
+ const style = this.isStackingView ? { width: width(), marginTop: i || this.searchDoc? this.gridGap : 0, marginBottom: this.searchDoc? 10:0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
{this.getDisplayDoc(d, (!d.isTemplateDoc && !d.isTemplateForField && !d.PARAMS) ? undefined : this.props.DataDoc, dxf, width)}
</div>;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 508b9e5e7..ca8b0c14e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -73,7 +73,7 @@ export enum CollectionViewType {
Pile = "pileup"
}
export interface CollectionViewCustomProps {
- filterAddDocument: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
+ filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
childLayoutTemplate?: () => Opt<Doc>; // specify a layout Doc template to use for children of the collection
childLayoutString?: string; // specify a layout string to use for children of the collection
childOpacity?: () => number;
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index f1438fd54..37718e028 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -24,7 +24,8 @@ import { ImageBox } from "./ImageBox";
import { KeyValueBox } from "./KeyValueBox";
import { PDFBox } from "./PDFBox";
import { PresBox } from "./PresBox";
-import { QueryBox } from "./QueryBox";
+import { SearchBox } from "../search/SearchBox";
+import { SearchItem } from "../search/SearchItem"
import { ColorBox } from "./ColorBox";
import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
import { LinkAnchorBox } from "./LinkAnchorBox";
@@ -193,7 +194,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
components={{
FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, SliderBox, FieldView,
CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
- PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, QueryBox,
+ PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, SearchItem,
ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
RecommendationsBox, ScreenshotBox, HTMLtag, ComparisonBox
}}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 71cb18e08..8709e76f4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1185,7 +1185,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
pointerEvents: this.ignorePointerEvents ? "none" : undefined,
color: StrCast(this.layoutDoc.color, "inherit"),
outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
- border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
+ border: this.layoutDoc.border ? StrCast(this.layoutDoc.border) : highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
background: finalColor,
opacity: finalOpacity,
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 305c04a90..a918526ed 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -52,6 +52,10 @@ export interface FieldViewProps {
setVideoBox?: (player: VideoBox) => void;
ContentScaling: () => number;
ChromeHeight?: () => number;
+ childLayoutTemplate?: () => Opt<Doc>;
+ highlighting?: string[];
+ lines?: string[];
+ doc?: Doc;
// properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
height?: number;
width?: number;
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 360ead18e..100e2d61e 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -1,4 +1,6 @@
-import { action } from 'mobx';
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faEdit } from '@fortawesome/free-regular-svg-icons';
+import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast } from '../../../fields/Doc';
@@ -56,17 +58,27 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps, LabelDocument
e.stopPropagation();
}
}
+
+
+
+ @observable backColor= "unset";
+
+ @observable clicked = false;
// (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")")
render() {
const params = Cast(this.paramsDoc["onClick-paramFieldKeys"], listSpec("string"), []);
const missingParams = params?.filter(p => !this.paramsDoc[p]);
params?.map(p => DocListCast(this.paramsDoc[p])); // bcz: really hacky form of prefetching ...
+ console.log(this.backColor);
return (
- <div className="labelBox-outerDiv" ref={this.createDropTarget} onContextMenu={this.specificContextMenu}
+ <div className="labelBox-outerDiv" onClick={()=>runInAction(()=>{this.clicked=!this.clicked; this.clicked? this.backColor=StrCast(this.layoutDoc.hovercolor) : this.backColor ="unset"})} onMouseLeave={()=>runInAction(()=>{ !this.clicked ?this.backColor="unset" : null})}
+ onMouseOver={()=>runInAction(()=>{this.backColor=StrCast(this.layoutDoc.hovercolor);})}ref={this.createDropTarget} onContextMenu={this.specificContextMenu}
style={{ boxShadow: this.layoutDoc.opacity ? StrCast(this.layoutDoc.boxShadow) : "" }}>
<div className="labelBox-mainButton" style={{
background: StrCast(this.layoutDoc.backgroundColor),
- color: StrCast(this.layoutDoc.color, "inherit"),
+ color: StrCast(this.layoutDoc.color),
+ backgroundColor:this.backColor,
+ fontSize: NumCast(this.layoutDoc.fontSize) || "inherit",
fontSize: NumCast(this.layoutDoc._fontSize) || "inherit",
fontFamily: StrCast(this.layoutDoc._fontFamily) || "inherit",
letterSpacing: StrCast(this.layoutDoc.letterSpacing),
diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx
index 0fff0b57f..1b6056be6 100644
--- a/src/client/views/nodes/QueryBox.tsx
+++ b/src/client/views/nodes/QueryBox.tsx
@@ -1,41 +1,38 @@
-import React = require("react");
-import { IReactionDisposer } from "mobx";
-import { observer } from "mobx-react";
-import { documentSchema } from "../../../fields/documentSchemas";
-import { Id } from '../../../fields/FieldSymbols';
-import { makeInterface, listSpec } from "../../../fields/Schema";
-import { StrCast, Cast } from "../../../fields/Types";
-import { ViewBoxAnnotatableComponent } from '../DocComponent';
-import { SearchBox } from "../search/SearchBox";
-import { FieldView, FieldViewProps } from './FieldView';
-import "./QueryBox.scss";
-import { List } from "../../../fields/List";
-import { SnappingManager } from "../../util/SnappingManager";
+// import React = require("react");
+// import { IReactionDisposer } from "mobx";
+// import { observer } from "mobx-react";
+// import { documentSchema } from "../../../new_fields/documentSchemas";
+// import { Id } from '../../../new_fields/FieldSymbols';
+// import { makeInterface, listSpec } from "../../../new_fields/Schema";
+// import { StrCast, Cast } from "../../../new_fields/Types";
+// import { ViewBoxAnnotatableComponent } from '../DocComponent';
+// import { SearchBox } from "../search/SearchBox";
+// import { FieldView, FieldViewProps } from './FieldView';
+// import "./QueryBox.scss";
+// import { List } from "../../../new_fields/List";
+// import { SnappingManager } from "../../util/SnappingManager";
-type QueryDocument = makeInterface<[typeof documentSchema]>;
-const QueryDocument = makeInterface(documentSchema);
+// type QueryDocument = makeInterface<[typeof documentSchema]>;
+// const QueryDocument = makeInterface(documentSchema);
-@observer
-export class QueryBox extends ViewBoxAnnotatableComponent<FieldViewProps, QueryDocument>(QueryDocument) {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(QueryBox, fieldKey); }
- _docListChangedReaction: IReactionDisposer | undefined;
- componentDidMount() {
- }
+// @observer
+// export class QueryBox extends ViewBoxAnnotatableComponent<FieldViewProps, QueryDocument>(QueryDocument) {
+// public static LayoutString(fieldKey: string) { return FieldView.LayoutString(QueryBox, fieldKey); }
+// _docListChangedReaction: IReactionDisposer | undefined;
+// componentDidMount() {
+// }
- componentWillUnmount() {
- this._docListChangedReaction?.();
- }
+// componentWillUnmount() {
+// this._docListChangedReaction?.();
+// }
- render() {
- const dragging = !SnappingManager.GetIsDragging() ? "" : "-dragging";
- return <div className={`queryBox${dragging}`} onWheel={(e) => e.stopPropagation()} >
- <SearchBox
- id={this.props.Document[Id]}
- setSearchQuery={q => this.dataDoc.searchQuery = q}
- searchQuery={StrCast(this.dataDoc.searchQuery)}
- setSearchFileTypes={q => this.dataDoc.searchFileTypes = new List<string>(q)}
- searchFileTypes={Cast(this.dataDoc.searchFileTypes, listSpec("string"), [])}
- filterQquery={StrCast(this.dataDoc.filterQuery)} />
- </div >;
- }
-} \ No newline at end of file
+// render() {
+// const dragging = !SnappingManager.GetIsDragging() ? "" : "-dragging";
+// return <div className={`queryBox${dragging}`} onWheel={(e) => e.stopPropagation()} >
+
+// <SearchBox Document={this.props.Document} />
+// </div >;
+// }
+// }
+
+// //<SearchBox id={this.props.Document[Id]} sideBar={side} Document={this.props.Document} searchQuery={StrCast(this.dataDoc.searchQuery)} filterQuery={this.dataDoc.filterQuery} />
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 134fe6e62..6b522f6d1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -251,21 +251,59 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._editorView.dispatch(tr.addMark(flattened[lastSel].from, flattened[lastSel].to, link));
}
}
- public highlightSearchTerms = (terms: string[]) => {
+ public highlightSearchTerms = (terms: string[])=> {
if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) {
+
const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
const res = terms.filter(t => t).map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
+ let length = res[0].length;
let tr = this._editorView.state.tr;
const flattened: TextSelection[] = [];
res.map(r => r.map(h => flattened.push(h)));
+ if (this._searchIndex>1){
+ this._searchIndex+=-2;
+ }
+ else if (this._searchIndex===1){
+ this._searchIndex=length-1;
+ }
+ else if (this._searchIndex===0){
+ this._searchIndex=length-2;
+ }
+
+ const lastSel = Math.min(flattened.length - 1, this._searchIndex);
+ flattened.forEach((h: TextSelection, ind: number) => tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark));
+ this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex;
+ this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
+ let index = this._searchIndex;
+
+ Doc.GetProto(this.dataDoc).searchIndex = index;
+ Doc.GetProto(this.dataDoc).length=length;
+ }
+ }
+
+ public highlightSearchTerms2 = (terms: string[])=> {
+ if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) {
+
+ const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
+ const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
+ const res = terms.filter(t => t).map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
+ let length = res[0].length;
+ let tr = this._editorView.state.tr;
+ const flattened: TextSelection[] = [];
+ res.map(r => r.map(h => flattened.push(h)));
const lastSel = Math.min(flattened.length - 1, this._searchIndex);
flattened.forEach((h: TextSelection, ind: number) => tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark));
this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex;
this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
+ let index = this._searchIndex;
+
+ Doc.GetProto(this.dataDoc).searchIndex = index;
+ Doc.GetProto(this.dataDoc).length=length;
}
}
+
public unhighlightSearchTerms = () => {
if (this._editorView && (this._editorView as any).docView) {
const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
@@ -684,7 +722,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this.setupEditor(this.config, this.props.fieldKey);
- this._disposers.search = reaction(() => this.rootDoc.searchMatch,
+ this._disposers.search = reaction(() => this.rootDoc.searchMatch2,
+ search => search ? this.highlightSearchTerms2([Doc.SearchQuery()]) : this.unhighlightSearchTerms(),
+ { fireImmediately: true });
+ this._disposers.search2 = reaction(() => this.rootDoc.searchMatch,
search => search ? this.highlightSearchTerms([Doc.SearchQuery()]) : this.unhighlightSearchTerms(),
{ fireImmediately: true });
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 516774f44..4976ffe43 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -103,6 +103,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
private _scrollTopReactionDisposer?: IReactionDisposer;
private _filterReactionDisposer?: IReactionDisposer;
private _searchReactionDisposer?: IReactionDisposer;
+ private _searchReactionDisposer2?: IReactionDisposer;
private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _selectionText: string = "";
@@ -150,6 +151,17 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
this._mainCont.current!.scrollTop = this.layoutDoc._scrollTop || 0;
this._searchReactionDisposer = reaction(() => this.Document.searchMatch, search => {
if (search) {
+ this.search(Doc.SearchQuery(), false);
+ this._lastSearch = Doc.SearchQuery();
+ }
+ else {
+ setTimeout(() => this._lastSearch === "mxytzlaf" && this.search("mxytzlaf", true), 200); // bcz: how do we clear search highlights?
+ this._lastSearch && (this._lastSearch = "mxytzlaf");
+ }
+ }, { fireImmediately: true });
+
+ this._searchReactionDisposer2 = reaction(() => this.Document.searchMatch2, search => {
+ if (search) {
this.search(Doc.SearchQuery(), true);
this._lastSearch = Doc.SearchQuery();
}
@@ -329,7 +341,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
}
@action
prevAnnotation = () => {
+ console.log(this.Index);
this.Index = Math.max(this.Index - 1, 0);
+ console.log(this.Index);
+ console.log(this.allAnnotations);
this.scrollToAnnotation(this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]);
}
@@ -337,6 +352,9 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
nextAnnotation = () => {
this.Index = Math.min(this.Index + 1, this.allAnnotations.length - 1);
this.scrollToAnnotation(this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index]);
+ this.Document.searchIndex = this.Index;
+ this.Document.length=this.allAnnotations.length;
+
}
@action
@@ -403,6 +421,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
phraseSearch: true,
query: searchString
});
+ this.Document.searchIndex = this.Index;
+ this.Document.length=this.allAnnotations.length;
}
else if (this._mainCont.current) {
const executeFind = () => {
@@ -416,7 +436,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
};
this._mainCont.current.addEventListener("pagesloaded", executeFind);
this._mainCont.current.addEventListener("pagerendered", executeFind);
+ this.Document.searchIndex = this.Index;
+ this.Document.length=this.allAnnotations.length;
}
+
}
@action
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index bb62113a1..cd64d71ff 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -45,9 +45,11 @@
&.searchBox-filter {
align-self: stretch;
+ button{
+ transform:none;
+ }
button:hover{
- transform:scale(1.0);
- background:"#121721";
+ transform:none;
}
}
@@ -81,8 +83,6 @@
.no-result {
width: 500px;
background: $light-color-secondary;
- border-color: $intermediate-color;
- border-bottom-style: solid;
padding: 10px;
height: 50px;
text-transform: uppercase;
@@ -96,20 +96,20 @@
background: #121721;
flex-direction: column;
transform-origin: top;
- transition: height 0.3s ease, display 0.6s ease;
+ transition: height 0.3s ease, display 0.6s ease, overflow 0.6s ease;
height:0px;
overflow:hidden;
.filter-header {
- display: flex;
+ //display: flex;
position: relative;
- flex-wrap:wrap;
+ //flex-wrap:wrap;
right: 1px;
color: grey;
- flex-direction: row-reverse;
+ //flex-direction: row-reverse;
transform-origin: top;
- justify-content: space-evenly;
+ //justify-content: space-evenly;
margin-bottom: 5px;
overflow:hidden;
transition:height 0.3s ease-out;
@@ -130,9 +130,7 @@
color: grey;
transform-origin: top;
border-top: 0px;
- //padding-top: 5px;
- margin-left: 10px;
- margin-right: 10px;
+
overflow:hidden;
transition:height 0.3s ease-out;
height:0px;
@@ -144,30 +142,28 @@
color: grey;
transform-origin: top;
border-top: 0px;
- //padding-top: 5px;
- margin-left: 10px;
- margin-right: 10px;
overflow:hidden;
transition:height 0.3s ease-out;
height:0px;
- .filter-keybar {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-evenly;
- height: auto;
- width: 100%;
- flex-direction: row-reverse;
- margin-top:5px;
-
- .filter-item {
- position: relative;
- border:1px solid grey;
- border-radius: 16px;
-
- }
- }
-
+ .labelBox-mainButton:hover{
+ color:"White";
+ }
+ // .filter-keybar {
+ // display: flex;
+ // flex-wrap: wrap;
+ // justify-content: space-evenly;
+ // height: auto;
+ // width: 100%;
+ // flex-direction: row-reverse;
+ // margin-top:5px;
+
+ // .filter-item {
+ // position: relative;
+ // border:1px solid grey;
+ // border-radius: 16px;
+ // }
+ // }
}
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c9d29e485..8449f514a 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -8,29 +8,45 @@ import * as rp from 'request-promise';
import { Doc } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { Utils } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
-import { SetupDrag } from '../../util/DragManager';
+import { Utils, returnTrue, emptyFunction, returnFalse, emptyPath, returnOne, returnEmptyString, returnEmptyFilter } from '../../../Utils';
+import { Docs, DocumentOptions } from '../../documents/Documents';
+import { SetupDrag, DragManager } from '../../util/DragManager';
import { SearchUtil } from '../../util/SearchUtil';
import "./SearchBox.scss";
import { SearchItem } from './SearchItem';
import { IconBar } from './IconBar';
-import { FieldView } from '../nodes/FieldView';
+import { FieldView, FieldViewProps } from '../nodes/FieldView';
import { DocumentType } from "../../documents/DocumentTypes";
import { DocumentView } from '../nodes/DocumentView';
import { SelectionManager } from '../../util/SelectionManager';
+import { FilterQuery } from 'mongodb';
+import { CollectionLinearView } from '../collections/CollectionLinearView';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
+
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import { ScriptField } from '../../../fields/ScriptField';
+import { PrefetchProxy } from '../../../fields/Proxy';
+import { List } from '../../../fields/List';
+import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan, faVideo, faCaretDown } from '@fortawesome/free-solid-svg-icons';
+import { Transform } from '../../util/Transform';
+import { MainView } from "../MainView";
+import { Scripting,_scriptingGlobals } from '../../util/Scripting';
+import { CollectionView, CollectionViewType } from '../collections/CollectionView';
+import { ViewBoxBaseComponent } from "../DocComponent";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, createSchema } from '../../../fields/Schema';
import { listSpec } from '../../../fields/Schema';
+import * as _ from "lodash";
+import { checkIfStateModificationsAreAllowed } from 'mobx/lib/internal';
+
library.add(faTimes);
-export interface SearchProps {
- id: string;
- searchQuery: string;
- filterQquery?: string;
- setSearchQuery: (q: string) => {};
- searchFileTypes: string[];
- setSearchFileTypes: (types: string[]) => {};
-}
+export const searchSchema = createSchema({
+ id: "string",
+ Document: Doc,
+ searchQuery: "string",
+});
export enum Keys {
TITLE = "title",
@@ -38,22 +54,37 @@ export enum Keys {
DATA = "data"
}
+export interface filterData{
+ deletedDocsStatus: boolean;
+ authorFieldStatus: boolean;
+ titleFieldStatus:boolean;
+ basicWordStatus:boolean;
+ icons: string[];
+}
+
+type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
+const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
+
+//React.Component<SearchProps>
@observer
-export class SearchBox extends React.Component<SearchProps> {
+export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
- private get _searchString() { return this.props.searchQuery; }
- private set _searchString(value) { this.props.setSearchQuery(value); }
+ @computed get _searchString() { return this.layoutDoc.searchQuery; }
+ @computed set _searchString(value) { this.layoutDoc.searchQuery=(value); }
@observable private _resultsOpen: boolean = false;
@observable private _searchbarOpen: boolean = false;
@observable private _results: [Doc, string[], string[]][] = [];
@observable private _openNoResults: boolean = false;
@observable private _visibleElements: JSX.Element[] = [];
+ @observable private _visibleDocuments: Doc[] = [];
private _resultsSet = new Map<Doc, number>();
private _resultsRef = React.createRef<HTMLDivElement>();
public inputRef = React.createRef<HTMLInputElement>();
private _isSearch: ("search" | "placeholder" | undefined)[] = [];
+ private _isSorted: ("sorted" | "placeholder" | undefined)[] = [];
+
private _numTotalResults = -1;
private _endIndex = -1;
@@ -63,30 +94,87 @@ export class SearchBox extends React.Component<SearchProps> {
private _curRequest?: Promise<any> = undefined;
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
-
+ private new_buckets: { [characterName: string]: number} = {};
//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 _basicWordStatus: boolean = false;
@observable private _nodeStatus: boolean = false;
@observable private _keyStatus: boolean = false;
+ @observable private newAssign: boolean = true;
constructor(props: any) {
+
super(props);
SearchBox.Instance = this;
+ if (!_scriptingGlobals.hasOwnProperty("handleNodeChange")){
+ Scripting.addGlobal(this.handleNodeChange);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("handleKeyChange")){
+ Scripting.addGlobal(this.handleKeyChange);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("handleWordQueryChange")){
+ Scripting.addGlobal(this.handleWordQueryChange);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("updateIcon")){
+ Scripting.addGlobal(this.updateIcon);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("updateTitleStatus")){
+ Scripting.addGlobal(this.updateTitleStatus);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("updateAuthorStatus")){
+ Scripting.addGlobal(this.updateAuthorStatus);
+ }
+ if (!_scriptingGlobals.hasOwnProperty("updateDeletedStatus")){
+ Scripting.addGlobal(this.updateDeletedStatus);
+ }
+
+
this.resultsScrolled = this.resultsScrolled.bind(this);
- }
- componentDidMount = action(() => {
+ new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template",
+ backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" }));
+
+
+ if (!this.searchItemTemplate) { // create exactly one presElmentBox template to use by any and all presentations.
+ Doc.UserDoc().searchItemTemplate = new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" }));
+ // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
+ // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
+ // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
+ // stored on each pres element.
+ (this.searchItemTemplate as Doc).lookupField = ScriptField.MakeFunction("lookupSearchBoxField(container, field, data)",
+ { field: "string", data: Doc.name, container: Doc.name });
+ }
+ }
+ @observable setupButtons =false;
+ componentDidMount = () => {
+ if (this.setupButtons==false){
+ this.setupDocTypeButtons();
+ this.setupKeyButtons();
+ this.setupDefaultButtons();
+ runInAction(()=>this.setupButtons==true);
+ }
if (this.inputRef.current) {
this.inputRef.current.focus();
- this._searchbarOpen = true;
+ runInAction( () => {this._searchbarOpen = true});
}
- if (this.props.searchQuery) { // bcz: why was this here? } && this.props.filterQquery) {
- this._searchString = this.props.searchQuery;
- this.submitSearch();
+ if (this.rootDoc.searchQuery&& this.newAssign) {
+ const sq = this.rootDoc.searchQuery;
+ runInAction(() => {
+
+ // this._deletedDocsStatus=this.props.filterQuery!.deletedDocsStatus;
+ // this._authorFieldStatus=this.props.filterQuery!.authorFieldStatus
+ // this._titleFieldStatus=this.props.filterQuery!.titleFieldStatus;
+ // this._basicWordStatus=this.props.filterQuery!.basicWordStatus;
+ // this._icons=this.props.filterQuery!.icons;
+ this.newAssign=false;
+ });
+ runInAction(() => {
+ this.layoutDoc._searchString = StrCast(sq);
+ this.submitSearch();
+ });
}
- });
+ };
@action
@@ -94,7 +182,7 @@ export class SearchBox extends React.Component<SearchProps> {
@action.bound
onChange(e: React.ChangeEvent<HTMLInputElement>) {
- this._searchString = e.target.value;
+ this.layoutDoc._searchString = e.target.value;
this._openNoResults = false;
this._results = [];
@@ -108,6 +196,9 @@ export class SearchBox extends React.Component<SearchProps> {
enter = (e: React.KeyboardEvent) => {
if (e.key === "Enter") {
+ if (this._icons!==this._allIcons){
+ runInAction(()=>{this.expandedBucket=false});
+ }
this.submitSearch();
}
}
@@ -134,10 +225,11 @@ export class SearchBox extends React.Component<SearchProps> {
//this also serves as an indicator if the word status filter is applied
@observable private _filterOpen: boolean = false;
//if icons = all icons, then no icon filter is applied
- get _icons() { return this.props.searchFileTypes; }
- set _icons(value) {
- this.props.setSearchFileTypes(value);
- }
+ // get _icons() { return this.props.searchFileTypes; }
+ // set _icons(value) {
+ // this.props.setSearchFileTypes(value);
+ // }
+ @observable _icons: string[] = this._allIcons;
//if all of these are true, no key filter is applied
@observable private _titleFieldStatus: boolean = true;
@observable private _authorFieldStatus: boolean = true;
@@ -162,7 +254,7 @@ export class SearchBox extends React.Component<SearchProps> {
query = query.replace(/\s+/g, ' ').trim();
}
- //if should be searched in a specific collection
+ // if should be searched in a specific collection
if (this._collectionStatus) {
query = this.addCollectionFilter(query);
query = query.replace(/\s+/g, ' ').trim();
@@ -176,15 +268,15 @@ export class SearchBox extends React.Component<SearchProps> {
@action
filterDocsByType(docs: Doc[]) {
- if (this._icons.length === this._allIcons.length) {
- return docs;
- }
const finalDocs: Doc[] = [];
+ const blockedTypes:string[]= ["preselement","docholder","collection","search","searchitem", "script", "fonticonbox", "button", "label"];
docs.forEach(doc => {
const layoutresult = Cast(doc.type, "string");
+ if (layoutresult && !blockedTypes.includes(layoutresult)){
if (layoutresult && this._icons.includes(layoutresult)) {
finalDocs.push(doc);
}
+ }
});
return finalDocs;
}
@@ -277,28 +369,115 @@ export class SearchBox extends React.Component<SearchProps> {
get fieldFiltersApplied() { return !(this._authorFieldStatus && this._titleFieldStatus); }
+ @observable expandedBucket:boolean=false;
@action
- submitSearch = async () => {
- const query = this._searchString;
+ submitSearch = async (reset?:boolean) => {
+ this.checkIcons();
+ if (reset){
+ this.layoutDoc._searchString="";
+ }
+ this.dataDoc[this.fieldKey] = new List<Doc>([]);
+ this.buckets=[];
+ this.new_buckets={};
+ const query = StrCast(this.layoutDoc._searchString);
this.getFinalQuery(query);
this._results = [];
this._resultsSet.clear();
this._isSearch = [];
+ this._isSorted=[];
this._visibleElements = [];
+ this._visibleDocuments = [];
if (query !== "") {
this._endIndex = 12;
this._maxSearchIndex = 0;
this._numTotalResults = -1;
await this.getResults(query);
-
runInAction(() => {
this._resultsOpen = true;
this._searchbarOpen = true;
this._openNoResults = true;
this.resultsScrolled();
+
});
}
}
+
+ @observable firststring: string = "";
+ @observable secondstring: string = "";
+
+ @observable bucketcount:number[]=[];
+
+ @action private makenewbuckets(){
+ console.log("new");
+ let highcount=0;
+ let secondcount=0;
+ this.firststring="";
+ this.secondstring="";
+ this.buckets=[];
+ this.bucketcount=[];
+ this.dataDoc[this.fieldKey] = new List<Doc>([]);
+ for (var key in this.new_buckets){
+ if (this.new_buckets[key]>highcount){
+ secondcount===highcount;
+ this.secondstring=this.firststring;
+ highcount=this.new_buckets[key];
+ this.firststring= key;
+ }
+ else if (this.new_buckets[key]>secondcount){
+ secondcount=this.new_buckets[key];
+ this.secondstring= key;
+ }
+ }
+
+ let bucket = Docs.Create.StackingDocument([],{ _viewType:CollectionViewType.Stacking,title: `default bucket`});
+ bucket._viewType === CollectionViewType.Stacking;
+ bucket._height=185;
+ bucket.bucketfield = "results";
+ bucket.isBucket=true;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, bucket);
+ this.buckets!.push(bucket);
+ this.bucketcount[0]=0;
+
+ if (this.firststring!==""){
+ let firstbucket = Docs.Create.StackingDocument([],{ _viewType:CollectionViewType.Stacking,title: this.firststring });
+ firstbucket._height=185;
+
+ firstbucket._viewType === CollectionViewType.Stacking;
+ firstbucket.bucketfield = this.firststring;
+ firstbucket.isBucket=true;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, firstbucket);
+ this.buckets!.push(firstbucket);
+ this.bucketcount[1]=0;
+
+ }
+
+ if (this.secondstring!==""){
+ let secondbucket = Docs.Create.StackingDocument([],{ _viewType:CollectionViewType.Stacking,title: this.secondstring });
+ secondbucket._height=185;
+ secondbucket._viewType === CollectionViewType.Stacking;
+ secondbucket.bucketfield = this.secondstring;
+ secondbucket.isBucket=true;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, secondbucket);
+ this.buckets!.push(secondbucket);
+ this.bucketcount[2]=0;
+ }
+
+ let webbucket = Docs.Create.StackingDocument([],{ _viewType:CollectionViewType.Stacking,title: this.secondstring });
+ webbucket._height=185;
+ webbucket._viewType === CollectionViewType.Stacking;
+ webbucket.bucketfield = "webs";
+ webbucket.isBucket=true;
+ const textDoc = Docs.Create.WebDocument(`https://bing.com/search?q=${this.layoutDoc._searchString}`, {
+ _width: 200, _nativeHeight: 962, _nativeWidth: 800, isAnnotating: false,
+ title: "bing", UseCors: true
+ });
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, webbucket);
+ Doc.AddDocToList(webbucket, this.props.fieldKey, textDoc);
+
+
+ }
+
+ @observable buckets:Doc[]|undefined;
getAllResults = async (query: string) => {
return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 });
@@ -309,11 +488,11 @@ export class SearchBox extends React.Component<SearchProps> {
const baseExpr = "NOT baseProto_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(" ")})`; // this line was causing issues for me, check solr logging -syip2
+ // const typeExpr = !types ? "" : ` (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})`;
// 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 $/, "");
return query;
- }
+ }
getDataStatus() { return this._deletedDocsStatus; }
@@ -321,17 +500,17 @@ export class SearchBox extends React.Component<SearchProps> {
private NumResults = 25;
private lockPromise?: Promise<void>;
getResults = async (query: string) => {
+ console.log("Get");
if (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, { 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: this.NumResults, 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;
}
-
const highlighting = res.highlighting || {};
const highlightList = res.docs.map(doc => highlighting[doc[Id]]);
const lines = new Map<string, string[]>();
@@ -340,13 +519,25 @@ export class SearchBox extends React.Component<SearchProps> {
const highlights: typeof res.highlighting = {};
docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]);
const filteredDocs = this.filterDocsByType(docs);
+
runInAction(() => {
- //this._results.push(...filteredDocs);
- filteredDocs.forEach(doc => {
+ filteredDocs.forEach((doc,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)) : [];
+ 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]);
@@ -354,6 +545,7 @@ export class SearchBox extends React.Component<SearchProps> {
this._results[index][1].push(...hlights);
this._results[index][2].push(...line);
}
+ }
});
});
@@ -363,6 +555,9 @@ export class SearchBox extends React.Component<SearchProps> {
await this._curRequest;
}
+ if (this._numTotalResults>3 && this.expandedBucket===false){
+ this.makenewbuckets();
+ }
this.resultsScrolled();
res();
});
@@ -371,9 +566,9 @@ export class SearchBox extends React.Component<SearchProps> {
collectionRef = React.createRef<HTMLSpanElement>();
startDragCollection = async () => {
- const res = await this.getAllResults(this.getFinalQuery(this._searchString));
- const filtered = this.filterDocsByType(res.docs);
- const docs = filtered.map(doc => {
+ const res = await this.getAllResults(this.getFinalQuery(StrCast(this.layoutDoc._searchString)));
+ const filtered = this.filterDocsByType(res.docs);
+ const docs = filtered.map(doc => {
const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
if (isProto) {
return Doc.MakeDelegate(doc);
@@ -404,7 +599,14 @@ export class SearchBox extends React.Component<SearchProps> {
y += 300;
}
}
- return Docs.Create.QueryDocument({ _autoHeight: true, title: this._searchString, filterQuery: this.filterQuery, searchQuery: this._searchString });
+ const filter : filterData = {
+ deletedDocsStatus: this._deletedDocsStatus,
+ authorFieldStatus: this._authorFieldStatus,
+ titleFieldStatus: this._titleFieldStatus,
+ basicWordStatus: this._basicWordStatus,
+ icons: this._icons,
+ }
+ return Docs.Create.SearchDocument({ _autoHeight: true, _viewType: CollectionViewType.Stacking , title: StrCast(this.layoutDoc._searchString), filterQuery: filter, searchQuery: StrCast(this.layoutDoc._searchString) });
}
@action.bound
@@ -427,6 +629,7 @@ export class SearchBox extends React.Component<SearchProps> {
this._results = [];
this._resultsSet.clear();
this._visibleElements = [];
+ this._visibleDocuments=[];
this._numTotalResults = -1;
this._endIndex = -1;
this._curRequest = undefined;
@@ -435,15 +638,20 @@ export class SearchBox extends React.Component<SearchProps> {
@action
resultsScrolled = (e?: React.UIEvent<HTMLDivElement>) => {
if (!this._resultsRef.current) return;
+
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 = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this._resultsRef.current.getBoundingClientRect().height / itemHght)));
+ const endIndex= 30;
this._endIndex = endIndex === -1 ? 12 : endIndex;
-
+ this._endIndex=30;
if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
this._visibleElements = [<div className="no-result">No Search Results</div>];
+ //this._visibleDocuments= Docs.Create.
+ let noResult= Docs.Create.TextDocument("",{title:"noResult"})
+ noResult.isBucket =false;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, noResult);
return;
}
@@ -456,16 +664,19 @@ export class SearchBox extends React.Component<SearchProps> {
else 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);
- // indicates if things are placeholders
+ this._visibleDocuments = Array<Doc>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
+ // indicates if things are placeholders
this._isSearch = Array<undefined>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
- }
+ this._isSorted = Array<undefined>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
+ }
for (let i = 0; i < this._numTotalResults; 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>;
}
}
@@ -473,31 +684,109 @@ export class SearchBox extends React.Component<SearchProps> {
if (this._isSearch[i] !== "search") {
let result: [Doc, string[], string[]] | undefined = undefined;
if (i >= this._results.length) {
- this.getResults(this._searchString);
+ 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())]);
- this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />;
- this._isSearch[i] = "search";
- }
+ let lines = new List<string>(result[2]);
+ result[0]._height=46;
+ result[0].lines=lines;
+ result[0].highlighting=highlights.join(", ");
+ this._visibleDocuments[i] = result[0];
+ this._isSearch[i] = "search";
+ if (this._numTotalResults>3 && this.expandedBucket===false){
+ let doctype = StrCast(result[0].type);
+ console.log(doctype);
+ if (doctype=== this.firststring){
+ if (this.bucketcount[1]<3){
+ result[0].parent= this.buckets![1];
+ Doc.AddDocToList(this.buckets![1], this.props.fieldKey, result[0]);
+ this.bucketcount[1]+=1;
+ }
+ }
+ else if (doctype=== this.secondstring){
+ if (this.bucketcount[2]<3){
+ result[0].parent= this.buckets![2];
+ Doc.AddDocToList(this.buckets![2], this.props.fieldKey, result[0]);
+ this.bucketcount[2]+=1;
+ }
+ }
+ else if (this.bucketcount[0]<3){
+ //Doc.AddDocToList(this.buckets![0], this.props.fieldKey, result[0]);
+ //this.bucketcount[0]+=1;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+ }
+ }
+ else {
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+ }
+ }
}
else {
result = this._results[i];
if (result) {
const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
- this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />;
+ let lines = new List<string>(result[2]);
+ result[0]._height=46;
+ result[0].lines= lines;
+ result[0].highlighting=highlights.join(", ");
+ if(i<this._visibleDocuments.length){
+ this._visibleDocuments[i]=result[0];
this._isSearch[i] = "search";
+ if (this._numTotalResults>3 && this.expandedBucket===false){
+
+ if (StrCast(result[0].type)=== this.firststring){
+ if (this.bucketcount[1]<3){
+ result[0].parent= this.buckets![1];
+ Doc.AddDocToList(this.buckets![1], this.props.fieldKey, result[0]);
+ this.bucketcount[1]+=1;
+ }
+ }
+ else if (StrCast(result[0].type)=== this.secondstring){
+ if (this.bucketcount[2]<3){
+ result[0].parent= this.buckets![2];
+ Doc.AddDocToList(this.buckets![2], this.props.fieldKey, result[0]);
+ this.bucketcount[2]+=1;
+ }
+ }
+ else if (this.bucketcount[0]<3){
+ //Doc.AddDocToList(this.buckets![0], this.props.fieldKey, result[0]);
+ //this.bucketcount[0]+=1;
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+ }
+ }
+ else {
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+ }
+ }
}
}
}
}
}
+ if (this._numTotalResults>3 && this.expandedBucket===false){
+ if (this.buckets![0]){
+ this.buckets![0]._height = this.bucketcount[0]*55 + 25;
+ }
+ if (this.buckets![1]){
+ this.buckets![1]._height = this.bucketcount[1]*55 + 25;
+ }
+ if (this.buckets![2]){
+ this.buckets![2]._height = this.bucketcount[2]*55 + 25;
+ }
+ }
if (this._maxSearchIndex >= this._numTotalResults) {
this._visibleElements.length = this._results.length;
+ this._visibleDocuments.length = this._results.length;
this._isSearch.length = this._results.length;
}
}
+ findCommonElements(arr2:string[]) {
+ let arr1= ["layout", "data"];
+ return arr1.some(item => arr2.includes(item))
+ }
+
@computed
get resFull() { return this._numTotalResults <= 8; }
@@ -506,29 +795,48 @@ export class SearchBox extends React.Component<SearchProps> {
//if true, any keywords can be used. if false, all keywords are required.
@action.bound
- handleWordQueryChange = () => {
+ handleWordQueryChange = async() => {
this._basicWordStatus = !this._basicWordStatus;
+ if (this._basicWordStatus) {
+ let doc = await Cast(this.props.Document.keywords, Doc)
+ doc!.backgroundColor= "grey";
+
+ }
+ else {
+ let doc = await Cast(this.props.Document.keywords, Doc)
+ doc!.backgroundColor= "black";
+ }
}
@action.bound
- handleNodeChange = () => {
+ handleNodeChange = async () => {
this._nodeStatus = !this._nodeStatus;
+
if (this._nodeStatus) {
- this.expandSection(`node${this.props.id}`);
+ this.expandSection(`node${this.props.Document[Id]}`);
+ let doc = await Cast(this.props.Document.nodes, Doc)
+ doc!.backgroundColor= "grey";
+
}
else {
- this.collapseSection(`node${this.props.id}`);
+ this.collapseSection(`node${this.props.Document[Id]}`);
+ let doc = await Cast(this.props.Document.nodes, Doc)
+ doc!.backgroundColor= "black";
}
}
@action.bound
- handleKeyChange = () => {
+ handleKeyChange = async () => {
this._keyStatus = !this._keyStatus;
if (this._keyStatus) {
- this.expandSection(`key${this.props.id}`);
+ this.expandSection(`key${this.props.Document[Id]}`);
+ let doc = await Cast(this.props.Document.keys, Doc)
+ doc!.backgroundColor= "grey";
}
else {
- this.collapseSection(`key${this.props.id}`);
+ this.collapseSection(`key${this.props.Document[Id]}`);
+ let doc = await Cast(this.props.Document.keys, Doc)
+ doc!.backgroundColor= "black";
}
}
@@ -536,11 +844,12 @@ export class SearchBox extends React.Component<SearchProps> {
handleFilterChange = () => {
this._filterOpen = !this._filterOpen;
if (this._filterOpen) {
- this.expandSection(`filterhead${this.props.id}`);
- document.getElementById(`filterhead${this.props.id}`)!.style.padding = "5";
+ this.expandSection(`filterhead${this.props.Document[Id]}`);
+ document.getElementById(`filterhead${this.props.Document[Id]}`)!.style.padding = "5";
+ console.log(this.props.Document[Id])
}
else {
- this.collapseSection(`filterhead${this.props.id}`);
+ this.collapseSection(`filterhead${this.props.Document[Id]}`);
}
@@ -553,7 +862,7 @@ export class SearchBox extends React.Component<SearchProps> {
collapseSection(thing: string) {
- const id = this.props.id;
+ const id = this.props.Document[Id];
const element = document.getElementById(thing)!;
// get the height of the element's inner content, regardless of its actual size
const sectionHeight = element.scrollHeight;
@@ -582,7 +891,6 @@ export class SearchBox extends React.Component<SearchProps> {
}
expandSection(thing: string) {
- console.log("expand");
const element = document.getElementById(thing)!;
// get the height of the element's inner content, regardless of its actual size
const sectionHeight = element.scrollHeight;
@@ -617,55 +925,335 @@ export class SearchBox extends React.Component<SearchProps> {
}
@action.bound
- updateTitleStatus() { this._titleFieldStatus = !this._titleFieldStatus; }
+ updateTitleStatus= async () =>{ this._titleFieldStatus = !this._titleFieldStatus;
+ if (this._titleFieldStatus){
+ let doc = await Cast(this.props.Document.title, Doc)
+ doc!.backgroundColor= "grey";
+ }
+ else{
+ let doc = await Cast(this.props.Document.title, Doc)
+ doc!.backgroundColor= "black";
+ }
+ }
@action.bound
- updateAuthorStatus() { this._authorFieldStatus = !this._authorFieldStatus; }
+ updateAuthorStatus=async () => { this._authorFieldStatus = !this._authorFieldStatus;
+ if (this._authorFieldStatus){
+ let doc = await Cast(this.props.Document.author, Doc)
+ doc!.backgroundColor= "grey";
+ }
+ else{
+ let doc = await Cast(this.props.Document.author, Doc)
+ doc!.backgroundColor= "black";
+ }
+ }
@action.bound
- updateDataStatus() { this._deletedDocsStatus = !this._deletedDocsStatus; }
+ updateDeletedStatus=async() =>{ this._deletedDocsStatus = !this._deletedDocsStatus;
+ if (this._deletedDocsStatus){
+ let doc = await Cast(this.props.Document.deleted, Doc)
+ doc!.backgroundColor= "grey";
+ }
+ else{
+ let doc = await Cast(this.props.Document.deleted, Doc)
+ doc!.backgroundColor= "black";
+ }
+ }
+
+ addButtonDoc = (doc: Doc) => Doc.AddDocToList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc);
+ remButtonDoc = (doc: Doc) => Doc.RemoveDocFromList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc);
+ moveButtonDoc = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
+
+ @computed get docButtons() {
+ const nodeBtns = this.props.Document.nodeButtons;
+ let width = () => NumCast(this.props.Document._width);
+ // if (StrCast(this.props.Document.title)==="sidebar search stack"){
+ width = MainView.Instance.flyoutWidthFunc;
+
+ // }
+ if (nodeBtns instanceof Doc) {
+ return <div id="hi" style={{height:"100px",}}>
+ <DocumentView
+ docFilters={returnEmptyFilter}
+ Document={nodeBtns}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={undefined}
+ addDocTab={returnFalse}
+ rootSelected={returnTrue}
+ pinToPres={emptyFunction}
+ onClick={undefined}
+ removeDocument={undefined}
+ ScreenToLocalTransform={this.getTransform}
+ ContentScaling={returnOne}
+ PanelWidth={width}
+ PanelHeight={() => 100}
+ renderDepth={0}
+ backgroundColor={returnEmptyString}
+ focus={emptyFunction}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ NativeHeight={()=>100}
+ NativeWidth={width}
+ />
+ </div>;
+ }
+ return (null);
+ }
+
+ @computed get keyButtons() {
+ const nodeBtns = this.props.Document.keyButtons;
+ let width = () => NumCast(this.props.Document._width);
+ // if (StrCast(this.props.Document.title)==="sidebar search stack"){
+ width = MainView.Instance.flyoutWidthFunc;
+ // }
+ if (nodeBtns instanceof Doc) {
+ return <div id="hi" style={{height:"35px",}}>
+ <DocumentView
+ docFilters={returnEmptyFilter}
+ Document={nodeBtns}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={undefined}
+ addDocTab={returnFalse}
+ rootSelected={returnTrue}
+ pinToPres={emptyFunction}
+ onClick={undefined}
+ removeDocument={undefined}
+ ScreenToLocalTransform={this.getTransform}
+ ContentScaling={returnOne}
+ PanelWidth={width}
+ PanelHeight={() => 100}
+ renderDepth={0}
+ backgroundColor={returnEmptyString}
+ focus={emptyFunction}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ NativeHeight={()=>100}
+ NativeWidth={width}
+ />
+ </div>;
+ }
+ return (null);
+ }
+ @computed get defaultButtons() {
+ const defBtns = this.props.Document.defaultButtons;
+ let width = () => NumCast(this.props.Document._width);
+ // if (StrCast(this.props.Document.title)==="sidebar search stack"){
+ width = MainView.Instance.flyoutWidthFunc;
+ // }
+ if (defBtns instanceof Doc) {
+ return <div id="hi" style={{height:"35px",}}>
+ <DocumentView
+ docFilters={returnEmptyFilter}
+
+ Document={defBtns}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={undefined}
+ addDocTab={returnFalse}
+ rootSelected={returnTrue}
+ pinToPres={emptyFunction}
+ onClick={undefined}
+ removeDocument={undefined}
+ ScreenToLocalTransform={this.getTransform}
+ ContentScaling={returnOne}
+ PanelWidth={width}
+ PanelHeight={() => 100}
+ renderDepth={0}
+ backgroundColor={returnEmptyString}
+ focus={emptyFunction}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ NativeHeight={()=>100}
+ NativeWidth={width}
+ />
+ </div>;
+ }
+ return (null);
+ }
+
+ @action.bound
+ updateIcon= async (icon: string) =>{
+ if (this._icons.includes(icon)){
+ _.pull(this._icons, icon);
+ let cap = icon.charAt(0).toUpperCase() + icon.slice(1)
+ console.log(cap);
+ let doc = await Cast(this.props.Document[cap], Doc)
+ doc!.backgroundColor= "black";
+ }
+ else{
+ this._icons.push(icon);
+ let cap = icon.charAt(0).toUpperCase() + icon.slice(1)
+ let doc = await Cast(this.props.Document[cap], Doc)
+ doc!.backgroundColor= "grey";
+ }
+ }
+
+ @action.bound
+ checkIcons = async ()=>{
+ for (let i=0; i<this._allIcons.length; i++){
+
+ let cap = this._allIcons[i].charAt(0).toUpperCase() + this._allIcons[i].slice(1)
+ let doc = await Cast(this.props.Document[cap], Doc)
+ if (this._icons.includes(this._allIcons[i])){
+ doc!.backgroundColor= "grey";
+ }
+ else{
+ doc!.backgroundColor= "black";
+ }
+ }
+ }
+
+ setupDocTypeButtons() {
+ let doc = this.props.Document;
+ const ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({ ...opts,
+ dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 100, _nativeHeight: 100, _width: 100,
+ _height: 100 })) as any as Doc;
+ doc.Audio = ficon({ onClick: ScriptField.MakeScript(`updateIcon("audio")`), title: "music button", icon: "music" });
+ doc.Collection = ficon({ onClick: ScriptField.MakeScript(`updateIcon("collection")`), title: "col button", icon: "object-group" });
+ doc.Image = ficon({ onClick: ScriptField.MakeScript(`updateIcon("image")`), title: "image button", icon: "image" });
+ doc.Link = ficon({ onClick: ScriptField.MakeScript(`updateIcon("link")`), title: "link button", icon: "link" });
+ doc.Pdf = ficon({ onClick: ScriptField.MakeScript(`updateIcon("pdf")`), title: "pdf button", icon: "file-pdf" });
+ doc.Rtf = ficon({ onClick: ScriptField.MakeScript(`updateIcon("rtf")`), title: "text button", icon: "sticky-note" });
+ doc.Video = ficon({ onClick: ScriptField.MakeScript(`updateIcon("video")`), title: "vid button", icon: "video" });
+ doc.Web = ficon({ onClick: ScriptField.MakeScript(`updateIcon("web")`), title: "web button", icon: "globe-asia" });
+
+ let buttons = [doc.None as Doc, doc.Audio as Doc, doc.Collection as Doc,
+ doc.Image as Doc, doc.Link as Doc, doc.Pdf as Doc, doc.Rtf as Doc, doc.Video as Doc, doc.Web as Doc];
+
+ const dragCreators = Docs.Create.MasonryDocument(buttons, {
+ _width: 500, backgroundColor:"#121721", _autoHeight: true, columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons",
+ dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), _yMargin: 5
+ });
+ doc.nodeButtons= dragCreators;
+ this.checkIcons()
+ }
+
+
+ setupKeyButtons() {
+ let doc = this.props.Document;
+ const button = (opts: DocumentOptions) => new PrefetchProxy( Docs.Create.ButtonDocument({...opts,
+ _width: 35, _height: 30,
+ borderRounding: "16px", border:"1px solid grey", color:"white", hovercolor: "rgb(170, 170, 163)", letterSpacing: "2px",
+ _fontSize: 7,
+ }))as any as Doc;
+ doc.title=button({ backgroundColor:"grey", title: "Title", onClick:ScriptField.MakeScript("updateTitleStatus(self)")});
+ doc.deleted=button({ title: "Deleted", onClick:ScriptField.MakeScript("updateDeletedStatus(self)")});
+ doc.author = button({ backgroundColor:"grey", title: "Author", onClick:ScriptField.MakeScript("updateAuthorStatus(self)")});
+ let buttons = [doc.title as Doc, doc.deleted as Doc, doc.author as Doc];
+
+ const dragCreators = Docs.Create.MasonryDocument(buttons, {
+ _width: 500, backgroundColor:"#121721", _autoHeight: true, columnWidth: 50, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons",_yMargin: 5
+ //dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
+ });
+ doc.keyButtons= dragCreators;
+ }
+
+ setupDefaultButtons() {
+ let doc = this.props.Document;
+ const button = (opts: DocumentOptions) => new PrefetchProxy( Docs.Create.ButtonDocument({...opts,
+ _width: 35, _height: 30,
+ borderRounding: "16px", border:"1px solid grey", color:"white",
+ //hovercolor: "rgb(170, 170, 163)",
+ letterSpacing: "2px",
+ _fontSize: 7,
+ }))as any as Doc;
+ doc.keywords=button({ title: "Keywords", onClick:ScriptField.MakeScript("handleWordQueryChange(self)")});
+ doc.keys=button({ title: "Keys", onClick:ScriptField.MakeScript(`handleKeyChange(self)`)});
+ doc.nodes = button({ title: "Nodes", onClick:ScriptField.MakeScript("handleNodeChange(self)")});
+ let buttons = [doc.keywords as Doc, doc.keys as Doc, doc.nodes as Doc];
+ const dragCreators = Docs.Create.MasonryDocument(buttons, {
+ _width: 500, backgroundColor:"#121721", _autoHeight: true, columnWidth: 60, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons",_yMargin: 5
+ //dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
+ });
+ doc.defaultButtons= dragCreators;
+ }
+ @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); }
+
+ childLayoutTemplate = () => this.layoutDoc._viewType === CollectionViewType.Stacking ? this.searchItemTemplate: undefined;
+ getTransform = () => {
+ return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
+ }
+ panelHeight = () => {
+ return this.props.PanelHeight() - 50;
+ }
+ selectElement = (doc: Doc) => {
+ //this.gotoDocument(this.childDocs.indexOf(doc), NumCasst(this.layoutDoc._itemIndex));
+ }
+
+ addDocument = (doc: Doc) => {
+ return null;
+ }
+ //Make id layour document
render() {
+ if (this.expandedBucket === true){
+ this.props.Document._gridGap=5;
+ }
+ else {
+ this.props.Document._gridGap=10;
+ }
+ this.props.Document._searchDoc=true;
return (
- <div className="searchBox-container">
+ <div style={{pointerEvents:"all"}}className="searchBox-container">
<div className="searchBox-bar">
- <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, () => this._searchString ? this.startDragCollection() : undefined)} ref={this.collectionRef} title="Drag Results as Collection">
+ <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} ref={this.collectionRef} title="Drag Results as Collection">
<FontAwesomeIcon icon="object-group" size="lg" />
</span>
- <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this.inputRef}
+ <input value={StrCast(this.layoutDoc._searchString)} onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this.inputRef}
className="searchBox-barChild searchBox-input" onPointerDown={this.openSearch} onKeyPress={this.enter} onFocus={this.openSearch}
style={{ width: this._searchbarOpen ? "500px" : "100px" }} />
- <button className="searchBox-barChild searchBox-filter" title="Advanced Filtering Options" onClick={() => this.handleFilterChange()}><FontAwesomeIcon icon="ellipsis-v" color="white" /></button>
+ <button className="searchBox-barChild searchBox-filter" style={{transform:"none"}} title="Advanced Filtering Options" onClick={() => this.handleFilterChange()}><FontAwesomeIcon icon="ellipsis-v" color="white" /></button>
</div>
-
- <div id={`filterhead${this.props.id}`} className="filter-form" >
- <div id={`filterhead2${this.props.id}`} className="filter-header" style={this._filterOpen ? {} : {}}>
- <button className="filter-item" style={this._basicWordStatus ? { background: "#aaaaa3", } : {}} onClick={this.handleWordQueryChange}>Keywords</button>
- <button className="filter-item" style={this._keyStatus ? { background: "#aaaaa3" } : {}} onClick={this.handleKeyChange}>Keys</button>
- <button className="filter-item" style={this._nodeStatus ? { background: "#aaaaa3" } : {}} onClick={this.handleNodeChange}>Nodes</button>
+ <div id={`filterhead${this.props.Document[Id]}`} className="filter-form" style={this._filterOpen && this._numTotalResults >0 ? {overflow:"visible"} : {overflow:"hidden"}}>
+ <div id={`filterhead2${this.props.Document[Id]}`} className="filter-header" >
+ {this.defaultButtons}
</div>
- <div id={`node${this.props.id}`} className="filter-body" style={this._nodeStatus ? { borderTop: "grey 1px solid" } : { borderTop: "0px" }}>
- <IconBar setIcons={(icons: string[]) => {
- this._icons = icons;
- }} />
+ <div id={`node${this.props.Document[Id]}`} className="filter-body" style={this._nodeStatus ? { borderTop: "grey 1px solid" } : { borderTop: "0px" }}>
+ {this.docButtons}
</div>
- <div className="filter-key" id={`key${this.props.id}`} style={this._keyStatus ? { borderTop: "grey 1px solid" } : { borderTop: "0px" }}>
- <div className="filter-keybar">
- <button className="filter-item" style={this._titleFieldStatus ? { background: "#aaaaa3", } : {}} onClick={this.updateTitleStatus}>Title</button>
- <button className="filter-item" style={this._deletedDocsStatus ? { background: "#aaaaa3", } : {}} onClick={this.updateDataStatus}>Deleted Docs</button>
- <button className="filter-item" style={this._authorFieldStatus ? { background: "#aaaaa3", } : {}} onClick={this.updateAuthorStatus}>Author</button>
- </div>
+ <div className="filter-key" id={`key${this.props.Document[Id]}`} style={this._keyStatus ? { borderTop: "grey 1px solid" } : { borderTop: "0px" }}>
+ {this.keyButtons}
</div>
</div>
+ <CollectionView {...this.props}
+ Document={this.props.Document}
+ PanelHeight={this.panelHeight}
+ moveDocument={returnFalse}
+ NativeHeight={()=>400}
+ childLayoutTemplate={this.childLayoutTemplate}
+ addDocument={undefined}
+ removeDocument={returnFalse}
+ focus={this.selectElement}
+ ScreenToLocalTransform={Transform.Identity} />
<div className="searchBox-results" onScroll={this.resultsScrolled} style={{
display: this._resultsOpen ? "flex" : "none",
height: this.resFull ? "auto" : this.resultHeight,
overflow: "visibile" // this.resFull ? "auto" : "visible"
}} ref={this._resultsRef}>
- {this._visibleElements}
</div>
</div>
);
}
-} \ No newline at end of file
+}
+
+Scripting.addGlobal(function lookupSearchBoxField(container: Doc, field: string, data: Doc) {
+ // if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data);
+ // if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 50 : 46;
+ // if (field === 'presStatus') return container.presStatus;
+ // if (field === '_itemIndex') return container._itemIndex;
+ if (field == "query") return container._searchString;
+ return undefined;
+});
+
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss
index 469f062b2..5ce022d41 100644
--- a/src/client/views/search/SearchItem.scss
+++ b/src/client/views/search/SearchItem.scss
@@ -11,15 +11,15 @@
.searchItem-overview .searchItem {
width: 100%;
background: $light-color-secondary;
- border-color: $intermediate-color;
- border-bottom-style: solid;
- padding: 10px;
- min-height: 50px;
+ padding: 8px;
+ min-height: 46px;
+ height:46px;
max-height: 150px;
height: auto;
z-index: 0;
display: flex;
overflow: visible;
+ box-shadow: rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw;
.searchItem-body {
display: flex;
@@ -146,7 +146,7 @@
}
.searchBox-placeholder {
- min-height: 50px;
+ min-height: 46px;
margin-left: 150px;
width: calc(100% - 150px);
text-transform: uppercase;
@@ -160,4 +160,27 @@
.collection-item {
width: 35px;
+}
+
+.bucket-title{
+ width:auto;
+ padding: 5px;
+ height: auto;
+ top: -18;
+ z-index: 55;
+ position: absolute;
+}
+
+.bucket-expand{
+ bottom: 0;
+ position: absolute;
+ width: 100%;
+ height: 15;
+ transform:none;
+ .bucket-expand:hover{
+ transform:none;
+ }
+ button:hover{
+ transform:none;
+ }
} \ No newline at end of file
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 74262d81a..c93611e9b 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -2,9 +2,9 @@ import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction } from "mobx";
+import { action, computed, observable, runInAction, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../../fields/Doc";
+import { Doc, DocCastAsync } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero, returnEmptyString, returnEmptyFilter } from "../../../Utils";
@@ -15,13 +15,21 @@ import { SearchUtil } from "../../util/SearchUtil";
import { Transform } from "../../util/Transform";
import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss";
import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionViewType } from "../collections/CollectionView";
+import { CollectionViewType, CollectionView } from "../collections/CollectionView";
import { ParentDocSelector } from "../collections/ParentDocumentSelector";
import { ContextMenu } from "../ContextMenu";
import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
import { SearchBox } from "./SearchBox";
import "./SearchItem.scss";
import "./SelectorContextMenu.scss";
+import { FieldViewProps, FieldView } from "../nodes/FieldView";
+import { ViewBoxBaseComponent } from "../DocComponent";
+import { makeInterface, createSchema, listSpec } from "../../../fields/Schema";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { PrefetchProxy } from "../../../fields/Proxy";
+import { Docs } from "../../documents/Documents";
+import { ScriptField } from "../../../fields/ScriptField";
+import { CollectionStackingView } from "../collections/CollectionStackingView";
export interface SearchItemProps {
doc: Doc;
@@ -122,30 +130,113 @@ export class LinkContextMenu extends React.Component<LinkMenuProps> {
}
+
+type SearchSchema = makeInterface<[typeof documentSchema]>;
+
+export const SearchSchema = createSchema({
+ targetDoc: Doc,
+});
+
+const SearchDocument = makeInterface(documentSchema);
+
+
+
@observer
-export class SearchItem extends React.Component<SearchItemProps> {
+export class SearchItem extends ViewBoxBaseComponent<FieldViewProps, SearchSchema>(SearchDocument) {
+
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchItem, fieldKey); }
+
+ constructor(props:any){
+ super(props);
+ //this.rootDoc._viewType= CollectionViewType.Stacking;
+ this.props.Document._height=46;
+ if (!this.searchItemTemplate) { // create exactly one presElmentBox template to use by any and all presentations.
+ Doc.UserDoc().searchItemTemplate = new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" }));
+ // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
+ // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
+ // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
+ // stored on each pres element.
+ (this.searchItemTemplate as Doc).lookupField = ScriptField.MakeFunction("lookupSearchBoxField(container, field, data)",
+ { field: "string", data: Doc.name, container: Doc.name });
+ }
+
+ }
@observable _selected: boolean = false;
onClick = () => {
- // I dont think this is the best functionality because clicking the name of the collection does that. Change it back if you'd like
- DocumentManager.Instance.jumpToDocument(this.props.doc, false);
+ DocumentManager.Instance.jumpToDocument(this.rootDoc, false);
}
@observable _useIcons = true;
@observable _displayDim = 50;
+ @computed get query() { return StrCast(this.lookupField("query")); }
+
+ private _oldHeight: number = 46;
+
componentDidMount() {
- Doc.SetSearchQuery(this.props.query);
- this.props.doc.searchMatch = true;
+ let parent: Doc |undefined = undefined;
+ let height = 0;
+ if (this.rootDoc.parent){
+ parent = Cast(this.rootDoc.parent, Doc, null);
+ if (parent!== undefined){
+ height=(NumCast(parent._height));
+ }
+ }
+
+ this._reactionDisposer2 = reaction(
+ () => this._useIcons,
+ el=> {
+ if (this.rootDoc.parent){
+ parent = Cast(this.rootDoc.parent, Doc, null) as Doc;
+ height=(NumCast(parent._height));
+ };
+ console.log(height);
+ console.log(this._oldHeight);
+ setTimeout(() =>{this._mainRef.current?.getBoundingClientRect()? this.props.Document._height= this._mainRef.current?.getBoundingClientRect().height : null;
+ parent!==undefined? this._mainRef.current?.getBoundingClientRect()? parent._height= -this._oldHeight + height +this._mainRef.current?.getBoundingClientRect().height : null: null;
+ this._mainRef.current?.getBoundingClientRect()? this._oldHeight= this._mainRef.current?.getBoundingClientRect().height : null;
+ // this._oldHeight 55? this._oldHeight =55:null;
+ }, 1);
+ }
+ );
+
+ this._reactionDisposer3 = reaction(
+ () => this._displayLines,
+ el=> {
+ if (this.rootDoc.parent){
+ parent = Cast(this.rootDoc.parent, Doc, null) as Doc;
+ height=(NumCast(parent._height));
+ };
+ setTimeout(() =>{this._mainRef.current?.getBoundingClientRect()? this.props.Document._height= this._mainRef.current?.getBoundingClientRect().height : null;
+ parent!==undefined? this._mainRef.current?.getBoundingClientRect()? parent._height= -this._oldHeight + height +this._mainRef.current?.getBoundingClientRect().height : null: null;
+ this._mainRef.current?.getBoundingClientRect()? this._oldHeight= this._mainRef.current?.getBoundingClientRect().height : null;
+ }, 1);
+ }
+ );
+
+ Doc.SetSearchQuery(this.query);
+ this.rootDoc.searchMatch = true;
}
componentWillUnmount() {
- this.props.doc.searchMatch = undefined;
+ this.rootDoc.searchMatch = undefined;
+ this._reactionDisposer2 && this._reactionDisposer2();
+ this._reactionDisposer3 && this._reactionDisposer3();
+
}
- //@computed
+
+
+ private _reactionDisposer2?: IReactionDisposer;
+ private _reactionDisposer3?: IReactionDisposer;
+
+
+
+ @computed get highlightPos(){return NumCast(this.rootDoc.searchIndex)}
+
@action
public DocumentIcon() {
- const layoutresult = StrCast(this.props.doc.type);
+ const layoutresult = StrCast(this.rootDoc.type);
if (!this._useIcons) {
const returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
const returnYDimension = () => this._displayDim;
@@ -156,10 +247,10 @@ export class SearchItem extends React.Component<SearchItemProps> {
})}
onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} >
<ContentFittingDocumentView
- Document={this.props.doc}
+ Document={this.rootDoc}
LibraryPath={emptyPath}
rootSelected={returnFalse}
- fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
+ fitToBox={StrCast(this.rootDoc.type).indexOf(DocumentType.COL) !== -1}
addDocument={returnFalse}
removeDocument={returnFalse}
addDocTab={returnFalse}
@@ -192,9 +283,12 @@ export class SearchItem extends React.Component<SearchItemProps> {
layoutresult.indexOf(DocumentType.LINK) !== -1 ? faLink :
layoutresult.indexOf(DocumentType.WEB) !== -1 ? faGlobeAsia :
faCaretUp;
- return <div onClick={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
+ return <div><div onClick={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
<FontAwesomeIcon icon={button} size="2x" />
- </div>;
+ </div>
+ <div className="searchItem-label">{this.rootDoc.type ? this.rootDoc.type : "Other"}</div>
+ </div>
+ ;
}
collectionRef = React.createRef<HTMLDivElement>();
@@ -202,38 +296,60 @@ export class SearchItem extends React.Component<SearchItemProps> {
@action
pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); }
- nextHighlight = (e: React.PointerEvent) => {
+ @action
+ nextHighlight = (e: React.MouseEvent) => {
e.preventDefault();
- e.button === 0 && SearchBox.Instance.openSearch(e);
- this.props.doc.searchMatch = false;
- setTimeout(() => this.props.doc.searchMatch = true, 0);
+ e.stopPropagation();
+ //e.button === 0 && SearchBox.Instance.openSearch(e);
+
+ this.rootDoc!.searchMatch = false;
+ setTimeout(() => this.rootDoc!.searchMatch = true, 0);
+ this.rootDoc.searchIndex=NumCast(this.rootDoc.searchIndex);
+ this.length=NumCast(this.rootDoc!.length);
}
+
+ @action
+ nextHighlight2 = (e: React.MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ //e.button === 0 && SearchBox.Instance.openSearch(e);
+
+ this.rootDoc!.searchMatch2 = false;
+ setTimeout(() => this.rootDoc!.searchMatch2 = true, 0);
+ this.rootDoc.searchIndex=NumCast(this.rootDoc.searchIndex);
+
+ this.length=NumCast(this.rootDoc!.length);
+ }
+
+ @observable length:number|undefined = 0;
+
highlightDoc = (e: React.PointerEvent) => {
- if (this.props.doc.type === DocumentType.LINK) {
- if (this.props.doc.anchor1 && this.props.doc.anchor2) {
+ if (this.rootDoc!.type === DocumentType.LINK) {
+ if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) {
- const doc1 = Cast(this.props.doc.anchor1, Doc, null);
- const doc2 = Cast(this.props.doc.anchor2, Doc, null);
+ const doc1 = Cast(this.rootDoc!.anchor1, Doc, null);
+ const doc2 = Cast(this.rootDoc!.anchor2, Doc, null);
Doc.BrushDoc(doc1);
Doc.BrushDoc(doc2);
}
} else {
- Doc.BrushDoc(this.props.doc);
+ Doc.BrushDoc(this.rootDoc!);
}
e.stopPropagation();
}
unHighlightDoc = (e: React.PointerEvent) => {
- if (this.props.doc.type === DocumentType.LINK) {
- if (this.props.doc.anchor1 && this.props.doc.anchor2) {
+ if (this.rootDoc!.type === DocumentType.LINK) {
+ if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) {
- const doc1 = Cast(this.props.doc.anchor1, Doc, null);
- const doc2 = Cast(this.props.doc.anchor2, Doc, null);
+ const doc1 = Cast(this.rootDoc!.anchor1, Doc, null);
+ const doc2 = Cast(this.rootDoc!.anchor2, Doc, null);
Doc.UnBrushDoc(doc1);
Doc.UnBrushDoc(doc2);
}
} else {
- Doc.UnBrushDoc(this.props.doc);
+ Doc.UnBrushDoc(this.rootDoc!);
}
}
@@ -243,7 +359,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
ContextMenu.Instance.clearItems();
ContextMenu.Instance.addItem({
description: "Copy ID", event: () => {
- Utils.CopyText(this.props.doc[Id]);
+ Utils.CopyText(StrCast(this.rootDoc[Id]));
},
icon: "fingerprint"
});
@@ -268,7 +384,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
Math.abs(e.clientY - this._downY) > Utils.DRAG_THRESHOLD) {
document.removeEventListener("pointermove", this.onPointerMoved);
document.removeEventListener("pointerup", this.onPointerUp);
- const doc = Doc.IsPrototype(this.props.doc) ? Doc.MakeDelegate(this.props.doc) : this.props.doc;
+ const doc = Doc.IsPrototype(this.rootDoc) ? Doc.MakeDelegate(this.rootDoc) : this.rootDoc;
DragManager.StartDocumentDrag([this._target], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY);
}
}
@@ -279,32 +395,160 @@ export class SearchItem extends React.Component<SearchItemProps> {
@computed
get contextButton() {
- return <ParentDocSelector Document={this.props.doc} addDocTab={(doc, where) => CollectionDockingView.AddRightSplit(doc)} />;
+ return <ParentDocSelector Document={this.rootDoc} addDocTab={(doc, where) => CollectionDockingView.AddRightSplit(doc)} />;
+ }
+
+ @computed get searchElementDoc() { return this.rootDoc; }
+ // @computed get targetDoc() { return this.searchElementDoc?.targetDoc as Doc; }
+
+ @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); }
+ childLayoutTemplate = () => this.layoutDoc._viewType === CollectionViewType.Stacking ? this.searchItemTemplate: undefined;
+ getTransform = () => {
+ return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
+ }
+ panelHeight = () => {
+ return this.props.PanelHeight();
+ }
+ selectElement = (doc: Doc) => {
+ //this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.layoutDoc._itemIndex));
+ }
+
+ newsearch(){
+ runInAction(()=>{
+ if (StrCast(this.rootDoc.bucketfield)!=="results"){
+ SearchBox.Instance._icons=[StrCast(this.rootDoc.bucketfield)];
+ SearchBox.Instance._icons=SearchBox.Instance._icons;
+ }
+ else{
+ SearchBox.Instance._icons=SearchBox.Instance._allIcons;
+ }
+ SearchBox.Instance.expandedBucket= true;
+ SearchBox.Instance.submitSearch();
+ })
+ }
+
+ @action
+ returnLines(){
+ if ((Cast(this.rootDoc.lines, listSpec("string")))!.length>1){
+ if (!this._displayLines) {
+ console.log(Cast(this.rootDoc.lines, listSpec("string")));
+ return <div style={{width: 10}}
+ onPointerDown={action(() => {
+ this._displayLines = !this._displayLines;
+ //this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
+ })}
+ //onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))}
+ >
+ {Cast(this.rootDoc.lines, listSpec("string"))!.filter((m, i) => i).map((l, i) => <div style={{overflow:"visible"}}id={i.toString()} className="searchItem-highlighting">{l}</div>)}
+ </div>;;
+ }
+ }
+ }
+
+ //this._displayDim = Number(SEARCH_THUMBNAIL_SIZE);
+
+ @observable _displayLines: boolean = true;
+
+ returnButtons(){
+ return <div>
+ <div onClick={action(() => { this.rootDoc!.type === DocumentType.PDF? this._displayLines = !this._displayLines : null;
+ })}>
+ {this.rootDoc!.type === DocumentType.PDF?"Expand Lines": null}
+ {NumCast(this.rootDoc!.length)>1?`Instance ${NumCast(this.rootDoc.searchIndex)===0? NumCast(this.rootDoc.length):NumCast(this.rootDoc.searchIndex) } of ${NumCast(this.rootDoc.length)}`: null}
+ <button onClick={this.nextHighlight} style={{padding:2, position:"absolute", left:77}}>
+ <FontAwesomeIcon icon="arrow-up" size="sm" />
+ </button>
+ <button onClick={this.nextHighlight2} style={{padding:2, position:"absolute", left:87}}>
+ <FontAwesomeIcon icon="arrow-down" size="sm" />
+ </button>
+ </div>
+ <div>
+ <div style={{background: "lightgrey"}}>
+ {this.returnLines()}
+ </div>
+ </div>
+ </div>
}
+ private _mainRef: React.RefObject<HTMLDivElement> = React.createRef();
+
+
render() {
- const doc1 = Cast(this.props.doc.anchor1, Doc);
- const doc2 = Cast(this.props.doc.anchor2, Doc);
+ const doc1 = Cast(this.rootDoc!.anchor1, Doc);
+ const doc2 = Cast(this.rootDoc!.anchor2, Doc);
+ if (StrCast(this.rootDoc.bucketfield)==="webs"){
+ this.props.Document._viewType=CollectionViewType.Stacking;
+ this.props.Document._chromeStatus='disabled';
+ this.props.Document._height=this.rootDoc._height;
+ return <div>
+ <CollectionView {...this.props}
+ Document={this.props.Document}
+ PanelHeight={this.panelHeight}
+ whenActiveChanged={emptyFunction}
+ onClick={undefined}
+ moveDocument={returnFalse}
+ childLayoutTemplate={undefined}
+ addDocument={undefined}
+ removeDocument={returnFalse}
+ focus={this.selectElement}
+ ScreenToLocalTransform={this.getTransform} />
+ </div>
+ }
+ if (this.rootDoc.isBucket === true){
+ this.props.Document._viewType=CollectionViewType.Stacking;
+ this.props.Document._chromeStatus='disabled';
+ this.props.Document._height=this.rootDoc._height;
+
+ return <div>
+ <CollectionView {...this.props}
+ Document={this.props.Document}
+ PanelHeight={this.panelHeight}
+ whenActiveChanged={emptyFunction}
+ onClick={undefined}
+ moveDocument={returnFalse}
+ childLayoutTemplate={this.childLayoutTemplate}
+ addDocument={undefined}
+ removeDocument={returnFalse}
+ focus={this.selectElement}
+ ScreenToLocalTransform={this.getTransform} />
+ <button onClick={()=>this.newsearch()}className="bucket-expand" style={{transform:"none", fontSize:"100%",textTransform:"none", background: "lightgray",color: "black", bottom: 8, marginBottom:-2, paddingTop:2,fontFamily:"Arial, sans-serif"}}>See all {StrCast(this.rootDoc.bucketfield)}...
+ </button>
+ </div>
+ }
+ else if (this.rootDoc.isBucket === false){
+ this.props.Document._chromeStatus='disabled';
+ return <div className="searchItem">
+ <div className="searchItem-body" >
+ <div className="searchItem-title-container">
+ <div className="searchItem-title" style={{height:"10px", overflow:"hidden", textOverflow:"ellipsis"}}>No Search Results</div>
+ </div>
+ </div>
+ </div>
+ }
+ else {
return <div className="searchItem-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}>
- <div className="searchItem" onPointerDown={this.nextHighlight} onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc}>
+ <div ref={this._mainRef} className="searchItem" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc}>
<div className="searchItem-body" onClick={this.onClick}>
<div className="searchItem-title-container">
- <div className="searchItem-title">{StrCast(this.props.doc.title)}</div>
- <div className="searchItem-highlighting">{this.props.highlighting.length ? "Matched fields:" + this.props.highlighting.join(", ") : this.props.lines.length ? this.props.lines[0] : ""}</div>
- {this.props.lines.filter((m, i) => i).map((l, i) => <div id={i.toString()} className="searchItem-highlighting">`${l}`</div>)}
- </div>
+ <div className="searchItem-title" style={{height:"10px", overflow:"hidden", textOverflow:"ellipsis"}}>{StrCast(this.rootDoc.title)}</div>
+ <div className="searchItem-highlighting">
+ {this.rootDoc.highlighting? StrCast(this.rootDoc.highlighting).length ? "Matched fields:" + StrCast(this.rootDoc.highlighting) : Cast(this.rootDoc.lines, listSpec("string"))!.length ? Cast(this.rootDoc.lines, listSpec("string"))![0] : "":null}</div>
+ <div className={`icon-${this._displayLines ? "q" : "a"}`}>
+ {NumCast(this.rootDoc.length) > 1 || this.rootDoc!.type === DocumentType.PDF?this.returnButtons(): null}
+ </div>
+ </div>
</div>
<div className="searchItem-info" style={{ width: this._useIcons ? "30px" : "100%" }}>
<div className={`icon-${this._useIcons ? "icons" : "live"}`}>
<div className="searchItem-type" title="Click to Preview" onPointerDown={this.onPointerDown}>{this.DocumentIcon()}</div>
- <div className="searchItem-label">{this.props.doc.type ? this.props.doc.type : "Other"}</div>
</div>
</div>
- <div className="searchItem-context" title="Drag as document">
- {(doc1 instanceof Doc && doc2 instanceof Doc) && this.props.doc.type === DocumentType.LINK ? <LinkContextMenu doc1={doc1} doc2={doc2} /> :
+ {/* <div className="searchItem-context" title="Drag as document">
+ {(doc1 instanceof Doc && doc2 instanceof Doc) && this.rootDoc!.type === DocumentType.LINK ? <LinkContextMenu doc1={doc1} doc2={doc2} /> :
this.contextButton}
- </div>
+ </div> */}
</div>
</div>;
+ }
}
} \ No newline at end of file
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 8c8720179..3438f00a3 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1167,4 +1167,4 @@ Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: bo
return docs.length ? new List(docs) : prevValue;
});
Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) { Doc.setDocFilter(container, key, value, modifiers); });
-Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number[]) { Doc.setDocFilterRange(container, key, range); }); \ No newline at end of file
+Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number[]) { Doc.setDocFilterRange(container, key, range); });
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index 753c31fcf..7251e07a1 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -176,7 +176,7 @@ export namespace SolrManager {
"audio": ["_t", "url"],
"web": ["_t", "url"],
"date": ["_d", value => new Date(value.date).toISOString()],
- "proxy": ["_i", "fieldId"],
+ // "proxy": ["_i", "fieldId"],
"list": ["_l", list => {
const results = [];
for (const value of list.fields) {
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index fe39b84e6..696ad0288 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -14,7 +14,6 @@ import { normalize } from "path";
import RouteSubscriber from "../RouteSubscriber";
const imageDataUri = require('image-data-uri');
import { isWebUri } from "valid-url";
-import { launch } from "puppeteer";
import { Opt } from "../../fields/Doc";
export enum Directory {
@@ -286,25 +285,26 @@ function delay(ms: number) {
*
* On failure, returns undefined.
*/
-async function captureYoutubeScreenshot(targetUrl: string): Promise<Opt<Buffer>> {
- const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
- const page = await browser.newPage();
- await page.setViewport({ width: 1920, height: 1080 });
+async function captureYoutubeScreenshot(targetUrl: string){
+ // const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
+ // const page = await browser.newPage();
+ // // await page.setViewport({ width: 1920, height: 1080 });
- await page.goto(targetUrl, { waitUntil: 'domcontentloaded' as any });
+ // // await page.goto(targetUrl, { waitUntil: 'domcontentloaded' as any });
- const videoPlayer = await page.$('.html5-video-player');
- videoPlayer && await page.focus("video");
- await delay(7000);
- const ad = await page.$('.ytp-ad-skip-button-text');
- await ad?.click();
- await videoPlayer?.click();
- await delay(1000);
- // hide youtube player controls.
- await page.evaluate(() => (document.querySelector('.ytp-chrome-bottom') as HTMLElement).style.display = 'none');
+ // const videoPlayer = await page.$('.html5-video-player');
+ // videoPlayer && await page.focus("video");
+ // await delay(7000);
+ // const ad = await page.$('.ytp-ad-skip-button-text');
+ // await ad?.click();
+ // await videoPlayer?.click();
+ // await delay(1000);
+ // // hide youtube player controls.
+ // await page.evaluate(() => (document.querySelector('.ytp-chrome-bottom') as HTMLElement).style.display = 'none');
- const buffer = await videoPlayer?.screenshot({ encoding: "binary" });
- await browser.close();
+ // const buffer = await videoPlayer?.screenshot({ encoding: "binary" });
+ // await browser.close();
- return buffer;
+ // return buffer;
+ return null;
} \ No newline at end of file
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index d55c2e198..19c98454c 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -221,7 +221,8 @@ export namespace WebSocket {
"script": ["_t", value => value.script.originalScript],
"RichTextField": ["_t", value => value.Text],
"date": ["_d", value => new Date(value.date).toISOString()],
- "proxy": ["_i", "fieldId"],
+ // "proxy": ["_i", "fieldId"],
+ // "proxy": ["", "fieldId"],
"list": ["_l", list => {
const results = [];
for (const value of list.fields) {
@@ -235,25 +236,27 @@ export namespace WebSocket {
};
function ToSearchTerm(val: any): { suffix: string, value: any } | undefined {
+
if (val === null || val === undefined) {
return;
}
const type = val.__type || typeof val;
+
let suffix = suffixMap[type];
if (!suffix) {
return;
}
-
if (Array.isArray(suffix)) {
const accessor = suffix[1];
if (typeof accessor === "function") {
val = accessor(val);
} else {
val = val[accessor];
+
}
suffix = suffix[0];
- }
+ }
return { suffix, value: val };
}
@@ -275,10 +278,18 @@ export namespace WebSocket {
dynfield = true;
const val = docfield[key];
key = key.substring(7);
- Object.values(suffixMap).forEach(suf => update[key + getSuffix(suf)] = { set: null });
+ if (key==="_height"){
+ Object.values(suffixMap).forEach(suf => {update[key] = { set: null };});
+ }
+ else {
+ Object.values(suffixMap).forEach(suf => {update[key + getSuffix(suf)] = { set: null };});
+ }
const term = ToSearchTerm(val);
if (term !== undefined) {
const { suffix, value } = term;
+ if (key==="_height"){
+ update[key] = { set: value };
+ }
update[key + suffix] = { set: value };
}
}