diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx
index 599d410d07f02..8bfd505949f82 100644
--- a/site/src/AppRouter.tsx
+++ b/site/src/AppRouter.tsx
@@ -55,6 +55,12 @@ const WorkspaceSchedulePage = lazy(
"./pages/WorkspaceSettingsPage/WorkspaceSchedulePage/WorkspaceSchedulePage"
),
)
+const WorkspaceParametersPage = lazy(
+ () =>
+ import(
+ "./pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage"
+ ),
+)
const TerminalPage = lazy(() => import("./pages/TerminalPage/TerminalPage"))
const TemplatePermissionsPage = lazy(
() =>
@@ -291,6 +297,10 @@ export const AppRouter: FC = () => {
/>
}>
} />
+ }
+ />
}
diff --git a/site/src/api/api.ts b/site/src/api/api.ts
index 1613a52384618..31a634997427d 100644
--- a/site/src/api/api.ts
+++ b/site/src/api/api.ts
@@ -1021,7 +1021,7 @@ export const getWorkspaceBuildParameters = async (
return response.data
}
type Claims = {
- license_expires?: jwt.NumericDate
+ license_expires?: number
account_type?: string
account_id?: string
trial: boolean
diff --git a/site/src/pages/WorkspaceSettingsPage/Sidebar.tsx b/site/src/pages/WorkspaceSettingsPage/Sidebar.tsx
index c325d3a4cb8f1..b53f80bd8a6b9 100644
--- a/site/src/pages/WorkspaceSettingsPage/Sidebar.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/Sidebar.tsx
@@ -6,6 +6,7 @@ import { FC, ElementType, PropsWithChildren, ReactNode } from "react"
import { Link, NavLink } from "react-router-dom"
import { combineClasses } from "utils/combineClasses"
import GeneralIcon from "@material-ui/icons/SettingsOutlined"
+import ParameterIcon from "@material-ui/icons/CodeOutlined"
import { Avatar } from "components/Avatar/Avatar"
const SidebarNavItem: FC<
@@ -65,6 +66,12 @@ export const Sidebar: React.FC<{ username: string; workspace: Workspace }> = ({
}>
General
+ }
+ >
+ Parameters
+
}
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersForm.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersForm.tsx
new file mode 100644
index 0000000000000..f1b380298469b
--- /dev/null
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersForm.tsx
@@ -0,0 +1,147 @@
+import {
+ FormFields,
+ FormFooter,
+ FormSection,
+ HorizontalForm,
+} from "components/Form/Form"
+import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"
+import { useFormik } from "formik"
+import { FC } from "react"
+import { useTranslation } from "react-i18next"
+import {
+ useValidationSchemaForRichParameters,
+ workspaceBuildParameterValue,
+} from "utils/richParameters"
+import * as Yup from "yup"
+import { getFormHelpers } from "utils/formUtils"
+import {
+ TemplateVersionParameter,
+ WorkspaceBuildParameter,
+} from "api/typesGenerated"
+
+export type WorkspaceParametersFormValues = {
+ rich_parameter_values: WorkspaceBuildParameter[]
+}
+
+export const WorkspaceParametersForm: FC<{
+ isSubmitting: boolean
+ templateVersionRichParameters: TemplateVersionParameter[]
+ buildParameters: WorkspaceBuildParameter[]
+ error: unknown
+ onCancel: () => void
+ onSubmit: (values: WorkspaceParametersFormValues) => void
+}> = ({
+ onCancel,
+ onSubmit,
+ templateVersionRichParameters,
+ buildParameters,
+ error,
+ isSubmitting,
+}) => {
+ const { t } = useTranslation("workspaceSettingsPage")
+ const mutableParameters = templateVersionRichParameters.filter(
+ (param) => param.mutable === true,
+ )
+ const immutableParameters = templateVersionRichParameters.filter(
+ (param) => param.mutable === false,
+ )
+ const form = useFormik({
+ onSubmit,
+ initialValues: {
+ rich_parameter_values: mutableParameters.map((parameter) => {
+ const buildParameter = buildParameters.find(
+ (p) => p.name === parameter.name,
+ )
+ if (!buildParameter) {
+ return {
+ name: parameter.name,
+ value: parameter.default_value,
+ }
+ }
+ return buildParameter
+ }),
+ },
+ validationSchema: Yup.object({
+ rich_parameter_values: useValidationSchemaForRichParameters(
+ "createWorkspacePage",
+ templateVersionRichParameters,
+ ),
+ }),
+ })
+ const getFieldHelpers = getFormHelpers(
+ form,
+ error,
+ )
+
+ return (
+
+ {mutableParameters.length > 0 && (
+
+
+ {mutableParameters.map((parameter, index) => (
+ {
+ await form.setFieldValue("rich_parameter_values." + index, {
+ name: parameter.name,
+ value: value,
+ })
+ }}
+ parameter={parameter}
+ initialValue={workspaceBuildParameterValue(
+ buildParameters,
+ parameter,
+ )}
+ />
+ ))}
+
+
+ )}
+ {/* They are displayed here only for visibility purposes */}
+ {immutableParameters.length > 0 && (
+
+ These parameters are also provided by your Terraform configuration
+ but they{" "}
+ cannot be changed after creating the workspace.
+ >
+ }
+ >
+
+ {immutableParameters.map((parameter, index) => (
+ {
+ throw new Error(
+ "Cannot change immutable parameter after creation",
+ )
+ }}
+ parameter={parameter}
+ initialValue={workspaceBuildParameterValue(
+ buildParameters,
+ parameter,
+ )}
+ />
+ ))}
+
+
+ )}
+
+
+ )
+}
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.stories.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.stories.tsx
new file mode 100644
index 0000000000000..6639674566251
--- /dev/null
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.stories.tsx
@@ -0,0 +1,46 @@
+import { ComponentMeta, Story } from "@storybook/react"
+import {
+ WorkspaceParametersPageView,
+ WorkspaceParametersPageViewProps,
+} from "./WorkspaceParametersPage"
+import { action } from "@storybook/addon-actions"
+import {
+ MockWorkspaceBuildParameter1,
+ MockWorkspaceBuildParameter2,
+ MockTemplateVersionParameter1,
+ MockTemplateVersionParameter2,
+ MockTemplateVersionParameter3,
+ MockWorkspaceBuildParameter3,
+} from "testHelpers/entities"
+
+export default {
+ title: "pages/WorkspaceParametersPageView",
+ component: WorkspaceParametersPageView,
+ args: {
+ submitError: undefined,
+ isSubmitting: false,
+ onCancel: action("cancel"),
+ data: {
+ buildParameters: [
+ MockWorkspaceBuildParameter1,
+ MockWorkspaceBuildParameter2,
+ MockWorkspaceBuildParameter3,
+ ],
+ templateVersionRichParameters: [
+ MockTemplateVersionParameter1,
+ MockTemplateVersionParameter2,
+ {
+ ...MockTemplateVersionParameter3,
+ mutable: false,
+ },
+ ],
+ },
+ },
+} as ComponentMeta
+
+const Template: Story = (args) => (
+
+)
+
+export const Example = Template.bind({})
+Example.args = {}
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.test.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.test.tsx
new file mode 100644
index 0000000000000..aae32a16c175d
--- /dev/null
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.test.tsx
@@ -0,0 +1,73 @@
+import userEvent from "@testing-library/user-event"
+import {
+ renderWithWorkspaceSettingsLayout,
+ waitForLoaderToBeRemoved,
+} from "testHelpers/renderHelpers"
+import WorkspaceParametersPage from "./WorkspaceParametersPage"
+import { screen, waitFor, within } from "@testing-library/react"
+import * as api from "api/api"
+import {
+ MockWorkspace,
+ MockTemplateVersionParameter1,
+ MockTemplateVersionParameter2,
+ MockWorkspaceBuildParameter1,
+ MockWorkspaceBuildParameter2,
+ MockWorkspaceBuild,
+} from "testHelpers/entities"
+
+test("Submit the workspace settings page successfully", async () => {
+ // Mock the API calls that loads data
+ jest
+ .spyOn(api, "getWorkspaceByOwnerAndName")
+ .mockResolvedValueOnce(MockWorkspace)
+ jest
+ .spyOn(api, "getTemplateVersionRichParameters")
+ .mockResolvedValueOnce([
+ MockTemplateVersionParameter1,
+ MockTemplateVersionParameter2,
+ ])
+ jest
+ .spyOn(api, "getWorkspaceBuildParameters")
+ .mockResolvedValueOnce([
+ MockWorkspaceBuildParameter1,
+ MockWorkspaceBuildParameter2,
+ ])
+ // Mock the API calls that submit data
+ const postWorkspaceBuildSpy = jest
+ .spyOn(api, "postWorkspaceBuild")
+ .mockResolvedValue(MockWorkspaceBuild)
+ // Setup event and rendering
+ const user = userEvent.setup()
+ renderWithWorkspaceSettingsLayout(, {
+ route: "/@test-user/test-workspace/settings",
+ path: "/@:username/:workspace/settings",
+ // Need this because after submit the user is redirected
+ extraRoutes: [{ path: "/@:username/:workspace", element: }],
+ })
+ await waitForLoaderToBeRemoved()
+ // Fill the form and submit
+ const form = screen.getByTestId("form")
+ const parameter1 = within(form).getByLabelText(
+ MockWorkspaceBuildParameter1.name,
+ { exact: false },
+ )
+ await user.clear(parameter1)
+ await user.type(parameter1, "new-value")
+ const parameter2 = within(form).getByLabelText(
+ MockWorkspaceBuildParameter2.name,
+ { exact: false },
+ )
+ await user.clear(parameter2)
+ await user.type(parameter2, "1")
+ await user.click(within(form).getByRole("button", { name: "Submit" }))
+ // Assert that the API calls were made with the correct data
+ await waitFor(() => {
+ expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, {
+ transition: "start",
+ rich_parameter_values: [
+ { name: MockTemplateVersionParameter1.name, value: "new-value" },
+ { name: MockTemplateVersionParameter2.name, value: "1" },
+ ],
+ })
+ })
+})
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.tsx
new file mode 100644
index 0000000000000..5b9795d13a755
--- /dev/null
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPage.tsx
@@ -0,0 +1,115 @@
+import {
+ getTemplateVersionRichParameters,
+ getWorkspaceBuildParameters,
+ postWorkspaceBuild,
+} from "api/api"
+import { Workspace } from "api/typesGenerated"
+import { Helmet } from "react-helmet-async"
+import { pageTitle } from "utils/page"
+import { useWorkspaceSettingsContext } from "../WorkspaceSettingsLayout"
+import { useMutation, useQuery } from "@tanstack/react-query"
+import { Loader } from "components/Loader/Loader"
+import {
+ WorkspaceParametersFormValues,
+ WorkspaceParametersForm,
+} from "./WorkspaceParametersForm"
+import { useNavigate } from "react-router-dom"
+import { makeStyles } from "@material-ui/core/styles"
+import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"
+import { displaySuccess } from "components/GlobalSnackbar/utils"
+import { FC } from "react"
+
+const getWorkspaceParameters = async (workspace: Workspace) => {
+ const latestBuild = workspace.latest_build
+ const [templateVersionRichParameters, buildParameters] = await Promise.all([
+ getTemplateVersionRichParameters(latestBuild.template_version_id),
+ getWorkspaceBuildParameters(latestBuild.id),
+ ])
+ return {
+ templateVersionRichParameters,
+ buildParameters,
+ }
+}
+
+const WorkspaceParametersPage = () => {
+ const { workspace } = useWorkspaceSettingsContext()
+ const query = useQuery({
+ queryKey: ["workspaceSettings", workspace.id],
+ queryFn: () => getWorkspaceParameters(workspace),
+ })
+ const navigate = useNavigate()
+ const mutation = useMutation({
+ mutationFn: (formValues: WorkspaceParametersFormValues) =>
+ postWorkspaceBuild(workspace.id, {
+ transition: "start",
+ rich_parameter_values: formValues.rich_parameter_values,
+ }),
+ onSuccess: () => {
+ displaySuccess(
+ "Parameters updated successfully",
+ "A new build was started to apply the new parameters",
+ )
+ },
+ })
+
+ return (
+ <>
+
+ {pageTitle([workspace.name, "Parameters"])}
+
+
+ {
+ navigate("../..")
+ }}
+ />
+ >
+ )
+}
+
+export type WorkspaceParametersPageViewProps = {
+ data: Awaited> | undefined
+ submitError: unknown
+ isSubmitting: boolean
+ onSubmit: (formValues: WorkspaceParametersFormValues) => void
+ onCancel: () => void
+}
+
+export const WorkspaceParametersPageView: FC<
+ WorkspaceParametersPageViewProps
+> = ({ data, submitError, isSubmitting, onSubmit, onCancel }) => {
+ const styles = useStyles()
+
+ return (
+ <>
+
+ Workspace parameters
+
+
+ {data ? (
+
+ ) : (
+
+ )}
+ >
+ )
+}
+
+const useStyles = makeStyles(() => ({
+ pageHeader: {
+ paddingTop: 0,
+ },
+}))
+
+export default WorkspaceParametersPage
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx
index ef3a7ce4ad488..33f2e36019819 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsForm.tsx
@@ -4,56 +4,37 @@ import {
FormSection,
HorizontalForm,
} from "components/Form/Form"
-import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"
import { useFormik } from "formik"
import { FC } from "react"
import { useTranslation } from "react-i18next"
-import {
- useValidationSchemaForRichParameters,
- workspaceBuildParameterValue,
-} from "utils/richParameters"
-import { WorkspaceSettings, WorkspaceSettingsFormValue } from "./data"
import * as Yup from "yup"
import { nameValidator, getFormHelpers, onChangeTrimmed } from "utils/formUtils"
import TextField from "@material-ui/core/TextField"
+import { Workspace } from "api/typesGenerated"
+
+export type WorkspaceSettingsFormValues = {
+ name: string
+}
export const WorkspaceSettingsForm: FC<{
isSubmitting: boolean
- settings: WorkspaceSettings
+ workspace: Workspace
error: unknown
onCancel: () => void
- onSubmit: (values: WorkspaceSettingsFormValue) => void
-}> = ({ onCancel, onSubmit, settings, error, isSubmitting }) => {
+ onSubmit: (values: WorkspaceSettingsFormValues) => void
+}> = ({ onCancel, onSubmit, workspace, error, isSubmitting }) => {
const { t } = useTranslation("workspaceSettingsPage")
- const mutableParameters = settings.templateVersionRichParameters.filter(
- (param) => param.mutable,
- )
- const form = useFormik({
+
+ const form = useFormik({
onSubmit,
initialValues: {
- name: settings.workspace.name,
- rich_parameter_values: mutableParameters.map((parameter) => {
- const buildParameter = settings.buildParameters.find(
- (p) => p.name === parameter.name,
- )
- if (!buildParameter) {
- return {
- name: parameter.name,
- value: parameter.default_value,
- }
- }
- return buildParameter
- }),
+ name: workspace.name,
},
validationSchema: Yup.object({
name: nameValidator(t("nameLabel")),
- rich_parameter_values: useValidationSchemaForRichParameters(
- "createWorkspacePage",
- settings.templateVersionRichParameters,
- ),
}),
})
- const getFieldHelpers = getFormHelpers(
+ const getFieldHelpers = getFormHelpers(
form,
error,
)
@@ -76,36 +57,6 @@ export const WorkspaceSettingsForm: FC<{
/>
- {mutableParameters.length > 0 && (
-
-
- {mutableParameters.map((parameter, index) => (
- {
- await form.setFieldValue("rich_parameter_values." + index, {
- name: parameter.name,
- value: value,
- })
- }}
- parameter={parameter}
- initialValue={workspaceBuildParameterValue(
- settings.buildParameters,
- parameter,
- )}
- />
- ))}
-
-
- )}
)
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx
index 39c48363fbf63..049fc97f131d7 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx
@@ -6,39 +6,17 @@ import {
import WorkspaceSettingsPage from "./WorkspaceSettingsPage"
import { screen, waitFor, within } from "@testing-library/react"
import * as api from "api/api"
-import {
- MockWorkspace,
- MockTemplateVersionParameter1,
- MockTemplateVersionParameter2,
- MockWorkspaceBuildParameter1,
- MockWorkspaceBuildParameter2,
- MockWorkspaceBuild,
-} from "testHelpers/entities"
+import { MockWorkspace } from "testHelpers/entities"
test("Submit the workspace settings page successfully", async () => {
// Mock the API calls that loads data
jest
.spyOn(api, "getWorkspaceByOwnerAndName")
.mockResolvedValueOnce(MockWorkspace)
- jest
- .spyOn(api, "getTemplateVersionRichParameters")
- .mockResolvedValueOnce([
- MockTemplateVersionParameter1,
- MockTemplateVersionParameter2,
- ])
- jest
- .spyOn(api, "getWorkspaceBuildParameters")
- .mockResolvedValueOnce([
- MockWorkspaceBuildParameter1,
- MockWorkspaceBuildParameter2,
- ])
// Mock the API calls that submit data
const patchWorkspaceSpy = jest
.spyOn(api, "patchWorkspace")
.mockResolvedValue()
- const postWorkspaceBuildSpy = jest
- .spyOn(api, "postWorkspaceBuild")
- .mockResolvedValue(MockWorkspaceBuild)
// Setup event and rendering
const user = userEvent.setup()
renderWithWorkspaceSettingsLayout(, {
@@ -53,18 +31,6 @@ test("Submit the workspace settings page successfully", async () => {
const name = within(form).getByLabelText("Name")
await user.clear(name)
await user.type(within(form).getByLabelText("Name"), "new-name")
- const parameter1 = within(form).getByLabelText(
- MockWorkspaceBuildParameter1.name,
- { exact: false },
- )
- await user.clear(parameter1)
- await user.type(parameter1, "new-value")
- const parameter2 = within(form).getByLabelText(
- MockWorkspaceBuildParameter2.name,
- { exact: false },
- )
- await user.clear(parameter2)
- await user.type(parameter2, "1")
await user.click(within(form).getByRole("button", { name: "Submit" }))
// Assert that the API calls were made with the correct data
await waitFor(() => {
@@ -72,11 +38,4 @@ test("Submit the workspace settings page successfully", async () => {
name: "new-name",
})
})
- expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, {
- transition: "start",
- rich_parameter_values: [
- { name: MockTemplateVersionParameter1.name, value: "new-value" },
- { name: MockTemplateVersionParameter2.name, value: "1" },
- ],
- })
})
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx
index ac7ea30e73cad..0e3fc4f06dec4 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.tsx
@@ -1,28 +1,27 @@
-import { getErrorMessage } from "api/errors"
-import { displayError } from "components/GlobalSnackbar/utils"
import { Helmet } from "react-helmet-async"
-import { useTranslation } from "react-i18next"
import { useNavigate, useParams } from "react-router-dom"
import { pageTitle } from "utils/page"
-import { useUpdateWorkspaceSettings, useWorkspaceSettings } from "./data"
import { useWorkspaceSettingsContext } from "./WorkspaceSettingsLayout"
import { WorkspaceSettingsPageView } from "./WorkspaceSettingsPageView"
+import { useMutation } from "@tanstack/react-query"
+import { displaySuccess } from "components/GlobalSnackbar/utils"
+import { patchWorkspace } from "api/api"
+import { WorkspaceSettingsFormValues } from "./WorkspaceSettingsForm"
const WorkspaceSettingsPage = () => {
- const { t } = useTranslation("workspaceSettingsPage")
const { username, workspace: workspaceName } = useParams() as {
username: string
workspace: string
}
const { workspace } = useWorkspaceSettingsContext()
- const { data: settings, error, isLoading } = useWorkspaceSettings(workspace)
const navigate = useNavigate()
- const updateSettings = useUpdateWorkspaceSettings(workspace.id, {
- onSuccess: ({ name }) => {
- navigate(`/@${username}/${name}`)
+ const mutation = useMutation({
+ mutationFn: (formValues: WorkspaceSettingsFormValues) =>
+ patchWorkspace(workspace.id, { name: formValues.name }),
+ onSuccess: (_, formValues) => {
+ displaySuccess("Workspace updated successfully")
+ navigate(`/@${username}/${formValues.name}/settings`)
},
- onError: (error) =>
- displayError(getErrorMessage(error, t("defaultErrorMessage"))),
})
return (
@@ -32,13 +31,11 @@ const WorkspaceSettingsPage = () => {
navigate(`/@${username}/${workspaceName}`)}
- onSubmit={updateSettings.mutate}
+ onSubmit={mutation.mutate}
/>
>
)
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.stories.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.stories.tsx
index cc32594a7c759..eb21ad342fb86 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.stories.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.stories.tsx
@@ -1,35 +1,19 @@
import { ComponentMeta, Story } from "@storybook/react"
-import {
- MockTemplateVersionParameter1,
- MockTemplateVersionParameter2,
- MockWorkspace,
- MockWorkspaceBuildParameter1,
- MockWorkspaceBuildParameter2,
-} from "testHelpers/entities"
+import { MockWorkspace } from "testHelpers/entities"
import {
WorkspaceSettingsPageView,
WorkspaceSettingsPageViewProps,
} from "./WorkspaceSettingsPageView"
+import { action } from "@storybook/addon-actions"
export default {
title: "pages/WorkspaceSettingsPageView",
component: WorkspaceSettingsPageView,
args: {
- formError: undefined,
- loadingError: undefined,
- isLoading: false,
+ error: undefined,
isSubmitting: false,
- settings: {
- workspace: MockWorkspace,
- buildParameters: [
- MockWorkspaceBuildParameter1,
- MockWorkspaceBuildParameter2,
- ],
- templateVersionRichParameters: [
- MockTemplateVersionParameter1,
- MockTemplateVersionParameter2,
- ],
- },
+ workspace: MockWorkspace,
+ onCancel: action("cancel"),
},
} as ComponentMeta
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.tsx
index 99bf6342ab885..4460428e51362 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPageView.tsx
@@ -1,30 +1,24 @@
import { makeStyles } from "@material-ui/core/styles"
-import { AlertBanner } from "components/AlertBanner/AlertBanner"
-import { Loader } from "components/Loader/Loader"
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"
-import { FC } from "react"
+import { ComponentProps, FC } from "react"
import { useTranslation } from "react-i18next"
-import { WorkspaceSettings, WorkspaceSettingsFormValue } from "./data"
import { WorkspaceSettingsForm } from "./WorkspaceSettingsForm"
+import { Workspace } from "api/typesGenerated"
export type WorkspaceSettingsPageViewProps = {
- formError: unknown
- loadingError: unknown
- isLoading: boolean
+ error: unknown
isSubmitting: boolean
- settings: WorkspaceSettings | undefined
+ workspace: Workspace
onCancel: () => void
- onSubmit: (formValues: WorkspaceSettingsFormValue) => void
+ onSubmit: ComponentProps["onSubmit"]
}
export const WorkspaceSettingsPageView: FC = ({
onCancel,
onSubmit,
- isLoading,
isSubmitting,
- settings,
- formError,
- loadingError,
+ error,
+ workspace,
}) => {
const { t } = useTranslation("workspaceSettingsPage")
const styles = useStyles()
@@ -35,17 +29,13 @@ export const WorkspaceSettingsPageView: FC = ({
{t("title")}
- {loadingError && }
- {isLoading && }
- {settings && (
-
- )}
+
>
)
}
diff --git a/site/src/pages/WorkspaceSettingsPage/data.ts b/site/src/pages/WorkspaceSettingsPage/data.ts
deleted file mode 100644
index 46e72b5b33616..0000000000000
--- a/site/src/pages/WorkspaceSettingsPage/data.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { useMutation, useQuery } from "@tanstack/react-query"
-import {
- getWorkspaceBuildParameters,
- getTemplateVersionRichParameters,
- patchWorkspace,
- postWorkspaceBuild,
-} from "api/api"
-import { Workspace, WorkspaceBuildParameter } from "api/typesGenerated"
-
-const getWorkspaceSettings = async (workspace: Workspace) => {
- const latestBuild = workspace.latest_build
- const [templateVersionRichParameters, buildParameters] = await Promise.all([
- getTemplateVersionRichParameters(latestBuild.template_version_id),
- getWorkspaceBuildParameters(latestBuild.id),
- ])
- return {
- workspace,
- templateVersionRichParameters,
- buildParameters,
- }
-}
-
-export const useWorkspaceSettings = (workspace: Workspace) => {
- return useQuery({
- queryKey: ["workspaceSettings", workspace.id],
- queryFn: () => getWorkspaceSettings(workspace),
- })
-}
-
-export type WorkspaceSettings = Awaited>
-
-export type WorkspaceSettingsFormValue = {
- name: string
- rich_parameter_values: WorkspaceBuildParameter[]
-}
-
-const updateWorkspaceSettings = async (
- workspaceId: string,
- formValues: WorkspaceSettingsFormValue,
-) => {
- await Promise.all([
- patchWorkspace(workspaceId, { name: formValues.name }),
- postWorkspaceBuild(workspaceId, {
- transition: "start",
- rich_parameter_values: formValues.rich_parameter_values,
- }),
- ])
-
- return formValues // So we can get then on the onSuccess callback
-}
-
-export const useUpdateWorkspaceSettings = (
- workspaceId?: string,
- options?: {
- onSuccess?: (
- result: Awaited>,
- ) => void
- onError?: (error: unknown) => void
- },
-) => {
- return useMutation({
- mutationFn: (formValues: WorkspaceSettingsFormValue) => {
- if (!workspaceId) {
- throw new Error("No workspace id")
- }
- return updateWorkspaceSettings(workspaceId, formValues)
- },
- onSuccess: options?.onSuccess,
- onError: options?.onError,
- })
-}
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts
index c0df35ba41fc1..91dc24132f009 100644
--- a/site/src/testHelpers/entities.ts
+++ b/site/src/testHelpers/entities.ts
@@ -1532,6 +1532,11 @@ export const MockWorkspaceBuildParameter2: TypesGen.WorkspaceBuildParameter = {
value: "3",
}
+export const MockWorkspaceBuildParameter3: TypesGen.WorkspaceBuildParameter = {
+ name: MockTemplateVersionParameter3.name,
+ value: "my-database",
+}
+
export const MockWorkspaceBuildParameter5: TypesGen.WorkspaceBuildParameter = {
name: MockTemplateVersionParameter5.name,
value: "5",