Skip to content

Commit

Permalink
Fix link, remove .schema.json from display name, pull correct example…
Browse files Browse the repository at this point in the history
… files

Update UI to use breadcrumb UI, simplify left nav, move version button

Update schema browser wording, Update breadcrumb sizing, Fix links for relative paths to other schemas, Scraps side nav for cards

Memoize all the things

Use useWindowSize hook to improve UI for current folder name

Generalize breadcrumb to component

Remove old error catch
  • Loading branch information
dakota002 committed Aug 28, 2023
1 parent 387719a commit c86e629
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 152 deletions.
166 changes: 86 additions & 80 deletions app/lib/schema-data.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
import { RequestError } from '@octokit/request-error'
import { Octokit } from '@octokit/rest'
import memoizee from 'memoizee'

Check warning on line 10 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L10

Added line #L10 was not covered by tests
import { extname, join } from 'path'
import { relative } from 'path/posix'

Expand All @@ -23,44 +24,43 @@ const repoData = {
owner: 'nasa-gcn',
}

function isErrnoException(e: unknown): e is NodeJS.ErrnoException {
return e instanceof Error && 'code' in e && 'errno' in e
}

export async function getVersionRefs() {
const releases = (await octokit.rest.repos.listReleases(repoData)).data.map(
(x) => ({ name: x.name, ref: x.tag_name })
)
return [...releases, { name: 'main', ref: 'main' }]
}

export async function loadJson(filePath: string, ref: string): Promise<Schema> {
if (!filePath) throw new Error('path must be defined')

if (extname(filePath) !== '.json')
throw new Response('not found', { status: 404 })

let body: Schema
try {
body = await loadContentFromGithub(filePath, ref)
if (body.allOf?.find((x) => x.$ref)) {
await loadSubSchema(body.allOf, body.$id)
}
if (body.anyOf?.find((x) => x.$ref)) {
await loadSubSchema(body.anyOf, body.$id)
}
if (body.oneOf?.find((x) => x.$ref, body.$id)) {
await loadSubSchema(body.oneOf, body.$id)
}
} catch (e) {
if (isErrnoException(e) && e.code === 'ENOENT') {
export const getVersionRefs = memoizee(
async function () {
const releases = (await octokit.rest.repos.listReleases(repoData)).data.map(
(x) => ({ name: x.name, ref: x.tag_name })

Check warning on line 30 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L27-L30

Added lines #L27 - L30 were not covered by tests
)
return [...releases, { name: 'main', ref: 'main' }]

Check warning on line 32 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L32

Added line #L32 was not covered by tests
},
{ promise: true }
)

export const loadJson = memoizee(
async function (filePath: string, ref: string): Promise<Schema> {

Check warning on line 38 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L37-L38

Added lines #L37 - L38 were not covered by tests
if (!filePath) throw new Error('path must be defined')

if (extname(filePath) !== '.json')
throw new Response('not found', { status: 404 })

Check warning on line 42 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L42

Added line #L42 was not covered by tests

let body: Schema
try {
body = await loadContentFromGithub(filePath, ref)

Check warning on line 46 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L45-L46

Added lines #L45 - L46 were not covered by tests
if (body.allOf?.find((x) => x.$ref)) {
await loadSubSchema(body.allOf, body.$id)

Check warning on line 48 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L48

Added line #L48 was not covered by tests
}
if (body.anyOf?.find((x) => x.$ref)) {
await loadSubSchema(body.anyOf, body.$id)

Check warning on line 51 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L51

Added line #L51 was not covered by tests
}
if (body.oneOf?.find((x) => x.$ref, body.$id)) {
await loadSubSchema(body.oneOf, body.$id)

Check warning on line 54 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L54

Added line #L54 was not covered by tests
}
} catch (e) {
throw new Response('Not found', { status: 404 })
}
throw e
}

return body
}
return body

Check warning on line 60 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L60

Added line #L60 was not covered by tests
},
{ promise: true }
)

async function loadContentFromGithub(path: string, ref?: string) {
const ghData = (
Expand Down Expand Up @@ -118,53 +118,59 @@ export type GitContentDataResponse = {
children?: GitContentDataResponse[]
}

export async function loadSchemaExamples(
path: string,
ref: string
): Promise<ExampleFiles[]> {
const dirPath = path.substring(0, path.lastIndexOf('/'))
const schemaName = path.substring(path.lastIndexOf('/') + 1)
const exampleFiles = (await getGithubDir(dirPath, ref)).filter(
(x) =>
x.name.startsWith(`${schemaName.split('.')[0]}.`) &&
x.name.endsWith('.example.json')
)

const result: ExampleFiles[] = []
for (const exampleFile of exampleFiles) {
const exPath = join(dirPath, '/', exampleFile.name)
const example = await loadContentFromGithub(exPath)
result.push({
name: exampleFile.name.replace('.example.json', ''),
content: example,
})
}
return result
}

export async function getGithubDir(
path?: string,
ref = 'main'
): Promise<GitContentDataResponse[]> {
return (
await octokit.repos.getContent({
...repoData,
path: path ?? 'gcn',
ref,
})
).data as GitContentDataResponse[]
}
export const loadSchemaExamples = memoizee(
async function (path: string, ref: string): Promise<ExampleFiles[]> {
const dirPath = path.substring(0, path.lastIndexOf('/'))
const schemaName = path.substring(path.lastIndexOf('/') + 1)
const exampleFiles = (await getGithubDir(dirPath, ref)).filter(
(x) =>

Check warning on line 126 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L121-L126

Added lines #L121 - L126 were not covered by tests
x.name.startsWith(`${schemaName.split('.')[0]}.`) &&
x.name.endsWith('.example.json')
)

const result: ExampleFiles[] = []
for (const exampleFile of exampleFiles) {
const exPath = join(dirPath, '/', exampleFile.name)
const example = await loadContentFromGithub(exPath, ref)
result.push({

Check warning on line 135 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L131-L135

Added lines #L131 - L135 were not covered by tests
name: exampleFile.name.replace('.example.json', ''),
content: example,
})
}
return result

Check warning on line 140 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L140

Added line #L140 was not covered by tests
},
{ promise: true }
)

export const getGithubDir = memoizee(
async function (

Check warning on line 146 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L145-L146

Added lines #L145 - L146 were not covered by tests
path?: string,
ref = 'main'
): Promise<GitContentDataResponse[]> {
return (

Check warning on line 150 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L150

Added line #L150 was not covered by tests
await octokit.repos.getContent({
...repoData,
path: path ?? 'gcn',
ref,
})
).data as GitContentDataResponse[]
},
{ promise: true }
)

async function getDefaultBranch() {
return (await octokit.rest.repos.get(repoData)).data.default_branch
}

export async function getLatestRelease() {
try {
return (await octokit.rest.repos.getLatestRelease(repoData)).data.tag_name
} catch (error) {
if (error instanceof RequestError && error.status === 404)
return await getDefaultBranch()
throw error
}
}
export const getLatestRelease = memoizee(
async function () {
try {
return (await octokit.rest.repos.getLatestRelease(repoData)).data.tag_name

Check warning on line 168 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L165-L168

Added lines #L165 - L168 were not covered by tests
} catch (error) {
if (error instanceof RequestError && error.status === 404)
return await getDefaultBranch()
throw error

Check warning on line 172 in app/lib/schema-data.server.ts

View check run for this annotation

Codecov / codecov/patch

app/lib/schema-data.server.ts#L171-L172

Added lines #L171 - L172 were not covered by tests
}
},
{ promise: true }
)
2 changes: 1 addition & 1 deletion app/routes/docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default function () {
</>,
...(enableSchemaBrowser
? [
<NavLink key="schema" to="schema/latest/gcn">
<NavLink key="schema" to="schema/stable/gcn">
Schema Browser
</NavLink>,
]
Expand Down
48 changes: 48 additions & 0 deletions app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*!
* Copyright © 2023 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
import {

Check warning on line 8 in app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx#L8

Added line #L8 was not covered by tests
Breadcrumb,
BreadcrumbBar,
BreadcrumbLink,
} from '@trussworks/react-uswds'

export default function BreadcrumbNav({

Check warning on line 14 in app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx#L14

Added line #L14 was not covered by tests
path,
pathPrepend,
className,
}: {
path: string
pathPrepend?: string
className?: string
}) {
const breadcrumbs = path.split('/')
const lastBreadcrumb = breadcrumbs.pop()

Check warning on line 24 in app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx#L23-L24

Added lines #L23 - L24 were not covered by tests

let cumulativePath = pathPrepend
return (

Check warning on line 27 in app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx#L26-L27

Added lines #L26 - L27 were not covered by tests
<BreadcrumbBar className={className}>
<>
{...breadcrumbs.map((breadcrumb) => {
cumulativePath = `${cumulativePath}/${breadcrumb}`
return (

Check warning on line 32 in app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/BreadcrumbNav.tsx#L30-L32

Added lines #L30 - L32 were not covered by tests
<Breadcrumb key={cumulativePath}>
<BreadcrumbLink href={cumulativePath}>
{breadcrumb}
</BreadcrumbLink>
</Breadcrumb>
)
})}
</>
<Breadcrumb>
<Breadcrumb current>
<h2 className="margin-y-0 display-inline">{lastBreadcrumb}</h2>
</Breadcrumb>
</Breadcrumb>
</BreadcrumbBar>
)
}
14 changes: 9 additions & 5 deletions app/routes/docs_.schema.$version.$/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
import { Link } from '@remix-run/react'
import { Link, useResolvedPath } from '@remix-run/react'

Check warning on line 8 in app/routes/docs_.schema.$version.$/components.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/components.tsx#L8

Added line #L8 was not covered by tests
import { Icon, Table } from '@trussworks/react-uswds'
import { useState } from 'react'

Expand Down Expand Up @@ -36,9 +36,17 @@ export type Schema = {
required?: string[]
}

function formatLinkString(path: string) {

Check warning on line 39 in app/routes/docs_.schema.$version.$/components.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/components.tsx#L39

Added line #L39 was not covered by tests
// eslint-disable-next-line react-hooks/rules-of-hooks
return useResolvedPath(`../${path}`, {

Check warning on line 41 in app/routes/docs_.schema.$version.$/components.tsx

View check run for this annotation

Codecov / codecov/patch

app/routes/docs_.schema.$version.$/components.tsx#L41

Added line #L41 was not covered by tests
relative: 'path',
})
}

function ReferencedElementRow({ item }: { item: ReferencedSchema }) {
const [showHiddenRow, toggleHiddenRow] = useState(false)
const locallyDefined = item.$ref?.startsWith('#')

return (
<>
<tr onClick={() => toggleHiddenRow(!showHiddenRow)}>
Expand Down Expand Up @@ -131,10 +139,6 @@ export function SchemaPropertiesTableBody({
)
}

function formatLinkString(schemaLinkString: string) {
return schemaLinkString.replace('schema', 'docs/schema')
}

export function formatFieldName(name: string, requiredProps?: string[]) {
let formattedName = name
if (requiredProps && requiredProps.includes(name)) formattedName += '*'
Expand Down
Loading

0 comments on commit c86e629

Please sign in to comment.