chore(site): move ssh keys management to react-query (#9625)

This commit is contained in:
Bruno Quaresma
2023-09-12 14:40:07 -03:00
committed by GitHub
parent 6db89b0372
commit 5ca8c4287f
5 changed files with 57 additions and 148 deletions
+24
View File
@@ -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);
},
};
};
@@ -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<PropsWithChildren<unknown>> = () => {
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 (
<>
<Section title={Language.title}>
<SSHKeysPageView
isLoading={isLoading}
hasLoaded={hasLoaded}
getSSHKeyError={getSSHKeyError}
regenerateSSHKeyError={regenerateSSHKeyError}
sshKey={sshKey}
onRegenerateClick={onRegenerateClick}
isLoading={userSSHKeyQuery.isLoading}
getSSHKeyError={userSSHKeyQuery.error}
regenerateSSHKeyError={regenerateSSHKeyMutation.error}
sshKey={userSSHKeyQuery.data}
onRegenerateClick={() => {
setIsConfirmingRegeneration(true);
}}
/>
</Section>
<ConfirmDialog
type="delete"
hideCancel={false}
open={sshState.matches("confirmSSHKeyRegenerate")}
confirmLoading={sshState.matches("regeneratingSSHKey")}
open={isConfirmingRegeneration}
confirmLoading={regenerateSSHKeyMutation.isLoading}
title={Language.regenerateDialogTitle}
confirmText={Language.confirmLabel}
onConfirm={() => {
sshSend({ type: "CONFIRM_REGENERATE_SSH_KEY" });
}}
onConfirm={regenerateSSHKeyMutation.mutate}
onClose={() => {
sshSend({ type: "CANCEL_REGENERATE_SSH_KEY" });
setIsConfirmingRegeneration(false);
}}
description={<>{Language.regenerateDialogMessage}</>}
/>
@@ -7,7 +7,6 @@ const meta: Meta<typeof SSHKeysPageView> = {
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",
}),
@@ -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<SSHKeysPageViewProps>
> = ({
isLoading,
hasLoaded,
getSSHKeyError,
regenerateSSHKeyError,
sshKey,
@@ -49,7 +47,7 @@ export const SSHKeysPageView: FC<
{Boolean(regenerateSSHKeyError) && (
<ErrorAlert error={regenerateSSHKeyError} dismissible />
)}
{hasLoaded && sshKey && (
{sshKey && (
<>
<p className={styles.description}>
The following public key is used to authenticate Git in workspaces.
-120
View File
@@ -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.");
},
},
},
);