From 39bb878a32821d2e14110f4158471890234f4769 Mon Sep 17 00:00:00 2001 From: Monika Hedman Date: Mon, 29 Apr 2019 19:52:35 -0400 Subject: search UI --- src/client/views/SearchBox.scss | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/client/views/SearchBox.scss (limited to 'src/client/views/SearchBox.scss') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss new file mode 100644 index 000000000..e1a1de142 --- /dev/null +++ b/src/client/views/SearchBox.scss @@ -0,0 +1,64 @@ +@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; + + .submit-search { + display: inline-block; + 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; + } + + 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; + } +} + +.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; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From df9fa3e362a6bdd616bc0b46ef9b425cfc5a010d Mon Sep 17 00:00:00 2001 From: Monika Hedman Date: Tue, 30 Apr 2019 16:17:39 -0400 Subject: before pull --- src/client/views/SearchBox.scss | 1 - src/fields/Document.ts | 15 +++++++-------- src/server/Search.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/server/database.ts | 12 ++++++++++++ src/server/index.ts | 19 ++++++++++++++++--- 5 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 src/server/Search.ts (limited to 'src/client/views/SearchBox.scss') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index e1a1de142..92363e681 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -9,7 +9,6 @@ align-items: center; .submit-search { - display: inline-block; text-align: right; color: $dark-color; -webkit-transition: right 0.4s; diff --git a/src/fields/Document.ts b/src/fields/Document.ts index 2797efc09..6f6533754 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -29,15 +29,14 @@ export class Document extends Field { } static FromJson(data: any, id: string, save: boolean): Document { let doc = new Document(id, save); - let fields = data as [string, string][]; - fields.forEach(pair => doc._proxies.set(pair[0], pair[1])); + let fields = data as { key: string, field: string }[]; + fields.forEach(pair => doc._proxies.set(pair.key, pair.field)); return doc; } - UpdateFromServer(data: [string, string][]) { - for (const key in data) { - const element = data[key]; - this._proxies.set(element[0], element[1]); + UpdateFromServer(data: { key: string, field: string }[]) { + for (const kv of data) { + this._proxies.set(kv.key, kv.field); } } @@ -448,9 +447,9 @@ export class Document extends Field { } ToJson() { - let fields: [string, string][] = []; + let fields: { key: string, field: string }[] = []; this._proxies.forEach((field, key) => - field && fields.push([key, field])); + field && fields.push({ key, field })); return { type: Types.Document, diff --git a/src/server/Search.ts b/src/server/Search.ts new file mode 100644 index 000000000..7d8602346 --- /dev/null +++ b/src/server/Search.ts @@ -0,0 +1,38 @@ +import * as rp from 'request-promise'; +import { Database } from './database'; + +export class Search { + public static Instance = new Search(); + private url = 'http://localhost:8983/solr/'; + + public updateDocument(document: any): rp.RequestPromise { + return rp.post(this.url + "dash/update/json/docs", { + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(document) + }); + } + + public async search(query: string) { + const searchResults = JSON.parse(await rp.get(this.url + "dash/select", { + qs: { + q: query + } + })); + const fields = searchResults.response.docs; + const ids = fields.map((field: any) => field.id); + const docs = await Database.Instance.searchQuery(ids); + const docIds = docs.map((doc: any) => doc._id); + return docIds; + } + + public async clear() { + return rp.post(this.url + "dash/update", { + body: { + delete: { + query: "*:*" + } + }, + json: true + }); + } +} \ No newline at end of file diff --git a/src/server/database.ts b/src/server/database.ts index 5457e4dd5..d5905c7b3 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -72,6 +72,18 @@ export class Database { }); } + public searchQuery(ids: string[], collectionName = Database.DocumentsCollection): Promise { + return new Promise(resolve => { + this.db && this.db.collection(collectionName).find({ "data.field": { "$in": ids } }).toArray((err, docs) => { + if (err) { + console.log(err.message); + console.log(err.errmsg); + } + resolve(docs); + }); + }); + } + public print() { console.log("db says hi!"); } diff --git a/src/server/index.ts b/src/server/index.ts index 70a7d266c..cb4268a2d 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -11,6 +11,7 @@ import { ObservableMap } from 'mobx'; import * as passport from 'passport'; import * as path from 'path'; import * as request from 'request'; +import * as rp from 'request-promise'; import * as io from 'socket.io'; import { Socket } from 'socket.io'; import * as webpack from 'webpack'; @@ -22,7 +23,7 @@ import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLo import { DashUserModel } from './authentication/models/user_model'; import { Client } from './Client'; import { Database } from './database'; -import { MessageStore, Transferable } from "./Message"; +import { MessageStore, Transferable, Types } from "./Message"; import { RouteStore } from './RouteStore'; const app = express(); const config = require('../../webpack.config'); @@ -32,6 +33,7 @@ const serverPort = 4321; import expressFlash = require('express-flash'); import flash = require('connect-flash'); import c = require("crypto"); +import { Search } from './Search'; const MongoStore = require('connect-mongo')(session); const mongoose = require('mongoose'); @@ -120,6 +122,12 @@ app.get("/pull", (req, res) => // GETTERS +app.get("/search", async (req, res) => { + let query = req.query.query || "hello"; + let results = await Search.Instance.search(query); + res.send(results); +}); + // anyone attempting to navigate to localhost at this port will // first have to login addSecureRoute( @@ -234,14 +242,16 @@ server.on("connection", function (socket: Socket) { Utils.AddServerHandler(socket, MessageStore.DeleteAll, deleteFields); }); -function deleteFields() { - return Database.Instance.deleteAll(); +async function deleteFields() { + await Database.Instance.deleteAll(); + await Search.Instance.clear(); } async function deleteAll() { await Database.Instance.deleteAll(); await Database.Instance.deleteAll('sessions'); await Database.Instance.deleteAll('users'); + await Search.Instance.clear(); } function barReceived(guid: String) { @@ -260,6 +270,9 @@ function getFields([ids, callback]: [string[], (result: Transferable[]) => void] function setField(socket: Socket, newValue: Transferable) { Database.Instance.update(newValue.id, newValue, () => socket.broadcast.emit(MessageStore.SetField.Message, newValue)); + if (newValue.type === Types.Text) { + Search.Instance.updateDocument({ id: newValue.id, data: (newValue as any).data }); + } } server.listen(serverPort); -- cgit v1.2.3-70-g09d2 From 96d9bd38cb3ae6d59945d15071e1b346e4d0a8e2 Mon Sep 17 00:00:00 2001 From: Monika Hedman Date: Tue, 7 May 2019 14:38:23 -0400 Subject: hacky way of getting search to work --- src/client/views/SearchBox.scss | 52 ++++++++++++++++++++++++++++++++--------- src/client/views/SearchBox.tsx | 52 +++++++++++------------------------------ 2 files changed, 55 insertions(+), 49 deletions(-) (limited to 'src/client/views/SearchBox.scss') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 92363e681..1aad13b2e 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -8,18 +8,7 @@ transition: width 0.4s ease-in-out; align-items: center; - .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; - } input[type=text] { width: 130px; @@ -38,6 +27,19 @@ 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 { @@ -60,4 +62,32 @@ #option { height: 20px; +} + +.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 index eb3cd56fd..eecd9c8bb 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -74,42 +74,19 @@ export class SearchBox extends React.Component { let results = JSON.parse(response); - this._results = results; - - let doc = await Server.GetField(results[1]); - if (doc instanceof Document) { - console.log("doc"); - console.log(doc.Title); - } - - // weird things happening - // console.log("results") - // console.log(results); - // console.log("type") - // console.log(results.type) - let temp: string = this._results[1].Id; - // console.log(this._results) - // console.log(this._results[1]) - - console.log(this._results[1].constructor.name) - - if (this._results[1] instanceof Document) { - console.log("is a doc") - } - - if (this._results[1]) { - console.log("is a string") - } - - console.log(temp); - let doc2 = await Server.GetField(temp); - console.log(doc2); - if (doc2 instanceof Document) { - console.log("doc2"); - console.log(doc2.Title); - } + //gets json result into a list of documents that can be used + this.getResults(results); + } + getResults = async (res: string[]) => { + let doc; + res.map(async result => { + doc = await Server.GetField(result); + if (doc instanceof Document) { + this._results.push(doc); + } + }); } @action @@ -143,10 +120,9 @@ export class SearchBox extends React.Component {
-- cgit v1.2.3-70-g09d2 From 93d2214b84eaef61c9a9f980d24b5c1addbd67dc Mon Sep 17 00:00:00 2001 From: Monika Hedman Date: Tue, 7 May 2019 16:26:51 -0400 Subject: things working --- src/client/views/SearchBox.scss | 6 ++++++ src/client/views/SearchBox.tsx | 46 ++++++++++++----------------------------- src/client/views/SearchItem.tsx | 2 +- 3 files changed, 20 insertions(+), 34 deletions(-) (limited to 'src/client/views/SearchBox.scss') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 1aad13b2e..f4fc0029e 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -64,6 +64,12 @@ height: 20px; } +.results { + top: 300px; + display: flex; + flex-direction: column; +} + .search-item { width: 500px; height: 50px; diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 0760578a8..ff215efab 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -15,6 +15,7 @@ import * as rp from 'request-promise'; import { Document } from '../../fields/Document'; import { SearchItem } from './SearchItem'; import { isString } from 'util'; +import { constant } from 'async'; library.add(faSearch); @@ -30,40 +31,15 @@ export class SearchBox extends React.Component { @observable private _results: Document[] = []; - // constructor(props: any) { - // super(props); - // let searchInput = document.getElementById("input"); - // if (searchInput) { - // // searchInput.addEventListener("keydown", this.onKeyPress) - // } - // } - - // //this is not working????? - // @action - // onKeyPress = (e: KeyboardEvent) => { - // console.log('things happening') - // //Number 13 is the "Enter" key on the keyboard - // if (e.keyCode === 13) { - // console.log("happi") - // // Cancel the default action, if needed - // e.preventDefault(); - // // Trigger the button element with a click - // let btn = document.getElementById("submit"); - // if (btn) { - // console.log("yesyesyes") - // btn.click(); - // } - // } - // } - @action.bound onChange(e: React.ChangeEvent) { 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', { @@ -112,19 +88,23 @@ export class SearchBox extends React.Component { this._open = !this._open; } + enter = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + this.submitSearch(); + } + } + render() { return (
- {/* -
+
+ {this._results.map(result => )} +
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index c8fd6457b..6021c0736 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -21,7 +21,7 @@ export interface SearchProps { export class SearchItem extends React.Component { onClick = () => { - console.log("clicked search item"); + console.log("document clicked: ", this.props.doc); } render() { -- cgit v1.2.3-70-g09d2 From b5fac34cf22bcb47854c00671848e25b7ee9d37f Mon Sep 17 00:00:00 2001 From: Monika Hedman Date: Wed, 8 May 2019 20:38:02 -0400 Subject: issues with icon --- src/client/views/SearchBox.scss | 50 ++++++++++++++++++++--------------------- src/client/views/SearchBox.tsx | 24 +++++++++++++++----- src/client/views/SearchItem.tsx | 36 ++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 34 deletions(-) (limited to 'src/client/views/SearchBox.scss') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index f4fc0029e..792d6dd3c 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -68,32 +68,32 @@ 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 { + width: 500px; + height: 50px; + background: $light-color-secondary; + display: flex; + justify-content: space-between; + 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-item:hover { + transition: all 0.1s; + background: $lighter-alt-accent; + } -.search-title { - text-transform: uppercase; - text-align: left; - width: 8vw; + .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 index 827d468df..7dd1af4e7 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -67,7 +67,7 @@ export class SearchBox extends React.Component { } @action - handleClick = (e: Event): void => { + handleClickFilter = (e: Event): void => { var className = (e.target as any).className; var id = (e.target as any).id; if (className !== "filter-button" && className !== "filter-form") { @@ -76,16 +76,28 @@ export class SearchBox extends React.Component { } + @action + handleClickResults = (e: Event): void => { + var className = (e.target as any).className; + var id = (e.target as any).id; + if (id !== "result") { + this._resultsOpen = false; + } + + } + componentWillMount() { - document.addEventListener('mousedown', this.handleClick, false); + document.addEventListener('mousedown', this.handleClickFilter, false); + document.addEventListener('mousedown', this.handleClickResults, false); } componentWillUnmount() { - document.removeEventListener('mousedown', this.handleClick, false); + document.removeEventListener('mousedown', this.handleClickFilter, false); + document.removeEventListener('mousedown', this.handleClickResults, false); } @action - toggleDisplay = () => { + toggleFilterDisplay = () => { this._open = !this._open; } @@ -101,9 +113,9 @@ export class SearchBox extends React.Component {
- +
-
+
{this._results.map(result => )}
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 81da7ebd2..539d6b5e5 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -1,21 +1,51 @@ import React = require("react"); import { Doc } from "../../new_fields/Doc"; import { DocumentManager } from "../util/DocumentManager"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Cast } from "../../new_fields/Types"; +import { FieldView, FieldViewProps } from './nodes/FieldView'; +import { computed } from "mobx"; +import { IconField } from "../../new_fields/IconField"; + export interface SearchProps { doc: Doc; } +library.add(faCaretUp); +library.add(faObjectGroup); +library.add(faStickyNote); +library.add(faFilePdf); +library.add(faFilm); + export class SearchItem extends React.Component { onClick = () => { - DocumentManager.Instance.jumpToDocument(this.props.doc) + DocumentManager.Instance.jumpToDocument(this.props.doc); + } + + //needs help + // @computed get layout(): string { const field = Cast(this.props.doc[fieldKey], IconField); return field ? field.icon : "

Error loading icon data

"; } + + + public static DocumentIcon(layout: string) { + let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf : + layout.indexOf("ImageBox") !== -1 ? faImage : + layout.indexOf("Formatted") !== -1 ? faStickyNote : + layout.indexOf("Video") !== -1 ? faFilm : + layout.indexOf("Collection") !== -1 ? faObjectGroup : + faCaretUp; + return ; } render() { return ( -
-
{this.props.doc.title}
+
+
title: {this.props.doc.title}
+
Type: {this.props.doc.layout}
+ {/*
{SearchItem.DocumentIcon(this.layout)}
*/}
); } -- cgit v1.2.3-70-g09d2