chore(site): refactor workspace quota to use react-query instead of XState (#9626)

This commit is contained in:
Bruno Quaresma
2023-09-12 14:58:35 -03:00
committed by GitHub
parent 64bc317cd4
commit b33cb0ef97
7 changed files with 32 additions and 81 deletions
+4 -2
View File
@@ -961,9 +961,11 @@ export const deleteGroup = async (groupId: string): Promise<void> => {
};
export const getWorkspaceQuota = async (
userID: string,
username: string,
): Promise<TypesGen.WorkspaceQuota> => {
const response = await axios.get(`/api/v2/workspace-quota/${userID}`);
const response = await axios.get(
`/api/v2/workspace-quota/${encodeURIComponent(username)}`,
);
return response.data;
};
+13
View File
@@ -0,0 +1,13 @@
import * as API from "api/api";
const getWorkspaceQuotaQueryKey = (username: string) => [
username,
"workspaceQuota",
];
export const workspaceQuota = (username: string) => {
return {
queryKey: getWorkspaceQuotaQueryKey(username),
queryFn: () => API.getWorkspaceQuota(username),
};
};
+3 -3
View File
@@ -68,7 +68,7 @@ export interface WorkspaceProps {
buildInfo?: TypesGen.BuildInfoResponse;
sshPrefix?: string;
template?: TypesGen.Template;
quota_budget?: number;
quotaBudget?: number;
handleBuildRetry: () => void;
buildLogs?: React.ReactNode;
}
@@ -101,7 +101,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
buildInfo,
sshPrefix,
template,
quota_budget,
quotaBudget,
handleBuildRetry,
templateWarnings,
buildLogs,
@@ -183,7 +183,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
<WorkspaceStats
workspace={workspace}
quota_budget={quota_budget}
quotaBudget={quotaBudget}
handleUpdate={handleUpdate}
canUpdateWorkspace={canUpdateWorkspace}
maxDeadlineDecrease={scheduleProps.maxDeadlineDecrease}
@@ -3,7 +3,6 @@ import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
import { Loader } from "components/Loader/Loader";
import { FC } from "react";
import { useParams } from "react-router-dom";
import { quotaMachine } from "xServices/quotas/quotasXService";
import { workspaceMachine } from "xServices/workspace/workspaceXService";
import { WorkspaceReadyPage } from "./WorkspaceReadyPage";
import { RequirePermission } from "components/RequirePermission/RequirePermission";
@@ -11,6 +10,8 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
import { useOrganizationId } from "hooks";
import { isAxiosError } from "axios";
import { Margins } from "components/Margins/Margins";
import { workspaceQuota } from "api/queries/workspaceQuota";
import { useQuery } from "@tanstack/react-query";
export const WorkspacePage: FC = () => {
const params = useParams() as {
@@ -28,9 +29,8 @@ export const WorkspacePage: FC = () => {
},
});
const { workspace, error } = workspaceState.context;
const [quotaState] = useMachine(quotaMachine, { context: { username } });
const { getQuotaError } = quotaState.context;
const pageError = error ?? getQuotaError;
const quotaQuery = useQuery(workspaceQuota(username));
const pageError = error ?? quotaQuery.error;
return (
<RequirePermission
@@ -48,12 +48,12 @@ export const WorkspacePage: FC = () => {
condition={
Boolean(workspace) &&
workspaceState.matches("ready") &&
quotaState.matches("success")
quotaQuery.isSuccess
}
>
<WorkspaceReadyPage
workspaceState={workspaceState}
quotaState={quotaState}
quota={quotaQuery.data}
workspaceSend={workspaceSend}
/>
</Cond>
@@ -11,7 +11,6 @@ import {
getMaxDeadlineChange,
getMinDeadline,
} from "utils/schedule";
import { quotaMachine } from "xServices/quotas/quotasXService";
import { StateFrom } from "xstate";
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
import { Workspace, WorkspaceErrors } from "./Workspace";
@@ -38,14 +37,14 @@ import { WorkspaceBuildLogsSection } from "./WorkspaceBuildLogsSection";
interface WorkspaceReadyPageProps {
workspaceState: StateFrom<typeof workspaceMachine>;
quotaState: StateFrom<typeof quotaMachine>;
workspaceSend: (event: WorkspaceEvent) => void;
quota?: TypesGen.WorkspaceQuota;
}
export const WorkspaceReadyPage = ({
workspaceState,
quotaState,
workspaceSend,
quota,
}: WorkspaceReadyPageProps): JSX.Element => {
const [_, bannerSend] = useActor(
workspaceState.children["scheduleBannerMachine"],
@@ -186,7 +185,7 @@ export const WorkspaceReadyPage = ({
buildInfo={buildInfo}
sshPrefix={sshPrefix}
template={template}
quota_budget={quotaState.context.quota?.budget}
quotaBudget={quota?.budget}
templateWarnings={templateVersion?.warnings}
buildLogs={
shouldDisplayBuildLogs && (
@@ -39,7 +39,7 @@ export interface WorkspaceStatsProps {
maxDeadlineIncrease: number;
maxDeadlineDecrease: number;
canUpdateWorkspace: boolean;
quota_budget?: number;
quotaBudget?: number;
onDeadlinePlus: (hours: number) => void;
onDeadlineMinus: (hours: number) => void;
handleUpdate: () => void;
@@ -47,7 +47,7 @@ export interface WorkspaceStatsProps {
export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
workspace,
quota_budget,
quotaBudget,
maxDeadlineDecrease,
maxDeadlineIncrease,
canUpdateWorkspace,
@@ -169,7 +169,7 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
className={styles.statsItem}
label={Language.costLabel}
value={`${workspace.latest_build.daily_cost} ${
quota_budget ? `/ ${quota_budget}` : ""
quotaBudget ? `/ ${quotaBudget}` : ""
}`}
/>
)}
@@ -1,63 +0,0 @@
import { assign, createMachine } from "xstate";
import * as API from "../../api/api";
import { WorkspaceQuota } from "../../api/typesGenerated";
export type QuotaContext = {
username: string;
quota?: WorkspaceQuota;
getQuotaError?: unknown;
};
export const quotaMachine = createMachine(
{
id: "quotasMachine",
predictableActionArguments: true,
tsTypes: {} as import("./quotasXService.typegen").Typegen0,
schema: {
context: {} as QuotaContext,
services: {
getQuota: {
data: {} as WorkspaceQuota,
},
},
},
initial: "gettingQuotas",
states: {
idle: {},
gettingQuotas: {
entry: "clearGetQuotaError",
invoke: {
id: "getQuota",
src: "getQuota",
onDone: {
target: "success",
actions: ["assignQuota"],
},
onError: {
target: "idle",
actions: ["assignGetQuotaError"],
},
},
},
success: {
type: "final",
},
},
},
{
actions: {
assignQuota: assign({
quota: (_, event) => event.data,
}),
assignGetQuotaError: assign({
getQuotaError: (_, event) => event.data,
}),
clearGetQuotaError: assign({
getQuotaError: (_) => undefined,
}),
},
services: {
getQuota: ({ username }) => API.getWorkspaceQuota(username),
},
},
);