###### tags: `New Relic`
# Opensource Website
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Opensource Website](#opensource-website)
- [Data Definitions](#data-definitions)
- [Project](#project)
- [Data fetching](#data-fetching)
- [Gatsby GraphQL](#gatsby-graphql)
- [Github API v3](#github-api-v3)
- [Github API v4](#github-api-v4)
- [Component Mocks](#component-mocks)
- [Landing page - V4](#landing-page---v4)
- [Top 3 projects](#top-3-projects)
- [Explore Projects](#explore-projects)
- [Explore Projects - V4](#explore-projects---v4)
- [Project Page - V2](#project-page---v2)
- [Blog Listing](#blog-listing)
- [Blog Article - V4](#blog-article---v4)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Data Definitions
### Project
We're designating a `Project` as an Open Source "Project". In Github this is more-so a`Repository` than a Github `Project`.
```json
{
"name": "nr1-workload-geoops",
"fullName": "newrelic/nr1-workload-geoops",
"slug": "newrelic-nr1-workload-geoops",
"owner": {
"login": "newrelic",
"type": "Organization"
},
"title": "New Relic One Workload Geoops",
"supportUrl": "https://discuss.newrelic.com/t/workload-geoops-nerdpack/99478",
"githubUrl": "https://github.com/newrelic/nr1-workload-geoops",
"permalink": "https://opensource.newrelic.com/projects/newrelic/nr1-workload-geoops",
"iconUrl": "https://github.com/newrelic/nr1-workload-geoops/blob/master/icon.png?raw=true",
"shortDescription": "Manage workloads across geographies",
"description": "New Relic One application for aligning Workload data (or other Entities) in a geographic management console. Think Point-of-Sale alignment of platform features.",
"ossCategory": "new-relic-one-catalog-project",
"primaryLanguage": "JavaScript",
"projectTags": [ "nr1-app" ],
"acceptsContributions": true,
"website": {
"title": "New Relic One Workload Geoops",
"url": "https://github.com/newrelic/nr1-workload-geoops"
},
"version": "0.1.0"
}
```
Notes:
`iconUrl` - we'll need to ensure we use something in Gatsby to rewrite the URL's from *.github.com to *.cdn.com, where CDN is wherever this ends up being hosted, whether that's a rewritten S3 url or a CDN.
### External Project
Project metadata when the project is external (for instance: New Relic's involvement in the `OpenTelemetry` standard).
```json
{
"name": "open-telemetry",
"fullName": "open-telemetry",
"title": "OpenTelemetry",
"slug": "open-telemetry",
"owner": {
"login": "open-telemetry",
"type": "Organization"
},
"excludeFromExploreProjects": true,
"githubUrl": "https://github.com/open-telemetry",
"permalink": "https://opensource.newrelic.com/open-telemetry",
"iconUrl": "/images/open-telemetry.png",
"shortDescription": "New Relic's involvement in OpenTelemetry short description",
"description": "Bacon ipsum dolor amet chicken brisket shankle, flank filet mignon pork belly ribeye chuck ham venison pig. Spare ribs bresaola jowl chislic chuck. Pig hamburger cow ham hock buffalo picanha. Landjaeger venison pork, burgdoggen leberkas shank fatback shankle rump ham hock tenderloin pork loin. Chuck tongue buffalo landjaeger boudin sirloin. Short loin swine kevin, tail sausage tri-tip doner. Tail capicola jerky andouille turducken tri-tip bresaola boudin doner cow.",
"projectTags": ["opentelemetry"],
"contributors": [{
"name": "Octocat",
"login": "octocat",
"contributorType": "approver",
"id": 1,
"avatarUrl": "https://github.com/images/error/octocat_happy.gif",
"url": "https://api.github.com/users/octocat",
"htmlUrl": "https://github.com/octocat"
},{
"name": "Octocat",
"login": "octocat",
"contributorType": "maintainer",
"id": 1,
"avatarUrl": "https://github.com/images/error/octocat_happy.gif",
"url": "https://api.github.com/users/octocat",
"htmlUrl": "https://github.com/octocat"
}],
"subProjects": ["open-telemetry-go", "open-telemetry-java"]
}
```
`ossCategory` - one of a defined enum of values w/in New Relic OSS, [defined here](https://github.com/newrelic/open-source-office/blob/master/examples/categories/index.md)
```json
"items": [
{
"title": "New Relic Experimental",
"slug": "newrelic-experimental",
"description": "This code is not necessarily used in production but is being developed in the open. It is provided with no expectation of support, ongoing development, or maintenance."
},
{
"title": "Community Project",
"slug": "community-project",
"description": "This is an official New Relic open source community project, supported by a maintainer(s) within New Relic."
},
{
"title": "New Relic One Catalog Project",
"slug": "new-relic-one-catalog-project",
"description": "This code is a part of the New Relic One Catalog. It is available for installation and configuration via the New Relic One homepage. You can install it via the Catalog launcher in New Relic One."
},
{
"title": "Example Code",
"slug": "example-code",
"description": "This code is not meant for production deployment, but is provided as a working example of a concept. It comes with no ongoing support or maintenance, but you are welcome to submit issues and PR's to the repo."
},
{
"title": "Product delivered in Open Source",
"slug": "product-delivered-in-open-source",
"description": "This code is currently maintained by New Relic engineering teams and delivered here in Github. See the README for troubleshooting and defect reporting instructions."
},
{
"title": "Archived",
"slug": "archived",
"description": "This code has been moved into a read-only state. It is no longer supported and is available for cloning only."
}
]
```
`projectType` = one of a defined enum of values w/in New Relic OSS
```json
"items": [
{
"title": "New Relic One App",
"slug": "nr1-app"
},
{
"title": "Infrastructure Integration",
"slug": "infrastructure-integration"
},
{
"title": "APM Agent",
"slug": "apm-agent"
},
{
"title": "Utility",
"slug": "utility"
},
{
"title": "Training",
"slug": "training"
}
]
```
`primaryLanguage` - maps to the value for a repository as returned by the [GitHub API](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml)
### Stats
```json
{
"version": "1.0.4",
"issues": {
"open": 14
},
"releases": 6,
"commits": 245,
"contributors": 6,
"pullRequests": {
"open": 2
},
"searchCategory": "good-first-issue",
"cachedIssues": [{
"title": "Allow backoff times to be user content",
"id":"26",
"url": "https://github.com/newrelic/nr1-workload-geoops/issues/26",
"createdBy": "breed-nr",
"createdAt": 1586797934554,
"comments": {
"count": 2
}
},{
"title": "Stuff here",
"id":"45",
"url": "https://github.com/newrelic/nr1-workload-geoops/issues/45",
"createdBy": "tangollama",
"createdAt": 1586797934559,
"comments": {
"count": 0
}
}],
"cachedContributors": [{
"name": "Octocat",
"login": "octocat",
"id": 1,
"avatarUrl": "https://github.com/images/error/octocat_happy.gif",
"url": "https://api.github.com/users/octocat",
"htmlUrl": "https://github.com/octocat",
"contributions": 32
},
{
"name": "Joel Worrall",
"login": "tangollama",
"id": 154545,
"avatarUrl": "https://github.com/images/error/octocat_happy.gif",
"url": "https://api.github.com/users/tangollama",
"htmlUrl": "https://github.com/tangollama",
"contributions": 323
}]
}
```
Notes:
`issues` and `pullRequests` are objects to support future expansion of the tracking by status.
`searchCategory` is the name of issue category we're searching for when we refresh the `cachedIssues` array.
`cachedIssues` is an array of issue data that we need to generate a view into the issue list.
`cachedContributors` is the list of top contributors for this project. The fields map in camel case to the current GitHub v3 API fields.
### Article
A blog article
> [name="Freddy"] Loosely stubbed here, dependent on Ghost + DevEx Team decisions around CMS
```json
{
"id": 1,
"title": "foo title",
"permalink": "https://opensource.newrelic.com/blog/brilliant-article-on-foo"
}
```
## Data fetching
### Gatsby GraphQL
Build a schema out of our `projects/<foo-project>.json` files
[Gatsby Data Fetching](https://www.gatsbyjs.org/docs/data-fetching/)
[Hybrid Apps & Hydration](https://www.gatsbyjs.org/docs/adding-app-and-website-functionality/#hybrid-app-pages)
### Github API v3
- Accepts authenticated API requests
- Accepts unauthenticated API requests
#### Discussion:
> [name="Freddy"] If we try to do client-side refreshes of stats, for unauthenticated API requests - are we going to hit a CORS issue? i.e. Can our website make API calls to Github on behalf of a user (IP address)? We won't run into this when we make these calls as part of our build process.
https://developer.github.com/v3/#cross-origin-resource-sharing
### Github API v4
[Link to Github GraphQL Explorer](https://developer.github.com/v4/explorer/)
> [name="Freddy"] For the uninitiated, when looking at Github's schema explorer, `edges` define relationships to other objects, and `nodes` define objects.
Notes:
- Accepts authenticated API requests only
- Should be utilized as part of our build process to fetch data on relevant projects.
**Examples**
Repository Stats:
```graphql
query RepositoryStats ($organizationId: ID) {
foo
}
```
## Component Mocks
### Landing page - V4
#### Top 3 projects
Gatsby GraphQL request to projects for top 3 marked with a tag of `HomePageHighlight` or `homepage-highlight`
```jsx
<List>
{projects.map(project => {
return (
<Item>
<Icon url={iconUrl}/>
<p>{description}</p>
<button onClick={() => this.navigateTo(githubUrl)}>
<Footer>
<LinkItem>View in Github</LinkItem>
<LinkItem onClick={() => this.navigate(project.website.url)}>
Go to {project.website.title}
</LinkItem>
</Footer>
</Item>
);
})}
</List>
```
#### Explore Projects
```jsx
<List>
{projects.map(project => {
return (
<Item>
<Card>
<Icon></Icon>
<Title>{project.title}</Title>
<span>{project.shortDescription}</span>
</Card>
</Item>
);
})}
</List>
```
#### Recent articles
```jsx
<List>
{articles.map(article => {
const truncatedDescription = article.description;
return (
<Card>
<HeaderImage></HeaderImage>
<h1>{article.title}</h1>
<p>{truncatedDescription}</p>
<Link to={article.permalink}>Read more</Link>
</Card>
);
})}
</List>
```
### Explore Projects - V4
```jsx
<Container>
<Header>
<NavBar></NavBar>
</Header>
<Body>
<BodyHeader>
<h1>Explore our projects</h1>
<h5>Projects and products that we're developing in open source</h5>
</BodyHeader>
<Search>
<SearchInput></SearchInput>
<Filters>
<CategoryFilter></CategoryFilter>
<ProjectFilter></ProjectFilter>
<SortBy></SortBy>
</Filters>
</Search>
<TopProjectsList></TopProjectsList>
<Projects>
{highlightedProjects.map(project => {
return (
<ProjectLargeCard>
<Icon>{project.iconUrl}</Icon>
<h3>{project.title}</h3>
<p>{project.description}</p>
<Button to={project.permalink}>View Project</Button>
<CardFooter>
<col>{project.ossCategory.title}</col>
<col>Version {project.version}</col>
</CardFooter>
</ProjectLargeCard>
)
})}
{projects.map(project => {
return (
<ProjectCard>
<Icon>{project.iconUrl}</Icon>
<h4>{project.title}</h4>
<p>{project.description}</p>
<CardFooter>
<col>{project.ossCategory.title}</col>
<col>Version {project.version}</col>
</CardFooter>
</ProjectCard>
);
})}
</Projects>
</Body>
</Container>
```
#### Discussion
> [name="Freddy"] When a user searches for or filters projects, what happens to the enlarged top 3 cards? Will we need to intelligently pick a "top 3" from the results, or is this just the first 3 of the result set?
### Project Page - V2
### Blog Listing
### Blog Article - V4