-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement versioned docs for OpenAPI w split operation pages #2623
Changes from all commits
b769044
48afd36
7c04d17
6493623
4ece600
32c8c2a
98c1e19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
* SPDX-License-Identifier: MPL-2.0 | ||
*/ | ||
|
||
import { getStaticProps } from 'views/open-api-docs-view-v2/server' | ||
import { generateStaticProps } from 'views/open-api-docs-view-v2/server' | ||
// Utils | ||
import { getOperationGroupKeyFromPath } from 'views/open-api-docs-view-v2/utils/get-operation-group-key-from-path' | ||
import { schemaTransformShortenHcp } from 'views/open-api-docs-view-v2/schema-transforms/schema-transform-shorten-hcp' | ||
|
@@ -15,19 +15,13 @@ import type { | |
OpenApiDocsViewV2Config, | ||
} from 'views/open-api-docs-view-v2/types' | ||
import type { OpenApiPreviewV2InputValues } from '../components/open-api-preview-inputs' | ||
import { schemaModComponent } from 'views/open-api-docs-view/utils/massage-schema-utils' | ||
|
||
/** | ||
* Given preview data submitted by the user, which includes OpenAPI JSON, | ||
* and given an optional operation slug that indicates whether to render | ||
* a view for a specific operation, | ||
* | ||
* Return static props for the appropriate OpenAPI docs view. | ||
* | ||
* TODO: this is largely a placeholder for now. | ||
* Will likely require a few more args to pass to getStaticProps, eg productData | ||
* for example, but those types of details are not yet needed by the underlying | ||
* view. | ||
*/ | ||
export default async function getPropsFromPreviewData( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to accommodate versioning, I made updates to the |
||
previewData: OpenApiPreviewV2InputValues | null, | ||
|
@@ -59,17 +53,16 @@ export default async function getPropsFromPreviewData( | |
}, | ||
] | ||
// Build page configuration based on the input values | ||
const pageConfig: OpenApiDocsViewV2Config = { | ||
const pageConfig: Omit<OpenApiDocsViewV2Config, 'schemaSource'> = { | ||
basePath: '/open-api-docs-preview-v2', | ||
breadcrumbLinksPrefix: [ | ||
{ | ||
title: 'Developer', | ||
url: '/', | ||
}, | ||
], | ||
operationSlug, | ||
openApiJsonString: previewData.openApiJsonString, | ||
schemaTransforms, | ||
productContext: 'hcp', | ||
// A generic set of resource links, as a preview of what typically | ||
// gets added to an OpenAPI docs page. | ||
resourceLinks: [ | ||
|
@@ -90,8 +83,6 @@ export default async function getPropsFromPreviewData( | |
href: 'https://www.hashicorp.com/customer-success', | ||
}, | ||
], | ||
// Release stage badge, to demo this feature | ||
releaseStage: 'Preview', | ||
// Status indicator for HCP Services generally, to demo this feature | ||
statusIndicatorConfig: { | ||
pageUrl: 'https://status.hashicorp.com', | ||
|
@@ -106,5 +97,25 @@ export default async function getPropsFromPreviewData( | |
pageConfig.getOperationGroupKey = getOperationGroupKeyFromPath | ||
} | ||
// Use the page config to generate static props for the view | ||
return await getStaticProps(pageConfig) | ||
const staticProps = await generateStaticProps({ | ||
...pageConfig, | ||
versionData: [ | ||
{ | ||
versionId: 'latest', | ||
releaseStage: 'Preview', | ||
sourceFile: previewData.openApiJsonString, | ||
}, | ||
], | ||
urlContext: { | ||
isVersionedUrl: false, | ||
versionId: 'latest', | ||
operationSlug, | ||
}, | ||
}) | ||
// If the specific view wasn't found, return null | ||
if ('notFound' in staticProps) { | ||
return null | ||
} | ||
// Otherwise, return the props, discarding the enclosing object | ||
return staticProps.props | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,18 +15,19 @@ import { DescriptionMdx } from './components/description-mdx' | |
// Types | ||
import type { MDXRemoteSerializeResult } from 'lib/next-mdx-remote' | ||
import type { StatusIndicatorConfig } from 'views/open-api-docs-view-v2/types' | ||
|
||
import type { ReactNode } from 'react' | ||
import type { ProductSlug } from 'types/products' | ||
// Styles | ||
import s from './style.module.css' | ||
|
||
export interface LandingContentProps { | ||
badgeText: string | ||
descriptionMdx?: MDXRemoteSerializeResult | ||
heading: string | ||
serviceProductSlug: ProductSlug | ||
schemaFileString?: string | ||
badgeText?: string | ||
descriptionMdx?: MDXRemoteSerializeResult | ||
serviceProductSlug?: ProductSlug | ||
statusIndicatorConfig?: StatusIndicatorConfig | ||
schemaFileString: string | ||
versionSwitcherSlot?: ReactNode | ||
} | ||
|
||
export function LandingContent({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The changes in this file add support for an optional |
||
|
@@ -36,6 +37,7 @@ export function LandingContent({ | |
serviceProductSlug, | ||
statusIndicatorConfig, | ||
schemaFileString, | ||
versionSwitcherSlot, | ||
}: LandingContentProps) { | ||
return ( | ||
<div className={s.overviewWrapper}> | ||
|
@@ -53,26 +55,33 @@ export function LandingContent({ | |
/> | ||
) : null} | ||
</span> | ||
<Badge | ||
className={s.releaseStageBadge} | ||
text={badgeText} | ||
type="outlined" | ||
size="small" | ||
/> | ||
{badgeText ? ( | ||
<Badge | ||
className={s.releaseStageBadge} | ||
text={badgeText} | ||
type="outlined" | ||
size="small" | ||
/> | ||
) : null} | ||
</header> | ||
{versionSwitcherSlot ? ( | ||
<div className={s.versionSwitcherSlot}>{versionSwitcherSlot}</div> | ||
) : null} | ||
</div> | ||
{descriptionMdx ? ( | ||
<DescriptionMdx mdxRemoteProps={descriptionMdx} /> | ||
) : null} | ||
<StandaloneLink | ||
text="Download Spec" | ||
icon={<IconDownload16 />} | ||
iconPosition="leading" | ||
download="hcp.swagger.json" | ||
href={`data:text/json;charset=utf-8,${encodeURIComponent( | ||
schemaFileString | ||
)}`} | ||
/> | ||
{schemaFileString ? ( | ||
<StandaloneLink | ||
text="Download Spec" | ||
icon={<IconDownload16 />} | ||
iconPosition="leading" | ||
download="hcp.swagger.json" | ||
href={`data:text/json;charset=utf-8,${encodeURIComponent( | ||
schemaFileString | ||
)}`} | ||
/> | ||
) : null} | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,11 +11,11 @@ import { OperationExamples } from '../operation-examples' | |
import { OperationDetails } from '../operation-details' | ||
// Types | ||
import type { PropertyDetailsSectionProps } from '../operation-details' | ||
import type { ReactNode } from 'react' | ||
// Styles | ||
import s from './style.module.css' | ||
|
||
export interface OperationContentProps { | ||
heading: string | ||
operationId: string | ||
tags: string[] | ||
slug: string | ||
|
@@ -32,6 +32,7 @@ export interface OperationContentProps { | |
* word breaks to allow long URLs to wrap to multiple lines. | ||
*/ | ||
urlPathForCodeBlock: string | ||
versionSwitcherSlot?: ReactNode | ||
} | ||
|
||
/** | ||
|
@@ -47,17 +48,22 @@ export interface OperationProps { | |
* Render detailed content for an individual operation. | ||
*/ | ||
export default function OperationContent({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to landing content, the changes in this file add support for a |
||
heading, | ||
slug, | ||
operationId, | ||
type, | ||
path, | ||
urlPathForCodeBlock, | ||
requestData, | ||
responseData, | ||
versionSwitcherSlot, | ||
}: OperationContentProps) { | ||
return ( | ||
<> | ||
<h1 className={s.heading}>{heading}</h1> | ||
<div className={s.header}> | ||
<h1 className={s.heading}>{operationId}</h1> | ||
{versionSwitcherSlot ? ( | ||
<div className={s.versionSwitcherSlot}>{versionSwitcherSlot}</div> | ||
) : null} | ||
</div> | ||
<OperationSections | ||
headerSlot={ | ||
<div className={s.methodAndPath}> | ||
|
@@ -66,7 +72,7 @@ export default function OperationContent({ | |
</div> | ||
} | ||
examplesSlot={ | ||
<OperationExamples heading={slug} code={urlPathForCodeBlock} /> | ||
<OperationExamples heading={operationId} code={urlPathForCodeBlock} /> | ||
} | ||
detailsSlot={ | ||
<OperationDetails | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,31 +4,30 @@ | |
*/ | ||
|
||
// Utils | ||
import { getOperationObjects } from '../../utils/get-operation-objects' | ||
|
||
import { getUrlPathCodeHtml } from '../../utils/get-url-path-code-html' | ||
import { truncateHcpOperationPath } from '../../utils/truncate-hcp-operation-path' | ||
import { getRequestData } from '../../utils/get-request-data' | ||
import { getResponseData } from '../../utils/get-response-data' | ||
import { slugifyOperationId } from 'views/open-api-docs-view-v2/utils/slugify-operation-id' | ||
// Types | ||
import type { OpenAPIV3 } from 'openapi-types' | ||
import type { OperationContentProps } from '.' | ||
import type { OperationObject } from '../../utils/get-operation-objects' | ||
|
||
/** | ||
* Transform the schemaData into props for an individual operation | ||
*/ | ||
export default async function getOperationContentProps( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made some minor modifications here to avoid passing duplicate data, and to lift the |
||
operationSlug: string, | ||
operation: OperationObject, | ||
schemaData: OpenAPIV3.Document | ||
): Promise<OperationContentProps> { | ||
const operationObjects = getOperationObjects(schemaData) | ||
const operation = operationObjects.find( | ||
(operation) => operation.operationId === operationSlug | ||
) | ||
/** | ||
* The API's base URL is used to prefix the operation path, | ||
* so users can quickly copy the full path to the operation | ||
*/ | ||
const apiBaseUrl = getApiBaseUrl(schemaData) | ||
const operationSlug = slugifyOperationId(operation.operationId) | ||
/** | ||
* Parse request and response details for this operation | ||
*/ | ||
|
@@ -53,8 +52,7 @@ export default async function getOperationContentProps( | |
* Return the operation content props | ||
*/ | ||
return { | ||
heading: operationSlug, | ||
operationId: operationSlug, | ||
operationId: operation.operationId, | ||
tags: operation.tags, | ||
slug: operationSlug, | ||
type: operation.type, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,15 @@ | |
* SPDX-License-Identifier: MPL-2.0 | ||
*/ | ||
|
||
/* HEADER AREA */ | ||
|
||
.header { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
display: flex; | ||
flex-wrap: wrap; | ||
justify-content: space-between; | ||
gap: 16px; | ||
} | ||
|
||
.heading { | ||
composes: hds-typography-display-600 from global; | ||
|
||
|
@@ -13,7 +22,9 @@ | |
margin: 0 0 9px 0; | ||
} | ||
|
||
/* HEADER AREA */ | ||
.versionSwitcherSlot { | ||
flex-shrink: 0; | ||
} | ||
|
||
.methodAndPath { | ||
display: flex; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was already lifted into the shared
lib
folder. I think we have a better pattern available for applying schema transforms, established in previous PRs... but previously we were apply the transforms after de-referencing the schema.With this in mind, I've lightly modified the interface of this function to accommodate an array of transform functions, rather than a single function as was supported previously. I've made corresponding updates in all places where this function is used.