aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts9
-rw-r--r--src/client/util/SearchUtil.ts55
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx8
-rw-r--r--src/client/views/newlightbox/utils.ts121
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx2
-rw-r--r--src/client/views/search/SearchBox.scss1
-rw-r--r--src/client/views/search/SearchBox.tsx27
7 files changed, 104 insertions, 119 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f1a0b37b3..ac418ecfe 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -81,6 +81,7 @@ export class FInfo {
this.description = d;
this.readOnly = readOnly ?? false;
}
+ searchable = () => true;
}
class BoolInfo extends FInfo {
fieldType? = 'boolean';
@@ -89,6 +90,7 @@ class BoolInfo extends FInfo {
super(d);
this.filterable = filterable;
}
+ override searchable = () => false;
}
class NumInfo extends FInfo {
fieldType? = 'number';
@@ -98,6 +100,7 @@ class NumInfo extends FInfo {
this.values = values;
this.filterable = filterable;
}
+ override searchable = () => false;
}
class StrInfo extends FInfo {
fieldType? = 'string';
@@ -116,34 +119,40 @@ class DocInfo extends FInfo {
this.values = values;
this.filterable = filterable;
}
+ override searchable = () => false;
}
class DimInfo extends FInfo {
fieldType? = 'enumeration';
values? = [DimUnit.Pixel, DimUnit.Ratio];
readOnly = false;
filterable = false;
+ override searchable = () => false;
}
class PEInfo extends FInfo {
fieldType? = 'enumeration';
values? = ['all', 'none'];
readOnly = false;
filterable = false;
+ override searchable = () => false;
}
class DAInfo extends FInfo {
fieldType? = 'enumeration';
values? = ['embed', 'copy', 'move', 'same', 'proto', 'none'];
readOnly = false;
filterable = false;
+ override searchable = () => false;
}
class CTypeInfo extends FInfo {
fieldType? = 'enumeration';
values? = Array.from(Object.keys(CollectionViewType));
readOnly = false;
filterable = false;
+ override searchable = () => false;
}
class DTypeInfo extends FInfo {
fieldType? = 'enumeration';
values? = Array.from(Object.keys(DocumentType));
+ override searchable = () => false;
}
class DateInfo extends FInfo {
fieldType? = 'date';
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 68c981399..218667d3e 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -3,47 +3,21 @@ import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { StrCast } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
+import { DocOptions, FInfo } from '../documents/Documents';
export namespace SearchUtil {
export type HighlightingResult = { [id: string]: { [key: string]: string[] } };
- export function SearchCollection(collectionDoc: Opt<Doc>, query: string) {
+ export function SearchCollection(collectionDoc: Opt<Doc>, query: string, matchKeyNames: boolean) {
const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.CONFIG, DocumentType.KVP, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
- const blockedKeys = [
- 'x',
- 'y',
- 'proto',
- 'width',
- 'layout_autoHeight',
- 'acl-Override',
- 'acl-Guest',
- 'embedContainer',
- 'zIndex',
- 'height',
- 'text_scrollHeight',
- 'text_height',
- 'cloneFieldFilter',
- 'isDataDoc',
- 'text_annotations',
- 'dragFactory_count',
- 'text_noTemplate',
- 'proto_embeddings',
- 'isSystem',
- 'layout_fieldKey',
- 'isBaseProto',
- 'xMargin',
- 'yMargin',
- 'links',
- 'layout',
- 'layout_keyValue',
- 'layout_fitWidth',
- 'type_collection',
- 'title_custom',
- 'freeform_panX',
- 'freeform_panY',
- 'freeform_scale',
- ];
- query = query.toLowerCase();
+ const blockedKeys = matchKeyNames
+ ? []
+ : Object.entries(DocOptions)
+ .filter(([key, info]: [string, FInfo]) => !info?.searchable())
+ .map(([key]) => key);
+
+ const exact = query.startsWith('=');
+ query = query.toLowerCase().split('=').lastElement();
const results = new ObservableMap<Doc, string[]>();
if (collectionDoc) {
@@ -54,11 +28,10 @@ export namespace SearchUtil {
if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth >= 0) {
const hlights = new Set<string>();
SearchUtil.documentKeys(doc).forEach(
- key =>
- (Field.toString(doc[key] as Field) + Field.toScriptString(doc[key] as Field))
- .toLowerCase() //
- .includes(query) && hlights.add(key)
- );
+ key => (val => (exact ? val === query.toLowerCase() : val.includes(query.toLowerCase())))(
+ matchKeyNames ? key : Field.toString(doc[key] as Field))
+ && hlights.add(key)
+ ); // prettier-ignore
blockedKeys.forEach(key => hlights.delete(key));
if (Array.from(hlights.keys()).length > 0) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d19c9f07d..d3c196a60 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -304,10 +304,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
focus = (anchor: Doc, options: FocusViewOptions) => {
if (this._lightboxDoc) return;
if (anchor === this.Document) {
- if (options.willZoomCentered && options.zoomScale) {
- this.fitContentOnce();
- options.didMove = true;
- }
+ // if (options.willZoomCentered && options.zoomScale) {
+ // this.fitContentOnce();
+ // options.didMove = true;
+ // }
}
if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor)) return;
const xfToCollection = options?.docTransform ?? Transform.Identity();
diff --git a/src/client/views/newlightbox/utils.ts b/src/client/views/newlightbox/utils.ts
index 6016abca4..c879718e3 100644
--- a/src/client/views/newlightbox/utils.ts
+++ b/src/client/views/newlightbox/utils.ts
@@ -1,121 +1,120 @@
-import { DocumentType } from "../../documents/DocumentTypes";
-import { IRecommendation } from "./components";
+import { DocumentType } from '../../documents/DocumentTypes';
+import { IRecommendation } from './components';
export interface IDocRequest {
- id: string,
- title: string,
- text: string,
- type: string
+ id: string;
+ title: string;
+ text: string;
+ type: string;
}
export const fetchRecommendations = async (src: string, query: string, docs?: IDocRequest[], dummy?: boolean) => {
- console.log("[rec] making request")
+ console.log('[rec] making request');
if (dummy) {
return {
- "recommendations": dummyRecs,
- "keywords": dummyKeywords,
- "num_recommendations": 4,
- "max_x": 100,
- "max_y": 100,
- "min_x": 0,
- "min_y": 0
-
+ recommendations: [], //dummyRecs,
+ keywords: dummyKeywords,
+ num_recommendations: 4,
+ max_x: 100,
+ max_y: 100,
+ min_x: 0,
+ min_y: 0,
};
}
const response = await fetch('http://127.0.0.1:8000/recommend', {
method: 'POST',
headers: {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json'
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
},
- body: JSON.stringify({
- "src": src,
- "query": query,
- "docs": docs
- })
- })
+ body: JSON.stringify({
+ src: src,
+ query: query,
+ docs: docs,
+ }),
+ });
const data = await response.json();
-
+
return data;
-}
+};
export const fetchKeywords = async (text: string, n: number, dummy?: boolean) => {
- console.log("[fetchKeywords]")
+ console.log('[fetchKeywords]');
if (dummy) {
return {
- "keywords": dummyKeywords
+ keywords: dummyKeywords,
};
}
const response = await fetch('http://127.0.0.1:8000/keywords', {
method: 'POST',
headers: {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json'
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
},
- body: JSON.stringify({
- "text": text,
- "n": n
- })
- })
- const data = await response.json()
+ body: JSON.stringify({
+ text: text,
+ n: n,
+ }),
+ });
+ const data = await response.json();
return data;
-}
+};
export const getType = (type: DocumentType | string) => {
- switch(type) {
+ switch (type) {
case DocumentType.AUDIO:
- return "Audio"
+ return 'Audio';
case DocumentType.VID:
- return "Video"
+ return 'Video';
case DocumentType.PDF:
- return "PDF"
+ return 'PDF';
case DocumentType.WEB:
- return "Webpage"
- case "YouTube":
- return "Video"
- case "HTML":
- return "Webpage"
+ return 'Webpage';
+ case 'YouTube':
+ return 'Video';
+ case 'HTML':
+ return 'Webpage';
default:
- return "Unknown: " + type
+ return 'Unknown: ' + type;
}
-}
+};
const dummyRecs = {
- "a": {
+ a: {
title: 'Vannevar Bush - American Engineer',
- previewUrl: 'https://cdn.britannica.com/98/23598-004-1E6A382E/Vannevar-Bush-Differential-Analyzer-1935.jpg',
+ previewUrl: 'https://cdn.britannica.com/98/23598-004-1E6A382E/Vannevar-Bush-Differential-Analyzer-1935.jpg',
type: 'web',
distance: 2.3,
source: 'www.britannica.com',
related_concepts: ['vannevar bush', 'knowledge'],
embedding: {
x: 0,
- y: 0
- }
+ y: 0,
+ },
},
- "b": {
+ b: {
title: "From Memex to hypertext: Vannevar Bush and the mind's machine",
type: 'pdf',
distance: 5.4,
source: 'Google Scholar',
related_concepts: ['memex', 'vannevar bush', 'hypertext'],
},
- "c": {
+ c: {
title: 'How the hyperlink changed everything | Small Thing Big Idea, a TED series',
- previewUrl: 'https://pi.tedcdn.com/r/talkstar-photos.s3.amazonaws.com/uploads/b17d043f-2642-4117-a913-52204505513f/MargaretGouldStewart_2018V-embed.jpg?u%5Br%5D=2&u%5Bs%5D=0.5&u%5Ba%5D=0.8&u%5Bt%5D=0.03&quality=82w=640',
+ previewUrl: 'https://pi.tedcdn.com/r/talkstar-photos.s3.amazonaws.com/uploads/b17d043f-2642-4117-a913-52204505513f/MargaretGouldStewart_2018V-embed.jpg?u%5Br%5D=2&u%5Bs%5D=0.5&u%5Ba%5D=0.8&u%5Bt%5D=0.03&quality=82w=640',
type: 'youtube',
distance: 5.3,
source: 'www.youtube.com',
- related_concepts: ['User Control', 'Explanations']
+ related_concepts: ['User Control', 'Explanations'],
},
- "d": {
+ d: {
title: 'Recommender Systems: Behind the Scenes of Machine Learning-Based Personalization',
- previewUrl: 'https://sloanreview.mit.edu/wp-content/uploads/2018/10/MAG-Ransbotham-Ratings-Recommendations-1200X627-1200x627.jpg',
+ previewUrl: 'https://sloanreview.mit.edu/wp-content/uploads/2018/10/MAG-Ransbotham-Ratings-Recommendations-1200X627-1200x627.jpg',
type: 'pdf',
distance: 9.3,
source: 'www.altexsoft.com',
- related_concepts: ['User Control', 'Explanations']
- }
-}
+ related_concepts: ['User Control', 'Explanations'],
+ },
+};
-const dummyKeywords = ['user control', 'vannevar bush', 'hypermedia', 'hypertext'] \ No newline at end of file
+const dummyKeywords = ['user control', 'vannevar bush', 'hypermedia', 'hypertext'];
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 4b242649a..3f793b85e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -184,7 +184,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
LinkFollower.FollowLink(this._linkDoc, this._linkSrc, false);
} else if (this._props.hrefs?.length) {
const webDoc =
- Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this._props.hrefs[0]).keys()).lastElement() ??
+ Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this._props.hrefs[0], false).keys()).lastElement() ??
Docs.Create.WebDocument(this._props.hrefs[0], { title: this._props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
DocumentManager.Instance.showDocument(webDoc, {
openLocation: OpenWhere.lightbox,
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 09e459f7d..94e64b952 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -8,6 +8,7 @@
background: none;
z-index: 1000;
padding: 0px;
+ overflow: auto;
cursor: default;
.searchBox-bar {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c8caff9fa..0b664beaa 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -162,12 +162,13 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
* which the first letter is capitalized. This is used when displaying the type on the
* right side of each search result.
*/
- static formatType(type: String): String {
- if (type === 'pdf') {
- return 'PDF';
- } else if (type === 'image') {
- return 'Img';
- }
+ static formatType(type: string, colType: string): String {
+ switch (type) {
+ case DocumentType.PDF : return 'PDF';
+ case DocumentType.IMG : return 'Img';
+ case DocumentType.RTF : return 'Rtf';
+ case DocumentType.COL : return 'Col:'+colType.substring(0,3);
+ } // prettier-ignore
return type.charAt(0).toUpperCase() + type.substring(1, 3);
}
@@ -183,7 +184,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
@action
searchCollection(query: string) {
this._selectedResult = undefined;
- this._results = SearchUtil.SearchCollection(CollectionDockingView.Instance?.Document, query);
+ this._results = SearchUtil.SearchCollection(CollectionDockingView.Instance?.Document, query, this._docTypeString === 'keys');
this.computePageRanks();
}
@@ -357,11 +358,11 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
*/
@computed
public get selectOptions() {
- const selectValues = ['all', DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.WEB, DocumentType.VID, DocumentType.AUDIO, DocumentType.COL];
+ const selectValues = ['all', DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.WEB, DocumentType.VID, DocumentType.AUDIO, DocumentType.COL, 'keys'];
return selectValues.map(value => (
<option key={value} value={value}>
- {SearchBox.formatType(value)}
+ {SearchBox.formatType(value, '')}
</option>
));
}
@@ -387,10 +388,10 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
className += ' searchBox-results-scroll-view-result-selected';
}
- const formattedType = SearchBox.formatType(StrCast(result[0].type));
+ const formattedType = SearchBox.formatType(StrCast(result[0].type), StrCast(result[0].type_collection));
const title = result[0].title;
- if (this._docTypeString === 'all' || this._docTypeString === result[0].type) {
+ if (this._docTypeString === 'keys' || this._docTypeString === 'all' || this._docTypeString === result[0].type) {
validResults++;
resultsJSX.push(
<Tooltip key={result[0][Id]} placement={'right'} title={<div className="dash-tooltip">{title as string}</div>}>
@@ -412,7 +413,9 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
}}
className={className}>
<div className="searchBox-result-title">{title as string}</div>
- <div className="searchBox-result-type">{formattedType}</div>
+ <div className="searchBox-result-type" style={{ color: SettingsManager.userVariantColor }}>
+ {formattedType}
+ </div>
<div className="searchBox-result-keys" style={{ color: SettingsManager.userVariantColor }}>
{result[1].join(', ')}
</div>