Separate artifact settings from GitHub graph fetch (#108)
Summary: We need to know the repo owner and name for purposes other than fetching the GitHub graph: for instance, fetching the `artifacts.json` file that describes the artifact subgraph. It makes sense that these should be settings global to the application. This commit separates a settings component and the original GitHub graph fetcher. This invalidates localStorage; you can manually migrate. Paired with @dandelionmane. Test Plan: Note that the data continues to be stored in localStorage and that it is updated on each keypress. Note that the state is properly passed around: if you change the repository name from `example-repo` to `sourcecred`, e.g., and click “Fetch GitHub graph”, then the proper graph is fetched. wchargin-branch: separate-artifact-settings
This commit is contained in:
parent
d310561b94
commit
007cf88172
|
@ -11,15 +11,18 @@ import type {
|
||||||
NodePayload as GithubNodePayload,
|
NodePayload as GithubNodePayload,
|
||||||
EdgePayload as GithubEdgePayload,
|
EdgePayload as GithubEdgePayload,
|
||||||
} from "../../github/githubPlugin";
|
} from "../../github/githubPlugin";
|
||||||
|
import type {Settings} from "./SettingsConfig";
|
||||||
import {ArtifactList} from "./ArtifactList";
|
import {ArtifactList} from "./ArtifactList";
|
||||||
import {ContributionList} from "./ContributionList";
|
import {ContributionList} from "./ContributionList";
|
||||||
import {GithubGraphFetcher} from "./GithubGraphFetcher";
|
import {GithubGraphFetcher} from "./GithubGraphFetcher";
|
||||||
|
import {SettingsConfig, defaultSettings} from "./SettingsConfig";
|
||||||
import standardAdapterSet from "./standardAdapterSet";
|
import standardAdapterSet from "./standardAdapterSet";
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
type State = {
|
type State = {
|
||||||
artifacts: Node<ArtifactNodePayload>[],
|
artifacts: Node<ArtifactNodePayload>[],
|
||||||
githubGraph: ?Graph<GithubNodePayload, GithubEdgePayload>,
|
githubGraph: ?Graph<GithubNodePayload, GithubEdgePayload>,
|
||||||
|
settings: Settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
function createSampleArtifact(name) {
|
function createSampleArtifact(name) {
|
||||||
|
@ -41,6 +44,7 @@ export default class App extends React.Component<Props, State> {
|
||||||
this.state = {
|
this.state = {
|
||||||
artifacts: [],
|
artifacts: [],
|
||||||
githubGraph: null,
|
githubGraph: null,
|
||||||
|
settings: defaultSettings(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +54,13 @@ export default class App extends React.Component<Props, State> {
|
||||||
<header className={css(styles.header)}>
|
<header className={css(styles.header)}>
|
||||||
<h1>Artifact editor</h1>
|
<h1>Artifact editor</h1>
|
||||||
</header>
|
</header>
|
||||||
|
<SettingsConfig
|
||||||
|
onChange={(settings) => {
|
||||||
|
this.setState({settings});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<GithubGraphFetcher
|
<GithubGraphFetcher
|
||||||
|
settings={this.state.settings}
|
||||||
onCreateGraph={(githubGraph) => {
|
onCreateGraph={(githubGraph) => {
|
||||||
this.setState({githubGraph});
|
this.setState({githubGraph});
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import type {Graph} from "../../../core/graph";
|
import type {Graph} from "../../../core/graph";
|
||||||
import LocalStore from "./LocalStore";
|
import type {Settings} from "./SettingsConfig";
|
||||||
import fetchGithubRepo from "../../github/fetchGithubRepo";
|
import fetchGithubRepo from "../../github/fetchGithubRepo";
|
||||||
import type {
|
import type {
|
||||||
NodePayload as GithubNodePayload,
|
NodePayload as GithubNodePayload,
|
||||||
|
@ -12,78 +12,25 @@ import type {
|
||||||
import {GithubParser} from "../../github/githubPlugin";
|
import {GithubParser} from "../../github/githubPlugin";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
settings: Settings,
|
||||||
onCreateGraph: (graph: Graph<GithubNodePayload, GithubEdgePayload>) => void,
|
onCreateGraph: (graph: Graph<GithubNodePayload, GithubEdgePayload>) => void,
|
||||||
};
|
};
|
||||||
type State = {
|
|
||||||
apiToken: string,
|
|
||||||
repoOwner: string,
|
|
||||||
repoName: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SETTINGS_KEY = "GithubGraphFetcher.settings";
|
|
||||||
|
|
||||||
export class GithubGraphFetcher extends React.Component<Props, State> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const defaultState = {
|
|
||||||
apiToken: "",
|
|
||||||
repoOwner: "",
|
|
||||||
repoName: "",
|
|
||||||
};
|
|
||||||
this.state = LocalStore.get(SETTINGS_KEY, defaultState);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export class GithubGraphFetcher extends React.Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
|
const {settings} = this.props;
|
||||||
|
const haveSettings =
|
||||||
|
!!settings.githubApiToken && !!settings.repoOwner && !!settings.repoName;
|
||||||
return (
|
return (
|
||||||
<div>
|
<button onClick={() => this.fetchGraph()} disabled={!haveSettings}>
|
||||||
<label>
|
Fetch GitHub graph
|
||||||
API token{" "}
|
</button>
|
||||||
<input
|
|
||||||
value={this.state.apiToken}
|
|
||||||
onChange={(e) => {
|
|
||||||
const value = e.target.value;
|
|
||||||
this.setState((state) => ({
|
|
||||||
apiToken: value,
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<label>
|
|
||||||
Repository owner{" "}
|
|
||||||
<input
|
|
||||||
value={this.state.repoOwner}
|
|
||||||
onChange={(e) => {
|
|
||||||
const value = e.target.value;
|
|
||||||
this.setState((state) => ({
|
|
||||||
repoOwner: value,
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<label>
|
|
||||||
Repository name{" "}
|
|
||||||
<input
|
|
||||||
value={this.state.repoName}
|
|
||||||
onChange={(e) => {
|
|
||||||
const value = e.target.value;
|
|
||||||
this.setState((state) => ({
|
|
||||||
repoName: value,
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<button onClick={() => this.fetchGraph()}>Fetch!</button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchGraph() {
|
fetchGraph() {
|
||||||
const {repoOwner, repoName, apiToken} = this.state;
|
const {repoOwner, repoName, githubApiToken} = this.props.settings;
|
||||||
LocalStore.set(SETTINGS_KEY, {apiToken, repoOwner, repoName});
|
fetchGithubRepo(repoOwner, repoName, githubApiToken)
|
||||||
fetchGithubRepo(repoOwner, repoName, apiToken)
|
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
const parser = new GithubParser(`${repoOwner}/${repoName}`);
|
const parser = new GithubParser(`${repoOwner}/${repoName}`);
|
||||||
parser.addData(json.data);
|
parser.addData(json.data);
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import LocalStore from "./LocalStore";
|
||||||
|
|
||||||
|
export type Settings = {
|
||||||
|
githubApiToken: string,
|
||||||
|
repoOwner: string,
|
||||||
|
repoName: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
onChange: (Settings) => void,
|
||||||
|
};
|
||||||
|
type State = Settings;
|
||||||
|
|
||||||
|
const LOCAL_STORE_SETTINGS_KEY = "SettingsConfig.settings";
|
||||||
|
|
||||||
|
export function defaultSettings() {
|
||||||
|
return {
|
||||||
|
githubApiToken: "",
|
||||||
|
repoOwner: "",
|
||||||
|
repoName: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SettingsConfig extends React.Component<Props, State> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = defaultSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setState(LocalStore.get(LOCAL_STORE_SETTINGS_KEY, this.state), () => {
|
||||||
|
this.props.onChange(this.state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
API token{" "}
|
||||||
|
<input
|
||||||
|
value={this.state.githubApiToken}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
this.setState(
|
||||||
|
(state) => ({
|
||||||
|
githubApiToken: value,
|
||||||
|
}),
|
||||||
|
this._updateSettings.bind(this)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
Repository owner{" "}
|
||||||
|
<input
|
||||||
|
value={this.state.repoOwner}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
this.setState(
|
||||||
|
(state) => ({
|
||||||
|
repoOwner: value,
|
||||||
|
}),
|
||||||
|
this._updateSettings.bind(this)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
Repository name{" "}
|
||||||
|
<input
|
||||||
|
value={this.state.repoName}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
this.setState(
|
||||||
|
(state) => ({
|
||||||
|
repoName: value,
|
||||||
|
}),
|
||||||
|
this._updateSettings.bind(this)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateSettings() {
|
||||||
|
LocalStore.set(LOCAL_STORE_SETTINGS_KEY, this.state);
|
||||||
|
this.props.onChange(this.state);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue