|
| 1 | +import React from "react"; |
| 2 | +import {GraphQLClient} from 'graphql-request' |
| 3 | +import {getServer} from "./Server"; |
| 4 | +import {NavigateCallback, NavigateTargetType, QUERY_CHANGES} from "./Navigation"; |
| 5 | +import {match} from "ts-pattern"; |
| 6 | + |
| 7 | +export type SearchBrowserProps = { |
| 8 | + repo: string |
| 9 | + filter: string |
| 10 | + searchstr: string |
| 11 | + rev: string |
| 12 | + navigateCallback: NavigateCallback |
| 13 | +} |
| 14 | + |
| 15 | +type State = { |
| 16 | + results: SearchResult[] |
| 17 | + client: GraphQLClient |
| 18 | +} |
| 19 | + |
| 20 | +export class SearchResults extends React.Component<SearchBrowserProps, State> { |
| 21 | + state: State = { |
| 22 | + results: [], |
| 23 | + client: new GraphQLClient(`${getServer()}/~/graphql/${this.props.repo}`, { |
| 24 | + mode: 'cors' |
| 25 | + }), |
| 26 | + }; |
| 27 | + |
| 28 | + startRequest() { |
| 29 | + this.state.client.rawRequest(QUERY_SEARCH, { |
| 30 | + searchstr: this.props.searchstr |
| 31 | + filter: this.props.filter, |
| 32 | + rev: this.props.rev |
| 33 | + }).then((d) => { |
| 34 | + const data = d.data |
| 35 | + |
| 36 | + this.setState({ |
| 37 | + results: data.results |
| 38 | + }) |
| 39 | + }) |
| 40 | + } |
| 41 | + |
| 42 | + componentDidMount() { |
| 43 | + this.startRequest() |
| 44 | + } |
| 45 | + |
| 46 | + componentDidUpdate( |
| 47 | + prevProps: Readonly<ChangesBrowserProps>, |
| 48 | + prevState: Readonly<State>, |
| 49 | + snapshot?: any) |
| 50 | + { |
| 51 | + if (prevProps !== this.props) { |
| 52 | + this.setState({ |
| 53 | + results: [], |
| 54 | + }) |
| 55 | + |
| 56 | + this.startRequest() |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + componentWillUnmount() { |
| 61 | + // TODO cancel request? |
| 62 | + } |
| 63 | + |
| 64 | + renderList(values: SearchResult[]) { |
| 65 | + |
| 66 | + const navigateBrowse = (rev: string, path: string, e: React.MouseEvent<HTMLDivElement>) => { |
| 67 | + this.props.navigateCallback(NavigateTargetType.File, { |
| 68 | + repo: this.props.repo, |
| 69 | + path: path, |
| 70 | + filter: this.props.filter, |
| 71 | + rev: rev, |
| 72 | + }) |
| 73 | + } |
| 74 | + |
| 75 | + return values.map((ee) => { |
| 76 | + let entry = ee.commit; |
| 77 | + return <div key={entry.hash} className="commit-list-entry"> |
| 78 | + <div className="changes-list-entry" > |
| 79 | + <span |
| 80 | + className="change-summary" |
| 81 | + onClick={navigateChange.bind(this, entry.original.hash)}> |
| 82 | + {entry.summary} |
| 83 | + </span> |
| 84 | + <span |
| 85 | + className="name" |
| 86 | + onClick={navigateChange.bind(this, entry.original.hash)}> |
| 87 | + {ee.name.replace("refs/heads/","")} |
| 88 | + </span> |
| 89 | + <span className="change-hash" |
| 90 | + onClick={navigateBrowse.bind(this, entry.original.hash)}> |
| 91 | + |
| 92 | + {entry.hash.slice(0,6)}</span> |
| 93 | + </div> |
| 94 | + </div> |
| 95 | + |
| 96 | + }) |
| 97 | + } |
| 98 | + |
| 99 | + render() { |
| 100 | + if (this.state.refs.length === 0) { |
| 101 | + return <div className={'history-browser-loading'}>Loading...</div> |
| 102 | + } else { |
| 103 | + return <div className={'changes-browser-list'}> |
| 104 | + {this.renderList(this.state.refs)} |
| 105 | + </div> |
| 106 | + } |
| 107 | + } |
| 108 | +} |
0 commit comments