diff --git a/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.test.tsx b/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.test.tsx
index 2aa396cb3b8ca..77ba216ea77cd 100644
--- a/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.test.tsx
+++ b/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.test.tsx
@@ -5,20 +5,20 @@ import { UpdateTemplateMeta } from "api/typesGenerated"
import { Language as FooterFormLanguage } from "components/FormFooter/FormFooter"
import { MockTemplate } from "../../testHelpers/entities"
import { renderWithAuth } from "../../testHelpers/renderHelpers"
-import {
- Language as FormLanguage,
- validationSchema,
-} from "./TemplateSettingsForm"
+import { getValidationSchema } from "./TemplateSettingsForm"
import { TemplateSettingsPage } from "./TemplateSettingsPage"
import i18next from "i18next"
+const { t } = i18next
+
const renderTemplateSettingsPage = async () => {
const renderResult = renderWithAuth(
, {
route: `/templates/${MockTemplate.name}/settings`,
path: `/templates/:templateId/settings`,
})
// Wait the form to be rendered
- await screen.findAllByLabelText(FormLanguage.nameLabel)
+ const label = t("nameLabel", { ns: "templateSettingsPage" })
+ await screen.findAllByLabelText(label)
return renderResult
}
@@ -39,28 +39,29 @@ const fillAndSubmitForm = async ({
icon,
allow_user_cancel_workspace_jobs,
}: Required
) => {
- const nameField = await screen.findByLabelText(FormLanguage.nameLabel)
+ const label = t("nameLabel", { ns: "templateSettingsPage" })
+ const nameField = await screen.findByLabelText(label)
await userEvent.clear(nameField)
await userEvent.type(nameField, name)
- const { t } = i18next
- const displayNameLabel = t("displayNameLabel", { ns: "templatePage" })
+ const displayNameLabel = t("displayNameLabel", { ns: "templateSettingsPage" })
const displayNameField = await screen.findByLabelText(displayNameLabel)
await userEvent.clear(displayNameField)
await userEvent.type(displayNameField, display_name)
- const descriptionField = await screen.findByLabelText(
- FormLanguage.descriptionLabel,
- )
+ const descriptionLabel = t("descriptionLabel", { ns: "templateSettingsPage" })
+ const descriptionField = await screen.findByLabelText(descriptionLabel)
await userEvent.clear(descriptionField)
await userEvent.type(descriptionField, description)
- const iconField = await screen.findByLabelText(FormLanguage.iconLabel)
+ const iconLabel = t("iconLabel", { ns: "templateSettingsPage" })
+ const iconField = await screen.findByLabelText(iconLabel)
await userEvent.clear(iconField)
await userEvent.type(iconField, icon)
- const maxTtlField = await screen.findByLabelText(FormLanguage.defaultTtlLabel)
+ const defaultTtlLabel = t("defaultTtlLabel", { ns: "templateSettingsPage" })
+ const maxTtlField = await screen.findByLabelText(defaultTtlLabel)
await userEvent.clear(maxTtlField)
await userEvent.type(maxTtlField, default_ttl_ms.toString())
@@ -79,8 +80,8 @@ const fillAndSubmitForm = async ({
describe("TemplateSettingsPage", () => {
it("renders", async () => {
const { t } = i18next
- const pageTitle = t("templateSettings.title", {
- ns: "templatePage",
+ const pageTitle = t("title", {
+ ns: "templateSettingsPage",
})
await renderTemplateSettingsPage()
const element = await screen.findByText(pageTitle)
@@ -90,8 +91,8 @@ describe("TemplateSettingsPage", () => {
it("allows an admin to delete a template", async () => {
const { t } = i18next
await renderTemplateSettingsPage()
- const deleteCta = t("templateSettings.dangerZone.deleteCta", {
- ns: "templatePage",
+ const deleteCta = t("dangerZone.deleteCta", {
+ ns: "templateSettingsPage",
})
const deleteButton = await screen.findByText(deleteCta)
expect(deleteButton).toBeDefined()
@@ -137,7 +138,7 @@ describe("TemplateSettingsPage", () => {
...validFormValues,
default_ttl_ms: 24 * 7,
}
- const validate = () => validationSchema.validateSync(values)
+ const validate = () => getValidationSchema().validateSync(values)
expect(validate).not.toThrowError()
})
@@ -146,7 +147,7 @@ describe("TemplateSettingsPage", () => {
...validFormValues,
default_ttl_ms: 0,
}
- const validate = () => validationSchema.validateSync(values)
+ const validate = () => getValidationSchema().validateSync(values)
expect(validate).not.toThrowError()
})
@@ -155,8 +156,10 @@ describe("TemplateSettingsPage", () => {
...validFormValues,
default_ttl_ms: 24 * 7 + 1,
}
- const validate = () => validationSchema.validateSync(values)
- expect(validate).toThrowError(FormLanguage.ttlMaxError)
+ const validate = () => getValidationSchema().validateSync(values)
+ expect(validate).toThrowError(
+ t("ttlMaxError", { ns: "templateSettingsPage" }),
+ )
})
it("allows a description of 128 chars", () => {
@@ -165,7 +168,7 @@ describe("TemplateSettingsPage", () => {
description:
"Nam quis nulla. Integer malesuada. In in enim a arcu imperdiet malesuada. Sed vel lectus. Donec odio urna, tempus molestie, port",
}
- const validate = () => validationSchema.validateSync(values)
+ const validate = () => getValidationSchema().validateSync(values)
expect(validate).not.toThrowError()
})
@@ -175,7 +178,9 @@ describe("TemplateSettingsPage", () => {
description:
"Nam quis nulla. Integer malesuada. In in enim a arcu imperdiet malesuada. Sed vel lectus. Donec odio urna, tempus molestie, port a",
}
- const validate = () => validationSchema.validateSync(values)
- expect(validate).toThrowError(FormLanguage.descriptionMaxError)
+ const validate = () => getValidationSchema().validateSync(values)
+ expect(validate).toThrowError(
+ t("descriptionMaxError", { ns: "templateSettingsPage" }),
+ )
})
})
diff --git a/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.tsx b/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.tsx
index e157e63880fa3..21816f6a8780b 100644
--- a/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.tsx
+++ b/site/src/pages/TemplateSettingsPage/TemplateSettingsPage.tsx
@@ -2,17 +2,15 @@ import { useMachine } from "@xstate/react"
import { useOrganizationId } from "hooks/useOrganizationId"
import { FC } from "react"
import { Helmet } from "react-helmet-async"
+import { useTranslation } from "react-i18next"
import { useNavigate, useParams } from "react-router-dom"
import { pageTitle } from "util/page"
import { templateSettingsMachine } from "xServices/templateSettings/templateSettingsXService"
import { TemplateSettingsPageView } from "./TemplateSettingsPageView"
-const Language = {
- title: "Template Settings",
-}
-
export const TemplateSettingsPage: FC = () => {
const { template: templateName } = useParams() as { template: string }
+ const { t } = useTranslation("templateSettingsPage")
const navigate = useNavigate()
const organizationId = useOrganizationId()
const [state, send] = useMachine(templateSettingsMachine, {
@@ -34,7 +32,7 @@ export const TemplateSettingsPage: FC = () => {
return (
<>
- {pageTitle(Language.title)}
+ {pageTitle(t("title"))}
= ({
}) => {
const classes = useStyles()
const isLoading = !template && !errors.getTemplateError
- const { t } = useTranslation("templatePage")
+ const { t } = useTranslation("templateSettingsPage")
if (isDeleted) {
return
}
return (
-
+
{Boolean(errors.getTemplateError) && (
@@ -78,24 +78,22 @@ export const TemplateSettingsPageView: FC = ({
/>
- {t("templateSettings.dangerZone.dangerZoneHeader")}
+ {t("dangerZone.dangerZoneHeader")}
- {t("templateSettings.dangerZone.deleteTemplateHeader")}
+ {t("dangerZone.deleteTemplateHeader")}
-
- {t("templateSettings.dangerZone.deleteTemplateCaption")}
-
+ {t("dangerZone.deleteTemplateCaption")}
diff --git a/site/src/util/formUtils.ts b/site/src/util/formUtils.ts
index 790e070341c5c..c76010e81b394 100644
--- a/site/src/util/formUtils.ts
+++ b/site/src/util/formUtils.ts
@@ -14,7 +14,7 @@ import * as Yup from "yup"
export const Language = {
nameRequired: (name: string): string => {
- return `Please enter a ${name.toLowerCase()}.`
+ return name ? `Please enter a ${name.toLowerCase()}.` : "Required"
},
nameInvalidChars: (name: string): string => {
return `${name} must start with a-Z or 0-9 and can contain a-Z, 0-9 or -`
@@ -37,7 +37,6 @@ interface FormHelpers {
helperText?: ReactNode
}
-// backendErrorName can be used if the backend names a field differently than the frontend does
export const getFormHelpers =
(form: FormikContextType, error?: Error | unknown) =>
(
@@ -54,6 +53,7 @@ export const getFormHelpers =
`name must be type of string, instead received '${typeof name}'`,
)
}
+
const apiErrorName = backendErrorName ?? name
// getIn is a util function from Formik that gets at any depth of nesting