aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/search
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/search')
-rw-r--r--src/client/views/search/FilterBox.tsx9
-rw-r--r--src/client/views/search/SearchBox.scss3
-rw-r--r--src/client/views/search/SearchBox.tsx29
-rw-r--r--src/client/views/search/SearchItem.scss108
-rw-r--r--src/client/views/search/SearchItem.tsx132
5 files changed, 107 insertions, 174 deletions
diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx
index 12e1bc265..684f50766 100644
--- a/src/client/views/search/FilterBox.tsx
+++ b/src/client/views/search/FilterBox.tsx
@@ -62,15 +62,6 @@ export class FilterBox extends React.Component {
super(props);
FilterBox.Instance = this;
}
-
- componentDidMount = () => {
- document.addEventListener("pointerdown", (e) => {
- if (!e.defaultPrevented && e.timeStamp !== this._pointerTime) {
- SearchBox.Instance.closeSearch();
- }
- });
- }
-
setupAccordion() {
$('document').ready(function () {
const acc = document.getElementsByClassName('filter-header');
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 4eb992d36..0825580b7 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -70,8 +70,7 @@
display: flex;
flex-direction: column;
height: 100%;
- overflow: hidden;
- overflow-y: auto;
+ overflow: visible;
.no-result {
width: 500px;
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c45fbe210..dd1ac7421 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -12,13 +12,11 @@ import { Utils } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { SetupDrag } from '../../util/DragManager';
import { SearchUtil } from '../../util/SearchUtil';
-import { MainView } from '../MainView';
import { FilterBox } from './FilterBox';
import "./FilterBox.scss";
import "./SearchBox.scss";
import { SearchItem } from './SearchItem';
import { IconBar } from './IconBar';
-import { string } from 'prop-types';
library.add(faTimes);
@@ -85,7 +83,11 @@ export class SearchBox extends React.Component {
this._maxSearchIndex = 0;
}
- enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } };
+ enter = (e: React.KeyboardEvent) => {
+ if (e.key === "Enter") {
+ this.submitSearch();
+ }
+ }
public static async convertDataUri(imageUri: string, returnedFilename: string) {
try {
@@ -232,8 +234,7 @@ export class SearchBox extends React.Component {
y += 300;
}
}
- return Docs.Create.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
-
+ return Docs.Create.TreeDocument(docs, { width: 200, height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
}
@action.bound
@@ -307,7 +308,7 @@ export class SearchBox extends React.Component {
this.getResults(this._searchString);
if (i < this._results.length) result = this._results[i];
if (result) {
- const highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
+ 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";
}
@@ -315,7 +316,7 @@ export class SearchBox extends React.Component {
else {
result = this._results[i];
if (result) {
- const highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
+ 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";
}
@@ -337,9 +338,9 @@ export class SearchBox extends React.Component {
render() {
return (
- <div className="searchBox-container">
+ <div className="searchBox-container" onPointerDown={e => { e.stopPropagation(); e.preventDefault(); }}>
<div className="searchBox-bar">
- <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef} title="Drag Results as Collection">
+ <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, () => this._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}
@@ -347,13 +348,13 @@ export class SearchBox extends React.Component {
style={{ width: this._searchbarOpen ? "500px" : "100px" }} />
<button className="searchBox-barChild searchBox-filter" title="Advanced Filtering Options" onClick={FilterBox.Instance.openFilter} onPointerDown={FilterBox.Instance.stopProp}><FontAwesomeIcon icon="ellipsis-v" color="white" /></button>
</div>
- {(this._numTotalResults > 0 || !this._searchbarOpen) ? (null) :
- (<div className="searchBox-quickFilter" onPointerDown={this.openSearch}>
- <div className="filter-panel"><IconBar /></div>
- </div>)}
+ <div className="searchBox-quickFilter" onPointerDown={this.openSearch}>
+ <div className="filter-panel"><IconBar /></div>
+ </div>
<div className="searchBox-results" onScroll={this.resultsScrolled} style={{
display: this._resultsOpen ? "flex" : "none",
- height: this.resFull ? "auto" : this.resultHeight, overflow: this.resFull ? "auto" : "visible"
+ height: this.resFull ? "auto" : this.resultHeight,
+ overflow: "visibile" // this.resFull ? "auto" : "visible"
}} ref={this.resultsRef}>
{this._visibleElements}
</div>
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss
index 9f12994c3..469f062b2 100644
--- a/src/client/views/search/SearchItem.scss
+++ b/src/client/views/search/SearchItem.scss
@@ -1,22 +1,14 @@
@import "../globalCssVariables";
-.search-overview {
+.searchItem-overview {
display: flex;
flex-direction: reverse;
justify-content: flex-end;
z-index: 0;
}
-.link-count {
- background: black;
- border-radius: 20px;
- color: white;
- width: 15px;
- text-align: center;
- margin-top: 5px;
-}
.searchBox-placeholder,
-.search-overview .search-item {
+.searchItem-overview .searchItem {
width: 100%;
background: $light-color-secondary;
border-color: $intermediate-color;
@@ -26,19 +18,19 @@
max-height: 150px;
height: auto;
z-index: 0;
- display: inline-block;
- overflow: auto;
+ display: flex;
+ overflow: visible;
- .main-search-info {
+ .searchItem-body {
display: flex;
flex-direction: row;
width: 100%;
- .search-title-container {
+ .searchItem-title-container {
width: 100%;
overflow: hidden;
- .search-title {
+ .searchItem-title {
text-transform: uppercase;
text-align: left;
width: 100%;
@@ -46,75 +38,28 @@
}
}
- .search-info {
+ .searchItem-info {
display: flex;
justify-content: flex-end;
- .link-container.item {
- margin-left: auto;
- margin-right: auto;
- height: 26px;
- width: 26px;
- border-radius: 13px;
- background: $dark-color;
- color: $light-color-secondary;
- display: flex;
- justify-content: center;
- align-items: center;
- -webkit-transition: all 0.2s ease-in-out;
- -moz-transition: all 0.2s ease-in-out;
- -o-transition: all 0.2s ease-in-out;
- transition: all 0.2s ease-in-out;
- transform-origin: top right;
- overflow: hidden;
- position: relative;
-
-
- .link-extended {
- // display: none;
- visibility: hidden;
- opacity: 0;
- position: relative;
- z-index: 500;
- overflow: hidden;
- -webkit-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s;
- -moz-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s;
- -o-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s;
- transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s;
- // transition-delay: 1s;
- }
-
- }
-
- .link-container.item:hover {
- width: 70px;
- }
-
- .link-container.item:hover .link-count {
- opacity: 0;
- }
-
- .link-container.item:hover .link-extended {
- opacity: 1;
- visibility: visible;
- // display: inline;
- }
-
.icon-icons {
width: 50px
}
.icon-live {
width: 175px;
+ height: 0px;
}
+ .icon-icons {
+ height:auto;
+ }
.icon-icons,
.icon-live {
- height: auto;
margin: auto;
- overflow: hidden;
+ overflow: visible;
- .search-type {
+ .searchItem-type {
display: inline-block;
width: 100%;
position: absolute;
@@ -133,11 +78,11 @@
}
}
- .search-type:hover+.search-label {
+ .searchItem-type:hover+.searchItem-label {
opacity: 1;
}
- .search-label {
+ .searchItem-label {
font-size: 10;
position: relative;
right: 0px;
@@ -151,8 +96,6 @@
}
.icon-live:hover {
- height: 175px;
-
.pdfBox-cont {
img {
width: 100% !important;
@@ -161,48 +104,51 @@
}
}
- .search-info:hover {
+ .searchItem-info:hover {
width: 60%;
}
}
}
-.search-item:hover~.searchBox-instances,
+.searchItem:hover~.searchBox-instances,
.searchBox-instances:hover,
.searchBox-instances:active {
opacity: 1;
background: $lighter-alt-accent;
- width:150px
}
-.search-item:hover {
+.searchItem:hover {
transition: all 0.2s;
background: $lighter-alt-accent;
}
-.search-highlighting {
+.searchItem-highlighting {
overflow: hidden;
text-overflow: ellipsis;
white-space: pre;
}
.searchBox-instances {
- float: left;
opacity: 1;
- width: 0px;
+ width:40px;
+ height:40px;
+ background: gray;
transition: all 0.2s ease;
color: black;
overflow: hidden;
+ right:-100;
+ display:inline-block;
}
-.search-overview:hover {
+.searchItem-overview:hover {
z-index: 1;
}
.searchBox-placeholder {
min-height: 50px;
margin-left: 150px;
+ width: calc(100% - 150px);
text-transform: uppercase;
text-align: left;
font-weight: bold;
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 6ffff0562..88a4d4c50 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -4,24 +4,24 @@ import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlob
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils } from "../../../Utils";
+import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, emptyPath } from "../../../Utils";
import { DocumentType } from "../../documents/DocumentTypes";
import { DocumentManager } from "../../util/DocumentManager";
import { DragManager, SetupDrag } from "../../util/DragManager";
-import { LinkManager } from "../../util/LinkManager";
import { SearchUtil } from "../../util/SearchUtil";
import { Transform } from "../../util/Transform";
import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss";
import { CollectionViewType } from "../collections/CollectionView";
import { CollectionDockingView } from "../collections/CollectionDockingView";
import { ContextMenu } from "../ContextMenu";
-import { DocumentView } from "../nodes/DocumentView";
import { SearchBox } from "./SearchBox";
import "./SearchItem.scss";
import "./SelectorContextMenu.scss";
+import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
+import { ButtonSelector, ParentDocSelector } from "../collections/ParentDocumentSelector";
export interface SearchItemProps {
doc: Doc;
@@ -135,12 +135,11 @@ export class SearchItem extends React.Component<SearchItemProps> {
@observable _displayDim = 50;
componentDidMount() {
- this.props.doc.search_string = this.props.query;
- this.props.doc.search_fields = this.props.highlighting.join(", ");
+ Doc.SetSearchQuery(this.props.query);
+ this.props.doc.searchMatch = true;
}
componentWillUnmount() {
- this.props.doc.search_string = undefined;
- this.props.doc.search_fields = undefined;
+ this.props.doc.searchMatch = undefined;
}
//@computed
@@ -150,36 +149,29 @@ export class SearchItem extends React.Component<SearchItemProps> {
if (!this._useIcons) {
const returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
const returnYDimension = () => this._displayDim;
- const scale = () => returnXDimension() / NumCast(Doc.Layout(this.props.doc).nativeWidth, returnXDimension());
const docview = <div
onPointerDown={action(() => {
this._useIcons = !this._useIcons;
this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
})}
- onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))}
- onPointerLeave={action(() => this._displayDim = 50)} >
- <DocumentView
- fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
+ onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} >
+ <ContentFittingDocumentView
Document={this.props.doc}
+ LibraryPath={emptyPath}
+ fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
addDocument={returnFalse}
removeDocument={returnFalse}
ruleProvider={undefined}
- ScreenToLocalTransform={Transform.Identity}
addDocTab={returnFalse}
pinToPres={returnFalse}
+ getTransform={Transform.Identity}
renderDepth={1}
PanelWidth={returnXDimension}
PanelHeight={returnYDimension}
focus={emptyFunction}
- backgroundColor={returnEmptyString}
- parentActive={returnFalse}
+ moveDocument={returnFalse}
+ active={returnFalse}
whenActiveChanged={returnFalse}
- bringToFront={emptyFunction}
- zoomToScale={emptyFunction}
- getScale={returnOne}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- ContentScaling={scale}
/>
</div>;
return docview;
@@ -194,33 +186,21 @@ export class SearchItem extends React.Component<SearchItemProps> {
layoutresult.indexOf(DocumentType.HIST) !== -1 ? faChartBar :
layoutresult.indexOf(DocumentType.WEB) !== -1 ? faGlobeAsia :
faCaretUp;
- return <div onPointerDown={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
+ return <div onClick={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
<FontAwesomeIcon icon={button} size="2x" />
</div>;
}
collectionRef = React.createRef<HTMLDivElement>();
- startDocDrag = () => {
- const doc = this.props.doc;
- const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
- if (isProto) {
- return Doc.MakeDelegate(doc);
- } else {
- return Doc.MakeAlias(doc);
- }
- }
-
- @computed
- get linkCount() { return LinkManager.Instance.getAllRelatedLinks(this.props.doc).length; }
@action
pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); }
nextHighlight = (e: React.PointerEvent) => {
- e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e);
- const sstring = StrCast(this.props.doc.search_string);
- this.props.doc.search_string = "";
- setTimeout(() => this.props.doc.search_string = sstring, 0);
+ e.preventDefault();
+ e.button === 0 && SearchBox.Instance.openSearch(e);
+ this.props.doc.searchMatch = false;
+ setTimeout(() => this.props.doc.searchMatch = true, 0);
}
highlightDoc = (e: React.PointerEvent) => {
if (this.props.doc.type === DocumentType.LINK) {
@@ -264,46 +244,62 @@ export class SearchItem extends React.Component<SearchItemProps> {
ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
}
+ _downX = 0;
+ _downY = 0;
+ _target: any;
onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+ this._downX = e.clientX;
+ this._downY = e.clientY;
e.stopPropagation();
- const doc = Doc.IsPrototype(this.props.doc) ? Doc.MakeDelegate(this.props.doc) : this.props.doc;
- DragManager.StartDocumentDrag([e.currentTarget], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY, {
- handlers: { dragComplete: emptyFunction },
- hideSource: false,
- });
+ this._target = e.currentTarget;
+ document.removeEventListener("pointermove", this.onPointerMoved);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ document.addEventListener("pointermove", this.onPointerMoved);
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
+ onPointerMoved = (e: PointerEvent) => {
+ if (Math.abs(e.clientX - this._downX) > Utils.DRAG_THRESHOLD ||
+ Math.abs(e.clientY - this._downY) > Utils.DRAG_THRESHOLD) {
+ console.log("DRAGGIGNG");
+ 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;
+ DragManager.StartDocumentDrag([this._target], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY);
+ }
+ }
+ onPointerUp = (e: PointerEvent) => {
+ document.removeEventListener("pointermove", this.onPointerMoved);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ }
+
+ @computed
+ get contextButton() {
+ return <ParentDocSelector Views={DocumentManager.Instance.DocumentViews} Document={this.props.doc} addDocTab={(doc, data, where) => CollectionDockingView.AddRightSplit(doc, data)} />;
}
render() {
const doc1 = Cast(this.props.doc.anchor1, Doc);
const doc2 = Cast(this.props.doc.anchor2, Doc);
- return (
- <div className="search-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}>
- <div className="search-item" onPointerDown={this.nextHighlight} onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} id="result"
- onClick={this.onClick}>
- <div className="main-search-info">
- <div title="Drag as document" onPointerDown={this.onPointerDown} style={{ marginRight: "7px" }}> <FontAwesomeIcon icon="file" size="lg" />
- <div className="link-container item">
- <div className="link-count" title={`${this.linkCount + " links"}`}>{this.linkCount}</div>
- </div>
- </div>
- <div className="search-title-container">
- <div className="search-title">{StrCast(this.props.doc.title)}</div>
- <div className="search-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="search-highlighting">`${l}`</div>)}
- </div>
- <div className="search-info" style={{ width: this._useIcons ? "15%" : "400px" }}>
- <div className={`icon-${this._useIcons ? "icons" : "live"}`}>
- <div className="search-type" title="Click to Preview">{this.DocumentIcon()}</div>
- <div className="search-label">{this.props.doc.type ? this.props.doc.type : "Other"}</div>
- </div>
- </div>
+ return <div className="searchItem-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}>
+ <div className="searchItem" onPointerDown={this.nextHighlight} 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>
+ <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="searchBox-instances">
+ <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} /> :
- <SelectorContextMenu {...this.props} />}
+ this.contextButton}
</div>
</div>
- );
+ </div>;
}
} \ No newline at end of file