diff options
author | vellichora <fangrui_tong@brown.edu> | 2020-03-01 17:20:45 -0500 |
---|---|---|
committer | vellichora <fangrui_tong@brown.edu> | 2020-03-01 17:20:45 -0500 |
commit | 60a35a83b1e07426092df6261be1a2c41bc74bbd (patch) | |
tree | 64bf1101d206d1a8e97a80097054dddb9045f4ad /src | |
parent | 14a2f361c73e468547d48792478e5e7e7e78f4d6 (diff) |
ui etc
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 5 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/QueryBox.tsx | 8 | ||||
-rw-r--r-- | src/client/views/search/FilterBox.scss | 9 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.scss | 186 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 77 |
6 files changed, 236 insertions, 53 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8ade14251..96830d8dc 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -44,8 +44,7 @@ import { ComputedField, ScriptField } from "../../new_fields/ScriptField"; import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { RecommendationsBox } from "../views/RecommendationsBox"; -import { SearchDocBox } from "../views/SearchDocBox"; - +import { SearchBox } from "../views/search/SearchBox"; //import { PresBox } from "../views/nodes/PresBox"; //import { PresField } from "../../new_fields/PresField"; @@ -262,7 +261,7 @@ export namespace Docs { options: { backgroundColor: "transparent" } }], [DocumentType.SEARCHBOX, { - layout: { view: SearchDocBox }, + layout: { view: SearchBox }, options: { width: 200, height: 200 }, }] ]); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 15dd1b29f..3ef8126bc 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -34,7 +34,7 @@ import { WebBox } from "./WebBox"; import { InkingStroke } from "../InkingStroke"; import React = require("react"); import { RecommendationsBox } from "../RecommendationsBox"; -import { SearchDocBox } from "../SearchDocBox"; +import { SearchBox } from "../search/SearchBox"; import { TraceMobx } from "../../../new_fields/util"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -105,7 +105,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, FontIconBox: FontIconBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, QueryBox, - ColorBox, DocuLinkBox, InkingStroke, DocumentBox, RecommendationsBox, SearchDocBox, + ColorBox, DocuLinkBox, InkingStroke, DocumentBox, RecommendationsBox, SearchBox, }} bindings={this.CreateBindings()} jsx={this.layout} diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index 99b5810fc..b2f9ca8fe 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -6,6 +6,7 @@ import { observer } from "mobx-react"; import { FilterBox } from "../search/FilterBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; +import { SearchBox } from "../search/SearchBox"; library.add(faArrowLeft); library.add(faArrowRight); @@ -29,7 +30,10 @@ export class QueryBox extends React.Component<FieldViewProps> { render() { return <div style={{ width: "100%", height: "100%", position: "absolute", pointerEvents: "all" }}> - <FilterBox></FilterBox> - </div>; + <div style={{ display: "flex", flexDirection: "row-reverse" }}> + <SearchBox /> + </div> + + </div >; } }
\ No newline at end of file diff --git a/src/client/views/search/FilterBox.scss b/src/client/views/search/FilterBox.scss index ebb39460d..094ea9cc5 100644 --- a/src/client/views/search/FilterBox.scss +++ b/src/client/views/search/FilterBox.scss @@ -4,7 +4,6 @@ .filter-form { padding: 25px; width: 440px; - background: whitesmoke; position: relative; right: 1px; color: grey; @@ -12,9 +11,7 @@ display: inline-block; transform-origin: top; overflow: auto; - border-radius: 15px; - box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw; - border: solid #BBBBBBBB 1px; + border-bottom: solid black 3px; .top-filter-header { @@ -124,7 +121,7 @@ max-width: 40px; flex: initial; - &.icon{ + &.icon { width: 40px; text-align: center; margin-bottom: 5px; @@ -150,7 +147,7 @@ transition: all 0.2s ease-in-out; } - &.icon:hover + .description { + &.icon:hover+.description { opacity: 1; } } diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 11714748a..70b9ef75e 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -4,13 +4,14 @@ .searchBox-container { display: flex; flex-direction: column; - width:100%; - height:100%; + width: 100%; + height: 100%; position: absolute; font-size: 10px; line-height: 1; overflow: hidden; } + .searchBox-bar { height: 32px; display: flex; @@ -19,7 +20,7 @@ padding-left: 2px; padding-right: 2px; -.searchBox-barChild { + .searchBox-barChild { &.searchBox-collection { flex: 0 1 auto; @@ -65,7 +66,7 @@ } .searchBox-results { - display:flex; + display: flex; flex-direction: column; top: 300px; display: flex; @@ -83,6 +84,181 @@ text-transform: uppercase; text-align: left; font-weight: bold; - margin-left: 28px; + } +} + +.filter-form { + padding: 25px; + width: 440px; + position: relative; + right: 1px; + color: grey; + flex-direction: column; + display: inline-block; + transform-origin: top; + overflow: auto; + border-bottom: solid black 3px; + + .top-filter-header { + + #header { + text-transform: uppercase; + letter-spacing: 2px; + font-size: 13; + width: 80%; + } + + .close-icon { + width: 20%; + opacity: .6; + position: relative; + display: block; + + .line { + display: block; + background: $alt-accent; + width: 20; + height: 3; + position: absolute; + right: 0; + border-radius: ($height-line / 2); + + &.line-1 { + transform: rotate(45deg); + top: 45%; + } + + &.line-2 { + transform: rotate(-45deg); + top: 45%; + } + } + } + + .close-icon:hover { + opacity: 1; + } + + } + + .filter-options { + + .filter-div { + margin-top: 10px; + margin-bottom: 10px; + display: inline-block; + width: 100%; + border-color: rgba(178, 206, 248, .2); // $darker-alt-accent + border-top-style: solid; + + .filter-header { + display: flex; + align-items: center; + margin-bottom: 10px; + letter-spacing: 2px; + + .filter-title { + font-size: 13; + text-transform: uppercase; + margin-top: 10px; + margin-bottom: 10px; + -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; + } + } + + .filter-header:hover .filter-title { + transform: scale(1.05); + } + + .filter-panel { + max-height: 0px; + width: 100%; + overflow: hidden; + opacity: 0; + transform-origin: top; + -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; + text-align: center; + } + } + } + + .filter-buttons { + border-color: rgba(178, 206, 248, .2); // $darker-alt-accent + border-top-style: solid; + padding-top: 10px; + } +} + +.active-filters { + display: flex; + flex-direction: row-reverse; + justify-content: flex-end; + width: 100%; + margin-right: 30px; + position: relative; + + .active-icon { + max-width: 40px; + flex: initial; + + &.icon { + width: 40px; + text-align: center; + margin-bottom: 5px; + position: absolute; + } + + &.container { + display: flex; + flex-direction: column; + width: 40px; + } + + &.description { + text-align: center; + top: 40px; + position: absolute; + width: 40px; + font-size: 9px; + opacity: 0; + -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; + } + + &.icon:hover+.description { + opacity: 1; + } + } + + .col-icon { + height: 35px; + margin-left: 5px; + width: 35px; + background-color: black; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + + .save-filter, + .reset-filter, + .all-filter { + background-color: gray; + } + + .save-filter:hover, + .reset-filter:hover, + .all-filter:hover { + background-color: $darker-alt-accent; + } } }
\ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 02b41bc70..5e40b2c8b 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -12,12 +12,13 @@ import { Utils } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { SetupDrag } from '../../util/DragManager'; import { SearchUtil } from '../../util/SearchUtil'; -import { FilterBox } from './FilterBox'; -import "./FilterBox.scss"; +// import { FilterBox } from './FilterBox'; +// import "./FilterBox.scss"; import "./SearchBox.scss"; import { SearchItem } from './SearchItem'; import { IconBar } from './IconBar'; import { FieldFilters } from './FieldFilters'; +import { FieldView } from '../nodes/FieldView'; library.add(faTimes); @@ -43,6 +44,7 @@ export class SearchBox extends React.Component { private _maxSearchIndex: number = 0; private _curRequest?: Promise<any> = undefined; + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); } constructor(props: any) { super(props); @@ -110,12 +112,12 @@ export class SearchBox extends React.Component { @action submitSearch = async () => { let query = this._searchString; - query = FilterBox.Instance.getFinalQuery(query); + // query = FilterBox.Instance.getFinalQuery(query); this._results = []; this._resultsSet.clear(); this._isSearch = []; this._visibleElements = []; - FilterBox.Instance.closeFilter(); + // FilterBox.Instance.closeFilter(); //if there is no query there should be no result if (query === "") { @@ -137,15 +139,17 @@ export class SearchBox extends React.Component { } getAllResults = async (query: string) => { - return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 }); - } + return SearchUtil.Search(query, true, { start: 0, rows: 10000000 }); - private get filterQuery() { - const types = FilterBox.Instance.filterTypes; - const includeDeleted = FilterBox.Instance.getDataStatus(); - return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted_b:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}" OR type_t:"extension"`).join(" ")})` : ""); + //return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 }); } + // private get filterQuery() { + // const types = FilterBox.Instance.filterTypes; + // const includeDeleted = FilterBox.Instance.getDataStatus(); + // return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted_b:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}" OR type_t:"extension"`).join(" ")})` : ""); + // } + private NumResults = 25; private lockPromise?: Promise<void>; @@ -155,7 +159,8 @@ export class SearchBox extends React.Component { } this.lockPromise = new Promise(async res => { while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { + //this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { + this._curRequest = SearchUtil.Search(query, true, { start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { // happens at the beginning if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { @@ -169,7 +174,8 @@ export class SearchBox extends React.Component { const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); const highlights: typeof res.highlighting = {}; docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); - const filteredDocs = FilterBox.Instance.filterDocsByType(docs); + //const filteredDocs = FilterBox.Instance.filterDocsByType(docs); + const filteredDocs = docs; runInAction(() => { // this._results.push(...filteredDocs); filteredDocs.forEach(doc => { @@ -201,8 +207,11 @@ export class SearchBox extends React.Component { collectionRef = React.createRef<HTMLSpanElement>(); startDragCollection = async () => { - const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); - const filtered = FilterBox.Instance.filterDocsByType(res.docs); + //const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); + const res = await this.getAllResults(this._searchString); + + //const filtered = FilterBox.Instance.filterDocsByType(res.docs); + const filtered = res.docs; // console.log(this._results) const docs = filtered.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); @@ -236,22 +245,24 @@ export class SearchBox extends React.Component { } } //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); + //return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); + return Docs.Create.QueryDocument({ + }); } @action.bound openSearch(e: React.SyntheticEvent) { e.stopPropagation(); this._openNoResults = false; - FilterBox.Instance.closeFilter(); + //FilterBox.Instance.closeFilter(); this._resultsOpen = true; this._searchbarOpen = true; - FilterBox.Instance._pointerTime = e.timeStamp; + //FilterBox.Instance._pointerTime = e.timeStamp; } @action.bound closeSearch = () => { - FilterBox.Instance.closeFilter(); + //FilterBox.Instance.closeFilter(); this.closeResults(); this._searchbarOpen = false; } @@ -352,17 +363,11 @@ export class SearchBox extends React.Component { <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this.inputRef} className="searchBox-barChild searchBox-input" onPointerDown={this.openSearch} onKeyPress={this.enter} onFocus={this.openSearch} 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> - <div className="searchBox-quickFilter" onPointerDown={this.openSearch}> - <div className="filter-panel"><IconBar /></div> + <button className="searchBox-barChild searchBox-filter" title="Advanced Filtering Options" onClick={() => runInAction(() => this._filterOpen = !this._filterOpen)}><FontAwesomeIcon icon="ellipsis-v" color="white" /></button> </div> - <div> - <div style={{ display: "flex", flexDirection: "row-reverse" }}> - <SearchBox /> - {/* {this.getActiveFilters()} */} - </div> - <div className="filter-form" onPointerDown={this.stopProp} id="filter-form" style={this._filterOpen ? { display: "flex" } : { display: "none" }}> + + <div style={{ display: "flex", flexDirection: "row-reverse" }}> + <div className="filter-form" style={this._filterOpen ? { display: "flex" } : { display: "none" }}> <div className="top-filter-header" style={{ display: "flex", width: "100%" }}> <div id="header">Filter Search Results</div> <div style={{ marginLeft: "auto" }}></div> @@ -383,20 +388,22 @@ export class SearchBox extends React.Component { <div className="filter-header"> <div className="filter-title icon">Filter by type of node</div> </div> - <div className="filter-panel"><IconBar /></div> + <div className="filter-panel"></div> </div> <div className="filter-div"> <div className="filter-header"> <div className="filter-title field">Filter by Basic Keys</div> </div> - <div className="filter-panel"><FieldFilters + <div className="filter-panel"> + {/* <FieldFilters titleFieldStatus={this._titleFieldStatus} dataFieldStatus={this._deletedDocsStatus} authorFieldStatus={this._authorFieldStatus} - updateAuthorStatus={this.updateAuthorStatus} updateDataStatus={this.updateDataStatus} updateTitleStatus={this.updateTitleStatus} /> </div> + updateAuthorStatus={this.updateAuthorStatus} updateDataStatus={this.updateDataStatus} updateTitleStatus={this.updateTitleStatus} /> </div> */} + </div> + </div> + <div className="filter-buttons" style={{ display: "flex", justifyContent: "space-around" }}> + <button className="save-filter" >Save Filters</button> + <button className="reset-filter" >Reset Filters</button> </div> - </div> - <div className="filter-buttons" style={{ display: "flex", justifyContent: "space-around" }}> - <button className="save-filter" >Save Filters</button> - <button className="reset-filter" >Reset Filters</button> </div> </div> </div> |