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