aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/CurrentUserUtils.ts27
-rw-r--r--src/client/views/GlobalKeyHandler.ts7
-rw-r--r--src/client/views/MainView.tsx37
-rw-r--r--src/client/views/search/SearchBox.scss19
-rw-r--r--src/client/views/search/SearchBox.tsx89
5 files changed, 81 insertions, 98 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 31384da3b..734b96b1e 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -46,6 +46,7 @@ export class CurrentUserUtils {
//TODO tfs: these should be temporary...
private static mainDocId: string | undefined;
+ public static searchBtn: Doc;
public static get id() { return this.curr_id; }
public static get MainDocId() { return this.mainDocId; }
public static set MainDocId(id: string | undefined) { this.mainDocId = id; }
@@ -533,15 +534,6 @@ export class CurrentUserUtils {
];
}
- /*static setupSearchPanel(doc: Doc) {
- if (doc.mySearchPanelDoc === undefined) {
- doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({
- _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
- childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
- })) as any as Doc;
- }
- }*/
-
static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
if (doc.menuStack === undefined) {
await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId); // sets up the right sidebar collection for mobile upload documents and sharing
@@ -562,10 +554,23 @@ export class CurrentUserUtils {
_height: 60,
watchedDocuments,
onClick: ScriptField.MakeScript(click, { scriptContext: "any" })
- }));
+ })
+ );
+
+ menuBtns.forEach(menuBtn => {
+ if (menuBtn.title == "Search") {
+ this.searchBtn = menuBtn;
+ }
+ });
// hack -- last button is assumed to be the userDoc
menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()");
+ menuBtns.forEach(menuBtn => {
+ if (menuBtn.title == "Search") {
+ doc.searchBtn = menuBtn
+ }
+ })
+
doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
title: "menuItemPanel",
childDropAction: "alias",
@@ -950,7 +955,7 @@ export class CurrentUserUtils {
if (doc.mySearchPanel === undefined) {
doc.mySearchPanel = new PrefetchProxy(Docs.Create.SearchDocument({
backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
- childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
+ childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "Search Sidebar", system: true
})) as any as Doc;
}
}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index d92cba3eb..2a3cb36c7 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -27,7 +27,6 @@ import { LightboxView } from "./LightboxView";
import { MainView } from "./MainView";
import { DocumentLinksButton } from "./nodes/DocumentLinksButton";
import { AnchorMenu } from "./pdf/AnchorMenu";
-import { SearchBox } from "./search/SearchBox";
import { CurrentUserUtils } from "../util/CurrentUserUtils";
import { SettingsManager } from "../util/SettingsManager";
@@ -225,7 +224,11 @@ export class KeyManager {
PromiseValue(Cast(Doc.UserDoc()["tabs-button-tools"], Doc)).then(pv => pv && (pv.onClick as ScriptField).script.run({ this: pv }));
break;
case "f":
- SearchBox.Instance.enter(undefined);
+ const searchBtn = Doc.UserDoc().searchBtn as Doc;
+
+ if (searchBtn) {
+ MainView.Instance.selectMenu(searchBtn);
+ }
break;
case "o":
const target = SelectionManager.Views()[0];
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 0d957518b..35222e91f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -387,9 +387,6 @@ export class MainView extends React.Component {
case "Settings":
SettingsManager.Instance.open();
break;
- case "Catalog":
- SearchBox.Instance.enter(undefined);
- break;
case "Help":
break;
default:
@@ -522,40 +519,6 @@ export class MainView extends React.Component {
</svg>;
}
- /*@computed get search() {
- TraceMobx();
- return <div className="mainView-searchPanel">
- <SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
- DataDoc={CurrentUserUtils.MySearchPanelDoc}
- fieldKey="data"
- dropAction="move"
- isSelected={returnTrue}
- isContentActive={returnTrue}
- select={returnTrue}
- setHeight={returnFalse}
- addDocument={undefined}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- rootSelected={returnTrue}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
- removeDocument={undefined}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.getPWidth}
- PanelHeight={this.getPHeight}
- renderDepth={0}
- focus={DocUtils.DefaultFocus}
- docViewPath={returnEmptyDoclist}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />
- </div>;
- }*/
-
@computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
return !DocumentLinksButton.invisibleWebDoc ? null :
<div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index f8e994da7..e4d1ac6a3 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -22,17 +22,18 @@
.searchBox-type {
display: block;
- width: 50px;
+ width: 55px;
outline: none;
padding: 1px 5px 1px 5px;
color: black;
height: 25px;
border: 1px solid black;
+ border-right: 0px;
}
.searchBox-input {
display: block;
- width: calc(100% - 50px);
+ width: calc(100% - 55px);
outline: none;
padding: 1px 5px 1px 5px;
color: black;
@@ -74,10 +75,20 @@
background: gray;
}
- .titletitle {
+ .searchBox-result-title {
display: relative;
float: left;
- left: 50px;
+ width: calc(100% - 60px);
+ text-align: left;
+ }
+
+ .searchBox-result-type {
+ font-size: 12px;
+ display: relative;
+ float: right;
+ width: 60px;
+ text-align: right;
+ color: #333;
}
}
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 374a754bf..3cbb4b3b1 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -35,29 +35,30 @@ export const searchSchema = createSchema({ Document: Doc });
type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
+const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
+
@observer
export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
public static Instance: SearchBox;
- private _allIcons: string[] = [DocumentType.INK, DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB];
private _resultsSet = new Map<Doc, number>();
private _inputRef = React.createRef<HTMLInputElement>();
- private _disposers: { [name: string]: IReactionDisposer } = {};
- private _blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
@observable _searchString = "";
@observable _docTypeString = "all";
- @observable _icons: string[] = this._allIcons;
@observable _results: [Doc, string[], string[]][] = [];
@observable _selectedResult: Doc | undefined = undefined;
@observable _deletedDocsStatus: boolean = false;
@observable _onlyAliases: boolean = true;
- @computed get filter() { return this._results?.length && (this.currentSelectedCollection?.props.Document._searchFilterDocs || this.currentSelectedCollection?.props.Document._docFilters); }
constructor(props: any) {
super(props);
SearchBox.Instance = this;
+ this._searchString = "reset_search";
+ this.submitSearch();
+ this._searchString = "";
+ this.submitSearch();
}
componentDidMount = action(() => {
@@ -67,11 +68,9 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
});
componentWillUnmount() {
- Object.values(this._disposers).forEach(disposer => disposer?.());
+ this.resetSearch;
}
- @computed get currentSelectedCollection() { return CollectionDockingView.Instance; }
-
onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
this._searchString = e.target.value;
this.submitSearch();
@@ -79,32 +78,13 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
this._docTypeString = e.target.value;
- this.submitSearch();
});
- /*enter = action((e: React.KeyboardEvent | undefined) => {
- if (!e || e.key === "Enter") {
- this.submitSearch();
- }
- });*/
-
onResultClick = action((doc: Doc) => {
this.selectElement(doc);
this._selectedResult = doc;
});
- @action
- filterDocsByType(docs: Doc[]) {
- const finalDocs: Doc[] = [];
- docs.forEach(doc => {
- const layoutresult = StrCast(doc.type, "string") as DocumentType;
- if (layoutresult && !this._blockedTypes.includes(layoutresult) && this._icons.includes(layoutresult)) {
- finalDocs.push(doc);
- }
- });
- return finalDocs;
- }
-
static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
let newarray: Doc[] = [];
while (docs.length > 0) {
@@ -120,23 +100,39 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
}
+ static formatType(type: String): String {
+ if (type == "pdf") {
+ return "PDF";
+ }
+ else if (type == "image") {
+ return "Img";
+ }
+
+ return type.charAt(0).toUpperCase() + type.substring(1, 3);
+ }
+
@action
searchCollection(query: string) {
- const selectedCollection = this.currentSelectedCollection;//SelectionManager.SelectedDocuments()[0];
+ const selectedCollection = CollectionDockingView.Instance;
+ const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
query = query.toLowerCase();
+ this._results = []
+
if (selectedCollection !== undefined) {
- // this._currentSelectedCollection = selectedCollection;
const docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]);
- const found: [Doc, string[], string[]][] = [];
SearchBox.foreachRecursiveDoc(docs, (doc: Doc) => {
- const hlights = new Set<string>();
- SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
- Array.from(hlights.keys()).length > 0 && found.push([doc, Array.from(hlights.keys()), []]);
+ const dtype = StrCast(doc.type, "string") as DocumentType;
+ if (dtype && !blockedTypes.includes(dtype)) {
+ const hlights = new Set<string>();
+ SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
+ Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys()), []]);
+ }
});
-
- this._results = found;
}
+
+ this._results = Array.from(new Set(this._results))
+ this._selectedResult = undefined
}
static documentKeys(doc: Doc) {
@@ -155,7 +151,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
submitSearch = async () => {
this.resetSearch();
- this.dataDoc[this.fieldKey] = new List<Doc>([]);
+ //this.dataDoc[this.fieldKey] = new List<Doc>([]);
let query = StrCast(this._searchString);
Doc.SetSearchQuery(query);
this._results = [];
@@ -169,6 +165,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
resetSearch = action(() => {
this._results.forEach(result => {
Doc.UnBrushDoc(result[0]);
+ Doc.UnHighlightDoc(result[0]);
Doc.ClearSearchMatches();
});
});
@@ -178,6 +175,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
render() {
+ var validResults = 0;
+
const results = this._results.map(result => {
var className = "searchBox-results-scroll-view-result";
@@ -186,28 +185,30 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
- return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="titletitle">{result[0].title}</div></div>)
+ validResults++;
+ return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="searchBox-result-title">{result[0].title}</div><div className="searchBox-result-type">{SearchBox.formatType(StrCast(result[0].type))}</div></div>)
}
return null;
})
- results.filter(result => result)
+ results.filter(result => result);
+
+ const selectOptions = selectValues.map(value => {
+ return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
+ })
return (
<div style={{ pointerEvents: "all" }} className="searchBox-container">
<div className="searchBox-bar">
<select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
- <option value="all">All</option>
- <option value="rtf">Text</option>
- <option value="img">Image</option>
- <option value="pdf">PDF</option>
+ {selectOptions}
</select>
- <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" ref={this._inputRef} className="searchBox-input" />
+ <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" ref={this._inputRef} />
</div >
<div className="searchBox-results-container">
<div className="searchBox-results-count">
- {`${results.length}` + " result" + (results.length == 1 ? "" : "s")}
+ {`${validResults}` + " result" + (validResults == 1 ? "" : "s")}
</div>
<div className="searchBox-results-scroll-view">
{results}