starting point for fixing build issues to get estimate on time savings

This commit is contained in:
darrell-thobe-sp
2024-11-18 11:58:37 -05:00
parent 9988970791
commit 0c9358d084
16 changed files with 337 additions and 204 deletions

View File

@@ -60,33 +60,23 @@ export function createApiPageMD({
frontMatter, frontMatter,
}: ApiPageMetadata) { }: ApiPageMetadata) {
return render([ return render([
`import ApiTabs from "@theme/ApiTabs";\n`,
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
`import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";\n`, `import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";\n`,
`import SecuritySchemes from "@theme/ApiExplorer/SecuritySchemes";\n`, `import ParamsDetails from "@theme/ParamsDetails";\n`,
`import MimeTabs from "@theme/MimeTabs";\n`, `import RequestSchema from "@theme/RequestSchema";\n`,
`import ParamsItem from "@theme/ParamsItem";\n`, `import StatusCodes from "@theme/StatusCodes";\n`,
`import ResponseSamples from "@theme/ResponseSamples";\n`,
`import SchemaItem from "@theme/SchemaItem";\n`,
`import SchemaTabs from "@theme/SchemaTabs";\n`,
`import Markdown from "@theme/Markdown";\n`,
`import Heading from "@theme/Heading";\n`,
`import OperationTabs from "@theme/OperationTabs";\n`, `import OperationTabs from "@theme/OperationTabs";\n`,
`import TabItem from "@theme/TabItem";\n\n`, `import TabItem from "@theme/TabItem";\n`,
`import Heading from "@theme/Heading";\n\n`,
createHeading(title), createHeading(title),
createMethodEndpoint(method, path), createMethodEndpoint(method, path),
infoPath && createAuthorization(infoPath), infoPath && createAuthorization(infoPath),
frontMatter.show_extensions frontMatter.show_extensions
? createVendorExtensions(extensions) ? createVendorExtensions(extensions)
: undefined, : undefined,
createDeprecation({ deprecated, description: deprecatedDescription }), createDeprecationNotice({ deprecated, description: deprecatedDescription }),
createExperimentalNotice(parameters),
createDescription(description), createDescription(description),
requestBody || parameters ? createRequestHeader("Request") : undefined, requestBody || parameters ? createRequestHeader("Request") : undefined,
createParamsDetails({ parameters, type: "path" }), createParamsDetails({ parameters }),
createParamsDetails({ parameters, type: "query" }),
createParamsDetails({ parameters, type: "header" }),
createParamsDetails({ parameters, type: "cookie" }),
createRequestBodyDetails({ createRequestBodyDetails({
title: "Body", title: "Body",
body: requestBody, body: requestBody,

View File

@@ -15,11 +15,11 @@ const config = {
future: { future: {
experimental_faster: { experimental_faster: {
swcJsLoader: true, swcJsLoader: true,
swcJsMinimizer: false, swcJsMinimizer: true,
swcHtmlMinimizer: false, swcHtmlMinimizer: true,
lightningCssMinimizer: false, lightningCssMinimizer: true,
rspackBundler: true, rspackBundler: true,
mdxCrossCompilerCache: false, mdxCrossCompilerCache: true,
}, },
}, },
title: 'SailPoint Developer Community', title: 'SailPoint Developer Community',

View File

@@ -34,10 +34,9 @@
opacity: 0.4; opacity: 0.4;
} }
.theme-code-block-highlighted-line { :global(.theme-code-block-highlighted-line)
.openapi-explorer__code-block-code-line-number::before { .openapi-explorer__code-block-code-line-number::before {
opacity: 0.8; opacity: 0.8;
}
} }
.openapi-explorer__code-block-code-line-number { .openapi-explorer__code-block-code-line-number {

View File

@@ -7,7 +7,6 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
import FormTextInput from "@theme/ApiExplorer/FormTextInput"; import FormTextInput from "@theme/ApiExplorer/FormTextInput";
import LiveApp from "@theme/ApiExplorer/LiveEditor"; import LiveApp from "@theme/ApiExplorer/LiveEditor";
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks"; import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
import Markdown from "@theme/Markdown";
import SchemaTabs from "@theme/SchemaTabs"; import SchemaTabs from "@theme/SchemaTabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
import { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types"; import { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
@@ -297,7 +296,7 @@ function Body({
</TabItem> </TabItem>
{/* @ts-ignore */} {/* @ts-ignore */}
<TabItem label="Example" value="example"> <TabItem label="Example" value="example">
{example.summary && <Markdown children={example.summary} />} {example.summary && <div>{example.summary}</div>}
{exampleBody && ( {exampleBody && (
<LiveApp <LiveApp
action={dispatch} action={dispatch}
@@ -335,7 +334,7 @@ function Body({
value={example.label} value={example.label}
key={example.label} key={example.label}
> >
{example.summary && <Markdown children={example.summary} />} {example.summary && <div>{example.summary}</div>}
{example.body && ( {example.body && (
<LiveApp action={dispatch} language={language}> <LiveApp action={dispatch} language={language}>
{example.body} {example.body}

View File

@@ -15,10 +15,12 @@ export type CodeSampleLanguage =
| "JavaScript" | "JavaScript"
| "Kotlin" | "Kotlin"
| "Objective-C" | "Objective-C"
| "OCaml"
| "Perl" | "Perl"
| "PHP" | "PHP"
| "PowerShell" | "PowerShell"
| "Python" | "Python"
| "R"
| "Ruby" | "Ruby"
| "Rust" | "Rust"
| "Scala" | "Scala"

View File

@@ -20,120 +20,10 @@ import {
getCodeSampleSourceFromLanguage, getCodeSampleSourceFromLanguage,
mergeArraysbyLanguage, mergeArraysbyLanguage,
mergeCodeSampleLanguage, mergeCodeSampleLanguage,
generateLanguageSet,
} from "./languages"; } from "./languages";
export const languageSet: Language[] = [ export const languageSet: Language[] = generateLanguageSet();
{
highlight: "bash",
language: "curl",
codeSampleLanguage: "Shell",
logoClass: "bash",
options: {
longFormat: false,
followRedirect: true,
trimRequestBody: true,
},
variant: "cURL",
variants: ["curl"],
},
{
highlight: "python",
language: "python",
codeSampleLanguage: "Python",
logoClass: "python",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "requests",
variants: ["requests", "http.client"],
},
{
highlight: "go",
language: "go",
codeSampleLanguage: "Go",
logoClass: "go",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "native",
variants: ["native"],
},
{
highlight: "javascript",
language: "nodejs",
codeSampleLanguage: "JavaScript",
logoClass: "nodejs",
options: {
ES6_enabled: true,
followRedirect: true,
trimRequestBody: true,
},
variant: "axios",
variants: ["axios", "native"],
},
{
highlight: "ruby",
language: "ruby",
codeSampleLanguage: "Ruby",
logoClass: "ruby",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "Net::HTTP",
variants: ["net::http"],
},
{
highlight: "csharp",
language: "csharp",
codeSampleLanguage: "C#",
logoClass: "csharp",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "RestSharp",
variants: ["restsharp", "httpclient"],
},
{
highlight: "php",
language: "php",
codeSampleLanguage: "PHP",
logoClass: "php",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "cURL",
variants: ["curl", "guzzle", "pecl_http", "http_request2"],
},
{
highlight: "java",
language: "java",
codeSampleLanguage: "Java",
logoClass: "java",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "OkHttp",
variants: ["okhttp", "unirest"],
},
{
highlight: "powershell",
language: "powershell",
codeSampleLanguage: "PowerShell",
logoClass: "powershell",
options: {
followRedirect: true,
trimRequestBody: true,
},
variant: "RestMethod",
variants: ["restmethod"],
},
];
export interface Props { export interface Props {
postman: sdk.Request; postman: sdk.Request;
@@ -283,7 +173,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
]); ]);
// no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set // no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
useEffect(function onSelectedVariantUpdate() { useEffect(function onSelectedVariantUpdate() {
if (selectedVariant && selectedVariant !== language.variant) { if (selectedVariant && selectedVariant !== language?.variant) {
const postmanRequest = buildPostmanRequest(postman, { const postmanRequest = buildPostmanRequest(postman, {
queryParams, queryParams,
pathParams, pathParams,
@@ -314,6 +204,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(function onSelectedSampleUpdate() { useEffect(function onSelectedSampleUpdate() {
if ( if (
language &&
language.samples && language.samples &&
language.samplesSources && language.samplesSources &&
selectedSample && selectedSample &&
@@ -332,6 +223,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
return ( return (
<> <>
{/* Outer language tabs */}
<CodeTabs <CodeTabs
groupId="code-samples" groupId="code-samples"
action={{ action={{
@@ -340,6 +232,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
setSelectedSample: setSelectedSample, setSelectedSample: setSelectedSample,
}} }}
languageSet={mergedLangs} languageSet={mergedLangs}
defaultValue={defaultLang[0]?.language ?? mergedLangs[0].language}
lazy lazy
> >
{mergedLangs.map((lang) => { {mergedLangs.map((lang) => {
@@ -352,6 +245,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
className: `openapi-tabs__code-item--${lang.logoClass}`, className: `openapi-tabs__code-item--${lang.logoClass}`,
}} }}
> >
{/* Inner x-codeSamples tabs */}
{lang.samples && ( {lang.samples && (
<CodeTabs <CodeTabs
className="openapi-tabs__code-container-inner" className="openapi-tabs__code-container-inner"
@@ -393,6 +287,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
</CodeTabs> </CodeTabs>
)} )}
{/* Inner generated code snippets */}
<CodeTabs <CodeTabs
className="openapi-tabs__code-container-inner" className="openapi-tabs__code-container-inner"
action={{ action={{

View File

@@ -1,7 +1,7 @@
import find from "lodash/find"; import find from "lodash/find";
import isArray from "lodash/isArray";
import mergeWith from "lodash/mergeWith"; import mergeWith from "lodash/mergeWith";
import unionBy from "lodash/unionBy"; import unionBy from "lodash/unionBy";
import codegen from "postman-code-generators";
import { CodeSample, Language } from "./code-snippets-types"; import { CodeSample, Language } from "./code-snippets-types";
@@ -43,10 +43,7 @@ export const mergeArraysbyLanguage = (arr1: any, arr2: any) => {
find(arr2, ["language", item["language"]]), find(arr2, ["language", item["language"]]),
]; ];
return mergeWith({}, ...matchingItems, (objValue: any) => { return mergeWith({}, ...matchingItems, (objValue: any) => {
if (isArray(objValue)) { return objValue;
return objValue;
}
return undefined;
}); });
}); });
}; };
@@ -66,3 +63,27 @@ export function getCodeSampleSourceFromLanguage(language: Language) {
return ""; return "";
} }
export function generateLanguageSet() {
const languageSet: Language[] = [];
codegen.getLanguageList().forEach((language: any) => {
const variants: any = [];
language.variants.forEach((variant: any) => {
variants.push(variant.key);
});
languageSet.push({
highlight: language.syntax_mode,
language: language.key,
codeSampleLanguage: language.label,
logoClass: language.key,
options: {
longFormat: false,
followRedirect: true,
trimRequestBody: true,
},
variant: variants[0],
variants: variants,
});
});
return languageSet;
}

View File

@@ -146,6 +146,24 @@ body[class="ReactModal__Body--open"] {
} }
} }
.openapi-tabs__code-item--dart {
color: var(--ifm-color-info);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/dart/dart-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-dart);
border-color: var(--openapi-code-tab-border-color-dart);
}
}
.openapi-tabs__code-item--javascript { .openapi-tabs__code-item--javascript {
color: var(--ifm-color-warning); color: var(--ifm-color-warning);
@@ -164,7 +182,7 @@ body[class="ReactModal__Body--open"] {
} }
} }
.openapi-tabs__code-item--bash { .openapi-tabs__code-item--curl {
color: var(--ifm-color-danger); color: var(--ifm-color-danger);
&::after { &::after {
@@ -179,7 +197,7 @@ body[class="ReactModal__Body--open"] {
} }
&.active { &.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-bash); box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-curl);
border-color: var(--ifm-color-danger); border-color: var(--ifm-color-danger);
} }
} }
@@ -220,6 +238,96 @@ body[class="ReactModal__Body--open"] {
} }
} }
.openapi-tabs__code-item--r {
color: var(--ifm-color-gray-500);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/r/r-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-r);
border-color: var(--openapi-code-tab-border-color-r);
}
}
.openapi-tabs__code-item--swift {
color: var(--ifm-color-danger);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/swift/swift-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-swift);
border-color: var(--openapi-code-tab-border-color-swift);
}
}
.openapi-tabs__code-item--c {
color: var(--ifm-color-info);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/c/c-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-c);
border-color: var(--openapi-code-tab-border-color-c);
}
}
.openapi-tabs__code-item--objective-c {
color: var(--ifm-color-info);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/objectivec/objectivec-plain.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-objective-c);
border-color: var(--openapi-code-tab-border-color-objective-c);
}
}
.openapi-tabs__code-item--ocaml {
color: var(--ifm-color-warning);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/ocaml/ocaml-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-objective-ocaml);
border-color: var(--openapi-code-tab-border-color-objective-ocaml);
}
}
.openapi-tabs__code-item--nodejs { .openapi-tabs__code-item--nodejs {
color: var(--ifm-color-success); color: var(--ifm-color-success);
@@ -256,6 +364,42 @@ body[class="ReactModal__Body--open"] {
} }
} }
.openapi-tabs__code-item--kotlin {
color: var(--ifm-color-gray-500);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/kotlin/kotlin-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-kotlin);
border-color: var(--openapi-code-tab-border-color-kotlin);
}
}
.openapi-tabs__code-item--rust {
color: var(--ifm-color-gray-500);
&::after {
content: "";
width: var(--code-tab-logo-width);
height: var(--code-tab-logo-height);
background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/rust/rust-original.svg")
no-repeat;
margin-block: auto;
}
&.active {
box-shadow: 0 0 0 3px var(--openapi-code-tab-shadow-color-rust);
border-color: var(--openapi-code-tab-border-color-rust);
}
}
.openapi-tabs__code-item--java { .openapi-tabs__code-item--java {
color: var(--ifm-color-warning); color: var(--ifm-color-warning);
@@ -292,6 +436,56 @@ body[class="ReactModal__Body--open"] {
} }
} }
.openapi-tabs__code-item--http {
color: var(--ifm-color-gray-500);
display: flex;
align-items: center;
justify-content: center;
position: relative;
&::after {
content: "";
display: inline-block;
width: 32px; /* Explicitly setting width to 32 pixels */
height: 32px; /* Explicitly setting height to 32 pixels */
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyIDIyTDggMTZMMTIgMTBNMjAgMjJMMjQgMTZMIDIwIDEwIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
background-size: contain;
background-repeat: no-repeat;
background-position: center; /* Center the SVG */
margin-top: 0.5rem;
}
&.active {
box-shadow: 0 0 0 3px var(--opeanpi-code-tab-shadow-color-http);
border-color: var(--openapi-code-tab-border-color-http);
}
}
.openapi-tabs__code-item--shell {
color: var(--ifm-color-gray-500);
display: flex;
align-items: center;
justify-content: center;
position: relative;
&::after {
content: "";
display: inline-block;
width: 32px; /* Explicitly setting width to 32 pixels */
height: 32px; /* Explicitly setting height to 32 pixels */
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyIDIyTDggMTZMMTIgMTBNMjAgMjJMMjQgMTZMIDIwIDEwIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
background-size: contain;
background-repeat: no-repeat;
background-position: center; /* Center the SVG */
margin-top: 0.5rem;
}
&.active {
box-shadow: 0 0 0 3px var(--opeanpi-code-tab-shadow-color-shell);
border-color: var(--openapi-code-tab-border-color-shell);
}
}
@media only screen and (min-width: 768px) and (max-width: 996px) { @media only screen and (min-width: 768px) and (max-width: 996px) {
.openapi-tabs__code-list { .openapi-tabs__code-list {
justify-content: space-around; justify-content: space-around;

View File

@@ -1,4 +1,4 @@
import React, { cloneElement, ReactElement } from "react"; import React, { cloneElement, ReactElement, useEffect, useRef } from "react";
import { import {
sanitizeTabsChildren, sanitizeTabsChildren,
@@ -36,10 +36,38 @@ function TabList({
selectValue, selectValue,
tabValues, tabValues,
}: CodeTabsProps & ReturnType<typeof useTabs>) { }: CodeTabsProps & ReturnType<typeof useTabs>) {
const tabRefs: (HTMLLIElement | null)[] = []; const tabRefs = useRef<(HTMLLIElement | null)[]>([]);
const tabsScrollContainerRef = useRef<any>();
const { blockElementScrollPositionUntilNextRender } = const { blockElementScrollPositionUntilNextRender } =
useScrollPositionBlocker(); useScrollPositionBlocker();
useEffect(() => {
const activeTab = tabRefs.current.find(
(tab) => tab?.getAttribute("aria-selected") === "true"
);
if (activeTab && tabsScrollContainerRef.current) {
const container = tabsScrollContainerRef.current;
const containerRect = container.getBoundingClientRect();
const activeTabRect = activeTab.getBoundingClientRect();
// Calculate the distance to scroll to align active tab to the left
const glowOffset = 3;
const scrollOffset =
activeTabRect.left -
containerRect.left +
container.scrollLeft -
glowOffset;
// Check if the active tab is not already at the left position
if (Math.abs(scrollOffset - container.scrollLeft) > 4) {
// Adjust the scroll of the container
container.scrollLeft = scrollOffset;
}
}
}, []);
const handleTabChange = ( const handleTabChange = (
event: event:
| React.FocusEvent<HTMLLIElement> | React.FocusEvent<HTMLLIElement>
@@ -47,7 +75,7 @@ function TabList({
| React.KeyboardEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>
) => { ) => {
const newTab = event.currentTarget; const newTab = event.currentTarget;
const newTabIndex = tabRefs.indexOf(newTab); const newTabIndex = tabRefs.current.indexOf(newTab);
const newTabValue = tabValues[newTabIndex]!.value; const newTabValue = tabValues[newTabIndex]!.value;
if (newTabValue !== selectedValue) { if (newTabValue !== selectedValue) {
@@ -73,7 +101,7 @@ function TabList({
newLanguage = languageSet.filter( newLanguage = languageSet.filter(
(lang: Language) => lang.language === newTabValue (lang: Language) => lang.language === newTabValue
)[0]; )[0];
action.setSelectedVariant(newLanguage.variant.toLowerCase()); action.setSelectedVariant(newLanguage.variants[0].toLowerCase());
action.setSelectedSample(newLanguage.sample); action.setSelectedSample(newLanguage.sample);
} }
action.setLanguage(newLanguage); action.setLanguage(newLanguage);
@@ -89,13 +117,15 @@ function TabList({
break; break;
} }
case "ArrowRight": { case "ArrowRight": {
const nextTab = tabRefs.indexOf(event.currentTarget) + 1; const nextTab = tabRefs.current.indexOf(event.currentTarget) + 1;
focusElement = tabRefs[nextTab] ?? tabRefs[0]!; focusElement = tabRefs.current[nextTab] ?? tabRefs.current[0]!;
break; break;
} }
case "ArrowLeft": { case "ArrowLeft": {
const prevTab = tabRefs.indexOf(event.currentTarget) - 1; const prevTab = tabRefs.current.indexOf(event.currentTarget) - 1;
focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!; focusElement =
tabRefs.current[prevTab] ??
tabRefs.current[tabRefs.current.length - 1]!;
break; break;
} }
default: default:
@@ -117,6 +147,7 @@ function TabList({
}, },
className className
)} )}
ref={tabsScrollContainerRef}
> >
{tabValues.map(({ value, label, attributes }) => ( {tabValues.map(({ value, label, attributes }) => (
<li <li
@@ -125,7 +156,7 @@ function TabList({
tabIndex={selectedValue === value ? 0 : -1} tabIndex={selectedValue === value ? 0 : -1}
aria-selected={selectedValue === value} aria-selected={selectedValue === value}
key={value} key={value}
ref={(tabControl) => tabRefs.push(tabControl)} ref={(tabControl) => tabRefs.current.push(tabControl)}
onKeyDown={handleKeydown} onKeyDown={handleKeydown}
onClick={handleTabChange} onClick={handleTabChange}
{...attributes} {...attributes}

View File

@@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import BrowserOnly from "@docusaurus/BrowserOnly"; import BrowserOnly from "@docusaurus/BrowserOnly";
import { useTypedSelector } from "@theme/ApiItem/hooks"; import { useTypedSelector } from "@theme/ApiItem/hooks";
function colorForMethod(method: string) { function colorForMethod(method: string) {
@@ -28,13 +27,18 @@ function colorForMethod(method: string) {
export interface Props { export interface Props {
method: string; method: string;
path: string; path: string;
context?: "endpoint" | "callback";
} }
function MethodEndpoint({ method, path }: Props) { function MethodEndpoint({ method, path, context }: Props) {
let serverValue = useTypedSelector((state: any) => state.server.value); let serverValue = useTypedSelector((state: any) => state.server.value);
let serverUrlWithVariables = ""; let serverUrlWithVariables = "";
const renderServerUrl = () => { const renderServerUrl = () => {
if (context === "callback") {
return "";
}
if (serverValue && serverValue.variables) { if (serverValue && serverValue.variables) {
serverUrlWithVariables = serverValue.url.replace(/\/$/, ""); serverUrlWithVariables = serverValue.url.replace(/\/$/, "");

View File

@@ -73,6 +73,7 @@ function ParamOptions() {
{optionalParams.length > 0 && ( {optionalParams.length > 0 && (
<> <>
<button <button
type="button"
className="openapi-explorer__show-more-btn" className="openapi-explorer__show-more-btn"
onClick={() => setShowOptional((prev) => !prev)} onClick={() => setShowOptional((prev) => !prev)}
> >

View File

@@ -114,6 +114,11 @@
} }
} }
.openapi-security__summary-container {
background: var(--ifm-pre-background);
border-radius: var(--ifm-pre-border-radius);
}
// Prevent auto zoom on mobile iOS devices when focusing on input elmenents // Prevent auto zoom on mobile iOS devices when focusing on input elmenents
@media screen and (-webkit-min-device-pixel-ratio: 0) and (max-device-width: 1024px) { @media screen and (-webkit-min-device-pixel-ratio: 0) and (max-device-width: 1024px) {
.prism-code, .prism-code,

View File

@@ -2,6 +2,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useDoc } from "@docusaurus/plugin-content-docs/client"; import { useDoc } from "@docusaurus/plugin-content-docs/client";
import Accept from "@theme/ApiExplorer/Accept";
import Authorization from "@theme/ApiExplorer/Authorization"; import Authorization from "@theme/ApiExplorer/Authorization";
import Body from "@theme/ApiExplorer/Body"; import Body from "@theme/ApiExplorer/Body";
import buildPostmanRequest from "@theme/ApiExplorer/buildPostmanRequest"; import buildPostmanRequest from "@theme/ApiExplorer/buildPostmanRequest";
@@ -23,7 +24,7 @@ import { FormProvider, useForm } from "react-hook-form";
import makeRequest from "./makeRequest"; import makeRequest from "./makeRequest";
function Request({ item }: { item: NonNullable<ApiItem> }) { function Request({ item }: { item: ApiItem }) {
const postman = new sdk.Request(item.postman); const postman = new sdk.Request(item.postman);
const metadata = useDoc(); const metadata = useDoc();
const { proxy, hide_send_button: hideSendButton } = metadata.frontMatter; const { proxy, hide_send_button: hideSendButton } = metadata.frontMatter;

View File

@@ -1,7 +1,8 @@
import React from "react"; import React from "react";
import { usePrismTheme } from "@docusaurus/theme-common"; // @ts-ignore
import { useDoc } from "@docusaurus/plugin-content-docs/client"; import { useDoc } from "@docusaurus/plugin-content-docs/client";
import { usePrismTheme } from "@docusaurus/theme-common";
import ApiCodeBlock from "@theme/ApiExplorer/ApiCodeBlock"; import ApiCodeBlock from "@theme/ApiExplorer/ApiCodeBlock";
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks"; import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
import SchemaTabs from "@theme/SchemaTabs"; import SchemaTabs from "@theme/SchemaTabs";
@@ -31,7 +32,7 @@ function formatXml(xml: string) {
return formatted.substring(1, formatted.length - 3); return formatted.substring(1, formatted.length - 3);
} }
function Response({ item }: { item: NonNullable<ApiItem> }) { function Response({ item }: { item: ApiItem }) {
const metadata = useDoc(); const metadata = useDoc();
const hideSendButton = metadata.frontMatter.hide_send_button; const hideSendButton = metadata.frontMatter.hide_send_button;
const prismTheme = usePrismTheme(); const prismTheme = usePrismTheme();

View File

@@ -8,8 +8,6 @@ function SecuritySchemes(props: any) {
const selected = useTypedSelector((state: any) => state.auth.selected); const selected = useTypedSelector((state: any) => state.auth.selected);
const infoAuthPath = `/${props.infoPath}#authentication`; const infoAuthPath = `/${props.infoPath}#authentication`;
console.log(props)
if (selected === undefined) return null; if (selected === undefined) return null;
if (options[selected]?.[0]?.type === undefined) { if (options[selected]?.[0]?.type === undefined) {
@@ -18,7 +16,7 @@ function SecuritySchemes(props: any) {
const selectedAuth = options[selected]; const selectedAuth = options[selected];
return ( return (
<details className="openapi-security__details" open={true}> <details className="openapi-security__details" open={false}>
<summary className="openapi-security__summary-container"> <summary className="openapi-security__summary-container">
<h4 className="openapi-security__summary-header"> <h4 className="openapi-security__summary-header">
Authorization: {selectedAuth[0].name ?? selectedAuth[0].type} Authorization: {selectedAuth[0].name ?? selectedAuth[0].type}
@@ -182,7 +180,6 @@ function SecuritySchemes(props: any) {
} }
if (isOauth2) { if (isOauth2) {
console.log(auth)
const { name, key, type, scopes, flows, ...rest } = auth; const { name, key, type, scopes, flows, ...rest } = auth;
return ( return (
<React.Fragment key={selected}> <React.Fragment key={selected}>
@@ -193,46 +190,39 @@ function SecuritySchemes(props: any) {
background: "var(--openapi-card-background-color)", background: "var(--openapi-card-background-color)",
}} }}
> >
{props.item['security'] && props.item['security'].length > 0 && ( <span>
<strong>name:</strong>{" "}
<Link to={infoAuthPath}>{name ?? key}</Link>
</span>
<span>
<strong>type: </strong>
{type}
</span>
{scopes && scopes.length > 0 && (
<span>
<strong>scopes: </strong>
<code> <code>
{props.item['security'].map((sec: any, index: number) => { {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
const key = Object.keys(sec)[0];
const securityScheme = props.item['securitySchemes']?.[key];
return (
<div key={key}>
<strong>type: </strong>
{securityScheme ? (
<Link to={infoAuthPath}>
{securityScheme['x-displayName']}
</Link>
) : (
<Link to={infoAuthPath}>{key}</Link> // Fallback to key if no displayName found
)}
{scopes && scopes.length > 0 && (
<div>
<span>
<strong>scopes: </strong>
<code>
{auth.scopes.length > 0 ? auth.scopes.join(', ') : "[]"}
</code>
</span>
</div>
)}
{props.item['x-sailpoint-userLevels'] && props.item['x-sailpoint-userLevels'].length > 0 && key !== 'applicationAuth' && (
<div>
<span>
<strong>user levels: </strong>
<code>
{props.item['x-sailpoint-userLevels'].length > 0 ? props.item['x-sailpoint-userLevels'].join(', ') : "[]"}
</code>
</span>
</div>
)}
{index < props.item['security'].length - 1 && (<hr></hr>) }
</div>
);
})}
</code> </code>
</span>
)}
{Object.keys(rest).map((k, i) => {
return (
<span key={k}>
<strong>{k}: </strong>
{typeof rest[k] === "object"
? JSON.stringify(rest[k], null, 2)
: String(rest[k])}
</span>
);
})}
{flows && (
<span>
<code>
<strong>flows: </strong>
{JSON.stringify(flows, null, 2)}
</code>
</span>
)} )}
</pre> </pre>
</React.Fragment> </React.Fragment>

View File

@@ -3,9 +3,9 @@ import React from "react";
import CodeSnippets from "@theme/ApiExplorer/CodeSnippets"; import CodeSnippets from "@theme/ApiExplorer/CodeSnippets";
import Request from "@theme/ApiExplorer/Request"; import Request from "@theme/ApiExplorer/Request";
import Response from "@theme/ApiExplorer/Response"; import Response from "@theme/ApiExplorer/Response";
import SecuritySchemes from "@theme/ApiExplorer/SecuritySchemes";
import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types"; import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types";
import sdk from "postman-collection"; import sdk from "postman-collection";
import SecuritySchemes from "./SecuritySchemes"
function ApiExplorer({ function ApiExplorer({
item, item,