aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/Main.scss3
-rw-r--r--src/client/views/Main.tsx4
-rw-r--r--src/client/views/SearchBox.scss99
-rw-r--r--src/client/views/SearchBox.tsx121
-rw-r--r--src/client/views/SearchItem.tsx34
-rw-r--r--src/server/Search.ts2
6 files changed, 261 insertions, 2 deletions
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index 5c5c252e9..2430e8f6c 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -47,7 +47,7 @@ h1 {
}
.jsx-parser {
- width:100%;
+ width: 100%;
pointer-events: none;
border-radius: inherit;
}
@@ -184,6 +184,7 @@ button:hover {
overflow: scroll;
z-index: 1;
}
+
#mainContent-div {
width: 100%;
height: 100%;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 617580332..677902c5b 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -31,6 +31,7 @@ import "./Main.scss";
import { MainOverlayTextBox } from './MainOverlayTextBox';
import { DocumentView } from './nodes/DocumentView';
import { PreviewCursor } from './PreviewCursor';
+import { SearchBox } from './SearchBox';
import { SelectionManager } from '../util/SelectionManager';
import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc';
import { Cast, FieldValue, StrCast } from '../../new_fields/Types';
@@ -38,7 +39,6 @@ import { DocServer } from '../DocServer';
import { listSpec } from '../../new_fields/Schema';
import { Id } from '../../new_fields/RefField';
-
@observer
export class Main extends React.Component {
public static Instance: Main;
@@ -266,9 +266,11 @@ export class Main extends React.Component {
<button className="toolbar-button round-button" title="Redo" onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button>
<button className="toolbar-button round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /></button>
</div >,
+ <div className="main-searchDiv" key="search" style={{ top: '34px', right: '1px', position: 'absolute' }} > <SearchBox /> </div>,
<div className="main-buttonDiv" key="logout" style={{ top: '34px', right: '1px', position: 'absolute' }} ref={logoutRef}>
<button onClick={() => request.get(DocServer.prepend(RouteStore.logout), emptyFunction)}>Log Out</button></div>
];
+
}
render() {
diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss
new file mode 100644
index 000000000..f4fc0029e
--- /dev/null
+++ b/src/client/views/SearchBox.scss
@@ -0,0 +1,99 @@
+@import "globalCssVariables";
+
+.searchBox {
+ height: 32px;
+ //display: flex;
+ //padding: 4px;
+ -webkit-transition: width 0.4s ease-in-out;
+ transition: width 0.4s ease-in-out;
+ align-items: center;
+
+
+
+ input[type=text] {
+ width: 130px;
+ -webkit-transition: width 0.4s;
+ transition: width 0.4s;
+ position: absolute;
+ right: 100px;
+ }
+
+ input[type=text]:focus {
+ width: 500px;
+ outline: 3px solid lightblue;
+ }
+
+ .filter-button {
+ position: absolute;
+ right: 30px;
+ }
+
+ .submit-search {
+ text-align: right;
+ color: $dark-color;
+ -webkit-transition: right 0.4s;
+ transition: right 0.4s;
+ }
+
+ .submit-search:hover {
+ color: $main-accent;
+ transform: scale(1.05);
+ cursor: pointer;
+ }
+}
+
+.filter-form {
+ background: $dark-color;
+ height: 400px;
+ width: 400px;
+ position: relative;
+ right: 1px;
+ color: $light-color;
+ padding: 10px;
+ flex-direction: column;
+}
+
+#header {
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ font-size: 100%;
+ height: 40px;
+}
+
+#option {
+ height: 20px;
+}
+
+.results {
+ top: 300px;
+ display: flex;
+ flex-direction: column;
+}
+
+.search-item {
+ width: 500px;
+ height: 50px;
+ background: $light-color-secondary;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ transition: all 0.1s;
+ border-width: 0.11px;
+ border-style: none;
+ border-color: $intermediate-color;
+ border-bottom-style: solid;
+ padding: 10px;
+ white-space: nowrap;
+ font-size: 13px;
+}
+
+.search-item:hover {
+ transition: all 0.1s;
+ background: $lighter-alt-accent;
+}
+
+.search-title {
+ text-transform: uppercase;
+ text-align: left;
+ width: 8vw;
+} \ No newline at end of file
diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx
new file mode 100644
index 000000000..a52598f4c
--- /dev/null
+++ b/src/client/views/SearchBox.tsx
@@ -0,0 +1,121 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import { observable, action, runInAction } from 'mobx';
+import { Utils } from '../../Utils';
+import { MessageStore } from '../../server/Message';
+import "./SearchBox.scss";
+import { faSearch } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { library } from '@fortawesome/fontawesome-svg-core';
+// const app = express();
+// import * as express from 'express';
+import { Search } from '../../server/Search';
+import * as rp from 'request-promise';
+import { SearchItem } from './SearchItem';
+import { isString } from 'util';
+import { constant } from 'async';
+import { DocServer } from '../DocServer';
+import { Doc } from '../../new_fields/Doc';
+import { Id } from '../../new_fields/RefField';
+
+
+library.add(faSearch);
+
+@observer
+export class SearchBox extends React.Component {
+ @observable
+ searchString: string = "";
+
+ @observable private _open: boolean = false;
+ @observable private _resultsOpen: boolean = false;
+
+ @observable
+ private _results: Doc[] = [];
+
+ @action.bound
+ onChange(e: React.ChangeEvent<HTMLInputElement>) {
+ this.searchString = e.target.value;
+ console.log(this.searchString)
+ }
+
+ @action
+ submitSearch = async () => {
+ runInAction(() => this._results = []);
+ let query = this.searchString;
+
+ let response = await rp.get('http://localhost:1050/search', {
+ qs: {
+ query
+ }
+ });
+ let results = JSON.parse(response);
+
+ //gets json result into a list of documents that can be used
+ this.getResults(results);
+
+ runInAction(() => { this._resultsOpen = true; });
+ }
+
+ @action
+ getResults = async (res: string[]) => {
+ res.map(async result => {
+ const doc = await DocServer.GetRefField(result);
+ if (doc instanceof Doc) {
+ runInAction(() => this._results.push(doc));
+ }
+ });
+ }
+
+ @action
+ handleClick = (e: Event): void => {
+ var className = (e.target as any).className;
+ var id = (e.target as any).id;
+ if (className !== "filter-button" && className !== "filter-form") {
+ this._open = false;
+ }
+
+ }
+
+ componentWillMount() {
+ document.addEventListener('mousedown', this.handleClick, false);
+ }
+
+ componentWillUnmount() {
+ document.removeEventListener('mousedown', this.handleClick, false);
+ }
+
+ @action
+ toggleDisplay = () => {
+ this._open = !this._open;
+ }
+
+ enter = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ if (e.key === "Enter") {
+ this.submitSearch();
+ }
+ }
+
+ render() {
+ return (
+ <div id="outer">
+ <div className="searchBox" id="outer">
+
+ <input value={this.searchString} onChange={this.onChange} type="text" placeholder="Search.." className="search" id="input" onKeyPress={this.enter} />
+ <button className="filter-button" onClick={this.toggleDisplay}> Filter </button>
+ <div className="submit-search" id="submit" onClick={this.submitSearch}><FontAwesomeIcon style={{ height: "100%" }} icon="search" size="lg" /></div>
+ <div className="results" style={this._resultsOpen ? { display: "flex" } : { display: "none" }}>
+ {this._results.map(result => <SearchItem doc={result} key={result[Id]} />)}
+ </div>
+ </div>
+ <div className="filter-form" id="filter" style={this._open ? { display: "flex" } : { display: "none" }}>
+ <div className="filter-form" id="header">Filter Search Results</div>
+ <div className="filter-form" id="option">
+ filter by collection, key, type of node
+ </div>
+
+ </div>
+ </div>
+
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx
new file mode 100644
index 000000000..82cb5404c
--- /dev/null
+++ b/src/client/views/SearchItem.tsx
@@ -0,0 +1,34 @@
+import React = require("react");
+import { Doc } from "../../new_fields/Doc";
+
+export interface SearchProps {
+ doc: Doc;
+ //description: string;
+ //event: (e: React.MouseEvent<HTMLDivElement>) => void;
+}
+
+// export interface SubmenuProps {
+// description: string;
+// subitems: ContextMenuProps[];
+// }
+
+// export interface ContextMenuItemProps {
+// type: ContextMenuProps | SubmenuProps;
+// }
+
+
+
+export class SearchItem extends React.Component<SearchProps> {
+
+ onClick = () => {
+ console.log("document clicked: ", this.props.doc);
+ }
+
+ render() {
+ return (
+ <div className="search-item" onClick={this.onClick}>
+ <div className="search-title">{this.props.doc.title}</div>
+ </div>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/server/Search.ts b/src/server/Search.ts
index 4911edd1d..6e7883bc9 100644
--- a/src/server/Search.ts
+++ b/src/server/Search.ts
@@ -40,6 +40,8 @@ export class Search {
}
public async search(query: string) {
+ console.log("____________________________");
+ console.log(query);
const searchResults = JSON.parse(await rp.get(this.url + "dash/select", {
qs: {
q: query