Skip to content

feat: add frontend support for enabling automatic workspace updates #10375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: add frontend support for enabling automatic workspace updates
  • Loading branch information
sreya committed Oct 21, 2023
commit a66709a99da90c1941b6ff0546459f998523bcde
2 changes: 1 addition & 1 deletion scripts/develop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fatal() {
trap 'fatal "Script encountered an error"' ERR

cdroot
start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@"
start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --experiments="template_update_policies" --dangerous-allow-cors-requests=true "$@"

echo '== Waiting for Coder to become ready'
# Start the timeout in the background so interrupting this script
Expand Down
15 changes: 15 additions & 0 deletions site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,21 @@ export const updateWorkspaceDormancy = async (
return response.data;
};

export const updateWorkspaceAutomaticUpdates = async (
workspaceId: string,
automaticUpdates: TypesGen.AutomaticUpdates,
): Promise<void> => {
const data: TypesGen.UpdateWorkspaceAutomaticUpdatesRequest = {
automatic_updates: automaticUpdates,
};

const response = await axios.put(
`/api/v2/workspaces/${workspaceId}/autoupdates`,
data,
);
return response.data;
};

export const restartWorkspace = async ({
workspace,
buildParameters,
Expand Down
59 changes: 56 additions & 3 deletions site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,30 @@ import {
HorizontalForm,
} from "components/Form/Form";
import { useFormik } from "formik";
import { type FC } from "react";
import { useState, type FC } from "react";
import * as Yup from "yup";
import {
nameValidator,
getFormHelpers,
onChangeTrimmed,
} from "utils/formUtils";
import { Workspace } from "api/typesGenerated";
import {
AutomaticUpdates,
AutomaticUpdateses,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this name sounds like we hired gollum 😂

Workspace,
} from "api/typesGenerated";
import { Alert } from "components/Alert/Alert";
import {
FormControl,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
} from "@mui/material";

export type WorkspaceSettingsFormValues = {
name: string;
automatic_updates: AutomaticUpdates;
};

export const WorkspaceSettingsForm: FC<{
Expand All @@ -31,6 +43,7 @@ export const WorkspaceSettingsForm: FC<{
onSubmit,
initialValues: {
name: workspace.name,
automatic_updates: workspace.automatic_updates,
},
validationSchema: Yup.object({
name: nameValidator("Name"),
Expand All @@ -41,9 +54,25 @@ export const WorkspaceSettingsForm: FC<{
error,
);

const capitalizeFirstLetter = (inputString: string): string => {
return inputString.charAt(0).toUpperCase() + inputString.slice(1);
};

const [automaticUpdates, setAutomaticUpdates] = useState<AutomaticUpdates>(
workspace.automatic_updates,
);

const handleChange = (event: SelectChangeEvent) => {
setAutomaticUpdates(event.target.value as AutomaticUpdates);
form.setFieldValue("automatic_updates", automaticUpdates);
};

return (
<HorizontalForm onSubmit={form.handleSubmit} data-testid="form">
<FormSection title="General" description="The name of your workspace.">
<FormSection
title="Workspace Name"
description="Update the name of your workspace."
>
<FormFields>
<TextField
{...getFieldHelpers("name")}
Expand All @@ -61,6 +90,30 @@ export const WorkspaceSettingsForm: FC<{
)}
</FormFields>
</FormSection>
<FormSection
title="Automatic Updates"
description="Configure your workspace to automatically update to the active template version when started."
>
<FormControl fullWidth>
<FormFields>
<InputLabel htmlFor="automatic_updates">Update Policy</InputLabel>
<Select
labelId="automatic_updates"
id="automatic_updates"
label="Update Policy"
value={automaticUpdates}
onChange={handleChange}
disabled={form.isSubmitting}
>
{AutomaticUpdateses.map((value) => (
<MenuItem value={value}>
{capitalizeFirstLetter(value)}
</MenuItem>
))}
</Select>
</FormFields>
</FormControl>
</FormSection>
<FormFooter onCancel={onCancel} isLoading={isSubmitting} />
</HorizontalForm>
);
Expand Down
11 changes: 8 additions & 3 deletions site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useWorkspaceSettings } from "./WorkspaceSettingsLayout";
import { WorkspaceSettingsPageView } from "./WorkspaceSettingsPageView";
import { useMutation } from "react-query";
import { displaySuccess } from "components/GlobalSnackbar/utils";
import { patchWorkspace } from "api/api";
import { patchWorkspace, updateWorkspaceAutomaticUpdates } from "api/api";
import { WorkspaceSettingsFormValues } from "./WorkspaceSettingsForm";

const WorkspaceSettingsPage = () => {
Expand All @@ -18,8 +18,13 @@ const WorkspaceSettingsPage = () => {
const workspace = useWorkspaceSettings();
const navigate = useNavigate();
const mutation = useMutation({
mutationFn: (formValues: WorkspaceSettingsFormValues) =>
patchWorkspace(workspace.id, { name: formValues.name }),
mutationFn: async (formValues: WorkspaceSettingsFormValues) => {
await patchWorkspace(workspace.id, { name: formValues.name });
await updateWorkspaceAutomaticUpdates(
workspace.id,
formValues.automatic_updates,
);
},
onSuccess: (_, formValues) => {
displaySuccess("Workspace updated successfully");
navigate(`/@${username}/${formValues.name}/settings`);
Expand Down