Skip to content

Commit

Permalink
Merge pull request #86 from opentofu/persist-cdktf-lang
Browse files Browse the repository at this point in the history
  • Loading branch information
Yantrio authored Sep 3, 2024
2 parents 0292e5d + 642f81b commit 85ba0c7
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 67 deletions.
40 changes: 14 additions & 26 deletions frontend/src/components/LanguagePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { clsx } from "clsx";
import { Link, useSearchParams } from "react-router-dom";

interface LanguageProps {
name: string;
selected: boolean;
onClick: () => void;
code: string | null;
}

function Language({ name, selected, onClick }: LanguageProps) {
function Language({ name, code }: LanguageProps) {
const [searchParams] = useSearchParams();
const isActive = searchParams.get("lang") === code;

return (
<button
onClick={onClick}
<Link
to={{ search: code ? `?lang=${code}` : "" }}
className={clsx(
"ml-2 h-10 border px-3 font-semibold text-inherit",
selected
"ml-2 inline-flex h-10 items-center border px-3 font-semibold text-inherit",
isActive
? "border-brand-500 bg-brand-500 dark:border-brand-800 dark:bg-brand-800 dark:text-brand-600"
: "border-gray-200 dark:border-gray-800",
)}
>
{name}
</button>
</Link>
);
}

Expand All @@ -28,32 +31,17 @@ function LanguageSkeleton() {

interface LanguagePickerProps {
languages: Array<{ name: string; code: string }>;
selected: string | null;
onChange: (language: string | null) => void;
}

export function LanguagePicker({
languages,
selected,
onChange,
}: LanguagePickerProps) {
export function LanguagePicker({ languages }: LanguagePickerProps) {
return (
<nav className="flex items-center">
<span className="mr-2 text-gray-700 dark:text-gray-300">
Provider language
</span>
<Language
name="OpenTofu"
selected={!selected}
onClick={() => onChange(null)}
/>
<Language name="OpenTofu" code={null} />
{languages.map(({ name, code }) => (
<Language
key={code}
name={name}
selected={selected === code}
onClick={() => onChange(code)}
/>
<Language key={code} name={name} code={code} />
))}
</nav>
);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { moduleSubmoduleLoader } from "./routes/ModuleSubmodule/loader";
import { ModuleSubmoduleRouteContext } from "./routes/ModuleSubmodule/types";
import { moduleSubmoduleReadmeLoader } from "./routes/ModuleSubmodule/Readme/loader";
import { moduleSubmoduleMiddleware } from "./routes/ModuleSubmodule/middleware";
import { ProviderDocsError } from "./routes/Provider/Docs/error";
import { ProviderError } from "./routes/Provider/components/Error";

export const router = createBrowserRouter(
[
Expand Down Expand Up @@ -237,6 +237,7 @@ export const router = createBrowserRouter(
path: ":provider/:version?",
element: <Provider />,
loader: providerLoader,
errorElement: <ProviderError />,
handle: {
middleware: providerMiddleware,
crumb: ({
Expand All @@ -259,7 +260,6 @@ export const router = createBrowserRouter(
path: "docs/:type/:doc",
element: <ProviderDocs />,
loader: providerDocsLoader,
errorElement: <ProviderDocsError />,
},
],
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/Provider/components/DocsContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function ProviderDocsContent() {
],
});

const editLink = getProviderDoc(versionData.docs, type, doc)?.edit_link;
const editLink = getProviderDoc(versionData, type, doc, lang)?.edit_link;

return (
<>
Expand Down
21 changes: 16 additions & 5 deletions frontend/src/routes/Provider/components/DocsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { chevron } from "@/icons/chevron";
import { useSuspenseQuery } from "@tanstack/react-query";
import clsx from "clsx";
import { useState, useTransition } from "react";
import { useHref, useLinkClickHandler } from "react-router-dom";
import { To, useHref, useLinkClickHandler } from "react-router-dom";

import { NestedItem, transformStructure } from "../docsSidebar";
import { useProviderParams } from "../hooks/useProviderParams";
import { getProviderVersionDataQuery } from "../query";

type TabLinkProps = {
to: string;
to: To;
label: string;
active?: boolean;
};
Expand Down Expand Up @@ -52,6 +52,7 @@ function DocsTreeViewItem({
isOpenByDefault = false,
nested = false,
}: DocsTreeViewItemProps) {
const { lang } = useProviderParams();
const [open, setOpen] = useState(isOpenByDefault);
let button;

Expand All @@ -71,7 +72,10 @@ function DocsTreeViewItem({
} else {
button = (
<TabLink
to={`docs/${item.type}/${item.name}`}
to={{
pathname: `docs/${item.type}/${item.name}`,
search: lang ? `?lang=${lang}` : "",
}}
label={item.name}
active={item.active}
/>
Expand All @@ -98,7 +102,7 @@ function DocsTreeViewItem({
}

export function ProviderDocsMenu() {
const { namespace, provider, version, doc, type } = useProviderParams();
const { namespace, provider, version, doc, type, lang } = useProviderParams();

const { data } = useSuspenseQuery(
getProviderVersionDataQuery(namespace, provider, version),
Expand All @@ -109,7 +113,14 @@ export function ProviderDocsMenu() {
return (
<TreeView className="mr-4 mt-4">
<TreeViewItem>
<TabLink to="." label="Overview" active={!type && !doc} />
<TabLink
to={{
pathname: `.`,
search: lang ? `?lang=${lang}` : "",
}}
label="Overview"
active={!type && !doc}
/>
</TreeViewItem>
{items.map((doc) => (
<DocsTreeViewItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NotFoundPageError } from "@/utils/errors";
import { Navigate, useLocation, useRouteError } from "react-router-dom";
import { useProviderParams } from "../hooks/useProviderParams";

export function ProviderDocsError() {
export function ProviderError() {
const routeError = useRouteError() as Error;
const location = useLocation();
const { namespace, provider, version } = useProviderParams();
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/routes/Provider/components/PageTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { useEffect } from "react";
import { getProviderDoc } from "../utils/getProviderDoc";

export function ProviderPageTitle() {
const { namespace, provider, version, doc, type } = useProviderParams();
const { namespace, provider, version, doc, type, lang } = useProviderParams();

const { data } = useSuspenseQuery(
getProviderVersionDataQuery(namespace, provider, version),
);

useEffect(() => {
const providerDoc = getProviderDoc(data.docs, type, doc);
const providerDoc = getProviderDoc(data, type, doc, lang);

if (providerDoc) {
document.title = `${providerDoc.title} - OpenTofu Registry`;
Expand All @@ -21,7 +21,7 @@ export function ProviderPageTitle() {
return () => {
document.title = "OpenTofu Registry";
};
}, [data, doc, type]);
}, [data, doc, type, lang]);

return null;
}
22 changes: 1 addition & 21 deletions frontend/src/routes/Provider/components/VersionInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useSearchParams } from "react-router-dom";
import { OldVersionBanner } from "@/components/OldVersionBanner";
import {
LanguagePicker,
Expand Down Expand Up @@ -28,28 +27,13 @@ export function ProviderVersionInfo() {
],
});

const [, setSearchParams] = useSearchParams();

const langs = Object.keys(versionData.cdktf_docs);
const language = langs.includes(lang) ? lang : null;

const languages = langs.map((language) => ({
code: language,
name: languageLabels[language],
}));

const handleLanguageChange = (language: string | null) => {
setSearchParams((params) => {
const next = new URLSearchParams(params);
if (language) {
next.set("lang", language);
} else {
next.delete("lang");
}
return next;
});
};

const latestVersion = data.versions[0].id;

let latestVersionLink = `/provider/${namespace}/${provider}/${latestVersion}`;
Expand All @@ -66,11 +50,7 @@ export function ProviderVersionInfo() {
<div className="flex flex-col gap-5">
<div className="flex items-center justify-between">
<VersionInfo currentVersion={version} latestVersion={latestVersion} />
<LanguagePicker
languages={languages}
selected={language}
onChange={handleLanguageChange}
/>
<LanguagePicker languages={languages} />
</div>
{version !== latestVersion && (
<OldVersionBanner latestVersionLink={latestVersionLink} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useSuspenseQuery } from "@tanstack/react-query";
import { useProviderParams } from "../hooks/useProviderParams";

export function ProviderVersionsSidebarBlock() {
const { namespace, provider, version, type, doc } = useProviderParams();
const { namespace, provider, version, type, doc, lang } = useProviderParams();

const { data } = useSuspenseQuery(getProviderDataQuery(namespace, provider));

Expand All @@ -16,7 +16,7 @@ export function ProviderVersionsSidebarBlock() {
latestVersion={data.versions[0]}
currentVersion={version || data.versions[0].id}
versionLink={(version) =>
`/provider/${namespace}/${provider}/${version}${type && doc ? `/docs/${type}/${doc}` : ""}`
`/provider/${namespace}/${provider}/${version}${type && doc ? `/docs/${type}/${doc}` : ""}${lang ? `?lang=${lang}` : ""}`
}
/>
);
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/routes/Provider/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ export const getProviderDocsQuery = (
return queryOptions({
queryKey: ["provider-doc", namespace, provider, type, name, lang, version],
queryFn: async () => {
const urlBase = `providers/${namespace}/${provider}/${version}`;
const requestURL =
const urlBase = `providers/${namespace}/${provider}/${version}/${lang ? `cdktf/${lang}/` : ""}`;

const path =
type === undefined && name === undefined
? `${urlBase}/index.md`
: `${urlBase}/${lang ? `cdktf/${lang}/` : ""}${type}/${name}.md`;
? `index.md`
: `${type}/${name}.md`;

const data = await api(requestURL).text();
const data = await api(`${urlBase}${path}`).text();
return data;
},
});
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/routes/Provider/utils/getProviderDoc.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { definitions } from "@/api";
import { isValidDocsType } from "./isValidDocsType";
import { isValidCDKTFLang } from "./isValidCDKTFLang";

export function getProviderDoc(
docs: definitions["ProviderDocs"],
providerVersionData: definitions["ProviderVersion"],
type: string | undefined,
doc: string | undefined,
lang: string | null,
) {
const docs = isValidCDKTFLang(lang)
? providerVersionData.cdktf_docs[lang]
: providerVersionData.docs;

if (!type && !doc) {
return docs.index;
}
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/routes/Provider/utils/isValidCDKTFLang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const cdktfLangs = ["typescript", "python", "go", "java", "csharp"];

export function isValidCDKTFLang(lang: string | null): lang is string {
return !!lang && cdktfLangs.includes(lang);
}

0 comments on commit 85ba0c7

Please sign in to comment.