diff options
-rw-r--r-- | src/client/views/search/IconBar.scss | 4 | ||||
-rw-r--r-- | src/client/views/search/IconBar.tsx | 20 | ||||
-rw-r--r-- | src/client/views/search/IconButton.scss | 1 | ||||
-rw-r--r-- | src/client/views/search/IconButton.tsx | 9 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.scss | 208 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 61 |
6 files changed, 180 insertions, 123 deletions
diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss index 2555ad271..c6dc2a6cd 100644 --- a/src/client/views/search/IconBar.scss +++ b/src/client/views/search/IconBar.scss @@ -3,9 +3,7 @@ .icon-bar { display: flex; justify-content: space-evenly; - align-items: center; height: 35px; width: 100%; - flex-wrap: wrap; - margin-bottom: 10px; + flex-direction: row-reverse; }
\ No newline at end of file diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx index cff397407..fe7dd4223 100644 --- a/src/client/views/search/IconBar.tsx +++ b/src/client/views/search/IconBar.tsx @@ -9,7 +9,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; import * as _ from "lodash"; import { IconButton } from './IconButton'; -import { FilterBox } from './FilterBox'; +import { DocumentType } from "../../documents/DocumentTypes"; + library.add(faSearch); library.add(faObjectGroup); @@ -25,6 +26,9 @@ library.add(faBan); @observer export class IconBar extends React.Component { + public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.TEXT, DocumentType.VID, DocumentType.WEB, DocumentType.TEMPLATE]; + + @observable private _icons: string[] = this._allIcons; static Instance: IconBar; @@ -33,16 +37,22 @@ export class IconBar extends React.Component { @observable public _reset: number = 0; @observable public _select: number = 0; + @action.bound + updateIcon(newArray: string[]) { this._icons = newArray; } + + @action.bound + getIcons(): string[] { return this._icons; } + constructor(props: any) { super(props); IconBar.Instance = this; } @action.bound - getList(): string[] { return FilterBox.Instance.getIcons(); } + getList(): string[] { return this.getIcons(); } @action.bound - updateList(newList: string[]) { FilterBox.Instance.updateIcon(newList); } + updateList(newList: string[]) { this.updateIcon(newList); } @action.bound resetSelf = () => { @@ -53,13 +63,13 @@ export class IconBar extends React.Component { @action.bound selectAll = () => { this._selectAllClicked = true; - this.updateList(FilterBox.Instance._allIcons); + this.updateList(this._allIcons); } render() { return ( <div className="icon-bar"> - {FilterBox.Instance._allIcons.map((type: string) => + {this._allIcons.map((type: string) => <IconButton key={type.toString()} type={type} /> )} </div> diff --git a/src/client/views/search/IconButton.scss b/src/client/views/search/IconButton.scss index 4a3107676..4ec03c7c9 100644 --- a/src/client/views/search/IconButton.scss +++ b/src/client/views/search/IconButton.scss @@ -5,7 +5,6 @@ flex-direction: column; align-items: center; width: 30px; - height: 60px; .type-icon { height: 30px; diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx index f01508141..bea8cc0a7 100644 --- a/src/client/views/search/IconButton.tsx +++ b/src/client/views/search/IconButton.tsx @@ -11,7 +11,6 @@ import '../globalCssVariables.scss'; import * as _ from "lodash"; import { IconBar } from './IconBar'; import { props } from 'bluebird'; -import { FilterBox } from './FilterBox'; import { Search } from '../../../server/Search'; import { gravity } from 'sharp'; @@ -34,7 +33,7 @@ interface IconButtonProps { @observer export class IconButton extends React.Component<IconButtonProps>{ - @observable private _isSelected: boolean = FilterBox.Instance.getIcons().indexOf(this.props.type) !== -1; + @observable private _isSelected: boolean = IconBar.Instance.getIcons().indexOf(this.props.type) !== -1; @observable private _hover = false; private _resetReaction?: IReactionDisposer; private _selectAllReaction?: IReactionDisposer; @@ -108,7 +107,7 @@ export class IconButton extends React.Component<IconButtonProps>{ @action.bound onClick = () => { - const newList: string[] = FilterBox.Instance.getIcons(); + const newList: string[] = IconBar.Instance.getIcons(); if (!this._isSelected) { this._isSelected = true; @@ -119,7 +118,7 @@ export class IconButton extends React.Component<IconButtonProps>{ _.pull(newList, this.props.type); } - FilterBox.Instance.updateIcon(newList); + IconBar.Instance.updateIcon(newList); } selected = { @@ -186,7 +185,7 @@ export class IconButton extends React.Component<IconButtonProps>{ > {this.getFA()} </div> - <div className="filter-description">{this.props.type}</div> + {/* <div className="filter-description">{this.props.type}</div> */} </div> ); } diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 70b9ef75e..11f5e4d91 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -88,113 +88,139 @@ } .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; + border-bottom: solid grey 1px; + margin: 5px; - .top-filter-header { + .filter-header { + display: flex; + position: relative; + right: 1px; + color: grey; + flex-direction: row-reverse; + transform-origin: top; + justify-content: space-evenly; + margin-bottom: 5px; - #header { - text-transform: uppercase; - letter-spacing: 2px; - font-size: 13; - width: 80%; - } - .close-icon { - width: 20%; - opacity: .6; + .filter-item { 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; + .filter-body { + position: relative; + right: 1px; + color: grey; + transform-origin: top; + border-top: grey 1px solid; + padding-top: 5px; + margin-left: 10px; + margin-right: 10px; } } +// .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; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 5e40b2c8b..1025629d5 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -46,6 +46,14 @@ export class SearchBox extends React.Component { private _curRequest?: Promise<any> = undefined; public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); } + + //if true, any keywords can be used. if false, all keywords are required. + //this also serves as an indicator if the word status filter is applied + @observable private _basicWordStatus: boolean = false; + @observable private _nodeStatus: boolean = false; + @observable private _keyStatus: boolean = false; + + constructor(props: any) { super(props); @@ -352,6 +360,22 @@ export class SearchBox extends React.Component { @observable private _filterOpen: boolean = false; + //if true, any keywords can be used. if false, all keywords are required. + @action.bound + handleWordQueryChange = () => { + this._basicWordStatus = !this._basicWordStatus; + } + + @action.bound + handleNodeChange = () => { + this._nodeStatus = !this._nodeStatus; + } + + @action.bound + handleKeyChange = () => { + this._keyStatus = !this._keyStatus; + } + render() { return ( @@ -366,16 +390,22 @@ export class SearchBox extends React.Component { <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 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> - <div className="close-icon" > - <span className="line line-1"></span> - <span className="line line-2"></span></div> - </div> - <div className="filter-options"> + <div className="filter-form" style={this._filterOpen ? { display: "flex" } : { display: "none" }}> + <div className="filter-header"> + <button className="filter-item" onClick={this.handleWordQueryChange}>Keywords</button> + <button className="filter-item" onClick={this.handleKeyChange}>Keys</button> + <button className="filter-item" onClick={this.handleNodeChange}>Nodes</button> + </div> + <div className="filter-body" style={this._nodeStatus ? { display: "flex" } : { display: "none" }}> + <IconBar /> + + </div> + <div style={this._keyStatus ? { display: "flex" } : { display: "none" }}> + + </div> + + + {/* <div className="filter-options"> <div className="filter-div"> <div className="filter-header"> <div className='filter-title words'>Required words</div> @@ -395,17 +425,12 @@ export class SearchBox extends React.Component { <div className="filter-title field">Filter by Basic Keys</div> </div> <div className="filter-panel"> - {/* <FieldFilters + <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> + </div> */} </div> <div className="searchBox-results" onScroll={this.resultsScrolled} style={{ display: this._resultsOpen ? "flex" : "none", |