From f2ac079772ab69e3b939438aed1be3c4d46c14fd Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 9 Apr 2024 21:07:52 +0000 Subject: [PATCH] API live share session Co-authored-by: Kira Pilot Co-authored-by: Michael Smith Co-authored-by: Asher --- plugins/backstage-plugin-coder/README.md | 145 +++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/plugins/backstage-plugin-coder/README.md b/plugins/backstage-plugin-coder/README.md index eb53cb29..3fd55bf7 100644 --- a/plugins/backstage-plugin-coder/README.md +++ b/plugins/backstage-plugin-coder/README.md @@ -131,6 +131,151 @@ spec: You can find more information about what properties are available (and how they're applied) in our [`catalog-info.yaml` file documentation](./docs/catalog-info.md). +## Advanced: Use the Coder API + +You can build custom React components and functions that use the Coder API on behalf of the authenticated user. + +### Example: List Coder workspaces + +```tsx +import { useCoderClient, getErrorMessage } from '@coder/coder-js-sdk'; // https://github.com/coder/coder/tree/main/js-sdk + +function CustomWorkspacesComponent () { + const coderClient = useCoderClient(); + const workspacesState = useAsync(() => { + return coderClient.api.getWorkspaces({ + q: "owner:me", + }); + }, []); + + return ( + +

Your workspaces

+ + {workspacesState.loading && } + {workspacesState.error && } + {workspaces.length > 0 && ( + {workspaces.map((workspace) => ( +
    {workspace.name}
      + ))} + )} + + ); +} +``` + +### Example: Custom Auth Component + +```tsx +import { useCoderClient, getErrorMessage } from '@backstage/backstage-plugin-coder'; // https://github.com/coder/coder/tree/main/js-sdk + +function useCoderClient () { + + const api = useApi(coderClientApiRef); + // + + return { + ...api.methods, + safeRenderState, + } +} + +const myRandomFunction = async () => { + + // some other Backstage thing + const coderClient = useCoderClient(); + + if (!coderClient.isAuthenticated) { + throw new Error("not logged in") + } else { + // do stuff + } +} + +function CustomWorkspacesComponent () { + const coderClient = useCoderClient(); + const workspacesState = useAsync(() => { + return coderClient.api.getWorkspaces({ + q: "owner:me", + }); + }, []); + + // TODO: myComponent, probably looks something like + //
      + + return ( + +

      Your workspaces

      + + {workspacesState.loading && } + {workspacesState.error && ( + + )} + {workspaces.length > 0 && ( + {workspaces.map((workspace) => ( +
        {workspace.name}
      + ))} + } +
      + ) +``` + +### Example: Skaffolder Step (or Backend) + +```tsx +// TODO: Figure out how the Skaffolder works +// is it FE or BE? +``` + +```tsx +import { OauthApps } from "@backstage..." + +const api = useApi(oauthsomethingsomething) +oapi.oauthtoken + +// using sdk directly: +import { sdkFactory } from "@coder/coder-js-sdk" +const sdk = sdkFactory(url, token) +``` + +// https://github.com/coder/backstage.cdr.dev/commit/0765dc204fcde0a7c3e7e449802d61e2dc70de01 + +### Example: Custom authentication flow + +```tsx +function CustomWorkspacesFunction () { + const coderClient = useCoderClient(); + const workspacesState = useAsync(() => { + return coderClient.api.getWorkspaces({ + q: "owner:me", + }); + }, []); + + const clientSnapshot = useSyncExternalStore( + coderClient.subscribe, + coderClient.getStateSnapshot + ); + + clientSnapshot.isAuthenticated; + const err = getErrorMessage(workspacesState.error) + + + const workspaces = coderClient.api.getWorkspaces({ + q: "owner:me", + }) + + if (coderClient.isAuthenticated()) { + + } else { + + } + +} +``` + ## Roadmap This plugin is in active development. The following features are planned: