diff --git a/site/src/api/queries/sshKeys.ts b/site/src/api/queries/sshKeys.ts new file mode 100644 index 0000000000000..ee82200c9cc3c --- /dev/null +++ b/site/src/api/queries/sshKeys.ts @@ -0,0 +1,24 @@ +import { QueryClient } from "@tanstack/react-query"; +import * as API from "api/api"; +import { GitSSHKey } from "api/typesGenerated"; + +const getUserSSHKeyQueryKey = (userId: string) => [userId, "sshKey"]; + +export const userSSHKey = (userId: string) => { + return { + queryKey: getUserSSHKeyQueryKey(userId), + queryFn: () => API.getUserSSHKey(userId), + }; +}; + +export const regenerateUserSSHKey = ( + userId: string, + queryClient: QueryClient, +) => { + return { + mutationFn: () => API.regenerateUserSSHKey(userId), + onSuccess: (newKey: GitSSHKey) => { + queryClient.setQueryData(getUserSSHKeyQueryKey(userId), newKey); + }, + }; +}; diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx index e34b8076808bb..b35cb2688707f 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx @@ -1,9 +1,10 @@ -import { useMachine } from "@xstate/react"; -import { PropsWithChildren, FC } from "react"; -import { sshKeyMachine } from "xServices/sshKey/sshKeyXService"; +import { PropsWithChildren, FC, useState } from "react"; import { ConfirmDialog } from "../../../components/Dialogs/ConfirmDialog/ConfirmDialog"; import { Section } from "../../../components/SettingsLayout/Section"; import { SSHKeysPageView } from "./SSHKeysPageView"; +import { regenerateUserSSHKey, userSSHKey } from "api/queries/sshKeys"; +import { displaySuccess } from "components/GlobalSnackbar/utils"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; export const Language = { title: "SSH keys", @@ -15,40 +16,47 @@ export const Language = { }; export const SSHKeysPage: FC> = () => { - const [sshState, sshSend] = useMachine(sshKeyMachine); - const isLoading = sshState.matches("gettingSSHKey"); - const hasLoaded = sshState.matches("loaded"); - const { getSSHKeyError, regenerateSSHKeyError, sshKey } = sshState.context; - - const onRegenerateClick = () => { - sshSend({ type: "REGENERATE_SSH_KEY" }); - }; + const [isConfirmingRegeneration, setIsConfirmingRegeneration] = + useState(false); + const queryClient = useQueryClient(); + const userSSHKeyQuery = useQuery(userSSHKey("me")); + const regenerateSSHKeyMutationOptions = regenerateUserSSHKey( + "me", + queryClient, + ); + const regenerateSSHKeyMutation = useMutation({ + ...regenerateSSHKeyMutationOptions, + onSuccess: (newKey) => { + regenerateSSHKeyMutationOptions.onSuccess(newKey); + displaySuccess("SSH Key regenerated successfully."); + setIsConfirmingRegeneration(false); + }, + }); return ( <>
{ + setIsConfirmingRegeneration(true); + }} />
{ - sshSend({ type: "CONFIRM_REGENERATE_SSH_KEY" }); - }} + onConfirm={regenerateSSHKeyMutation.mutate} onClose={() => { - sshSend({ type: "CANCEL_REGENERATE_SSH_KEY" }); + setIsConfirmingRegeneration(false); }} description={<>{Language.regenerateDialogMessage}} /> diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx index e66cdef869806..96f1e3a51bf23 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx @@ -7,7 +7,6 @@ const meta: Meta = { component: SSHKeysPageView, args: { isLoading: false, - hasLoaded: true, sshKey: { user_id: "test-user-id", created_at: "2022-07-28T07:45:50.795918897Z", @@ -30,7 +29,7 @@ export const Loading: Story = { export const WithGetSSHKeyError: Story = { args: { - hasLoaded: false, + sshKey: undefined, getSSHKeyError: mockApiError({ message: "Failed to get SSH key", }), diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx index c14c801771c31..ac848e60e5c40 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx @@ -14,7 +14,6 @@ export const Language = { export interface SSHKeysPageViewProps { isLoading: boolean; - hasLoaded: boolean; getSSHKeyError?: unknown; regenerateSSHKeyError?: unknown; sshKey?: GitSSHKey; @@ -25,7 +24,6 @@ export const SSHKeysPageView: FC< React.PropsWithChildren > = ({ isLoading, - hasLoaded, getSSHKeyError, regenerateSSHKeyError, sshKey, @@ -49,7 +47,7 @@ export const SSHKeysPageView: FC< {Boolean(regenerateSSHKeyError) && ( )} - {hasLoaded && sshKey && ( + {sshKey && ( <>

The following public key is used to authenticate Git in workspaces. diff --git a/site/src/xServices/sshKey/sshKeyXService.ts b/site/src/xServices/sshKey/sshKeyXService.ts deleted file mode 100644 index c7f8d048f0eec..0000000000000 --- a/site/src/xServices/sshKey/sshKeyXService.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { getUserSSHKey, regenerateUserSSHKey } from "api/api"; -import { GitSSHKey } from "api/typesGenerated"; -import { displaySuccess } from "components/GlobalSnackbar/utils"; -import { createMachine, assign } from "xstate"; - -interface Context { - sshKey?: GitSSHKey; - getSSHKeyError?: unknown; - regenerateSSHKeyError?: unknown; -} - -type Events = - | { type: "REGENERATE_SSH_KEY" } - | { type: "CONFIRM_REGENERATE_SSH_KEY" } - | { type: "CANCEL_REGENERATE_SSH_KEY" }; - -export const sshKeyMachine = createMachine( - { - id: "sshKeyState", - predictableActionArguments: true, - schema: { - context: {} as Context, - events: {} as Events, - services: {} as { - getSSHKey: { - data: GitSSHKey; - }; - regenerateSSHKey: { - data: GitSSHKey; - }; - }, - }, - tsTypes: {} as import("./sshKeyXService.typegen").Typegen0, - initial: "gettingSSHKey", - states: { - gettingSSHKey: { - entry: "clearGetSSHKeyError", - invoke: { - src: "getSSHKey", - onDone: [ - { - actions: "assignSSHKey", - target: "loaded", - }, - ], - onError: [ - { - actions: "assignGetSSHKeyError", - target: "notLoaded", - }, - ], - }, - }, - notLoaded: { - type: "final", - }, - loaded: { - on: { - REGENERATE_SSH_KEY: { - target: "confirmSSHKeyRegenerate", - }, - }, - }, - confirmSSHKeyRegenerate: { - on: { - CANCEL_REGENERATE_SSH_KEY: { - target: "loaded", - }, - CONFIRM_REGENERATE_SSH_KEY: { - target: "regeneratingSSHKey", - }, - }, - }, - regeneratingSSHKey: { - entry: "clearRegenerateSSHKeyError", - invoke: { - src: "regenerateSSHKey", - onDone: [ - { - actions: ["assignSSHKey", "notifySuccessSSHKeyRegenerated"], - target: "loaded", - }, - ], - onError: [ - { - actions: "assignRegenerateSSHKeyError", - target: "loaded", - }, - ], - }, - }, - }, - }, - { - services: { - getSSHKey: () => getUserSSHKey(), - regenerateSSHKey: () => regenerateUserSSHKey(), - }, - actions: { - assignSSHKey: assign({ - sshKey: (_, { data }) => data, - }), - assignGetSSHKeyError: assign({ - getSSHKeyError: (_, { data }) => data, - }), - clearGetSSHKeyError: assign({ - getSSHKeyError: (_) => undefined, - }), - assignRegenerateSSHKeyError: assign({ - regenerateSSHKeyError: (_, { data }) => data, - }), - clearRegenerateSSHKeyError: assign({ - regenerateSSHKeyError: (_) => undefined, - }), - notifySuccessSSHKeyRegenerated: () => { - displaySuccess("SSH Key regenerated successfully."); - }, - }, - }, -);