diff --git a/bin/gen-sidebar.ts b/bin/gen-sidebar.ts index 8cb5d9e49..9fd391ce5 100644 --- a/bin/gen-sidebar.ts +++ b/bin/gen-sidebar.ts @@ -200,7 +200,7 @@ function noteOrder(groupPath: string, pages: string[]) { // ---------------------------------------------------------------- conversion type NimbusItem = - | { label: string; link: string; badge?: NavBadge; icon?: string; hidden?: boolean } + | { label: string; link: string; badge?: NavBadge; statusBadge?: string; deprecated?: boolean; icon?: string; hidden?: boolean } | { label: string; items: NimbusItem[]; collapsed?: boolean; segment?: string; landing?: string; icon?: string }; function convertPages(pages: Json[], groupPath: string): NimbusItem[] { @@ -399,6 +399,28 @@ const items: NimbusItem[] = tabs.map((t) => { return { label, items: [], collapsed: false }; }); +// Enrich every API link, whether authored as a page, operation pointer, or tag group. +// Keys use pageLink so localized navigation receives the same operation metadata. +if (!previewRemote) { + const apiPages = new Map( + [...getApiOperations("cloud"), ...getApiOperations("clickstack")] + .map((operation) => [pageLink(operation.route), operation]), + ); + const enrichApiLinks = (nodes: NimbusItem[]) => { + for (const item of nodes) { + if ("items" in item) { + enrichApiLinks(item.items); + continue; + } + const operation = apiPages.get(item.link); + if (!operation) continue; + item.statusBadge = operation.badge; + item.deprecated = operation.operation.deprecated || undefined; + } + }; + enrichApiLinks(items); +} + const outFile = path.join(outDir, locale ? `sidebar.items.${locale}.json` : "sidebar.items.json"); fs.writeFileSync(outFile, JSON.stringify(items, null, 2) + "\n"); diff --git a/package.json b/package.json index 0bd3fba40..d49d921e6 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,8 @@ "react-dom": "^19.0.0", "redirects-in-workers": "^0.0.7", "satteri": "^0.10.5", - "tailwind-merge": "^3.5.0" + "tailwind-merge": "^3.5.0", + "shiki": "^4.4.3" }, "devDependencies": { "@astrojs/check": "^0.9.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a52e29cb1..23b2af82a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,9 @@ importers: satteri: specifier: ^0.10.5 version: 0.10.5 + shiki: + specifier: ^4.4.3 + version: 4.4.3 tailwind-merge: specifier: ^3.5.0 version: 3.6.0 diff --git a/src/components/api/ApiOperation.astro b/src/components/api/ApiOperation.astro index 2afb82bf3..e4d45954d 100644 --- a/src/components/api/ApiOperation.astro +++ b/src/components/api/ApiOperation.astro @@ -1,4 +1,6 @@ --- +import ApiPlayground from "./ApiPlayground.astro"; +import type { ApiOperationPage as SourceOperation } from "@/lib/openapi"; import ApiBody from "@/components/ui/api-layout/ApiBody.astro"; import type { ApiSecurityScheme } from "@/components/ui/api-layout/auth"; import { ApiCodeRail } from "@/components/ui/api-code-rail"; @@ -7,22 +9,15 @@ import type { ApiOperationPage } from "@cloudflare/nimbus-docs/api"; interface Props { page: ApiOperationPage; authSchemes?: Record; + source: SourceOperation; } -const { page, authSchemes = {} } = Astro.props; -const editableParameters = page.parameters - .filter((group) => group.location === "path" || group.location === "query") - .flatMap((group) => group.fields.map((field) => ({ field, location: group.location }))); -const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source ?? ""; +const { page, authSchemes = {}, source } = Astro.props; ---
@@ -36,35 +31,14 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source aria-label="Copy request URL" >Copy
- -
- - + +
{page.descriptionHtml &&
} +
{(page.samples.length > 0 || page.responses.some((response) => response.example !== undefined)) && ( @@ -82,82 +56,128 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source @@ -170,6 +190,7 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source margin-top: 1.25rem; } + .ch-api-reference, .ch-api-console { min-width: 0; @@ -180,9 +201,9 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source align-items: center; gap: 0.5rem; padding: 0.375rem; - border: 1px solid var(--border); + border: 1px solid var(--color-border); border-radius: 0.75rem; - background: color-mix(in srgb, var(--muted) 58%, transparent); + background: color-mix(in srgb, var(--color-muted) 58%, transparent); } .ch-api-request-line { @@ -193,9 +214,9 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source align-items: center; gap: 0.65rem; padding: 0.45rem 0.65rem; - border: 1px solid color-mix(in srgb, var(--border) 80%, transparent); + border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent); border-radius: 0.55rem; - background: var(--background); + background: var(--color-background); } .ch-api-method { @@ -230,7 +251,7 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source margin-left: auto; border: 0; background: transparent; - color: var(--muted-foreground); + color: var(--color-muted-foreground); } .ch-api-try { display: inline-flex; @@ -252,73 +273,29 @@ const curlSample = page.samples.find((sample) => sample.lang === "curl")?.source .ch-api-description { margin: 1.15rem 0 1.8rem; - color: var(--foreground); + color: var(--color-foreground); line-height: 1.75; } - .ch-api-try-fields { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 0.7rem; - margin-top: 0.75rem; - padding: 0.85rem; - border: 1px solid var(--border); - border-radius: 0.65rem; - background: var(--card); - } - - .ch-api-try-fields label, - .ch-api-try-fields label > span { - display: flex; - } - - .ch-api-try-fields label { - min-width: 0; - flex-direction: column; - gap: 0.35rem; - color: var(--muted-foreground); - font-size: 0.7rem; - } - - .ch-api-try-fields label > span { - align-items: center; - gap: 0.4rem; - } - - .ch-api-try-fields small { - font-size: 0.62rem; - color: var(--muted-foreground); - } - - .ch-api-try-fields small.is-required { color: var(--danger); } - .ch-api-try-fields input { - min-width: 0; - padding: 0.5rem 0.55rem; - border: 1px solid var(--border); - border-radius: 0.4rem; - background: var(--background); - color: var(--foreground); - font: inherit; + .ch-api-description :global(h2) { + margin: 2rem 0 14px; + padding-bottom: 14px; + border-bottom: 1px solid var(--color-border); + color: var(--color-foreground); + font-size: 1.125rem; + font-weight: 600; + line-height: 1.5; } - .ch-api-try-fields[hidden] { display: none; } - .ch-api-console { - position: sticky; - top: 5rem; - margin-top: -12.35rem; - } + .ch-api-try { text-decoration: none; } + .ch-api-console { position: sticky; top: 5rem; margin-top: -10rem; } .ch-api-console :global(.nb-cr-layer) { margin: 0; } - @media (max-width: 79.99rem) { .ch-api-operation { grid-template-columns: minmax(0, 1fr); } .ch-api-console { position: relative; top: auto; margin-top: 0; } } - @media (max-width: 40rem) { - .ch-api-endpoint { align-items: stretch; } .ch-api-request-line { flex-wrap: wrap; } .ch-api-path { order: 2; width: 100%; } - .ch-api-copy { margin-left: auto; } - .ch-api-try-fields { grid-template-columns: minmax(0, 1fr); } } diff --git a/src/components/api/ApiPage.astro b/src/components/api/ApiPage.astro index d0befebd6..22c4026ec 100644 --- a/src/components/api/ApiPage.astro +++ b/src/components/api/ApiPage.astro @@ -47,12 +47,6 @@ const breadcrumbs = [ { label: source.tag, href: tagRoute }, { label: source.tag, href: browserPath }, ]; -const headings = [ - ...(view.auth.length ? [{ depth: 2, text: "Authorizations", slug: "authorizations" }] : []), - ...view.parameters.map((group) => ({ depth: 2, text: group.label, slug: group.anchor })), - ...(view.body.length || view.bodyUnion ? [{ depth: 2, text: "Request body", slug: "request-body" }] : []), - ...(view.responses.length ? [{ depth: 2, text: "Response", slug: "response" }] : []), -]; const markdownPath = withBase(`/${source.route}.md`); const markdownUrl = Astro.site ? new URL(markdownPath, Astro.site).href : markdownPath; const language = localeInfo(currentLocale); @@ -69,6 +63,9 @@ const alternates = Astro.site })), ] : []; +const issueUrl = new URL("https://github.com/ClickHouse/ClickHouse/issues/new"); +issueUrl.searchParams.set("template", "60_documentation-issue.yaml"); +issueUrl.searchParams.set("page", browserPath); const fallbackNotice = notTranslatedNotice(currentLocale); --- @@ -76,10 +73,16 @@ const fallbackNotice = notTranslatedNotice(currentLocale); title={view.title} description={view.description} sidebar={sidebar} - headings={headings} + headings={[ + ...(view.auth.length ? [{ depth: 2, text: "Authorizations", slug: "authorizations" }] : []), + ...view.parameters.map(group => ({ depth: 2, text: group.label, slug: group.anchor })), + ...(view.body.length || view.bodyUnion ? [{ depth: 2, text: "Request body", slug: "request-body" }] : []), + ...(view.responses.length ? [{ depth: 2, text: "Response", slug: "response" }] : []), + ]} breadcrumbs={breadcrumbs} prevNext={prevNext} mode="wide" + showPageActions={false} markdownUrl={markdownUrl} editUrl={source.editUrl} lang={language.hreflang} @@ -101,10 +104,10 @@ const fallbackNotice = notTranslatedNotice(currentLocale); {fallbackNotice.message} )} - + +