Skip to content
This repository has been archived by the owner on May 25, 2023. It is now read-only.

Commit

Permalink
fix: persisted query fix with fragments (#1034)
Browse files Browse the repository at this point in the history
* persisted query fix with fragments

* fix error message

* Create fetching-data-from-github.md

* Update fetching-data-from-github.md

* remove console

* fixes note bug

* unpersist the goal query

* fix: take proper parameter for FetchGoals mutation

* fix: display note form only when we have a note ready

* fix: proper useEffect switch for notes input

Co-authored-by: TED Vortex <ted.vortex@gmail.com>
  • Loading branch information
bdougie and 0-vortex committed Jul 14, 2021
1 parent 1bed455 commit 6ac20a8
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 34 deletions.
24 changes: 24 additions & 0 deletions docs/fetching-data-from-github.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Fetching Data from the GitHub GraphQL API
Over the past few years, GitHub has been enabling developers to build on our platform as 3rd party integrators. This enablement does not come without limitation in rate-limiting and token access. Open Sauced, originally started as a way try the GitHub GraphQL API out with a production ready application.

## Implementation Approach
Open Sauced is exclusively power by the public data from open source reposistories. No only is the data sourced from open sourced repos, the onboarding flow for Open Sauced walks the user through creating their own open sourced repo to track their own contributions.

## OneGraph
[OneGraph](https://www.onegraph.com/) is the tool used to consume the GitHub GraphQL API through one consistent GraphQL interface.

## Persisted Queries
Persisted queries are an advanced GraphQL feature that allow clients to pre-register queries with the server. In a typical workflow, the client will send the query to the server as part of a build process and the server will send back an id. When the client wants to run the query, it sends the id instead of the full query string.

Developers use persisted queries because they reduce the amount of bandwidth sent from the client to the server and they improve security by locking down the queries that can be sent to the server.

OneGraph makes this all easy to do, read up m oreon that in [their documentation](https://www.onegraph.com/docs/persisted_queries.html).

## Goals Repository
Each Open Sauced user ues their own GitHub repository as a database. The repository is generated during sign up and the companion for finding open source contributions. All data in this repository is a mirror of the data you see on the opensauced.pizza dashboard.

https://github.com/open-sauced/goals-template

## References
- [Using Persisted Queries](https://www.onegraph.com/docs/persisted_queries.html)
- [GraphQL Enterprise Connect: "Persisted GraphQL", Brian Douglas](https://www.youtube.com/watch?v=yr5kSZljBxo)
50 changes: 29 additions & 21 deletions src/components/Contributions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,25 @@ import {CardPadding} from "../styles/Card";
import {AccentLink, MicroFont} from "../styles/Typography";
import IssuesLoader from "./IssuesLoader";

function Contributions({repoName, owner}) {
function Contributions({repoName, owner, viewer}) {
const [issues, setIssues] = useState(null);
const [loading, setLoading] = useState(false);

useEffect(() => {
setLoading(true);
api.persistedInteractionsFetch({owner, repo:repoName}).then(response => {
const {data} = response.data.gitHub.repository.issues;
setIssues(data);
setLoading(false);
});

const ContributionsCollectionQueryVars = (owner, repo, target) => `repo:${owner}/${repo} involves:${target}`;

api
.persistedInteractionsFetch({query: ContributionsCollectionQueryVars(owner, repoName, viewer)})
.then(response => {
const {nodes} = response.data.gitHub.search;
setIssues(nodes);
setLoading(false);
})
.catch(e => {
console.log(e);
});
}, []);

return (
Expand All @@ -34,21 +42,21 @@ function Contributions({repoName, owner}) {
) : (
<List>
{issues &&
issues.map(issue => (
<li key={issue.node.id}>
<a rel="noreferrer" target="_blank" href={issue.node.url}>
<IssuesListItem
type="contributions"
title={issue.node.title}
labels={issue.node.labels}
opened={issue.node.createdAt}
participants={issue.node.participants}
comments={issue.node.comments}
milestone={issue.node.milestone}
/>
</a>
</li>
))}
issues.map(issue => (
<li key={issue.id}>
<a rel="noreferrer" target="_blank" href={issue.url}>
<IssuesListItem
type="contributions"
title={issue.title}
labels={issue.labels}
opened={issue.createdAt}
participants={issue.participants}
comments={issue.comments}
milestone={issue.milestone}
/>
</a>
</li>
))}
</List>
)}
</Card>
Expand Down
2 changes: 1 addition & 1 deletion src/components/IssueListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function IssueListItem({title, labels, author, opened, type, participants, comme
<b>{title}</b>
</p>
<div>
{labels.data.length > 0 && labels.data.map(label => (
{labels.data && labels.data.length > 0 && labels.data.map(label => (
<span
style={{
backgroundColor: `#${label.node.color}`,
Expand Down
14 changes: 10 additions & 4 deletions src/components/NoteForm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState} from "react";
import React, {useEffect, useState} from "react";
import Button from "../styles/Button";
import {NoteArea, RenderedNote} from "../styles/TextArea";
import Card from "./Card";
Expand All @@ -13,6 +13,10 @@ function NoteForm({goalId, repoName, note}) {
const [input, setInput] = useState(note);
const [editing, setEditing] = useState(false);

useEffect(() => {
setInput(note);
}, [note]);

const _handleNoteUpdate = () => {
api
.updateGoal(goalId, repoName, "OPEN", input)
Expand All @@ -39,8 +43,8 @@ function NoteForm({goalId, repoName, note}) {
return (
<Card>
{!editing ? (
<RenderedNote data-testid="notes-content" >
<ReactMarkdown className="noteContent" source={input || ""} />
<RenderedNote data-testid="notes-content">
<ReactMarkdown className="noteContent" children={input} />
</RenderedNote>
) : (
<NoteArea
Expand Down Expand Up @@ -69,7 +73,9 @@ function NoteForm({goalId, repoName, note}) {
<Button primary onClick={_handleCancelEditing}>
Cancel
</Button>
) : ""}
) : (
""
)}
</FlexCenter>
</Card>
);
Expand Down
12 changes: 6 additions & 6 deletions src/components/Repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {fontSize} from "../styles/variables";

function Repository({user, match}) {
const {
params: {repoName, repoOwner, id},
params: {repoName, repoOwner, id: issueNumber},
} = match;
const [repository, setRepository] = useState(null);
const [error, setError] = useState(null);
Expand Down Expand Up @@ -56,11 +56,11 @@ function Repository({user, match}) {
});

api
.persistedGoalFetch({number:parseInt(id)})
.fetchGoalQuery(parseInt(issueNumber))
.then(res => {
const {id, body} = res.data.gitHub.viewer.repository.issue;
setNote(body);
setIssueId(id);
const {issue} = res.data.gitHub.viewer.repository;
setNote(issue.body);
setIssueId(issue.id);
})
.catch(e => {
console.log(e);
Expand Down Expand Up @@ -248,7 +248,7 @@ function Repository({user, match}) {
<DetailInfo text={`${humanizeNumber(stargazers.totalCount)} stars`} icon="StarIcon" />
{licenseInfo && <DetailInfo text={`${licenseInfo.name}`} icon="LawIcon" />}
</Card>
<Contributions repoName={name} owner={owner.login} />
{user && <Contributions viewer={user.login} repoName={name} owner={owner.login} />}
{owner && <Form note={note} goalId={issueId} repoName={nameWithOwner} />}
{owner && <DangerZone note={note} goalId={issueId} repoName={nameWithOwner} />}
</FormColumn>
Expand Down
20 changes: 20 additions & 0 deletions src/lib/apiGraphQL.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ const operationsDoc = `
}
}
query FetchGoal($number: Int!) {
gitHub {
viewer {
repository(name: "open-sauced-goals") {
issue(number: $number) {
id
body
title
number
}
}
}
}
}
query FetchGoals() {
gitHub {
viewer {
Expand Down Expand Up @@ -310,6 +325,10 @@ function fetchIssuesAfterQuery(owner, repo, cursor) {
return fetchOneGraph(operationsDoc, "IssuesAfterQuery", {owner: owner, repo: repo, cursor: cursor});
}

function fetchGoalQuery(issueNumber) {
return fetchOneGraph(operationsDoc, "FetchGoal", {number: issueNumber});
}

function fetchGoalsQuery() {
return fetchOneGraph(operationsDoc, "FetchGoals");
}
Expand Down Expand Up @@ -362,6 +381,7 @@ const api = {

return issueFetcher({owner, repo, cursor});
},
fetchGoalQuery,
fetchGoalsQuery,
fetchMemberStatus,
fetchRateLimit,
Expand Down
5 changes: 3 additions & 2 deletions src/lib/persistedGraphQL.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const url = "https://serve.onegraph.com/graphql?app_id=06238984-0a96-4774-95ad-d
const doc_id0 = "9c4b4f3d-c27d-434f-ba20-7ccf8308a9a1"; // FetchUserForkCount
const doc_id1 = "a0722788-adb0-4731-96fb-9e50c72a2528"; // RepoQuery
const doc_id2 = "ed0abd8a-3ff3-46ce-bd1f-04f94af25d12"; // FetchGoal
const doc_id3 = "c8c187a1-853f-446b-b3fa-b4876447c954"; // IssuesQuery
const doc_id3 = "8f18e222-57ee-4f12-885a-959e4d4df778"; // ContributionsCollectionQuery
const doc_id4 = "8ecd5737-ebba-4807-a20b-4155272500bf"; // IssuesByLabelQuery
const doc_id5 = "89a3dc22-4355-494e-9d6f-a29c21e065e0"; // FetchDeploymentStatusQuery
const doc_id6 = "a510812e-ad0d-4181-bda3-805ee2481a83"; // IssuesByLabelQuery
Expand Down Expand Up @@ -43,10 +43,11 @@ function makeFetch(doc_id, requiredVariables = [], operationName = false) {
return response;
};
}

const persistedForkFetch = makeFetch(doc_id0, ["repoName", "repoOwner"], "FetchUserForkCount");
const persistedRepoDataFetch = makeFetch(doc_id1, ["repo", "owner"]);
const persistedGoalFetch = makeFetch(doc_id2, ["number"]);
const persistedInteractionsFetch = makeFetch(doc_id3, ["repo", "owner"]);
const persistedInteractionsFetch = makeFetch(doc_id3, ["query"]);
const persistedIssuesFetch = makeFetch(doc_id4, ["repo", "owner"]);
const persistedDeploymentFetch = makeFetch(doc_id5);
const persistedIssuesByLabelFetch = makeFetch(doc_id6, ["repo", "owner"], "IssuesByLabelQuery");
Expand Down

0 comments on commit 6ac20a8

Please sign in to comment.