chore(site): remove workspace schedule banner service (#10588)

Related to https://github.com/coder/coder/issues/9943
This commit is contained in:
Bruno Quaresma
2023-11-08 16:48:54 -03:00
committed by GitHub
parent 2cf2904515
commit a328d20bcb
4 changed files with 50 additions and 165 deletions
+26 -1
View File
@@ -1,6 +1,8 @@
import * as API from "api/api";
import { QueryClient, type QueryOptions } from "react-query";
import { putWorkspaceExtension } from "api/api";
import dayjs from "dayjs";
import { getDeadline, getMaxDeadline, getMinDeadline } from "utils/schedule";
import {
type WorkspaceBuildParameter,
type Workspace,
@@ -99,3 +101,26 @@ export function workspaces(config: WorkspacesRequest = {}) {
queryFn: () => API.getWorkspaces({ q, limit }),
} as const satisfies QueryOptions<WorkspacesResponse>;
}
export const decreaseDeadline = (workspace: Workspace) => {
return {
mutationFn: (hours: number) => {
const proposedDeadline = getDeadline(workspace).subtract(hours, "hours");
const newDeadline = dayjs.max(proposedDeadline, getMinDeadline());
return putWorkspaceExtension(workspace.id, newDeadline);
},
};
};
export const increaseDeadline = (workspace: Workspace) => {
return {
mutationFn: (hours: number) => {
const proposedDeadline = getDeadline(workspace).add(hours, "hours");
const newDeadline = dayjs.min(
proposedDeadline,
getMaxDeadline(workspace),
);
return putWorkspaceExtension(workspace.id, newDeadline);
},
};
};
@@ -1,4 +1,3 @@
import { useActor } from "@xstate/react";
import { useDashboard } from "components/Dashboard/DashboardProvider";
import dayjs from "dayjs";
import { useFeatureVisibility } from "hooks/useFeatureVisibility";
@@ -34,6 +33,9 @@ import { templateVersion, templateVersions } from "api/queries/templates";
import { Alert } from "components/Alert/Alert";
import { Stack } from "components/Stack/Stack";
import { useWorkspaceBuildLogs } from "hooks/useWorkspaceBuildLogs";
import { decreaseDeadline, increaseDeadline } from "api/queries/workspaces";
import { getErrorMessage } from "api/errors";
import { displaySuccess, displayError } from "components/GlobalSnackbar/utils";
interface WorkspaceReadyPageProps {
workspaceState: StateFrom<typeof workspaceMachine>;
@@ -56,9 +58,6 @@ export const WorkspaceReadyPage = ({
isLoadingMoreBuilds,
hasMoreBuilds,
}: WorkspaceReadyPageProps): JSX.Element => {
const [_, bannerSend] = useActor(
workspaceState.children["scheduleBannerMachine"],
);
const { buildInfo } = useDashboard();
const featureVisibility = useFeatureVisibility();
const {
@@ -121,10 +120,25 @@ export const WorkspaceReadyPage = ({
} = useMutation({
mutationFn: restartWorkspace,
});
// keep banner machine in sync with workspace
useEffect(() => {
bannerSend({ type: "REFRESH_WORKSPACE", workspace });
}, [bannerSend, workspace]);
const onDeadlineChangeSuccess = () => {
displaySuccess("Updated workspace shutdown time.");
};
const onDeadlineChangeFails = (error: unknown) => {
displayError(
getErrorMessage(error, "Failed to update workspace shutdown time."),
);
};
const decreaseMutation = useMutation({
...decreaseDeadline(workspace),
onSuccess: onDeadlineChangeSuccess,
onError: onDeadlineChangeFails,
});
const increaseMutation = useMutation({
...increaseDeadline(workspace),
onSuccess: onDeadlineChangeSuccess,
onError: onDeadlineChangeFails,
});
return (
<>
@@ -144,18 +158,8 @@ export const WorkspaceReadyPage = ({
<Workspace
scheduleProps={{
onDeadlineMinus: (hours: number) => {
bannerSend({
type: "DECREASE_DEADLINE",
hours,
});
},
onDeadlinePlus: (hours: number) => {
bannerSend({
type: "INCREASE_DEADLINE",
hours,
});
},
onDeadlineMinus: decreaseMutation.mutate,
onDeadlinePlus: increaseMutation.mutate,
maxDeadlineDecrease: getMaxDeadlineChange(deadline, getMinDeadline()),
maxDeadlineIncrease: getMaxDeadlineChange(
getMaxDeadline(workspace),
@@ -1,5 +1,4 @@
import { getErrorMessage } from "api/errors";
import { workspaceScheduleBannerMachine } from "xServices/workspaceSchedule/workspaceScheduleBannerXService";
import { assign, createMachine } from "xstate";
import * as API from "api/api";
import * as TypesGen from "api/typesGenerated";
@@ -416,15 +415,6 @@ export const workspaceMachine = createMachine(
},
},
},
schedule: {
invoke: {
id: "scheduleBannerMachine",
src: "scheduleBannerMachine",
data: {
workspace: (context: WorkspaceContext) => context.workspace,
},
},
},
},
},
error: {
@@ -672,7 +662,6 @@ export const workspaceMachine = createMachine(
context.eventSource?.close();
};
},
scheduleBannerMachine: workspaceScheduleBannerMachine,
getSSHPrefix: async () => {
return API.getDeploymentSSHConfig();
},
@@ -1,133 +0,0 @@
/**
* @fileoverview workspaceScheduleBanner is an xstate machine backing a form,
* presented as an Alert/banner, for reactively updating a workspace schedule.
*/
import { getErrorMessage } from "api/errors";
import { Workspace } from "api/typesGenerated";
import dayjs from "dayjs";
import minMax from "dayjs/plugin/minMax";
import { getDeadline, getMaxDeadline, getMinDeadline } from "utils/schedule";
import { assign, createMachine } from "xstate";
import * as API from "api/api";
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
dayjs.extend(minMax);
export const Language = {
errorExtension: "Failed to update workspace shutdown time.",
successExtension: "Updated workspace shutdown time.",
};
export interface WorkspaceScheduleBannerContext {
workspace: Workspace;
}
export type WorkspaceScheduleBannerEvent =
| {
type: "INCREASE_DEADLINE";
hours: number;
}
| {
type: "DECREASE_DEADLINE";
hours: number;
}
| {
type: "REFRESH_WORKSPACE";
workspace: Workspace;
};
export const workspaceScheduleBannerMachine = createMachine(
{
id: "workspaceScheduleBannerState",
predictableActionArguments: true,
tsTypes: {} as import("./workspaceScheduleBannerXService.typegen").Typegen0,
schema: {
events: {} as WorkspaceScheduleBannerEvent,
context: {} as WorkspaceScheduleBannerContext,
},
initial: "idle",
on: {
REFRESH_WORKSPACE: { actions: "assignWorkspace" },
},
states: {
idle: {
on: {
INCREASE_DEADLINE: "increasingDeadline",
DECREASE_DEADLINE: "decreasingDeadline",
},
},
increasingDeadline: {
invoke: {
src: "increaseDeadline",
id: "increaseDeadline",
onDone: {
target: "idle",
actions: "displaySuccessMessage",
},
onError: {
target: "idle",
actions: "displayFailureMessage",
},
},
tags: "loading",
},
decreasingDeadline: {
invoke: {
src: "decreaseDeadline",
id: "decreaseDeadline",
onDone: {
target: "idle",
actions: "displaySuccessMessage",
},
onError: {
target: "idle",
actions: "displayFailureMessage",
},
},
tags: "loading",
},
},
},
{
actions: {
// This error does not have a detail, so using the snackbar is okay
displayFailureMessage: (_, event) => {
displayError(getErrorMessage(event.data, Language.errorExtension));
},
displaySuccessMessage: () => {
displaySuccess(Language.successExtension);
},
assignWorkspace: assign((_, event) => ({
workspace: event.workspace,
})),
},
services: {
increaseDeadline: async (context, event) => {
if (!context.workspace.latest_build.deadline) {
throw Error("Deadline is undefined.");
}
const proposedDeadline = getDeadline(context.workspace).add(
event.hours,
"hours",
);
const newDeadline = dayjs.min(
proposedDeadline,
getMaxDeadline(context.workspace),
);
await API.putWorkspaceExtension(context.workspace.id, newDeadline);
},
decreaseDeadline: async (context, event) => {
if (!context.workspace.latest_build.deadline) {
throw Error("Deadline is undefined.");
}
const proposedDeadline = getDeadline(context.workspace).subtract(
event.hours,
"hours",
);
const newDeadline = dayjs.max(proposedDeadline, getMinDeadline());
await API.putWorkspaceExtension(context.workspace.id, newDeadline);
},
},
},
);