aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordg314 <david_grossman@brown.edu>2021-07-17 15:13:39 -0400
committerdg314 <david_grossman@brown.edu>2021-07-17 15:13:39 -0400
commit48dbde117728e4b36bae11f0f16a796059ecf7ee (patch)
tree90ed4c780c7afaa612e4a4c916121bd875ba6259 /src
parent4cb75250bacbd08f4ae2c6ef6b4a00472bc890c3 (diff)
initial search panel
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts27
-rw-r--r--src/client/views/MainView.tsx11
-rw-r--r--src/client/views/StyleProvider.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/SchemaTable.tsx3
-rw-r--r--src/client/views/search/SearchBox.tsx117
6 files changed, 41 insertions, 121 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 12733e815..596ccd9a6 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -35,6 +35,8 @@ import { UndoManager } from "./UndoManager";
import { SnappingManager } from "./SnappingManager";
import { InkTool } from "../../fields/InkField";
import { computedFn } from "mobx-utils";
+import { CollectionSchemaBooleanCell } from "../views/collections/CollectionSchemaCells";
+import { Console } from "console";
export let resolvedPorts: { server: number, socket: number };
@@ -53,6 +55,7 @@ export class CurrentUserUtils {
@observable public static GuestDashboard: Doc | undefined;
@observable public static GuestMobile: Doc | undefined;
@observable public static propertiesWidth: number = 0;
+ @observable public static searchPanelWidth: number = 0;
// sets up the default User Templates - slideView, headerView
static setupUserTemplateButtons(doc: Doc) {
@@ -516,6 +519,7 @@ export class CurrentUserUtils {
static async menuBtnDescriptions(doc: Doc) {
return [
{ title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
+ { title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
{ title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' },
{ title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
{ title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
@@ -529,14 +533,15 @@ export class CurrentUserUtils {
];
}
- static setupSearchPanel(doc: Doc) {
+ /*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
@@ -807,6 +812,7 @@ export class CurrentUserUtils {
(doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Clear All"]);
}
}
+
static setupFilterDocs(doc: Doc) {
// setup Filter item
if (doc.currentFilter === undefined) {
@@ -939,6 +945,21 @@ export class CurrentUserUtils {
}
}
+ // Search sidebar is where searches within the document are performed
+ static setupSearchSidebar(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;
+ }
+ if (doc.mySearchPanel === undefined) {
+ const searchPanelDoc = Cast(doc.mySearchPanelDoc, Doc, null);
+ //const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
+ doc.mySearchPanel = new PrefetchProxy(Docs.Create.StackingDocument([searchPanelDoc], { title: "Search", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true }));
+ }
+ }
+
static setupClickEditorTemplates(doc: Doc) {
if (doc["clickFuncs-child"] === undefined) {
// to use this function, select it from the context menu of a collection. then edit the onChildClick script. Add two Doc variables: 'target' and 'thisContainer', then assign 'target' to some target collection. After that, clicking on any document in the initial collection will open it in the target
@@ -1023,8 +1044,8 @@ export class CurrentUserUtils {
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
this.setupImportSidebar(doc);
+ this.setupSearchSidebar(doc); // sets up the search sidebar
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
- this.setupSearchPanel(doc);
this.setupOverlays(doc); // documents in overlay layer
this.setupDockedButtons(doc); // the bottom bar of font icons
await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eeb1fc95..bc9c6f4d2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -180,8 +180,8 @@ export class MainView extends React.Component {
const targClass = targets[0].className.toString();
if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
const check = targets.some((thing) =>
- (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
- thing.className === "collectionSchema-header-menuOptions"));
+ (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+ thing.className === "collectionSchema-header-menuOptions"));
!check && SearchBox.Instance.resetSearch(true);
}
!targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
@@ -388,7 +388,6 @@ export class MainView extends React.Component {
SettingsManager.Instance.open();
break;
case "Catalog":
- SearchBox.Instance._searchFullDB = "My Stuff";
SearchBox.Instance.enter(undefined);
break;
case "Help":
@@ -523,7 +522,7 @@ export class MainView extends React.Component {
</svg>;
}
- @computed get search() {
+ /*@computed get search() {
TraceMobx();
return <div className="mainView-searchPanel">
<SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
@@ -555,7 +554,7 @@ export class MainView extends React.Component {
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined} />
</div>;
- }
+ }*/
@computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
return !DocumentLinksButton.invisibleWebDoc ? null :
@@ -604,7 +603,7 @@ export class MainView extends React.Component {
<GroupManager />
<GoogleAuthenticationManager />
<DocumentDecorations boundsLeft={this.leftOffset} boundsTop={this.topOffset} />
- {this.search}
+ {/*this.search*/}
<CollectionMenu />
{LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
{DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 9e61351c4..e670420d1 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -100,7 +100,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
const backColor = backgroundCol();// || (darkScheme() ? "black" : "white");
if (!backColor) return undefined;
const nonAlphaColor = backColor.startsWith("#") ? (backColor as string).substring(0, 7) :
- backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor
+ backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor;
const col = Color(nonAlphaColor).rgb();
const colsum = (col.red() + col.green() + col.blue());
if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black";
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index b33c437a9..971dd5cbf 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -556,7 +556,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
style={{
overflow: this.props.scrollOverflow === true ? "scroll" : undefined, backgroundColor: "white",
pointerEvents: this.props.Document._searchDoc !== undefined && !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined,
- width: name === "collectionSchemaView-searchContainer" ? "auto" : this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
+ width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
}} >
<div className="collectionSchemaView-tableContainer"
style={{ width: `calc(100% - ${this.previewWidth()}px)` }}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 0c69ee030..0175b0dc2 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -196,6 +196,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
<div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
<FontAwesomeIcon icon={sortIcon} size="lg" />
</div>
+ {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
</div>;
return {
@@ -559,7 +560,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()}
onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
{this.reactTable}
- {this.props.Document._chromeHidden ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+ {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
{!this._showDoc ? (null) :
<div className="collectionSchemaView-documentPreview" ref="overlay"
style={{
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index b722868d6..740a28825 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -3,9 +3,9 @@ import { Tooltip } from '@material-ui/core';
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Field, Opt, DocListCastAsync } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym } from '../../../fields/Doc';
import { documentSchema } from "../../../fields/documentSchemas";
-import { Copy, Id } from '../../../fields/FieldSymbols';
+import { Copy, Id, ToString } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -52,8 +52,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
private docsforfilter: Doc[] | undefined = [];
private realTotalResults: number = 0;
private newsearchstring = "";
- private collectionRef = React.createRef<HTMLDivElement>();
-
@observable _undoBackground: string | undefined = "";
@observable _icons: string[] = this._allIcons;
@@ -116,62 +114,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
});
- getFinalQuery(query: string): string {
- //alters the query so it looks in the correct fields
- //if this is true, th`en not all of the field boxes are checked
- //TODO: data
- const initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []);
-
- const filters: string[] = [];
-
- for (const initFilter of initialfilters) {
- const fields = initFilter.split(":");
- if (fields[2] !== undefined) {
- filters.push(fields[0]);
- filters.push(fields[1]);
- filters.push(fields[2]);
- }
- }
-
- const finalfilters: { [key: string]: string[] } = {};
-
- for (let i = 0; i < filters.length; i = i++) {
- const fields = filters[i].split(":");
- if (finalfilters[fields[0]] !== undefined) {
- finalfilters[fields[0]].push(fields[1]);
- }
- else {
- finalfilters[fields[0]] = [fields[1]];
- }
- }
-
- for (const key in finalfilters) {
- const values = finalfilters[key];
- if (values.length === 1) {
- const mod = "_t:";
- const newWords: string[] = [];
- const oldWords = values[0].split(" ");
- oldWords.forEach((word, i) => i === 0 ? newWords.push(key + mod + word) : newWords.push("AND " + key + mod + word));
- query = `(${query}) AND (${newWords.join(" ")})`;
- }
- else {
- for (let i = 0; i < values.length; i++) {
- const mod = "_t:";
- const newWords: string[] = [];
- const oldWords = values[i].split(" ");
- oldWords.forEach((word, i) => i === 0 ? newWords.push(key + mod + word) : newWords.push("AND " + key + mod + word));
- const v = "(" + newWords.join(" ") + ")";
- if (i === 0) {
- query = `(${query}) AND (${v}` + (values.length === 1 ? ")" : "");
- }
- else query = query + " OR " + v + (i === values.length - 1 ? ")" : "");
- }
- }
- }
-
- return query.replace(/-\s+/g, '');
- }
-
@action
filterDocsByType(docs: Doc[]) {
const finalDocs: Doc[] = [];
@@ -340,7 +282,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
this._results[index][1].push(...hlights);
this._results[index][2].push(...line);
}
-
}));
this._curRequest = undefined;
@@ -360,37 +301,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
return this._lockPromise;
}
- startDragCollection = async () => {
- const res = await this.getAllResults(this.getFinalQuery(StrCast(this.layoutDoc._searchString)));
- const filtered = this.filterDocsByType(res.docs);
- const docs = filtered.map(doc => Doc.GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeDelegate(doc) : Doc.MakeAlias(doc));
- let x = 0;
- let y = 0;
- for (const doc of docs.map(d => Doc.Layout(d))) {
- doc.x = x;
- doc.y = y;
- const size = 200;
- const aspect = Doc.NativeHeight(doc) / (Doc.NativeWidth(doc) || 1);
- if (aspect > 1) {
- doc._height = size;
- doc._width = size / aspect;
- } else if (aspect > 0) {
- doc._width = size;
- doc._height = size * aspect;
- } else {
- doc._width = size;
- doc._height = size;
- }
- x += 250;
- if (x > 1000) {
- x = 0;
- y += 300;
- }
- }
- const headers = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).map(h => { const v = h[Copy](); v.color = "#f1efeb"; return v; });
- return Docs.Create.SchemaDocument(headers, DocListCast(this.dataDoc[this.fieldKey]), { _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString) });
- }
-
@action.bound
openSearch(e: React.SyntheticEvent) {
e.stopPropagation();
@@ -479,6 +389,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
render() {
const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
+
return (
<div style={{ pointerEvents: "all" }} className="searchBox-container">
<div className="searchBox-bar" style={{ background: SearchBox.Instance._undoBackground }}>
@@ -487,7 +398,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
{`${Doc.CurrentUserEmail}`}
<div className="searchBox-logoff" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
Logoff
- </div>
+ </div>
</div>
<div className="searchBox-lozenge" onClick={() => DocServer.UPDATE_SERVER_CACHE()}>
{`UI project`}
@@ -499,10 +410,10 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
</select>
<div className="searchBox-dashboards" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}>
New
- </div>
+ </div>
<div className="searchBox-dashboards" onClick={undoBatch(() => CurrentUserUtils.snapshotDashboard(Doc.UserDoc()))}>
Snapshot
- </div>
+ </div>
</div>
</div>
<div className="searchBox-query" >
@@ -511,24 +422,12 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
style={{ padding: 1, paddingLeft: 20, paddingRight: 60, color: "black", height: 20, width: 250 }} />
<div style={{ display: "flex", alignItems: "center" }}>
<div style={{ position: "absolute", left: 10 }}>
- <Tooltip title={<div className="dash-tooltip" >drag search results as collection</div>}>
- <div ref={this.collectionRef}><FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
- style={{ cursor: "hand", color: "black", padding: 1, position: "relative" }} /></div>
- </Tooltip>
+ <FontAwesomeIcon icon={"search"} size="lg"
+ style={{ color: "black", padding: 1, position: "relative" }} />
</div>
<div style={{ position: "absolute", left: Doc.UserDoc().noviceMode ? 220 : 200, width: 30, zIndex: 9000, color: "grey", background: "white", }}>
{`${this._results.length}` + " of " + `${this.realTotalResults}`}
</div>
- {Doc.UserDoc().noviceMode ? (null) : <div style={{ cursor: "default", left: 235, position: "absolute", }}>
- <Tooltip title={<div className="dash-tooltip" >only display documents matching search</div>} >
- <div>
- <FontAwesomeIcon icon={"filter"} size="lg"
- style={{ cursor: "hand", padding: 1, backgroundColor: this.filter ? "white" : "lightgray", color: this.filter ? "black" : "white" }}
- onPointerDown={e => { e.stopPropagation(); SetupDrag(this.collectionRef, () => this.layoutDoc._searchString ? this.startDragCollection() : undefined); }}
- onClick={action(() => this.setSearchFilter(this.currentSelectedCollection, this.filter ? undefined : this.docsforfilter))} />
- </div>
- </Tooltip>
- </div>}
</div>
</div >
</div >