Skip to content

Commit a66709a

Browse files
committed
feat: add frontend support for enabling automatic workspace updates
1 parent a7243b3 commit a66709a

File tree

4 files changed

+80
-7
lines changed

4 files changed

+80
-7
lines changed

scripts/develop.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fatal() {
136136
trap 'fatal "Script encountered an error"' ERR
137137

138138
cdroot
139-
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 "$@"
139+
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 "$@"
140140

141141
echo '== Waiting for Coder to become ready'
142142
# Start the timeout in the background so interrupting this script

site/src/api/api.ts

+15
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,21 @@ export const updateWorkspaceDormancy = async (
576576
return response.data;
577577
};
578578

579+
export const updateWorkspaceAutomaticUpdates = async (
580+
workspaceId: string,
581+
automaticUpdates: TypesGen.AutomaticUpdates,
582+
): Promise<void> => {
583+
const data: TypesGen.UpdateWorkspaceAutomaticUpdatesRequest = {
584+
automatic_updates: automaticUpdates,
585+
};
586+
587+
const response = await axios.put(
588+
`/api/v2/workspaces/${workspaceId}/autoupdates`,
589+
data,
590+
);
591+
return response.data;
592+
};
593+
579594
export const restartWorkspace = async ({
580595
workspace,
581596
buildParameters,

site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx

+56-3
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,30 @@ import {
66
HorizontalForm,
77
} from "components/Form/Form";
88
import { useFormik } from "formik";
9-
import { type FC } from "react";
9+
import { useState, type FC } from "react";
1010
import * as Yup from "yup";
1111
import {
1212
nameValidator,
1313
getFormHelpers,
1414
onChangeTrimmed,
1515
} from "utils/formUtils";
16-
import { Workspace } from "api/typesGenerated";
16+
import {
17+
AutomaticUpdates,
18+
AutomaticUpdateses,
19+
Workspace,
20+
} from "api/typesGenerated";
1721
import { Alert } from "components/Alert/Alert";
22+
import {
23+
FormControl,
24+
InputLabel,
25+
MenuItem,
26+
Select,
27+
SelectChangeEvent,
28+
} from "@mui/material";
1829

1930
export type WorkspaceSettingsFormValues = {
2031
name: string;
32+
automatic_updates: AutomaticUpdates;
2133
};
2234

2335
export const WorkspaceSettingsForm: FC<{
@@ -31,6 +43,7 @@ export const WorkspaceSettingsForm: FC<{
3143
onSubmit,
3244
initialValues: {
3345
name: workspace.name,
46+
automatic_updates: workspace.automatic_updates,
3447
},
3548
validationSchema: Yup.object({
3649
name: nameValidator("Name"),
@@ -41,9 +54,25 @@ export const WorkspaceSettingsForm: FC<{
4154
error,
4255
);
4356

57+
const capitalizeFirstLetter = (inputString: string): string => {
58+
return inputString.charAt(0).toUpperCase() + inputString.slice(1);
59+
};
60+
61+
const [automaticUpdates, setAutomaticUpdates] = useState<AutomaticUpdates>(
62+
workspace.automatic_updates,
63+
);
64+
65+
const handleChange = (event: SelectChangeEvent) => {
66+
setAutomaticUpdates(event.target.value as AutomaticUpdates);
67+
form.setFieldValue("automatic_updates", automaticUpdates);
68+
};
69+
4470
return (
4571
<HorizontalForm onSubmit={form.handleSubmit} data-testid="form">
46-
<FormSection title="General" description="The name of your workspace.">
72+
<FormSection
73+
title="Workspace Name"
74+
description="Update the name of your workspace."
75+
>
4776
<FormFields>
4877
<TextField
4978
{...getFieldHelpers("name")}
@@ -61,6 +90,30 @@ export const WorkspaceSettingsForm: FC<{
6190
)}
6291
</FormFields>
6392
</FormSection>
93+
<FormSection
94+
title="Automatic Updates"
95+
description="Configure your workspace to automatically update to the active template version when started."
96+
>
97+
<FormControl fullWidth>
98+
<FormFields>
99+
<InputLabel htmlFor="automatic_updates">Update Policy</InputLabel>
100+
<Select
101+
labelId="automatic_updates"
102+
id="automatic_updates"
103+
label="Update Policy"
104+
value={automaticUpdates}
105+
onChange={handleChange}
106+
disabled={form.isSubmitting}
107+
>
108+
{AutomaticUpdateses.map((value) => (
109+
<MenuItem value={value}>
110+
{capitalizeFirstLetter(value)}
111+
</MenuItem>
112+
))}
113+
</Select>
114+
</FormFields>
115+
</FormControl>
116+
</FormSection>
64117
<FormFooter onCancel={onCancel} isLoading={isSubmitting} />
65118
</HorizontalForm>
66119
);

site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useWorkspaceSettings } from "./WorkspaceSettingsLayout";
55
import { WorkspaceSettingsPageView } from "./WorkspaceSettingsPageView";
66
import { useMutation } from "react-query";
77
import { displaySuccess } from "components/GlobalSnackbar/utils";
8-
import { patchWorkspace } from "api/api";
8+
import { patchWorkspace, updateWorkspaceAutomaticUpdates } from "api/api";
99
import { WorkspaceSettingsFormValues } from "./WorkspaceSettingsForm";
1010

1111
const WorkspaceSettingsPage = () => {
@@ -18,8 +18,13 @@ const WorkspaceSettingsPage = () => {
1818
const workspace = useWorkspaceSettings();
1919
const navigate = useNavigate();
2020
const mutation = useMutation({
21-
mutationFn: (formValues: WorkspaceSettingsFormValues) =>
22-
patchWorkspace(workspace.id, { name: formValues.name }),
21+
mutationFn: async (formValues: WorkspaceSettingsFormValues) => {
22+
await patchWorkspace(workspace.id, { name: formValues.name });
23+
await updateWorkspaceAutomaticUpdates(
24+
workspace.id,
25+
formValues.automatic_updates,
26+
);
27+
},
2328
onSuccess: (_, formValues) => {
2429
displaySuccess("Workspace updated successfully");
2530
navigate(`/@${username}/${formValues.name}/settings`);

0 commit comments

Comments
 (0)