aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/search
diff options
context:
space:
mode:
authorSophie Zhang <sophie_zhang@brown.edu>2023-09-18 17:40:01 -0400
committerSophie Zhang <sophie_zhang@brown.edu>2023-09-18 17:40:01 -0400
commit013f25f01e729feee5db94900c61f4be4dd46869 (patch)
tree765dd5f2e06d6217ca79438e1098cefc8da627bf /src/client/views/search
parentf5e765adff1e7b32250eb503c9724a4ac99117f3 (diff)
parent84aa8806a62e2e957e8281d7d492139e3d8225f2 (diff)
Merge branch 'master' into sophie-report-manager
Diffstat (limited to 'src/client/views/search')
-rw-r--r--src/client/views/search/IconBar.tsx28
-rw-r--r--src/client/views/search/SearchBox.tsx183
2 files changed, 59 insertions, 152 deletions
diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx
index 6103b245c..540c1b5e1 100644
--- a/src/client/views/search/IconBar.tsx
+++ b/src/client/views/search/IconBar.tsx
@@ -1,17 +1,15 @@
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { DocumentType } from "../../documents/DocumentTypes";
-// import "./SearchBox.scss";
-import "./IconBar.scss";
+import { DocumentType } from '../../documents/DocumentTypes';
+import './IconBar.scss';
import { IconButton } from './IconButton';
-import "./IconButton.scss";
+import './IconButton.scss';
export interface IconBarProps {
setIcons: (icons: string[]) => void;
}
-
@observer
export class IconBar extends React.Component<IconBarProps> {
public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB, DocumentType.MAP];
@@ -32,7 +30,9 @@ export class IconBar extends React.Component<IconBarProps> {
}
@action.bound
- getIcons(): string[] { return this._icons; }
+ getIcons(): string[] {
+ return this._icons;
+ }
constructor(props: any) {
super(props);
@@ -40,29 +40,33 @@ export class IconBar extends React.Component<IconBarProps> {
}
@action.bound
- getList(): string[] { return this.getIcons(); }
+ getList(): string[] {
+ return this.getIcons();
+ }
@action.bound
- updateList(newList: string[]) { this.updateIcon(newList); }
+ updateList(newList: string[]) {
+ this.updateIcon(newList);
+ }
@action.bound
resetSelf = () => {
this._resetClicked = true;
this.updateList([]);
- }
+ };
@action.bound
selectAll = () => {
this._selectAllClicked = true;
this.updateList(this._allIcons);
- }
+ };
render() {
return (
<div className="icon-bar">
- {this._allIcons.map((type: string) =>
+ {this._allIcons.map((type: string) => (
<IconButton key={type.toString()} type={type} />
- )}
+ ))}
</div>
);
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index e911bd283..aa46e57dc 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -18,6 +18,8 @@ import './SearchBox.scss';
import { fetchRecommendations } from '../newlightbox/utils';
import { IRecommendation, Recommendation } from '../newlightbox/components';
import { Colors } from '../global/globalEnums';
+import { SettingsManager } from '../../util/SettingsManager';
+import { SearchUtil } from '../../util/SearchUtil';
const DAMPENING_FACTOR = 0.9;
const MAX_ITERATIONS = 25;
@@ -131,34 +133,6 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
* @param {Doc[]} docs - docs to be searched through recursively
* @param {number, Doc => void} func - function to be called on each doc
*
- * This method iterates through an array of docs and all docs within those docs, calling
- * the function func on each doc.
- */
- static foreachRecursiveDoc(docs: Doc[], func: (depth: number, doc: Doc) => void) {
- let newarray: Doc[] = [];
- var depth = 0;
- const visited: Doc[] = [];
- while (docs.length > 0) {
- newarray = [];
- docs.filter(d => d && !visited.includes(d)).forEach(d => {
- visited.push(d);
- const fieldKey = Doc.LayoutFieldKey(d);
- const annos = !Field.toString(Doc.LayoutField(d) as Field).includes('CollectionView');
- const data = d[annos ? fieldKey + '_annotations' : fieldKey];
- data && newarray.push(...DocListCast(data));
- const sidebar = d[fieldKey + '_sidebar'];
- sidebar && newarray.push(...DocListCast(sidebar));
- func(depth, d);
- });
- docs = newarray;
- depth++;
- }
- }
-
- /**
- * @param {Doc[]} docs - docs to be searched through recursively
- * @param {number, Doc => void} func - function to be called on each doc
- *
* This method iterates asynchronously through an array of docs and all docs within those
* docs, calling the function func on each doc.
*/
@@ -212,74 +186,10 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
@action
searchCollection(query: string) {
this._selectedResult = undefined;
- this._results = SearchBox.staticSearchCollection(CollectionDockingView.Instance?.rootDoc, query);
+ this._results = SearchUtil.SearchCollection(CollectionDockingView.Instance?.rootDoc, query);
this.computePageRanks();
}
- @action
- static staticSearchCollection(rootDoc: Opt<Doc>, query: string) {
- const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.CONFIG, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, 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 results = new Map<Doc, string[]>();
- if (rootDoc) {
- const docs = DocListCast(rootDoc[Doc.LayoutFieldKey(rootDoc)]);
- const docIDs: String[] = [];
- SearchBox.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
- const dtype = StrCast(doc.type) as DocumentType;
- if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth >= 0) {
- const hlights = new Set<string>();
- SearchBox.documentKeys(doc).forEach(
- key =>
- Field.toString(doc[key] as Field)
- .toLowerCase()
- .includes(query) && hlights.add(key)
- );
- blockedKeys.forEach(key => hlights.delete(key));
-
- if (Array.from(hlights.keys()).length > 0) {
- results.set(doc, Array.from(hlights.keys()));
- }
- }
- docIDs.push(doc[Id]);
- });
- }
- return results;
- }
/**
* This method initializes the page rank of every document to the reciprocal
@@ -373,17 +283,6 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
}
/**
- * @param {Doc} doc - doc for which keys are returned
- *
- * This method returns a list of a document doc's keys.
- */
- static documentKeys(doc: Doc) {
- const keys: { [key: string]: boolean } = {};
- Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => (keys[key] = false)));
- return Array.from(Object.keys(keys));
- }
-
- /**
* This method submits a search with the _searchString as its query and updates
* the results array accordingly.
*/
@@ -398,22 +297,21 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
if (query) {
this.searchCollection(query);
- const response = await fetchRecommendations('', query, [], true)
- const recs = response.recommendations
- const recommendations:IRecommendation[] = []
+ const response = await fetchRecommendations('', query, [], true);
+ const recs = response.recommendations;
+ const recommendations: IRecommendation[] = [];
for (const key in recs) {
const title = recs[key].title;
- console.log(title);
- const url = recs[key].url
- const type = recs[key].type
- const text = recs[key].text
- const transcript = recs[key].transcript
- const previewUrl = recs[key].previewUrl
- const embedding = recs[key].embedding
- const distance = recs[key].distance
- const source = recs[key].source
- const related_concepts = recs[key].related_concepts
- const docId = recs[key].doc_id
+ const url = recs[key].url;
+ const type = recs[key].type;
+ const text = recs[key].text;
+ const transcript = recs[key].transcript;
+ const previewUrl = recs[key].previewUrl;
+ const embedding = recs[key].embedding;
+ const distance = recs[key].distance;
+ const source = recs[key].source;
+ const related_concepts = recs[key].related_concepts;
+ const docId = recs[key].doc_id;
recommendations.push({
title: title,
data: url,
@@ -425,11 +323,11 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
distance: Math.round(distance * 100) / 100,
source: source,
related_concepts: related_concepts,
- docId: docId
- })
+ docId: docId,
+ });
}
- const setRecommendations = action(() => this._recommendations = recommendations)
- setRecommendations()
+ const setRecommendations = action(() => (this._recommendations = recommendations));
+ setRecommendations();
}
};
@@ -439,6 +337,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
*/
resetSearch = action(() => {
this._results.forEach((_, doc) => {
+ DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true);
Doc.UnBrushDoc(doc);
Doc.UnHighlightDoc(doc);
Doc.ClearSearchMatches();
@@ -461,7 +360,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
*/
@computed
public get selectOptions() {
- const selectValues = ['all', 'rtf', 'image', 'pdf', 'web', 'video', 'audio', 'collection'];
+ const selectValues = ['all', DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.WEB, DocumentType.VID, DocumentType.AUDIO, DocumentType.COL];
return selectValues.map(value => (
<option key={value} value={value}>
@@ -517,19 +416,19 @@ 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-keys">{result[1].join(', ')}</div>
+ <div className="searchBox-result-keys" style={{ color: SettingsManager.userVariantColor }}>
+ {result[1].join(', ')}
+ </div>
</div>
</Tooltip>
);
}
});
- const recommendationsJSX: JSX.Element[] = this._recommendations.map((props) => (
- <Recommendation {...props}/>
- ))
+ const recommendationsJSX: JSX.Element[] = this._recommendations.map(props => <Recommendation {...props} />);
return (
- <div className="searchBox-container" style={{pointerEvents: 'all', background: StrCast(Doc.UserDoc().userBackgroundColor)}}>
+ <div className="searchBox-container" style={{ pointerEvents: 'all', color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}>
<div className="searchBox-bar">
{isLinkSearch ? null : (
<select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
@@ -552,20 +451,24 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
ref={this._inputRef}
/>
</div>
- {resultsJSX.length > 0 && <div className="searchBox-results-container">
- <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
- <div className="section-title">Results</div>
- <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ {resultsJSX.length > 0 && (
+ <div className="searchBox-results-container">
+ <div className="section-header" style={{ background: SettingsManager.userVariantColor }}>
+ <div className="section-title">Results</div>
+ <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ </div>
+ <div className="searchBox-results-view">{resultsJSX}</div>
</div>
- <div className="searchBox-results-view">{resultsJSX}</div>
- </div>}
- {recommendationsJSX.length > 0 && <div className="searchBox-recommendations-container">
- <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
- <div className="section-title">Recommendations</div>
- <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ )}
+ {recommendationsJSX.length > 0 && (
+ <div className="searchBox-recommendations-container">
+ <div className="section-header" style={{ background: SettingsManager.userVariantColor }}>
+ <div className="section-title">Recommendations</div>
+ <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ </div>
+ <div className="searchBox-recommendations-view">{recommendationsJSX}</div>
</div>
- <div className="searchBox-recommendations-view">{recommendationsJSX}</div>
- </div>}
+ )}
</div>
);
}