Skip to content

Commit

Permalink
fix: api playground loading state (#1477)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity committed Sep 13, 2024
1 parent 885eee2 commit 0cb2883
Show file tree
Hide file tree
Showing 34 changed files with 1,026 additions and 828 deletions.
16 changes: 7 additions & 9 deletions packages/ui/app/src/atoms/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
type ResolvedEndpointDefinition,
type ResolvedWebSocketChannel,
} from "../resolver/types";
import { APIS_ATOM, FLATTENED_APIS_ATOM, useFlattenedApi } from "./apis";
import { FLATTENED_APIS_ATOM, useFlattenedApi } from "./apis";
import { FEATURE_FLAGS_ATOM } from "./flags";
import { useAtomEffect } from "./hooks";
import { HEADER_HEIGHT_ATOM } from "./layout";
Expand All @@ -44,10 +44,7 @@ import { IS_MOBILE_SCREEN_ATOM } from "./viewport";
const PLAYGROUND_IS_OPEN_ATOM = atom(false);
PLAYGROUND_IS_OPEN_ATOM.debugLabel = "PLAYGROUND_IS_OPEN_ATOM";

export const HAS_PLAYGROUND_ATOM = atom(
(get) => get(FEATURE_FLAGS_ATOM).isApiPlaygroundEnabled && Object.keys(get(APIS_ATOM)).length > 0,
);
HAS_PLAYGROUND_ATOM.debugLabel = "HAS_PLAYGROUND_ATOM";
export const IS_PLAYGROUND_ENABLED_ATOM = atom((get) => get(FEATURE_FLAGS_ATOM).isApiPlaygroundEnabled);

export const MAX_PLAYGROUND_HEIGHT_ATOM = atom((get) => {
const isMobileScreen = get(IS_MOBILE_SCREEN_ATOM);
Expand Down Expand Up @@ -116,10 +113,6 @@ PLAYGROUND_NODE.debugLabel = "PLAYGROUND_NODE";
export const PREV_PLAYGROUND_NODE_ID = atom<FernNavigation.NodeId | undefined>(undefined);
PREV_PLAYGROUND_NODE_ID.debugLabel = "PREV_PLAYGROUND_NODE_ID";

export function useHasPlayground(): boolean {
return useAtomValue(HAS_PLAYGROUND_ATOM);
}

export function usePlaygroundNodeId(): FernNavigation.NodeId | undefined {
return useAtomValue(PLAYGROUND_NODE_ID);
}
Expand Down Expand Up @@ -360,3 +353,8 @@ export function usePlaygroundWebsocketFormState(
),
];
}

export const PLAYGROUND_REQUEST_TYPE_ATOM = atomWithStorage<"curl" | "typescript" | "python">(
"api-playground-atom-alpha",
"curl",
);
6 changes: 3 additions & 3 deletions packages/ui/app/src/components/FernLinkButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FernButtonSharedProps, getButtonClassName, renderButtonContent } from "@fern-ui/components";
import { ButtonContent, FernButtonSharedProps, getButtonClassName } from "@fern-ui/components";
import Link from "next/link";
import { ComponentProps, PropsWithChildren, forwardRef } from "react";
import { ComponentProps, PropsWithChildren, createElement, forwardRef } from "react";
import { FernLink } from "./FernLink";

interface FernLinkButtonProps extends ComponentProps<typeof Link>, PropsWithChildren<FernButtonSharedProps> {}
Expand Down Expand Up @@ -46,7 +46,7 @@ export const FernLinkButton = forwardRef<HTMLAnchorElement, FernLinkButtonProps>
: undefined
}
>
{renderButtonContent(props)}
{createElement(ButtonContent, { ...props, className: "" })}
</FernLink>
);
});
2 changes: 1 addition & 1 deletion packages/ui/app/src/css/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@import "./components";
@import "../syntax-highlighting/FernSyntaxHighlighter";
@import "../api-reference";
@import "../playground/PlaygroundEndpoint";
@import "../playground";
@import "../components";
@import "../mdx/components";
@import "./utilities";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { Callout } from "../mdx/components/callout";
import { ResolvedEndpointDefinition, ResolvedTypeDefinition } from "../resolver/types";
import { useApiKeyInjectionConfig } from "../services/useApiKeyInjectionConfig";
import { PasswordInputGroup } from "./PasswordInputGroup";
import { PlaygroundEndpointForm } from "./PlaygroundEndpointForm";
import { PlaygroundEndpointForm } from "./endpoint/PlaygroundEndpointForm";
import { PlaygroundAuthState } from "./types";
import { oAuthClientCredentialReferencedEndpointLoginFlow } from "./utils";

Expand Down
6 changes: 3 additions & 3 deletions packages/ui/app/src/playground/PlaygroundButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import { FernButton, FernTooltip, FernTooltipProvider } from "@fern-ui/component
import { PlaySolid } from "iconoir-react";
import { useAtomValue } from "jotai";
import { FC } from "react";
import { HAS_PLAYGROUND_ATOM, useSetAndOpenPlayground } from "../atoms";
import { IS_PLAYGROUND_ENABLED_ATOM, useSetAndOpenPlayground } from "../atoms";
import { usePlaygroundSettings } from "../hooks/usePlaygroundSettings";

export const PlaygroundButton: FC<{
state: FernNavigation.NavigationNodeApiLeaf;
}> = ({ state }) => {
const openPlayground = useSetAndOpenPlayground();
const hasPlayground = useAtomValue(HAS_PLAYGROUND_ATOM);
const isPlaygroundEnabled = useAtomValue(IS_PLAYGROUND_ENABLED_ATOM);
const settings = usePlaygroundSettings(state.id);

if (!hasPlayground) {
if (!isPlaygroundEnabled) {
return null;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/ui/app/src/playground/PlaygroundContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dynamic from "next/dynamic";
import { FC, useEffect } from "react";
import useSWR from "swr";
import { APIS_ATOM, store } from "../atoms";
import { HAS_PLAYGROUND_ATOM, useInitPlaygroundRouter } from "../atoms/playground";
import { IS_PLAYGROUND_ENABLED_ATOM, useInitPlaygroundRouter } from "../atoms/playground";
import { useApiRoute } from "../hooks/useApiRoute";
import { ResolvedRootPackage } from "../resolver/types";

Expand All @@ -18,7 +18,7 @@ const fetcher = async (url: string) => {

export const PlaygroundContextProvider: FC = () => {
const key = useApiRoute("/api/fern-docs/resolve-api");
const { data } = useSWR<Record<string, ResolvedRootPackage> | null>(key, fetcher, {
const { data, isLoading } = useSWR<Record<string, ResolvedRootPackage> | null>(key, fetcher, {
revalidateOnFocus: false,
});
useEffect(() => {
Expand All @@ -29,6 +29,6 @@ export const PlaygroundContextProvider: FC = () => {

useInitPlaygroundRouter();

const hasPlayground = useAtomValue(HAS_PLAYGROUND_ATOM);
return hasPlayground ? <PlaygroundDrawer /> : null;
const isPlaygroundEnabled = useAtomValue(IS_PLAYGROUND_ENABLED_ATOM);
return isPlaygroundEnabled ? <PlaygroundDrawer isLoading={isLoading} /> : null;
};
19 changes: 10 additions & 9 deletions packages/ui/app/src/playground/PlaygroundDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { HEADER_HEIGHT_ATOM, useAtomEffect, useFlattenedApis, useSidebarNodes }
import {
MAX_PLAYGROUND_HEIGHT_ATOM,
PLAYGROUND_NODE_ID,
useHasPlayground,
useIsPlaygroundOpen,
usePlaygroundFormStateAtom,
usePlaygroundNode,
Expand All @@ -22,14 +21,18 @@ import {
import { IS_MOBILE_SCREEN_ATOM, MOBILE_SIDEBAR_ENABLED_ATOM, VIEWPORT_HEIGHT_ATOM } from "../atoms/viewport";
import { FernErrorBoundary } from "../components/FernErrorBoundary";
import { isEndpoint, isWebSocket, type ResolvedApiEndpointWithPackage } from "../resolver/types";
import { PlaygroundEndpoint } from "./PlaygroundEndpoint";
import { PlaygroundEndpointSelectorContent, flattenApiSection } from "./PlaygroundEndpointSelectorContent";
import { PlaygroundWebSocket } from "./PlaygroundWebSocket";
import { HorizontalSplitPane } from "./VerticalSplitPane";
import { PlaygroundEndpoint } from "./endpoint/PlaygroundEndpoint";
import { PlaygroundEndpointSelectorContent, flattenApiSection } from "./endpoint/PlaygroundEndpointSelectorContent";
import { PlaygroundEndpointSkeleton } from "./endpoint/PlaygroundEndpointSkeleton";
import { useResizeY } from "./useSplitPlane";

export const PlaygroundDrawer = memo((): ReactElement | null => {
const hasPlayground = useHasPlayground();
interface PlaygroundDrawerProps {
isLoading: boolean;
}

export const PlaygroundDrawer = memo(({ isLoading }: PlaygroundDrawerProps): ReactElement | null => {
const selectionState = usePlaygroundNode();
const apis = useFlattenedApis();

Expand Down Expand Up @@ -115,15 +118,13 @@ export const PlaygroundDrawer = memo((): ReactElement | null => {

const setFormState = useSetAtom(usePlaygroundFormStateAtom(selectionState?.id ?? FernNavigation.NodeId("")));

if (!hasPlayground || apiGroups.length === 0) {
return null;
}

const renderContent = () =>
selectionState?.type === "endpoint" && matchedEndpoint != null ? (
<PlaygroundEndpoint endpoint={matchedEndpoint} types={types} />
) : selectionState?.type === "webSocket" && matchedWebSocket != null ? (
<PlaygroundWebSocket websocket={matchedWebSocket} types={types} />
) : isLoading ? (
<PlaygroundEndpointSkeleton />
) : (
<div className="size-full flex flex-col items-center justify-center">
<ArrowLeft className="size-8 mb-2 t-muted" />
Expand Down
Loading

0 comments on commit 0cb2883

Please sign in to comment.