feat: implement ssh forwarding
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { fetchApi } from "@/api";
|
||||
import useSWR, { useSWRConfig } from "swr";
|
||||
import type { Workspace } from "./types";
|
||||
import { WorkspaceStatus, type Workspace } from "./types";
|
||||
import { useCallback, useState } from "react";
|
||||
import { QueryStatus } from "@/lib/query";
|
||||
import type { QueryStatus } from "@/lib/query";
|
||||
|
||||
function useWorkspaces() {
|
||||
return useSWR(
|
||||
@@ -20,29 +20,143 @@ function useCreateWorkspace() {
|
||||
async ({
|
||||
workspaceName,
|
||||
imageId,
|
||||
}: { workspaceName: string; imageId: string }): Promise<Workspace> => {
|
||||
}: {
|
||||
workspaceName: string;
|
||||
imageId: string;
|
||||
}): Promise<Workspace | null> => {
|
||||
setStatus({ type: "loading" });
|
||||
try {
|
||||
const res = await fetchApi(`/workspaces/${workspaceName}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ imageId }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
const workspace = await mutate(
|
||||
"/workspaces",
|
||||
fetchApi(`/workspaces/${workspaceName}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ imageId }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then((res): Promise<Workspace> => res.json()),
|
||||
{
|
||||
populateCache: (createdWorkspace, workspaces) => [
|
||||
...workspaces,
|
||||
createdWorkspace,
|
||||
],
|
||||
throwOnError: true,
|
||||
},
|
||||
});
|
||||
const workspace = await res.json();
|
||||
|
||||
setStatus({ type: "ok" });
|
||||
|
||||
return workspace;
|
||||
);
|
||||
return workspace ?? null;
|
||||
} catch (error: unknown) {
|
||||
setStatus({ type: "error", error });
|
||||
return null;
|
||||
}
|
||||
},
|
||||
[],
|
||||
[mutate],
|
||||
);
|
||||
|
||||
return { createWorkspace, status };
|
||||
}
|
||||
|
||||
export { useWorkspaces, useCreateWorkspace };
|
||||
function useChangeWorkspaceStatus() {
|
||||
const [status, setStatus] = useState<QueryStatus>({ type: "idle" });
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
const startWorkspace = useCallback(
|
||||
async (workspaceName: string) => {
|
||||
setStatus({ type: "loading" });
|
||||
try {
|
||||
await mutate(
|
||||
"/workspaces",
|
||||
fetchApi(`/workspaces/${workspaceName}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ status: WorkspaceStatus.Running }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then((res): Promise<Workspace> => res.json()),
|
||||
{
|
||||
populateCache: (updatedWorkspace, workspaces) =>
|
||||
workspaces.map((workspace: Workspace) =>
|
||||
workspace.containerId === updatedWorkspace.containerId
|
||||
? updatedWorkspace
|
||||
: workspace,
|
||||
),
|
||||
throwOnError: true,
|
||||
},
|
||||
);
|
||||
setStatus({ type: "ok" });
|
||||
} catch (error: unknown) {
|
||||
setStatus({ type: "error", error });
|
||||
}
|
||||
},
|
||||
[mutate],
|
||||
);
|
||||
|
||||
const stopWorkspace = useCallback(
|
||||
async (workspaceName: string) => {
|
||||
setStatus({ type: "loading" });
|
||||
try {
|
||||
await mutate(
|
||||
"/workspaces",
|
||||
fetchApi(`/workspaces/${workspaceName}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ status: WorkspaceStatus.Stopped }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then((res): Promise<Workspace> => res.json()),
|
||||
{
|
||||
populateCache: (updatedWorkspace, workspaces) =>
|
||||
workspaces.map((workspace: Workspace) =>
|
||||
workspace.containerId === updatedWorkspace.containerId
|
||||
? updatedWorkspace
|
||||
: workspace,
|
||||
),
|
||||
throwOnError: true,
|
||||
},
|
||||
);
|
||||
setStatus({ type: "ok" });
|
||||
} catch (error: unknown) {
|
||||
setStatus({ type: "error", error });
|
||||
}
|
||||
},
|
||||
[mutate],
|
||||
);
|
||||
|
||||
return { startWorkspace, stopWorkspace, status };
|
||||
}
|
||||
|
||||
function useDeleteWorkspace() {
|
||||
const [status, setStatus] = useState<QueryStatus>({ type: "idle" });
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
const deleteWorkspace = useCallback(
|
||||
async (workspaceName: string) => {
|
||||
setStatus({ type: "loading" });
|
||||
try {
|
||||
await mutate(
|
||||
"/workspaces",
|
||||
fetchApi(`/workspaces/${workspaceName}`, { method: "DELETE" }),
|
||||
{
|
||||
populateCache: (_, workspaces) =>
|
||||
workspaces.filter(
|
||||
(workspace: Workspace) => workspace.name === workspaceName,
|
||||
),
|
||||
throwOnError: true,
|
||||
},
|
||||
);
|
||||
setStatus({ type: "ok" });
|
||||
} catch (error: unknown) {
|
||||
setStatus({ type: "error", error });
|
||||
}
|
||||
},
|
||||
[mutate],
|
||||
);
|
||||
|
||||
return { deleteWorkspace, status };
|
||||
}
|
||||
|
||||
export {
|
||||
useWorkspaces,
|
||||
useCreateWorkspace,
|
||||
useChangeWorkspaceStatus,
|
||||
useDeleteWorkspace,
|
||||
};
|
||||
|
Reference in New Issue
Block a user