Fetch generated graphs on the frontend (#251)

Summary:
This commit enables the cred explorer to fetch pre-generated graphs. The
form has poor UX, but gets the job done. (To do later: saving in
localStorage, allowing fetching the list of possible graphs, linking the
submit button so that it’s triggered by `Enter`, etc.).

Test Plan:
Set up with `node ./bin/sourcecred.js graph sourcecred sourcecred`, then
run `yarn start` and check the following cases:
  - success case: `sourcecred`/`sourcecred`
  - error case: `sarcecrod`/`sarcecrod` (nice console error)
  - error case: the repository owner or name is an empty string or has
    invalid characters, like `../../secret.txt` (nice console error)

wchargin-branch: fetch-graphs
This commit is contained in:
William Chargin 2018-05-09 12:47:56 -07:00 committed by GitHub
parent 6ca4f77b6d
commit 8e4668cc91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 1 deletions

View File

@ -3,20 +3,91 @@
import React from "react";
import {StyleSheet, css} from "aphrodite/no-important";
import {Graph} from "../../core/graph";
type Props = {};
type State = {};
type State = {
repoOwner: string,
repoName: string,
graph: ?Graph<mixed, mixed>,
};
export default class App extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
repoOwner: "",
repoName: "",
graph: null,
};
}
render() {
const {graph} = this.state;
return (
<div>
<header className={css(styles.header)}>
<h1>Cred Explorer</h1>
</header>
<p>Welcome to the SourceCred Explorer!</p>
<div>
<label>
Repository owner:
<input
value={this.state.repoOwner}
onChange={(e) => {
const value = e.target.value;
this.setState({repoOwner: value});
}}
/>
</label>
<br />
<label>
Repository name:
<input
value={this.state.repoName}
onChange={(e) => {
const value = e.target.value;
this.setState({repoName: value});
}}
/>
</label>
<br />
<button onClick={() => this.loadGraph()}>Load graph</button>
{graph ? (
<p>
Graph loaded: {graph.nodes().length} nodes, {graph.edges().length}{" "}
edges.
</p>
) : (
<p>Graph not loaded.</p>
)}
</div>
</div>
);
}
loadGraph() {
const validRe = /^[A-Za-z0-9_-]+$/;
const {repoOwner, repoName} = this.state;
if (!repoOwner.match(validRe)) {
console.error(`Invalid repository owner: ${JSON.stringify(repoOwner)}`);
return;
}
if (!repoName.match(validRe)) {
console.error(`Invalid repository name: ${JSON.stringify(repoName)}`);
return;
}
fetch(`/api/v1/data/graphs/${repoOwner}/${repoName}/graph.json`)
.then((resp) => (resp.ok ? resp.json() : Promise.reject(resp)))
.then((json) => Graph.fromJSON(json))
.then((graph) => {
this.setState({graph});
})
.catch((e) => {
console.error("Error while fetching:", e);
});
}
}
const styles = StyleSheet.create({