diff options
-rw-r--r-- | src/client/views/search/CheckBox.tsx | 22 | ||||
-rw-r--r-- | src/client/views/search/CollectionFilters.tsx | 41 | ||||
-rw-r--r-- | src/client/views/search/FieldFilters.tsx | 15 | ||||
-rw-r--r-- | src/client/views/search/FilterBox.scss | 108 | ||||
-rw-r--r-- | src/client/views/search/IconBar.scss | 60 | ||||
-rw-r--r-- | src/client/views/search/IconBar.tsx | 50 | ||||
-rw-r--r-- | src/client/views/search/IconButton.scss | 52 | ||||
-rw-r--r-- | src/client/views/search/IconButton.tsx | 47 | ||||
-rw-r--r-- | src/client/views/search/NaviconButton.scss | 60 | ||||
-rw-r--r-- | src/client/views/search/NaviconButton.tsx | 10 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.scss | 184 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 70 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.scss | 276 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.tsx | 2 | ||||
-rw-r--r-- | src/client/views/search/SelectorContextMenu.scss | 15 | ||||
-rw-r--r-- | src/client/views/search/ToggleBar.tsx | 20 |
16 files changed, 520 insertions, 512 deletions
diff --git a/src/client/views/search/CheckBox.tsx b/src/client/views/search/CheckBox.tsx index c75980e7c..a9d48219a 100644 --- a/src/client/views/search/CheckBox.tsx +++ b/src/client/views/search/CheckBox.tsx @@ -16,11 +16,11 @@ interface CheckBoxProps { @observer export class CheckBox extends React.Component<CheckBoxProps>{ // true = checked, false = unchecked - @observable _status: boolean; - @observable uncheckTimeline: anime.AnimeTimelineInstance; - @observable checkTimeline: anime.AnimeTimelineInstance; - @observable checkRef: any; - @observable _resetReaction?: IReactionDisposer; + @observable private _status: boolean; + @observable private uncheckTimeline: anime.AnimeTimelineInstance; + @observable private checkTimeline: anime.AnimeTimelineInstance; + @observable private checkRef: any; + @observable private _resetReaction?: IReactionDisposer; constructor(props: CheckBoxProps) { @@ -60,15 +60,15 @@ export class CheckBox extends React.Component<CheckBoxProps>{ } this._resetReaction = reaction( - () => this.props.parent.resetBoolean, + () => this.props.parent._resetBoolean, () => { - if (this.props.parent.resetBoolean) { + if (this.props.parent._resetBoolean) { runInAction(() => { this.reset(); - this.props.parent.resetCounter++; - if (this.props.parent.resetCounter === this.props.numCount) { - this.props.parent.resetCounter = 0; - this.props.parent.resetBoolean = false; + this.props.parent._resetCounter++; + if (this.props.parent._resetCounter === this.props.numCount) { + this.props.parent._resetCounter = 0; + this.props.parent._resetBoolean = false; } }); } diff --git a/src/client/views/search/CollectionFilters.tsx b/src/client/views/search/CollectionFilters.tsx index 3dd87157d..48d0b2ddb 100644 --- a/src/client/views/search/CollectionFilters.tsx +++ b/src/client/views/search/CollectionFilters.tsx @@ -17,18 +17,19 @@ export class CollectionFilters extends React.Component<CollectionFilterProps> { static Instance: CollectionFilters; - @observable public resetBoolean = false; - @observable public resetCounter: number = 0; - @observable collectionsSelected = this.props.collectionStatus; - @observable timeline: anime.AnimeTimelineInstance; - @observable ref: any; + @observable public _resetBoolean = false; + @observable public _resetCounter: number = 0; + + @observable private _collectionsSelected = this.props.collectionStatus; + @observable private _timeline: anime.AnimeTimelineInstance; + @observable private _ref: any; constructor(props: CollectionFilterProps) { super(props); CollectionFilters.Instance = this; - this.ref = React.createRef(); + this._ref = React.createRef(); - this.timeline = anime.timeline({ + this._timeline = anime.timeline({ loop: false, autoplay: false, direction: "reverse", @@ -36,32 +37,32 @@ export class CollectionFilters extends React.Component<CollectionFilterProps> { } componentDidMount = () => { - this.timeline.add({ - targets: this.ref.current, + this._timeline.add({ + targets: this._ref.current, easing: "easeInOutQuad", duration: 500, opacity: 1, }); - if (this.collectionsSelected) { - this.timeline.play(); - this.timeline.reverse(); + if (this._collectionsSelected) { + this._timeline.play(); + this._timeline.reverse(); } } @action.bound - resetCollectionFilters() { this.resetBoolean = true; } + resetCollectionFilters() { this._resetBoolean = true; } @action.bound updateColStat(val: boolean) { this.props.updateCollectionStatus(val); - if (this.collectionsSelected !== val) { - this.timeline.play(); - this.timeline.reverse(); - } + if (this._collectionsSelected !== val) { + this._timeline.play(); + this._timeline.reverse(); + } - this.collectionsSelected = val; + this._collectionsSelected = val; } render() { @@ -70,8 +71,8 @@ export class CollectionFilters extends React.Component<CollectionFilterProps> { <div className="collection-filters"> <div className="collection-filters main"> <CheckBox default={false} title={"limit to current collection"} parent={this} numCount={3} updateStatus={this.updateColStat} originalStatus={this.props.collectionStatus} /> - </div> - <div className="collection-filters optional" ref={this.ref}> + </div> + <div className="collection-filters optional" ref={this._ref}> <CheckBox default={true} title={"Search in self"} parent={this} numCount={3} updateStatus={this.props.updateSelfCollectionStatus} originalStatus={this.props.collectionSelfStatus} /> <CheckBox default={true} title={"Search in parent"} parent={this} numCount={3} updateStatus={this.props.updateParentCollectionStatus} originalStatus={this.props.collectionParentStatus} /> </div> diff --git a/src/client/views/search/FieldFilters.tsx b/src/client/views/search/FieldFilters.tsx index eb12e654f..befe5d54d 100644 --- a/src/client/views/search/FieldFilters.tsx +++ b/src/client/views/search/FieldFilters.tsx @@ -16,8 +16,9 @@ export interface FieldFilterProps { export class FieldFilters extends React.Component<FieldFilterProps> { static Instance: FieldFilters; - @observable public resetBoolean = false; - @observable public resetCounter: number = 0; + + @observable public _resetBoolean = false; + @observable public _resetCounter: number = 0; constructor(props: FieldFilterProps) { super(props); @@ -25,15 +26,15 @@ export class FieldFilters extends React.Component<FieldFilterProps> { } resetFieldFilters() { - this.resetBoolean = true; + this._resetBoolean = true; } render() { return ( - <div className = "field-filters"> - <CheckBox default = {true} numCount={3} parent={this} originalStatus={this.props.titleFieldStatus} updateStatus={this.props.updateTitleStatus} title={Keys.TITLE} /> - <CheckBox default = {true} numCount={3} parent={this} originalStatus={this.props.authorFieldStatus} updateStatus={this.props.updateAuthorStatus} title={Keys.AUTHOR} /> - <CheckBox default = {true} numCount={3} parent={this} originalStatus={this.props.dataFieldStatus} updateStatus={this.props.updateDataStatus} title={Keys.DATA} /> + <div className="field-filters"> + <CheckBox default={true} numCount={3} parent={this} originalStatus={this.props.titleFieldStatus} updateStatus={this.props.updateTitleStatus} title={Keys.TITLE} /> + <CheckBox default={true} numCount={3} parent={this} originalStatus={this.props.authorFieldStatus} updateStatus={this.props.updateAuthorStatus} title={Keys.AUTHOR} /> + <CheckBox default={true} numCount={3} parent={this} originalStatus={this.props.dataFieldStatus} updateStatus={this.props.updateDataStatus} title={Keys.DATA} /> </div> ); } diff --git a/src/client/views/search/FilterBox.scss b/src/client/views/search/FilterBox.scss new file mode 100644 index 000000000..1eb8963d7 --- /dev/null +++ b/src/client/views/search/FilterBox.scss @@ -0,0 +1,108 @@ +@import "../globalCssVariables"; +@import "./NaviconButton.scss"; + +.filter-form { + padding: 25px; + width: 600px; + background: $dark-color; + position: relative; + right: 1px; + color: $light-color; + flex-direction: column; + display: inline-block; + transform-origin: top; + overflow: auto; + + .top-filter-header { + + #header { + text-transform: uppercase; + letter-spacing: 2px; + font-size: 25; + width: 80%; + } + + .close-icon { + width: 20%; + opacity: .6; + position: relative; + display: inline-block; + + .line { + display: block; + background: $alt-accent; + width: $width-line; + height: $height-line; + 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; + + .filter-title { + font-size: 18; + 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; + } + } + } + + .filter-buttons { + border-color: rgba(178, 206, 248, .2); // $darker-alt-accent + border-top-style: solid; + padding-top: 10px; + } +}
\ No newline at end of file diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss index cb7de15a0..e384722ce 100644 --- a/src/client/views/search/IconBar.scss +++ b/src/client/views/search/IconBar.scss @@ -7,64 +7,6 @@ height: 40px; width: 100%; flex-wrap: wrap; + margin-bottom: 10px; } -.icon-title { - color: $light-color; - text-transform: uppercase; - padding: 5px; -} - -.type-icon { - height: 45px; - width: 45px; - color: $light-color; - border-radius: 50%; - 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; - font-size: 2em; -} - -.fontawesome-icon { - height: 24px; - width: 24px; -} - -.filter-description{ - text-transform: capitalize; -} - -.type-icon:hover { - transform: scale(1.1); - background-color: $darker-alt-accent; - opacity: 1; - - +.filter-description { - opacity: 1; - } -} - -.type-outer { - display: flex; - flex-direction: column; - align-items: center; - width: 45px; - height: 60px; -} - -.filter-description { - font-size: 10; - text-align: center; - height: 15px; - margin-top: 5px; - 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; -}
\ No newline at end of file diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx index a446159fe..c5b4d33cf 100644 --- a/src/client/views/search/IconBar.tsx +++ b/src/client/views/search/IconBar.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; import { observer } from 'mobx-react'; import { observable, action } from 'mobx'; -import "./SearchBox.scss"; +// import "./SearchBox.scss"; import "./IconBar.scss"; +import "./IconButton.scss"; import { DocTypes } from '../../documents/Documents'; import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan, faTimesCircle, faCheckCircle } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -28,11 +29,10 @@ export class IconBar extends React.Component { static Instance: IconBar; - allIcons: string[] = [DocTypes.AUDIO, DocTypes.COL, DocTypes.HIST, DocTypes.IMG, DocTypes.LINK, DocTypes.PDF, DocTypes.TEXT, DocTypes.VID, DocTypes.WEB]; - @observable public ResetClicked: boolean = false; - @observable public SelectAllClicked: boolean = false; - public Reset: number = 0; - public Select: number = 0; + @observable public _resetClicked: boolean = false; + @observable public _selectAllClicked: boolean = false; + @observable public _reset: number = 0; + @observable public _select: number = 0; constructor(props: any) { super(props); @@ -47,37 +47,37 @@ export class IconBar extends React.Component { @action.bound resetSelf = () => { - this.ResetClicked = true; + this._resetClicked = true; this.updateList([]); } @action.bound selectAll = () => { - this.SelectAllClicked = true; - this.updateList(this.allIcons); + this._selectAllClicked = true; + this.updateList(SearchBox.Instance._allIcons); } render() { return ( - <div className="icon-bar"> - <div className="type-outer"> - <div className={"type-icon all"} - onClick={this.selectAll}> - <FontAwesomeIcon className="fontawesome-icon" icon={faCheckCircle} /> + <div className="icon-bar"> + <div className="type-outer"> + <div className={"type-icon all"} + onClick={this.selectAll}> + <FontAwesomeIcon className="fontawesome-icon" icon={faCheckCircle} /> + </div> + <div className="filter-description">Select All</div> </div> - <div className="filter-description">Select All</div> - </div> - {this.allIcons.map((type: string) => - <IconButton type={type} /> - )} - <div className="type-outer"> - <div className={"type-icon none"} - onClick={this.resetSelf}> - <FontAwesomeIcon className="fontawesome-icon" icon={faTimesCircle} /> + {SearchBox.Instance._allIcons.map((type: string) => + <IconButton type={type} /> + )} + <div className="type-outer"> + <div className={"type-icon none"} + onClick={this.resetSelf}> + <FontAwesomeIcon className="fontawesome-icon" icon={faTimesCircle} /> + </div> + <div className="filter-description">Clear</div> </div> - <div className="filter-description">Clear</div> </div> - </div> ); } } diff --git a/src/client/views/search/IconButton.scss b/src/client/views/search/IconButton.scss new file mode 100644 index 000000000..94b294ba5 --- /dev/null +++ b/src/client/views/search/IconButton.scss @@ -0,0 +1,52 @@ +@import "../globalCssVariables"; + +.type-outer { + display: flex; + flex-direction: column; + align-items: center; + width: 45px; + height: 60px; + + .type-icon { + height: 45px; + width: 45px; + color: $light-color; + border-radius: 50%; + 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; + font-size: 2em; + + .fontawesome-icon { + height: 24px; + width: 24px; + } + } + + .filter-description { + text-transform: capitalize; + font-size: 10; + text-align: center; + height: 15px; + margin-top: 5px; + 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; + } + + .type-icon:hover { + transform: scale(1.1); + background-color: $darker-alt-accent; + opacity: 1; + + +.filter-description { + opacity: 1; + } + } +}
\ No newline at end of file diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx index 541fe5ba5..c40bb587f 100644 --- a/src/client/views/search/IconButton.tsx +++ b/src/client/views/search/IconButton.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { observer } from 'mobx-react'; import { observable, action, runInAction, IReactionDisposer, reaction } from 'mobx'; import "./SearchBox.scss"; -import "./IconBar.scss"; +import "./IconButton.scss"; import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan, faVideo, faCaretDown } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { library, icon } from '@fortawesome/fontawesome-svg-core'; @@ -33,9 +33,8 @@ interface IconButtonProps { @observer export class IconButton extends React.Component<IconButtonProps>{ - @observable isSelected: boolean = SearchBox.Instance.getIcons().indexOf(this.props.type) !== -1; - @observable hover = false; - + @observable private _isSelected: boolean = SearchBox.Instance.getIcons().indexOf(this.props.type) !== -1; + @observable private _hover = false; private _resetReaction?: IReactionDisposer; private _selectAllReaction?: IReactionDisposer; @@ -47,30 +46,30 @@ export class IconButton extends React.Component<IconButtonProps>{ componentDidMount = () => { this._resetReaction = reaction( - () => IconBar.Instance.ResetClicked, + () => IconBar.Instance._resetClicked, () => { - if (IconBar.Instance.ResetClicked) { + if (IconBar.Instance._resetClicked) { runInAction(() => { this.reset(); - IconBar.Instance.Reset++; - if (IconBar.Instance.Reset === 9) { - IconBar.Instance.Reset = 0; - IconBar.Instance.ResetClicked = false; + IconBar.Instance._reset++; + if (IconBar.Instance._reset === 9) { + IconBar.Instance._reset = 0; + IconBar.Instance._resetClicked = false; } }); } }, ); this._selectAllReaction = reaction( - () => IconBar.Instance.SelectAllClicked, + () => IconBar.Instance._selectAllClicked, () => { - if (IconBar.Instance.SelectAllClicked) { + if (IconBar.Instance._selectAllClicked) { runInAction(() => { this.select(); - IconBar.Instance.Select++; - if (IconBar.Instance.Select === 9) { - IconBar.Instance.Select = 0; - IconBar.Instance.SelectAllClicked = false; + IconBar.Instance._select++; + if (IconBar.Instance._select === 9) { + IconBar.Instance._select = 0; + IconBar.Instance._selectAllClicked = false; } }); } @@ -110,12 +109,12 @@ export class IconButton extends React.Component<IconButtonProps>{ onClick = () => { let newList: string[] = SearchBox.Instance.getIcons(); - if (!this.isSelected) { - this.isSelected = true; + if (!this._isSelected) { + this._isSelected = true; newList.push(this.props.type); } else { - this.isSelected = false; + this._isSelected = false; _.pull(newList, this.props.type); } @@ -137,16 +136,16 @@ export class IconButton extends React.Component<IconButtonProps>{ }; @action.bound - public reset() { this.isSelected = false; } + public reset() { this._isSelected = false; } @action.bound - public select() { this.isSelected = true; } + public select() { this._isSelected = true; } @action - onMouseLeave = () => { this.hover = false; } + onMouseLeave = () => { this._hover = false; } @action - onMouseEnter = () => { this.hover = true; } + onMouseEnter = () => { this._hover = true; } getFA = () => { switch (this.props.type) { @@ -182,7 +181,7 @@ export class IconButton extends React.Component<IconButtonProps>{ onMouseLeave={this.onMouseLeave} onClick={this.onClick}> <div className="type-icon" id={this.props.type + "-icon"} - style={this.hover ? this.hoverStyle : this.isSelected ? this.selected : this.notSelected} + style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected} > {this.getFA()} </div> diff --git a/src/client/views/search/NaviconButton.scss b/src/client/views/search/NaviconButton.scss index 634b4aeb5..c23bab461 100644 --- a/src/client/views/search/NaviconButton.scss +++ b/src/client/views/search/NaviconButton.scss @@ -10,36 +10,38 @@ $translateY: ($height-icon / 2); $translateX: 0; #hamburger-icon { - width:$width-line; - height:$height-icon; - position:relative; - display:block; - transition: all $transition-time; - -webkit-transition: all $transition-time; - -moz-transition: all $transition-time; - - .line { - display:block; - background:$alt-accent; - width:$width-line; - height:$height-line; - position:absolute; - left:0; - border-radius:($height-line / 2); + width: $width-line; + height: $height-icon; + position: relative; + display: block; transition: all $transition-time; -webkit-transition: all $transition-time; -moz-transition: all $transition-time; - - &.line-1 { - top:0; - } - &.line-2 { - top:50%; - } - &.line-3 { - top:100%; + + .line { + display: block; + background: $alt-accent; + width: $width-line; + height: $height-line; + position: absolute; + left: 0; + border-radius: ($height-line / 2); + transition: all $transition-time; + -webkit-transition: all $transition-time; + -moz-transition: all $transition-time; + + &.line-1 { + top: 0; + } + + &.line-2 { + top: 50%; + } + + &.line-3 { + top: 100%; + } } - } } .filter-header.active { @@ -48,9 +50,11 @@ $translateX: 0; -webkit-transform: translateY($translateY) translateX($translateX) rotate($rotation); -moz-transform: translateY($translateY) translateX($translateX) rotate($rotation); } + .line-2 { - opacity:0; + opacity: 0; } + .line-3 { transform: translateY($translateY * -1) translateX($translateX) rotate($rotation * -1); -webkit-transform: translateY($translateY * -1) translateX($translateX) rotate($rotation * -1); @@ -61,5 +65,5 @@ $translateX: 0; .filter-header:hover #hamburger-icon { transform: scale(1.1); -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); + -moz-transform: scale(1.1); }
\ No newline at end of file diff --git a/src/client/views/search/NaviconButton.tsx b/src/client/views/search/NaviconButton.tsx index e319b945a..3fa36b163 100644 --- a/src/client/views/search/NaviconButton.tsx +++ b/src/client/views/search/NaviconButton.tsx @@ -10,14 +10,14 @@ export interface NaviconProps{ export class NaviconButton extends React.Component<NaviconProps> { - @observable ref: React.RefObject<HTMLAnchorElement> = React.createRef(); + @observable private _ref: React.RefObject<HTMLAnchorElement> = React.createRef(); componentDidMount = () => { let that = this; - if(this.ref.current){this.ref.current.addEventListener("click", function(e) { + if(this._ref.current){this._ref.current.addEventListener("click", function(e) { e.preventDefault(); - if(that.ref.current){ - that.ref.current.classList.toggle('active'); + if(that._ref.current){ + that._ref.current.classList.toggle('active'); return false; } });} @@ -25,7 +25,7 @@ export class NaviconButton extends React.Component<NaviconProps> { render() { return ( - <a id="hamburger-icon" href="#" ref = {this.ref} title="Menu"> + <a id="hamburger-icon" href="#" ref = {this._ref} title="Menu"> <span className="line line-1"></span> <span className="line line-2"></span> <span className="line line-3"></span> diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index d94edba79..e570484e4 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -8,170 +8,54 @@ align-items: center; padding-left: 2px; padding-right: 2px; - - .searchBox-input { - width: 130px; - -webkit-transition: width 0.4s; - transition: width 0.4s; - align-self: stretch; - } - - .searchBox-input:focus { - width: 500px; - outline: 3px solid lightblue; - } + // padding: 2px; .searchBox-barChild { - flex: 0 1 auto; - margin-left: 2px; - margin-right: 2px; - } - - .searchBox-filter { - align-self: stretch; - } - -} - -.filter-title { - font-size: 18; - 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; -} - -.searchBox-results { - margin-left: 27px; //Is there a better way to do this? -} - -.filter-form { - padding: 25px; - width: 600px; - background: $dark-color; - position: relative; - right: 1px; - color: $light-color; - flex-direction: column; - display: inline-block; - transform-origin: top; - overflow: auto; - - .filter-header { - display: flex; - align-items: center; - margin-bottom: 10px; - } - - .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; - } - .close-icon { - width: 20%; - opacity: .6; - position: relative; - display: inline-block; - - .line { - display: block; - background: $alt-accent; - width: $width-line; - height: $height-line; - position: absolute; - right: 0; - border-radius: ($height-line / 2); - - &.line-1 { - transform: rotate(45deg); - top: 45%; - } - - &.line-2 { - transform: rotate(-45deg); - top: 45%; - } + &.searchBox-collection { + flex: 0 1 auto; + margin-left: 2px; + margin-right: 2px } + &.searchBox-input { + width: 130px; + -webkit-transition: width 0.4s; + transition: width 0.4s; + align-self: stretch; + margin-left: 2px; + margin-right: 2px + } - } + .searchBox-input:focus { + width: 500px; + outline: 3px solid lightblue; + } - .close-icon:hover { - opacity: 1; + &.searchBox-filter { + align-self: stretch; + margin-left: 2px; + margin-right: 2px + } } } -#header { - text-transform: uppercase; - letter-spacing: 2px; - font-size: 25; - width: 80%; -} - .searchBox-results { + margin-left: 27px; top: 300px; display: flex; flex-direction: column; margin-right: 72px; -} - -.filter-collection { - display: inline-block; - width: 100%; -} - -.field-title { - color: $light-color; - text-transform: uppercase; - margin-top: 5px; - margin-bottom: 5px; -} -.filter-buttons { - border-color: rgba(178, 206, 248, .2); // $darker-alt-accent - border-top-style: solid; - padding-top: 10px; -} - -.filter-div { - margin-top: 10px; - margin-bottom: 10px; - display: block; - width: 100%; - border-color: rgba(178, 206, 248, .2); // $darker-alt-accent - border-top-style: solid; -} - -.collection-title { - color: $light-color; - text-transform: uppercase; - margin-top: 5px; - margin-bottom: 5px; -} - -.no-result { - width: 500px; - background: $light-color-secondary; - border-color: $intermediate-color; - border-bottom-style: solid; - padding: 10px; - height: 50px; - text-transform: uppercase; - text-align: left; - font-weight: bold; + .no-result { + width: 500px; + background: $light-color-secondary; + border-color: $intermediate-color; + border-bottom-style: solid; + padding: 10px; + height: 50px; + text-transform: uppercase; + text-align: left; + font-weight: bold; + } }
\ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 07e7496cf..1fc777a8c 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -25,6 +25,7 @@ import { CollectionFilters } from './CollectionFilters'; import { NaviconButton } from './NaviconButton'; import * as $ from 'jquery'; import * as anime from 'animejs'; +import "./FilterBox.scss"; library.add(faTimes); @@ -38,23 +39,22 @@ export enum Keys { export class SearchBox extends React.Component { static Instance: SearchBox; + public _allIcons: string[] = [DocTypes.AUDIO, DocTypes.COL, DocTypes.HIST, DocTypes.IMG, DocTypes.LINK, DocTypes.PDF, DocTypes.TEXT, DocTypes.VID, DocTypes.WEB]; - @observable _searchString: string = ""; + @observable private _searchString: string = ""; //if true, any keywords can be used. if false, all keywords are required. - @observable _basicWordStatus: boolean = true; + @observable private _basicWordStatus: boolean = true; @observable private _filterOpen: boolean = false; @observable private _resultsOpen: boolean = false; @observable private _results: Doc[] = []; @observable private _openNoResults: boolean = false; - allIcons: string[] = [DocTypes.AUDIO, DocTypes.COL, DocTypes.HIST, DocTypes.IMG, DocTypes.LINK, DocTypes.PDF, DocTypes.TEXT, DocTypes.VID, DocTypes.WEB]; - @observable _icons: string[] = this.allIcons; - @observable _selectedTypes: any[] = []; - @observable titleFieldStatus: boolean = true; - @observable authorFieldStatus: boolean = true; - @observable dataFieldStatus: boolean = true; - @observable collectionStatus = false; - @observable collectionSelfStatus = true; - @observable collectionParentStatus = true; + @observable private _icons: string[] = this._allIcons; + @observable private _titleFieldStatus: boolean = true; + @observable private _authorFieldStatus: boolean = true; + @observable private _dataFieldStatus: boolean = true; + @observable private _collectionStatus = false; + @observable private _collectionSelfStatus = true; + @observable private _collectionParentStatus = true; @observable private _wordStatusOpen: boolean = false; @observable private _typeOpen: boolean = false; @observable private _colOpen: boolean = false; @@ -180,19 +180,19 @@ export class SearchBox extends React.Component { applyBasicFieldFilters(query: string) { let finalQuery = ""; - if (this.titleFieldStatus) { + if (this._titleFieldStatus) { finalQuery = finalQuery + this.basicFieldFilters(query, Keys.TITLE); } - if (this.authorFieldStatus) { + if (this._authorFieldStatus) { finalQuery = finalQuery + this.basicFieldFilters(query, Keys.AUTHOR); } - if (this.dataFieldStatus) { + if (this._dataFieldStatus) { finalQuery = finalQuery + this.basicFieldFilters(query, Keys.DATA); } return finalQuery; } - get fieldFiltersApplied() { return !(this.dataFieldStatus && this.authorFieldStatus && this.titleFieldStatus); } + get fieldFiltersApplied() { return !(this._dataFieldStatus && this._authorFieldStatus && this._titleFieldStatus); } //TODO: basically all of this //gets all of the collections of all the docviews that are selected @@ -238,7 +238,7 @@ export class SearchBox extends React.Component { } //if should be searched in a specific collection - if (this.collectionStatus) { + if (this._collectionStatus) { query = this.addCollectionFilter(query); query = query.replace(/\s+/g, ' ').trim(); } @@ -448,29 +448,29 @@ export class SearchBox extends React.Component { toggleWordStatusOpen() { this._wordStatusOpen = !this._wordStatusOpen; } @action.bound - updateTitleStatus(newStat: boolean) { this.titleFieldStatus = newStat; } + updateTitleStatus(newStat: boolean) { this._titleFieldStatus = newStat; } @action.bound - updateAuthorStatus(newStat: boolean) { this.authorFieldStatus = newStat; } + updateAuthorStatus(newStat: boolean) { this._authorFieldStatus = newStat; } @action.bound - updateDataStatus(newStat: boolean) { this.dataFieldStatus = newStat; } + updateDataStatus(newStat: boolean) { this._dataFieldStatus = newStat; } @action.bound - updateCollectionStatus(newStat: boolean) { this.collectionStatus = newStat; } + updateCollectionStatus(newStat: boolean) { this._collectionStatus = newStat; } @action.bound - updateSelfCollectionStatus(newStat: boolean) { this.collectionSelfStatus = newStat; } + updateSelfCollectionStatus(newStat: boolean) { this._collectionSelfStatus = newStat; } @action.bound - updateParentCollectionStatus(newStat: boolean) { this.collectionParentStatus = newStat; } + updateParentCollectionStatus(newStat: boolean) { this._collectionParentStatus = newStat; } - getCollectionStatus() { return this.collectionStatus; } - getSelfCollectionStatus() { return this.collectionSelfStatus; } - getParentCollectionStatus() { return this.collectionParentStatus; } - getTitleStatus() { return this.titleFieldStatus; } - getAuthorStatus() { return this.authorFieldStatus; } - getDataStatus() { return this.dataFieldStatus; } + getCollectionStatus() { return this._collectionStatus; } + getSelfCollectionStatus() { return this._collectionSelfStatus; } + getParentCollectionStatus() { return this._collectionParentStatus; } + getTitleStatus() { return this._titleFieldStatus; } + getAuthorStatus() { return this._authorFieldStatus; } + getDataStatus() { return this._dataFieldStatus; } // Useful queries: // Delegates of a document: {!join from=id to=proto_i}id:{protoId} @@ -480,8 +480,8 @@ export class SearchBox extends React.Component { <div> <div className="searchBox-container"> <div className="searchBox-bar"> - <span onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef}> - <FontAwesomeIcon icon="object-group" className="searchBox-barChild" size="lg" /> + <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef}> + <FontAwesomeIcon icon="object-group" size="lg" /> </span> <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..." className="searchBox-barChild searchBox-input" onPointerDown={this.openSearch} onKeyPress={this.enter} @@ -500,13 +500,13 @@ export class SearchBox extends React.Component { </div> {this._filterOpen ? ( <div className="filter-form" onPointerDown={this.stopProp} id="filter-form" style={this._filterOpen ? { display: "flex" } : { display: "none" }}> - <div style={{ display: "flex", width: "100%" }}> + <div className = "top-filter-header" style={{ display: "flex", width: "100%" }}> <div id="header">Filter Search Results</div> <div className="close-icon" onClick={this.closeFilter}> <span className="line line-1"></span> <span className="line line-2"></span></div> </div> - <div> + <div className = "filter-options"> <div className="filter-div"> <div className="filter-header"> <div className='filter-title words'>Required words</div> @@ -531,7 +531,7 @@ export class SearchBox extends React.Component { </div> <div className="filter-panel"><CollectionFilters updateCollectionStatus={this.updateCollectionStatus} updateParentCollectionStatus={this.updateParentCollectionStatus} updateSelfCollectionStatus={this.updateSelfCollectionStatus} - collectionStatus={this.collectionStatus} collectionParentStatus={this.collectionParentStatus} collectionSelfStatus={this.collectionSelfStatus} /></div> + collectionStatus={this._collectionStatus} collectionParentStatus={this._collectionParentStatus} collectionSelfStatus={this._collectionSelfStatus} /></div> </div> <div className="filter-div"> <div className="filter-header"> @@ -539,12 +539,12 @@ export class SearchBox extends React.Component { <div style={{ marginLeft: "auto" }}><NaviconButton onClick={this.toggleFieldOpen} /></div> </div> <div className="filter-panel"><FieldFilters - titleFieldStatus={this.titleFieldStatus} dataFieldStatus={this.dataFieldStatus} authorFieldStatus={this.authorFieldStatus} + titleFieldStatus={this._titleFieldStatus} dataFieldStatus={this._dataFieldStatus} authorFieldStatus={this._authorFieldStatus} updateAuthorStatus={this.updateAuthorStatus} updateDataStatus={this.updateDataStatus} updateTitleStatus={this.updateTitleStatus} /> </div> </div> </div> <div className="filter-buttons" style={{ display: "flex", justifyContent: "space-around" }}> - <button className="minimizwe-filter" onClick={this.minimizeAll}>Minimize All</button> + <button className="minimize-filter" onClick={this.minimizeAll}>Minimize All</button> <button className="advanced-filter" >Advanced Filters</button> <button className="save-filter" >Save Filters</button> <button className="reset-filter" onClick={this.resetFilters}>Reset Filters</button> diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss index c82d4bb06..9859d6293 100644 --- a/src/client/views/search/SearchItem.scss +++ b/src/client/views/search/SearchItem.scss @@ -1,149 +1,151 @@ @import "../globalCssVariables"; -.search-item { - width: 500px; - background: $light-color-secondary; - border-color: $intermediate-color; - border-bottom-style: solid; - padding: 10px; - height: 70px; -} - -.search-info { +.search-overview { display: flex; + flex-direction: row-reverse; justify-content: flex-end; - width: 40%; -} + height: 70px; -.main-search-info { - display: flex; - flex-direction: row; - width: 100%; -} - -.search-item:hover { - transition: all 0.2s; - background: $lighter-alt-accent; -} - -.search-title { - text-transform: uppercase; - text-align: left; - width: 80%; - font-weight: bold; -} - -.link-container.item { - height: 26px; - width: 26px; - border-radius: 13px; - background: $dark-color; - color: $light-color-secondary; - display: flex; - justify-content: center; - align-items: center; - margin-right: 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; - transform-origin: top right; - overflow: hidden; - - .link-count { - opacity: 1; - position: absolute; - z-index: 1000; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; + .search-item { + width: 500px; + background: $light-color-secondary; + border-color: $intermediate-color; + border-bottom-style: solid; + padding: 10px; + height: 70px; + + .main-search-info { + display: flex; + flex-direction: row; + width: 100%; + + .search-title { + text-transform: uppercase; + text-align: left; + width: 80%; + font-weight: bold; + } + + .search-info { + display: flex; + justify-content: flex-end; + width: 40%; + + .link-container.item { + height: 26px; + width: 26px; + border-radius: 13px; + background: $dark-color; + color: $light-color-secondary; + display: flex; + justify-content: center; + align-items: center; + right: 120px; + -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: absolute; + + .link-count { + opacity: 1; + position: absolute; + z-index: 1000; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; + } + + .link-extended { + opacity: 0; + position: absolute; + z-index: 500; + overflow: hidden; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; + } + } + + .link-container.item:hover { + width: 70px; + } + + .link-container.item:hover .link-count { + opacity: 0; + } + + .link-container.item:hover .link-extended { + opacity: 1; + } + + .icon { + // display: inline-block; + // // align-items: right; + // display: flex; + position: absolute; + + .search-type { + width: 25PX; + height: 25PX; + display: flex; + justify-content: center; + align-items: center; + position: relative; + margin-right: 5px; + } + + .search-type:hover+.search-label { + opacity: 1; + } + + .search-label { + font-size: 10; + padding: 5px; + position: absolute; + right: 0px; + text-transform: capitalize; + opacity: 0; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; + } + } + } + } } - .link-extended { - opacity: 0; - position: absolute; - z-index: 500; - overflow: hidden; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; + .search-item:hover~.searchBox-instances, + .searchBox-instances:hover, + .searchBox-instances:active { + opacity: 1; + background: $lighter-alt-accent; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); } -} - -.link-container.item:hover{ - width: 70px; -} -.link-container.item:hover .link-count{ - opacity: 0; -} - -.link-container.item:hover .link-extended{ - opacity: 1; -} + .search-item:hover { + transition: all 0.2s; + background: $lighter-alt-accent; + } -.search-type { - width: 25PX; - height: 25PX; - display: flex; - justify-content: center; - align-items: center; -} - - -.searchBox-instances { - float: left; - opacity: 1; - width: 150px; - transition: all 0.2s ease; - color: black; - transform-origin: top right; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); - height: 100% -} - -.contexts.collection { - border-color: $darker-alt-accent; - border-bottom-style: solid; -} + .searchBox-instances { + float: left; + opacity: 1; + width: 150px; + transition: all 0.2s ease; + color: black; + transform-origin: top right; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + height: 100% + } -.search-overview { - display: flex; - flex-direction: row-reverse; - justify-content: flex-end; - height: 70px; -} - -.parents { - background: $lighter-alt-accent; - padding: 10px; -} - -.search-item:hover~.searchBox-instances, -.searchBox-instances:hover, -.searchBox-instances:active { - opacity: 1; - background: $lighter-alt-accent; - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); -} - -.search-label{ - text-align: right; - float: right; - text-transform: capitalize; - opacity: 0; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; -} - -.search-type:hover +.search-label{ - opacity: 1; }
\ No newline at end of file diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index fa9d58152..71ad9a5ee 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -17,6 +17,7 @@ import { CollectionViewType } from "../collections/CollectionBaseView"; import { DocTypes } from "../../documents/Documents"; import { SearchBox } from "./SearchBox"; import { DocumentView } from "../nodes/DocumentView"; +import "./SelectorContextMenu.scss"; export interface SearchItemProps { doc: Doc; @@ -39,7 +40,6 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> { constructor(props: SearchItemProps) { super(props); - this.fetchDocuments(); } diff --git a/src/client/views/search/SelectorContextMenu.scss b/src/client/views/search/SelectorContextMenu.scss new file mode 100644 index 000000000..49f77b9bf --- /dev/null +++ b/src/client/views/search/SelectorContextMenu.scss @@ -0,0 +1,15 @@ +@import "../globalCssVariables"; + +.parents { + background: $lighter-alt-accent; + padding: 10px; + + .contexts { + text-transform: uppercase; + } + + .collection { + border-color: $darker-alt-accent; + border-bottom-style: solid; + } +}
\ No newline at end of file diff --git a/src/client/views/search/ToggleBar.tsx b/src/client/views/search/ToggleBar.tsx index b1d22d38c..dbe16cbdb 100644 --- a/src/client/views/search/ToggleBar.tsx +++ b/src/client/views/search/ToggleBar.tsx @@ -18,15 +18,15 @@ export interface ToggleBarProps { export class ToggleBar extends React.Component<ToggleBarProps>{ static Instance: ToggleBar; - @observable forwardTimeline: anime.AnimeTimelineInstance; - @observable _toggleButton: React.RefObject<HTMLDivElement>; - @observable _originalStatus: boolean = this.props.originalStatus; + @observable private _forwardTimeline: anime.AnimeTimelineInstance; + @observable private _toggleButton: React.RefObject<HTMLDivElement>; + @observable private _originalStatus: boolean = this.props.originalStatus; constructor(props: ToggleBarProps) { super(props); ToggleBar.Instance = this; this._toggleButton = React.createRef(); - this.forwardTimeline = anime.timeline({ + this._forwardTimeline = anime.timeline({ loop: false, autoplay: false, direction: "reverse", @@ -38,7 +38,7 @@ export class ToggleBar extends React.Component<ToggleBarProps>{ let totalWidth = 265; if (this._originalStatus) { - this.forwardTimeline.add({ + this._forwardTimeline.add({ targets: this._toggleButton.current, translateX: totalWidth, easing: "easeInOutQuad", @@ -46,7 +46,7 @@ export class ToggleBar extends React.Component<ToggleBarProps>{ }); } else { - this.forwardTimeline.add({ + this._forwardTimeline.add({ targets: this._toggleButton.current, translateX: -totalWidth, easing: "easeInOutQuad", @@ -57,16 +57,16 @@ export class ToggleBar extends React.Component<ToggleBarProps>{ @action.bound onclick() { - this.forwardTimeline.play(); - this.forwardTimeline.reverse(); + this._forwardTimeline.play(); + this._forwardTimeline.reverse(); this.props.handleChange(); } @action.bound public resetToggle = () => { if (!this.props.getStatus()) { - this.forwardTimeline.play(); - this.forwardTimeline.reverse(); + this._forwardTimeline.play(); + this._forwardTimeline.reverse(); this.props.handleChange(); } } |