1import React from "react"; 2 3import RecordComponent from "../components/RecordComponent"; 4import SlideDialog from "../components/SlideDialog"; 5import { apiRequest } from "../utils"; 6import i18n from "../i18n"; 7import dialogSystem from "../dialogSystem"; 8import makeRichPromise from "../richPromise"; 9 10class FindFiles extends RecordComponent { 11 constructor(props) { 12 super(props); 13 this.state = { 14 query: "", 15 currentSelection: -1, 16 results: [], 17 }; 18 } 19 20 componentDidMount() { 21 super.componentDidMount(); 22 this.refs.q.focus(); 23 } 24 25 onInputChange(e) { 26 const q = e.target.value; 27 28 if (q === "") { 29 this.setState({ 30 query: "", 31 results: [], 32 currentSelection: -1, 33 }); 34 } else { 35 this.setState({ 36 query: q, 37 }); 38 39 apiRequest( 40 "/find", 41 { 42 data: { 43 q: q, 44 alt: this.getRecordAlt(), 45 lang: i18n.currentLanguage, 46 }, 47 method: "POST", 48 }, 49 makeRichPromise 50 ).then((resp) => { 51 this.setState({ 52 results: resp.results, 53 currentSelection: Math.min( 54 this.state.currentSelection, 55 resp.results.length - 1 56 ), 57 }); 58 }); 59 } 60 } 61 62 onInputKey(e) { 63 let sel = this.state.currentSelection; 64 const max = this.state.results.length; 65 if (e.which === 40) { 66 e.preventDefault(); 67 sel = (sel + 1) % max; 68 } else if (e.which === 38) { 69 e.preventDefault(); 70 sel = (sel - 1 + max) % max; 71 } else if (e.which === 13) { 72 this.onActiveItem(this.state.currentSelection); 73 } 74 this.setState({ 75 currentSelection: sel, 76 }); 77 } 78 79 onActiveItem(index) { 80 const item = this.state.results[index]; 81 if (item !== undefined) { 82 const target = 83 this.props.match.params.page === "preview" ? ".preview" : ".edit"; 84 const urlPath = this.getUrlRecordPathWithAlt(item.path); 85 dialogSystem.dismissDialog(); 86 this.transitionToAdminPage(target, { path: urlPath }); 87 } 88 } 89 90 selectItem(index) { 91 this.setState({ 92 currentSelection: Math.min(index, this.state.results.length - 1), 93 }); 94 } 95 96 renderResults() { 97 const rv = this.state.results.map((result, idx) => { 98 const parents = result.parents.map((item, idx) => { 99 return ( 100 <span className="parent" key={idx}> 101 {item.title} 102 </span> 103 ); 104 }); 105 106 return ( 107 <li 108 key={idx} 109 className={idx === this.state.currentSelection ? "active" : ""} 110 onClick={this.onActiveItem.bind(this, idx)} 111 onMouseEnter={this.selectItem.bind(this, idx)} 112 > 113 {parents} 114 <strong>{result.title}</strong> 115 </li> 116 ); 117 }); 118 119 return <ul className="search-results">{rv}</ul>; 120 } 121 122 render() { 123 return ( 124 <SlideDialog 125 hasCloseButton 126 closeOnEscape 127 title={i18n.trans("FIND_FILES")} 128 > 129 <div className="form-group"> 130 <input 131 type="text" 132 ref="q" 133 className="form-control" 134 value={this.state.query} 135 onChange={this.onInputChange.bind(this)} 136 onKeyDown={this.onInputKey.bind(this)} 137 placeholder={i18n.trans("FIND_FILES_PLACEHOLDER")} 138 /> 139 </div> 140 {this.renderResults()} 141 </SlideDialog> 142 ); 143 } 144} 145 146export default FindFiles; 147